Inversenberechnung wie in Matlab



  • Ich könnte mir vorstellen, dass Matlab die Zahl nur als unendlich anzeigt, aber sie intern halt "nur" sehr groß ist.

    (Ich kenne Matlab aber nicht, ausser den Namen. Solch ein Verhalten würde ich am ehesten nachvollziehen können.)



  • Skym0sh0 schrieb:

    Ich könnte mir vorstellen, dass Matlab die Zahl nur als unendlich anzeigt, aber sie intern halt "nur" sehr groß ist.

    Nein, Matlab arbeitet auch nur mit normalen doubles. Ein Überlauf nach oben ist "Inf".



  • Du meinst Gauss-Jordan?

    Gäbe es auch die Möglichkeit die Matrix zu verkleinern, sprich alle Einträge zum Beispiel durch 10000 zu teilen. Dann ist die Determinante nicht mehr unendlich...
    Komme ich mit diesem Ansatz zur Inversen meiner ursprünglichen Matrix?
    Irgendwie krieg ich das mit Matlab grade nicht hin.



  • Bashar schrieb:

    Skym0sh0 schrieb:

    Ich könnte mir vorstellen, dass Matlab die Zahl nur als unendlich anzeigt, aber sie intern halt "nur" sehr groß ist.

    Nein, Matlab arbeitet auch nur mit normalen doubles. Ein Überlauf nach oben ist "Inf".

    Okay, gut zu wissen 🙂

    Von welchem Zahlenbereich redest du denn hier?
    Denn selbst wenn du durch irgendeinen Faktor teilst, dann schiesst du auf der anderen Seite Genauigkeit weg...



  • Won schrieb:

    Gäbe es auch die Möglichkeit die Matrix zu verkleinern, sprich alle Einträge zum Beispiel durch 10000 zu teilen. Dann ist die Determinante nicht mehr unendlich...
    Komme ich mit diesem Ansatz zur Inversen meiner ursprünglichen Matrix?
    Irgendwie krieg ich das mit Matlab grade nicht hin.

    Ne, das wird nicht viel bringen. Die Determinante von großen Matrizen (Achtung, groß heißt bei Matrizen übrgens normalerweise nicht dass deren Einträge groß sind, sondern ihre Dimension) wird halt sehr schnell sehr groß. Bei einer 1000x1000 Diagonal-Matrix (was noch eine sehr kleine Matrix ist) mit lauter Zweiern auf der Diagonale (was auch sehr kleine Einträge sind!) ist die Determinante bereits ungefähr 1.0715e+301. Kratzt also bereits am obersten Bereich den double überhaupt darstellen kann.

    Won schrieb:

    Hallo,
    Weiß jemand was für ein Verfahren Matlab verwendet oder was ein stabiles Verfahren ist, was ich einsetzen kann?

    Matlab verwendet nicht nur ein Verfahren sondern (hinter den Kulissen) eine ganze Batterie an verschiedenen Verfahren zum Lösen eine Linearen Gleichungssystems (dazu äquivalent Matrix-Inverse). Dabei wird in Abhängigkeit vom Typ der Matrix das jeweils beste Verfahren gewählt, siehe hier (unter "more about" auf "Algorithms" klicken). Für das normale Gauß-Verfahren (mit Pivotisierung) brauchst du aber die Detereminante doch auch gar nicht?

    Du solltest auch überlegen ob du wirklich die Inverse berechnen willst, oder nicht doch ein Lineares Gleichungssystem lösen. Das ist sowohl in Sachen Laufzeit als auch Numerisch wesentlich angenehmer. Und in den meisten Fällen will man das und nicht die Inverse eine Matrix.



  • happystudent schrieb:

    Won schrieb:

    Gäbe es auch die Möglichkeit die Matrix zu verkleinern, sprich alle Einträge zum Beispiel durch 10000 zu teilen. Dann ist die Determinante nicht mehr unendlich...
    Komme ich mit diesem Ansatz zur Inversen meiner ursprünglichen Matrix?
    Irgendwie krieg ich das mit Matlab grade nicht hin.

    Ne, das wird nicht viel bringen. Die Determinante von großen Matrizen (Achtung, groß heißt bei Matrizen übrgens normalerweise nicht dass deren Einträge groß sind, sondern ihre Dimension) wird halt sehr schnell sehr groß. Bei einer 1000x1000 Diagonal-Matrix (was noch eine sehr kleine Matrix ist) mit lauter Zweiern auf der Diagonale (was auch sehr kleine Einträge sind!) ist die Determinante bereits ungefähr 1.0715e+301. Kratzt also bereits am obersten Bereich den double überhaupt darstellen kann.

    Ich kann deine Logik nicht nachvollziehen. Dein Beispiel zeigt doch gerade, dass es sehr viel bringt, die Matrix durch einen skalaren Faktor zu teilen, in deinem Fall durch 2.

    Ich weiß nicht, ob das die beste Möglichkeit ist, deshalb würde ich es nicht selbst vorschlagen, aber wirkungslos ist es mit Sicherheit nicht.

    Das Problem dürfte sein, dass man gar nicht weiß, wodurch man teilen soll, ohne dass man einen Unterlauf produziert.



  • Bashar schrieb:

    Ich kann deine Logik nicht nachvollziehen. Dein Beispiel zeigt doch gerade, dass es sehr viel bringt, die Matrix durch einen skalaren Faktor zu teilen, in deinem Fall durch 2.

    Ich weiß nicht, ob das die beste Möglichkeit ist, deshalb würde ich es nicht selbst vorschlagen, aber wirkungslos ist es mit Sicherheit nicht.

    Das Problem dürfte sein, dass man gar nicht weiß, wodurch man teilen soll, ohne dass man einen Unterlauf produziert.

    Du hast hier keine lineare Abbildung.

    Natürlich kannst du die Diagonal-Elemente der 1000x1000 Matrix durch 2 Teilen. Dann hast du 1*1*1*...*1 = 1. Danach musst du halt wieder alles mit 2^1000 multiplizieren um das Richtige Ergebnis zu erhalten. Von daher ist das komplett sinnlos. Durch noch größere Werte zu teilen (wie etwa 10000 wie vorgeschlagen) ist völlig aussichtslos, da du dann mit 10000^1000 multiplizieren müsstest um das korrekte Ergebnis zu erhalten - viel Spass dabei.

    Aber das ist ja auch kein Problem, du brauchst die Determinante überhaupt nicht um die Inverse zu berechnen. Eben weil die Determinante so schnell explodiert ist sie auch völlig ungeeignet für eine solche Berechnung. Das macht man höchstens mal bei irgendwelchen 2x2 Matritzen auf Blatt und Papier.



  • happystudent schrieb:

    Du hast hier keine lineare Abbildung.

    Echt?

    Natürlich kannst du die Diagonal-Elemente der 1000x1000 Matrix durch 2 Teilen. Dann hast du 1*1*1*...*1 = 1. Danach musst du halt wieder alles mit 2^1000 multiplizieren um das Richtige Ergebnis zu erhalten. Von daher ist das komplett sinnlos. Durch noch größere Werte zu teilen (wie etwa 10000 wie vorgeschlagen) ist völlig aussichtslos, da du dann mit 10000^1000 multiplizieren müsstest um das korrekte Ergebnis zu erhalten - viel Spass dabei.

    Dein Problem ist jetzt nicht wirklich, dass das in double nicht darstellbar ist? Das ist doch sowieso klar, deshalb machen wir den ganzen Zirkus doch überhaupt erst! Wir ziehen einen Faktor aus der Matrix raus, freuen uns über eine darstellbare Determinante, bilden die Inverse auf naive Weise und multiplizieren erst dann den Faktor wieder rein, bzw. teilen nochmal dadurch:

    (kA)1=1kA1(kA)^{-1} = \frac{1}{k} A^{-1}



  • Bashar schrieb:

    Echt?

    Ja echt.

    Dein Problem ist jetzt nicht wirklich, dass das in double nicht darstellbar ist?

    Die Inverse ist perfekt in double darstellbar, die Determinante eben nicht. Natürlich ist es ein Problem wenn ein Zwischenergebnis einen Overflow verursacht.

    Bashar schrieb:

    Das ist doch sowieso klar, deshalb machen wir den ganzen Zirkus doch überhaupt erst! Wir ziehen einen Faktor aus der Matrix raus, freuen uns über eine darstellbare Determinante, bilden die Inverse auf naive Weise und multiplizieren erst dann den Faktor wieder rein, bzw. teilen nochmal dadurch:

    (kA)1=1kA1(kA)^{-1} = \frac{1}{k} A^{-1}

    Und genau das funktioniert eben nicht, da du keine lineare Abbildung hast 🙄

    A=(a1000a2000a3)det(A)=a_1a_2a_3=c3(a_1ca_2ca_3c)A = \begin{pmatrix} a_1 & 0 & 0 \\ 0 & a_2 & 0 \\ 0 & 0 & a_3 \\ \end{pmatrix} \rightarrow \det(A) = a\_1\cdot a\_2\cdot a\_3 = c^3\cdot(\frac{a\_1}{c}\cdot\frac{a\_2}{c}\cdot\frac{a\_3}{c})

    Du kannst nicht einfach "durch 10000 teilen und dann am Ende wieder mit 10000 multiplizieren". Du teilst n mal durch c, also musst du auch mit c^n multiplizieren.

    Des weiteren ist deine Behauptung einfach falsch, wie sich durch ein einfaches Gegenbeispiel zeigen lässt:

    A=(200020002)(100A)1=(0.0050000.0050000.005).A = \begin{pmatrix} 2 & 0 & 0 \\ 0 & 2 & 0 \\ 0 & 0 & 2 \\ \end{pmatrix} \rightarrow (100\cdot A)^{-1} = \begin{pmatrix} 0.005 & 0 & 0 \\ 0 & 0.005 & 0 \\ 0 & 0 & 0.005 \\ \end{pmatrix} \, .

    Dagegen gilt:

    100A1=(500005000050).100\cdot A^{-1} = \begin{pmatrix} 50 & 0 & 0 \\ 0 & 50 & 0 \\ 0 & 0 & 50 \\ \end{pmatrix} \, .

    Deine Methode klappt also nicht, eben weil wir hier eine nichtlineare Abbildung haben. Es geht hier nicht mal um irgendwelche double/Overflow Geschichten, das klappt grundsätzlich nicht.



  • happystudent schrieb:

    Bashar schrieb:

    Echt?

    Ja echt.

    In welcher Form hättest du die Sarkasmus-Tags gerne?

    Dein Problem ist jetzt nicht wirklich, dass das in double nicht darstellbar ist?

    Die Inverse ist perfekt in double darstellbar, die Determinante eben nicht. Natürlich ist es ein Problem wenn ein Zwischenergebnis einen Overflow verursacht.

    Deshalb ist das ja auch kein Zwischenergebnis. Du stellst dich ganz schön an.

    Bashar schrieb:

    Das ist doch sowieso klar, deshalb machen wir den ganzen Zirkus doch überhaupt erst! Wir ziehen einen Faktor aus der Matrix raus, freuen uns über eine darstellbare Determinante, bilden die Inverse auf naive Weise und multiplizieren erst dann den Faktor wieder rein, bzw. teilen nochmal dadurch:

    (kA)1=1kA1(kA)^{-1} = \frac{1}{k} A^{-1}

    Und genau das funktioniert eben nicht, da du keine lineare Abbildung hast 🙄

    Na und wie das funktioniert. Vielleicht hältst du mal kurz mit deinen Reflexen inne und denkst unvoreingenommen darüber nach, ob die Formel stimmt.

    A=(a1000a2000a3)det(A)=a_1a_2a_3=c3(a_1ca_2ca_3c)A = \begin{pmatrix} a_1 & 0 & 0 \\ 0 & a_2 & 0 \\ 0 & 0 & a_3 \\ \end{pmatrix} \rightarrow \det(A) = a\_1\cdot a\_2\cdot a\_3 = c^3\cdot(\frac{a\_1}{c}\cdot\frac{a\_2}{c}\cdot\frac{a\_3}{c})

    Du kannst nicht einfach "durch 10000 teilen und dann am Ende wieder mit 10000 multiplizieren". Du teilst n mal durch c, also musst du auch mit n^c multiplizieren.

    Um die Determinante zu haben, ja. Ich will aber nicht die Determinante, ich will die Inverse. Die Determinante will ich schon deshalb nicht, weil sie nicht mit double darstellbar ist. Hab ich alles schonmal geschrieben, nochmal wiederhole ich es nicht.

    Des weiteren ist deine Behauptung einfach falsch, wie sich durch ein einfaches Gegenbeispiel zeigen lässt:

    A=(200020002)(100A)1=(0.0050000.0050000.005).A = \begin{pmatrix} 2 & 0 & 0 \\ 0 & 2 & 0 \\ 0 & 0 & 2 \\ \end{pmatrix} \rightarrow (100\cdot A)^{-1} = \begin{pmatrix} 0.005 & 0 & 0 \\ 0 & 0.005 & 0 \\ 0 & 0 & 0.005 \\ \end{pmatrix} \, .

    Dagegen gilt:

    100A1=(500005000050).100\cdot A^{-1} = \begin{pmatrix} 50 & 0 & 0 \\ 0 & 50 & 0 \\ 0 & 0 & 50 \\ \end{pmatrix} \, .

    Das war nicht meine Behauptung. Ich hab mit 1k\frac{1}{k} multipliziert.



  • Bashar schrieb:

    Das war nicht meine Behauptung. Ich hab mit 1k\frac{1}{k} multipliziert.

    Das bringt aber doch nichts. Wenn dein k so groß ist dass es den Wertebereich sprengt, ist das Endergebnis falsch.



  • Warum sollte k denn so groß sein? Vorgeschlagene Werte waren bisher 10000 und 2, das ist doch absolut im Rahmen.

    Das Problem ist wie gesagt, dass man ein passendes k nicht kennt. Mal überschlagen: Der double-Wertebereich geht so größenordnungsmäßig über 600 Zehnerpotenzen, bei einer 600x600-Matrix muss man also das richtige k schon auf einen Faktor von 10 genau treffen, um nicht nach oben oder nach unten rauszufliegen.


  • Mod

    happystudent schrieb:

    Das bringt aber doch nichts. Wenn dein k so groß ist dass es den Wertebereich sprengt, ist das Endergebnis falsch.

    Wieso sollte das nichts bringen? Nicht k sprengt den Wertebereich, sondern die Determinante von kAkA. Das kann schiefgehen, wenn der Wertebereich doppelt und dreifach nicht ausreicht, aber in sehr vielen Fällen kommt man damit weiter.



  • Bashar schrieb:

    Warum sollte k denn so groß sein? Vorgeschlagene Werte waren bisher 10000 und 2, das ist doch absolut im Rahmen.

    Das Problem ist wie gesagt, dass man ein passendes k nicht kennt. Mal überschlagen: Der double-Wertebereich geht so größenordnungsmäßig über 600 Zehnerpotenzen, bei einer 600x600-Matrix muss man also das richtige k schon auf einen Faktor von 10 genau treffen, um nicht nach oben oder nach unten rauszufliegen.

    Ok, also schauen wir uns nochmal an worauf sich meine ursprüngliche Antwort bezogen hat:

    Won schrieb:

    Allerdings kann Matlab die Inverse berechnen, meine vorprogrammierte Inversefunktion (die mithilfe der Adjunkten, und damit natürlich auch mit der Determinanten funktioniert) allerdings nicht, da da ja mit der Determinante weitergerechnet wird.

    Problem ist also, die Determinante ist zu groß. Darauf wurde vorgeschlagen bzw. gefragt:

    Won schrieb:

    Gäbe es auch die Möglichkeit die Matrix zu verkleinern, sprich alle Einträge zum Beispiel durch 10000 zu teilen. Dann ist die Determinante nicht mehr unendlich...

    worauf ich dann geantwortet hatte dass das nichts bringt um die Determinante zu verkleinern. Seine Idee war ja weiterhin die Methode mit Adjunkten zu benutzen, nur eben die Problematische Determinante klein zu halten. Die Methode ist ja:

    A1=1detAadj(A)A^{-1} = \frac{1}{\det{A}}\cdot adj(A)

    Angenommen man verkleinert jetzt die Determinante indem man einen Faktor aus der Matrix rauszieht, dann muss man diesen Faktor danach trotzdem wieder auf die Ergebnis-Matrix drauf multiplizieren um die finale Inverse zu bekommen.

    Die Inverse berechnet man einfach viel leichter komplett ohne Determinante. Und auch ohne einen Faktor rauszuziehen. Dass man einen numerisch günstigen Wert benutzt wird bereits durch Pivotisierung erreicht, dafür muss man gar nichts mehr aus der Matrix rausziehen.


  • Mod

    happystudent, wir sind hier alle Internetforenveteranen. Bitte versuch nicht, mit irgendwelchen Billigargumentationstricks zu kommen, bloß um eine Diskussion zu "gewinnen" (als ob es darum ginge 🙄 ), die nicht zu gewinnen ist (weil deine Ursprungsaussage sachlich falsch war). Manchmal liegt man eben einfach falsch. Dann mit solch durchschaubaren Tricks zu kommen ("aber in Wirklichkeit meinte ich das ganz anders!") schadet bloß deiner Reputation erheblich.

    Die vorgeschlagene Methode funktioniert, zumindest wenn man sich nicht absichtlich dumm stellt. Es gibt auch bessere Methoden.



  • Ich hatte kurz das Gefühl (nachdem ich deine Edits beim Vorposting teilweise beobachtet habe), dass du es verstanden hast, aber das ist offenbar doch nicht der Fall. 😞 Dein Posting fügt dem bisher gesagten absolut nichts neues hinzu, alle deine Bedenken hast du schonmal geäußert und ich habe sie schonmal irgendwo angesprochen, und ich habe wie gesagt keine Lust, das nochmal zu wiederholen. Schon gar nicht, wenn ich erstens *alles* wiederholen müsste und zweitens annehmen muss, dass es nicht auf fruchtbaren Boden fällt.



  • SeppJ schrieb:

    happystudent, wir sind hier alle Internetforenveteranen. Bitte versuch nicht, mit irgendwelchen Billigargumentationstricks zu kommen, bloß um eine Diskussion zu "gewinnen" (als ob es darum ginge 🙄 ), die nicht zu gewinnen ist (weil deine Ursprungsaussage sachlich falsch war). Manchmal liegt man eben einfach falsch. Dann mit solch durchschaubaren Tricks zu kommen ("aber in Wirklichkeit meinte ich das ganz anders!") schadet bloß deiner Reputation erheblich.

    Die vorgeschlagene Methode funktioniert, zumindest wenn man sich nicht absichtlich dumm stellt. Es gibt auch bessere Methoden.

    Also mir geht es nicht darum eine Diskussion zu gewinnen oder zu verlieren. Ich war bloß überzeugt dass es so ist, allerdings habe ich gerade meinen Denkfehler bemerkt - die Methode funktioniert tatsächlich.

    Als "Trick" war das aber nicht gedacht, ich hatte von Anfang an gemeint dass man die Inverse lieber ganz anders ausrechnen soll und nicht über Adjunkten. Die Begründung war falsch, ja. Hatte da zwei Sachen verwechselt.

    Bashar schrieb:

    Dein Posting fügt dem bisher gesagten absolut nichts neues hinzu, alle deine Bedenken hast du schonmal geäußert und ich habe sie schonmal irgendwo angesprochen, und ich habe wie gesagt keine Lust, das nochmal zu wiederholen.

    Hätte ich auch nicht 😉

    Entschuldigung auf jeden Fall, war mir der Sache so sicher dass ich nicht mehr richtig darüber nachgedacht habe. Das war blöd.

    @Topic: Sehr gut funktioniert (trotz allem) das einfache Gauß-Verfahren mit Pivotisierung. Dann muss man sich auch über nichts Gedanken machen (etwa wie groß ein k sein sollte das man rauszieht) weil das alles automatisch macht. Hab das mal nach diesem Code implementiert und hat immer sehr gut funktioniert, das würde ich dir empfehlen.



  • Danke für den Link, genau sowas hab ich gesucht 🙂
    Wenn ich das mit dem Faktor in Matlab ausprobiere (zum Beispiel B=A101B = A*10^{-1} ) dann verliere ich nicht sehr viel genauigkeit, wenn ich A1B1101A^{-1} - B^{-1} * 10^{-1} berechne. Da liegt der Fehler bei x1020x\cdot 10^{-20} für die einzelnen Einträge.
    Allerdings ist das natürlich ein berechtigter Einwand, dass man nicht weiß, wie groß der Multiplikationsfaktor sein muss. Es wird also auf die Gauß-Methode rauslaufen 🙂


Anmelden zum Antworten