Blatt 5


Zuerst mit convvertToMatrix() in eine Matrix konvertieren ist nicht Sinn der Sache. Man sollte schon ueber die einzelnen Eintraege mit getEntry() iterieren. Man darf es natuerlich auch gerne effizienter machen und direkt auf der CRS-Struktur arbeiten.


hier stand mal gepoempel…gibt nen eignen thread dafuer


Ich bekomm beim Solver mit der Eingabe der Aufgabe 0 von Blatt 4 bei der L Matrix an Stelle (3,2) eine -0 statt einer 0. Ist das schlimm

Edit: Noch eine Frage: Es ist schon richtig, dass für die LU Zerlegung die Eingabematrix quadratisch und alle 3 Matritzen die gleiche Dimension haben müssen oder?


Nö. :slight_smile:

Jup.


Thx.

Müssen wir fürs Vorwärts / Rückwärtseinsetzen L bzw. U darauf testen ob sie tatsächlich (obere bzw. untere) Dreiecksmatritzen sind?


Nein.


Ich verstehe nicht so ganz, wie wir effizient die LU-Zerlegung machen sollen.

Wenn default-Matrizen für l und u angegeben werden (so wie in der main), dann haben diese die Größe 0. Sprich ich muss eine eigene Matrix anlegen und diese dann umkopieren bzw. l und u löschen und neu erstellen, weil ich nicht direkt auf l und u arbeiten kann.
Aber das ist doch irgendwie blöd?!?


Diese default Matritzen in der main versteh ich auch nicht ganz. Müsste man die nicht mit dem Konstruktor der Höhe und Breite der Matrix entgegennimmt (und die Dimensionen von m1 übergeben) erstellen?


Du kannst beispielsweise den Assignmentoperator der Matrix dafuer benutzen (der kuemmert sich darum, dass die Matrix die richtige Groesse hat):

void Solver::decomposeLU(const Matrix &m, Matrix &l, Matrix &u) {
...
    l = Matrix(size, size);
...
}

Allerdings kannst du davon ausgehen, dass in den Testcases nur Aufrufe folgender Form vorkommen:

Solver s;
Matrix a(10,10);
Matrix l(10,10);
Matrix u(10,10);
s.decomposeLU(a,l,u);

Also es reicht also auch, wenn man in der decomposeLU(…) einfach getEntry() bzw. setEntry() verwendet. Bitte verwendet aber auf kein “new” innerhalb der Methoden des Solvers.


Eine Matrix der Größe 0 mit dem parameterlosen Konstruktor anzulegen, ist kein großer overhead, wenn du dir die Implementierung mal anguckst. Du musst in deiner Methode auch nichts explizit (um-)kopieren oder löschen, das kannst du dir gleich zu Anfang vom operator= erledigen lassen, der dann letztlich (bei einer Matrix, in der noch keine Daten gespeichert waren) auch nicht wirklich mehr zu tun hat als Speicher zu allokieren und die Daten reinzuschreiben (und irgendwo muss das ja sowieso einmal gemacht werden).

(Hmm, war etwas zu langsam. Aber doppelt hält besser… ^^)


Ah, ok… Danke :wink:

In der main steht es nämlich so:

Matrix m("blablub");
Matrix l, u;

decomposeLU(m, l, u);

Muss die Ausgabe eigentlich so aussehen wie bei der Matrix? Weil meine ist ein bisschen angepasst und lesbarer (wie ich finde!) gestaltet habe :wink:

Ansonsten müsste ich das noch umändern…


Nein, muss nicht ganz genauso aussehen. Aber es sollte halt in irgendeiner Form lesbar sein :wink:


Kurze Frage ich kenn mich mit C++ ja nicht so aus, aber haette man fuer __values, _colIndices, _rowPtr, nicht besser einen vector (http://www.cplusplus.com/reference/stl/vector/) nehmen sollen? Weil den kann man resizen und Elemente einfuegen somit kann man sich das “reconstructing the internal arrays” sparen und ausserdem sagt der Stroustrup dass Arrays (in C++) “boesse” sind und man (im Besonderen bei variabler Laenge) einen vector vorziehen soll. Aber kann ja Gruende geben warum man hier keinen vector genommen hat, die waeren gut zu erfahren.


Wie stellst du dir das vor?
Hier gibt es Leute, die wundern sich darüber, dass Indizierungen auf einmal bei 0 anfangen. Und jetzt noch Vektoren anstatt Arrays zu verwenden würde die Leute doch vollends irritieren xD


Waere schoener gewesen.
(Man haete vllt auch _colIndices und _values in einem Array/vector speichern koennen)
ABER: mit std::vector kann man die Aufgabenstellung nicht erfuellen, da 0en nicht gespeichert werden duerfen, um Speicher zu sparen* und der std::vector gibt normalerweise keinen Speicher mehr zurueck.
Die einzige moeglichkeit den Speicher frei zu geben waere:
~vector(); vector(…);

*weisz nicht ob das sinnvoll ist. Beim staendigen Neuanlegen, fragementiert man den Speicher wahrs nur…


Das hab ich in der Rechnerübung auch schon mal blöd nachgefragt :smiley: - Ganz meiner Meinung :wink:

(v.a. wenn man sich die tolle setEntry anschaut!)