Beiträge von Jakube

    Ich finde die Idee eine ganze Zeile mittels dem >>-Operator einzulesen generell nicht gut (Ich würde so etwas zumindest selber nicht machen).
    Durch Logging habe ich gesehen, dass ohnehin immer wieder die Zeile gelöscht wird. Außerdem wird die >>-Operation schon aufgerufen, ohne dass man irgendwelche Eingaben macht und im ersten Bruch steht dann ein ganz sonderbarer Wert.

    Ich würde einfach eine Zeile mit cin einlesen. Und dann diese ganz normal verarbeiten. Mein Beispielscode ist sicher nicht der beste, aber weiter möchte ich mich damit auch nicht befassen.

    Eine mögliche Eingabe wäre jetzt:

    Code
    1/5,2/5,4/3
    2,14/23,36/44

    (habe das Trennungssymbol durch einen Beistrich ersetzt)

    Hoffe das hilft dir weiter.

    P.S. Falls du nicht den ganzen Code posten möchtest, dann entferne doch einfach die uninteressanten Stellen. Z.B. das Lösen des Gleichungssystem hat ja nichts mit deiner Frage zu tun.

    Entweder meine Überlegung ist falsch, oder im Code ist ein offensichtlicher Fehler, den ich nicht sehe, so wie man manchmal den Wald vor lauter Bäumen nicht mehr sieht.

    Ich habe ein wenig hinein-gedebuggt und gleich 3 schwere Fehler entdeckt.

    Meine Entdeckungen:

    1) Das Kriterium i=0 ist natürlich nicht ausschlaggebend dafür, dass man nicht Diagonalisieren kann. Es kann ja sein, dass der maximale Wert in der ersten Zeile (i=0) steht. Abbrechen soll das ganze, wenn val=0 ist.

    2) Trotzdem konnte das Programm die Matrix nicht diagonalisieren. Ich habe mir jedes Mal die Matrix ausgegeben, und gesehen, dass in der Schleife bei j=1 nur noch negative Zahlen in der 2. Spalte sehen. Da du nach einem Eintrag suchst, der größer 0 ist, bricht das ganze natürlich ab. Am besten du benutzt die fabs-Funktion. Außerdem kannst du die Abfrage if (Matrix[i][j] != 0) weglassen (stört nicht, bringt aber auch nichts).

    Code
    for (i = j; i < max; i++)
    {
       if (fabs(Matrix[i][j]) > val)
       {
          val = fabs(Matrix[i][j]);
          pos = i;
       }
    }


    Dazu muss man auch die Mathebibliothek einbinden.

    Code
    #include <math.h>


    Nun konnte das Programm die Matrix diagonalisieren, allerdings gab es noch immer falsche Ergebnisse. Mit weiterem Logging fand ich:

    3) Beim Zeilentauschen habe ich die Variable tmp als Integer definiert. Falls in einer zu tauschen Zeile eine Kommazahl steht, wird diese einfach abgeschnitten. Es sollte natürlich

    Code
    float tmp;

    sein.
    Ich muss zugeben, dass ich für diesen Fehler verantwortlich bin ;).
    Lustig dass dieser Fehler nicht früher aufgetreten ist. Man kann nie genug testen!

    Code
    for (int i = 0; i < max; i++)
       delete [] Matrix[i];


    Mit diesen Anweisungen werden die Arrays gelöscht, auf die der Zeiger zeigt, nicht?

    Ja, stimmt.

    Code
    delete [] Matrix;


    Und hier wird der Zeiger auf die Arrays gelöscht
    Nur so, ob ich es verstanden habe, weil das mit den dynamischen mehrdimensionalen Arrays mir neu ist

    Stimmt fast. Es werden "die" Zeiger auf die Arrays gelöscht. Matrix ist im Grunde ja ein Array, in dem mehrere Zeiger gespeichert sind. Der erste Zeiger zeigt auf die erste Gleichung, der zweite Zeiger auf die 2. Gleichung, ... Dieses Array wird gelöscht.

    Wahrscheinlich hast du vergessen Ergebnis[0] und Ergebnis[1] zu tauschen:cool:


    Kann sein.


    Jetzt ist der Code schon ein wenig übersichtlicher und auch die Diagonalmatrix stimmt, wenn man z.B. die erste Zeile mit der 3.ten tauscht.

    Der Code für's Rückeinsetzen funktioniert aber nur, wenn man wirklich eine Diagonalmatrix hat, sprich die Matrix beginnt in der ersten Zeile mit 0 Nuller, die 2. Zeile beginnt mit 1 Nuller, die 3. mit 2 Nuller, usw. Die Zeilen gehören allerdings noch sortiert. Du kannst dir das leicht überlegen. Beim zurückeinsetzten fängt man ja in der letzten Zeile an (wo alle Faktoren bis auf einen 0 sind) und berechnet die Lösung für die letzte Variable. Dann geht man zur vorletzten Zeile (wo alle bis auf die letzten 2 Faktoren Null sind) und berechnet daraus die Lösung für die vorletzte Variable. Usw.

    Ich bin mir nicht sicher, ob dein Code für's Diagonalisieren immer funktioniert. Normalerweise geht man so vor.

    • Man sucht eine Zeile, bei der die 1. Position ungleich 0 ist. Diese Zeile vertauscht man mit der ersten Zeile. Danach zieht man diese Zeile mit einem geeigneten Faktor von den darunter ab. Damit sichert man sich, dass in der ersten Spalte zuerst ein Element ungleich 0 ist und dann lauter 0er.
    • Dann sucht man eine Zeile, die an der 2. Position ungleich 0 ist. (die erste Zeile dürfen wir nicht mehr verwenden). Diese Zeile tauscht man wieder mit der 2. Zeile.
      Danach zeiht man diese Zeile von den darunter ab. Jetzt sind die ersten 2 Zeilen und die ersten 2 Spalten in Diagonalgestalt.
    • Dann sucht man eine Zeile, die an der 3. Position ungleich 0 ist. usw.


    Findet man einmal keine geeignete Zeile, so bedeutet dass, das dieses mind. 1 Gleichung linear von den anderen abhängt und man kann diese Matrix nicht diagonalisieren. Es gibt keine eindeutige Lösung.

    Ich hab mal deinen Code ein wenig umgeschrieben.

    Hab nur mal kurz drauf geschaut.

    Ich glaub dass es genau umgekehrt ist, dass Diagonalisieren funktioniert nicht, das Rückeinsetzen schon.

    Zumindest, wenn ich die erste mit der 2ten Zeile vertausche

    Code
    Matrix vor Diagonalisieren
    0|0|1|3|10
    0|2|1|1|11
    1|1|1|1|15
     0|2|1|4|23


    dann bekomme ich folgende Diagonalmatrix:

    Code
    0|0|1|3|10
    0|2|0|-2|1
    1|0|0|-1|4.5
    0|0|0|3|12

    Wenn man von der Reihenfolge der Zeilen absieht, ist das zwar eine Diagonalmatrix, allerdings sind die Lösungen dieser Matrix nicht mehr die selben wie bei der ersten.

    Wieso suchst du eigentlich in der aktuellen Zeile nach dem ersten Eintrag ungleich Null? Solltest du nicht nach dem erste Eintrag ungleich Null in der Spalte suchen. Schau dir mal diesen PseudoCode an: http://en.wikipedia.org/wiki/Gaussian_elimination#Pseudocode, der gibt dir im Grunde genau vor, was zu tun ist. Anstatt argmax kannst du auch immer die erste Zeile, bei der, der Eintrag ungleich Null ist, nehmen.

    Ich werde den Code jetzt nicht näher anschauen, da mich deine Notation ziemlich verwirrt. (Eventuell dich auch.)
    Normalerweise speichert man ein Gleichungssystem im Format Matrix[Zeile][Spalte] und nicht Matrix[Spalte][Zeile].