Unbekannter fehler Matrizen Multiplizieren
-
Oder sollte ich eher noch eine schlichtere set Funktion schreiben die nur 1 pushback macht und diese dann in eine fill Funktion einbinden?
Richtig. Zuerst ein fundamentaler Setter/Getter, dann Funktionen mit höherer Funktionalität. Und diese dann auch als non-member.
-
Geh nochmal einen Schritt zurück.
Möglicherweise schaust Du nochmal in Dein Buch, was dort z.B. zustd::vectorsteht.Wie würdest Du eine Funktion schreiben, die einen
std::vectorkomplett mit zufälligen Werten füllt?
Welche Member vonstd::vectorbenutzt Du dabei?Und in einem zweiten Schritt baust Du dann diese, bzw. ähnliche, Member in Deine Matrix.
-
Genau, und dann hängst Du mit 12 Membern rum, die erstmal die Basis-Iteratoren liefern, alles Proxy-Iteratoren (boost hilft hier ja!), die eines von zwei Proxy-Objekten halten, welche dann jeweils wieder 6 Member haben, um sich zu zu verhalten wie ein Vektor usw.. also 24 Funktionen und 2 Proxy-Klassen...
Iterators at their best! Iterate it baby!
-
mit iterator hab ich leider noch nichts gemacht.
Auf jeden fall ist mir gerade eine idee gekommen.
Könnte man nicht einfach die ersten beiden fächer vom vector dazu benutzen um die zahl der reihen und spalten zu speichern?Mir ist auch aufgefallen das die anzahl der spalten für die rechnung garnicht notwendig ist. Mann muss nur die index spalte angeben. Vieleicht mein Sone ja das mit redundant?!
Ich weiss allerdings nicht ob man im konstruktor die matrix dann überhaupt korrekt öffnen kann. Es würde ja vorraussetzen dann man einer variablen der klasse 2 werte übergeben müsste damit eben data=row*col möglich ist. Ich hoffe ihr versteht was ich meine

So oder so Beste Grüße
Photon
-
Iteratoren...Papperlapp.
Hier nochmal mein Beispiel von oben:
class mat{ int rows_, cols_; std::vector<int> data_; public: mat(int rows, int cols) : rows_(rows), cols_(cols), data_(rows*cols){} int rows() const { return rows_; } int cols() const { return cols_; } int& operator()(int col, int row) { return data_[ row*rows_+col ]; } const int& operator()(int col, int row) const { return data_[ row*rows_+col ]; } };Dazu ist es doch einfach eine (freie!)
fill()Funktion zu schreiben, oder?
Das alles ist keine Magie - bis auf einen überladenen Operator.Alternativ wäre eine einfache Funktion - wie Sone vorschlug:
class mat{ // .... public: // .... int& at(int col, int row) { return data_[ row*rows_+col ]; } const int& at(int col, int row) const { return data_[ row*rows_+col ]; } };
-
Photon schrieb:
Mir ist auch aufgefallen das die anzahl der spalten für die rechnung garnicht notwendig ist. Mann muss nur die index spalte angeben. Vieleicht mein Sone ja das mit redundant?!
Redundant heißt so viel wie überflüssig. Und die Anzahl der Spalten ist schon in der Größe des Arrays inbegriffen (Teilen der Größe des Arrays durch die Anzahl der Reihen ergibt ..).
Ich weiss allerdings nicht ob man im konstruktor die matrix dann überhaupt korrekt öffnen kann. Es würde ja vorraussetzen dann man einer variablen der klasse 2 werte übergeben müsste damit eben data=row*col möglich ist. Ich hoffe ihr versteht was ich meine

Du brauchst natürlich schon beide Konstruktorparameter, aber du musst die Anzahl der Spalte nicht als Member halten.
Das alles ist keine Magie - bis auf einen überladenen Operator.
Was ist an einer Operatorfunktion so grundlegend anders als bei einer 'gewöhnlichen' Memberfunktion? Beides Funktionen. Oder meinst du, das kennt er noch nicht?
-
- schrieb:
Das alles ist keine Magie - bis auf einen überladenen Operator.
Was ist an einer Operatorfunktion so grundlegend anders als bei einer 'gewöhnlichen' Memberfunktion? Beides Funktionen. Oder meinst du, das kennt er noch nicht?
Fast sicher.
Aber ich hab's schön kursiv gesetzt, damit er gleich weiss, wo in seinem Buch, bzw. seinen Büchern er nachschlagen muss.
-
- schrieb:
Redundant heißt so viel wie überflüssig. Und die Anzahl der Spalten ist schon in der Größe des Arrays inbegriffen (Teilen der Größe des Arrays durch die Anzahl der Reihen ergibt ..).
Ich würde es trotzdem speichern. Manchmal ist redundanz gut um den Compiler nicht zu verwirren. Und es gibt ganz gute Gründe, weswegen die Arraygröße davon abweichen kann

-
Moind leute ich grab den alten thread nochmal aus.
Ich hab ein problem mit der klasse. der compiler sagt mir das die 2 funktionen nicht im scope von main deklariert sind. Brauch ich da etwa ne prototype funktion? wenn ja wo pack ich die hin eigentlich in die klasse oder?
Liebe Grüße
Photon#include <iostream> #include <vector> class matrix{ private: unsigned int row, col; std::vector<unsigned int> data; public: matrix(unsigned int row,unsigned int col) : row(row),col(col),data(row*col){} void fill_matrix(matrix& mat){ for(unsigned int i=0;i<=row*col;i++){ mat.data.push_back(i); } } void print_matrix(const matrix& mat){ unsigned int a=0; for(unsigned int i=0;i<=col;i++){ for (unsigned int j=0;j<=row;j++){ std::cout<<mat.data[a]; } std::cout<<"\n"; a++; } } }; int main() { matrix a(3,3); fill_matrix(a); print_matrix(a); }
-
Schau dir nochmal an, was eine Memberfunktion ist und was das tolle an ihnen ist.
-
ok danke hab das mit den mebmer functions nochmal nachgeschlagen allerdings wird meine Matrix nur mit nullen gefüllt. Weis jemand warum?
#include <iostream> #include <vector> class matrix{ private: unsigned int row, col; std::vector<unsigned int> data; public: matrix(unsigned int row,unsigned int col) : row(row),col(col),data(row*col){} void fill_matrix(){ for(unsigned int i=0;i<row*col;i++){ data.push_back(i); } } void print_matrix(){ unsigned int a=0; for(unsigned int i=0;i<col;i++){ for (unsigned int j=0;j<row;j++){ std::cout<<data[a]; } std::cout<<"\n"; a++; } } }; int main() { matrix a(3,3); a.fill_matrix(); a.print_matrix(); }
-
eindeutig. beim fill fügst du einfach neue elemente hinten ran statt die bestehenden elemente zu ändern.
-
Welchen Wert hat denn a (Zeile 31)?
std::cout<<data[a];gib ihn doch einfach mal mit aus.
-
Danke leute das waren die beiden fehler
hatte auch genau an die beiden dinge gedacht und ein bisschen rumprobiert.Kann ich eigentlich was da in fill steht in den kontruktor packen?
Edit: habs einfach gemacht und hat geklappt

-
jo ist np, indem du im konstruktor "this->fill_matrix();" schreibst oder - wenn du die methode ansonsten gar nicht möchtest - einfach den code aus "fill_matrix" in den konstruktor hineinkopierst.
-
ok danke jetzt hab ich das nächste Problem wie schreibe ich memberfunktionen um sowas hier benutzen kann?
Matrix a; Matrix b; Matrix c = a*b;Also der logische ihnhalt der Funktion ist mir klar als non member function bekomm ich das auch hin in dem ich einfach die 2 Matrizen als Argument übergebe aber wie man was als member schreibt ist mir schleierhaft.
Hat jemand einen tip ?
-
das macht man in der regel so:
class matrix { // ... public: // ... matrix& operator*= (matrix const& rhs) { // code zum multiplizieren von (*this) mit rhs return *this; } }; const matrix operator* (matrix lhs, matrix const& rhs) // kopie im parameter machen -> codeoptimierung manchmal besser! { return lhs *= rhs; }matrizen zu multiplizieren ist ein wenig spezieller als z.b. vektoren zu addieren, da sich die tatsächliche grösse von (*this) in operator*= ändern kann. zur gewährleistung der strong guarantee, solltest du eine kopie machen (bei der instanzierung schon die grösse bestimmen!), da reinrechnen und dann (*this) mit der kopie swappen. das swappen auch in eine methode auslagern und dann bequem die datenzeiger swappen für mehr speed. und da deine matrix keine template-klasse ist, ab besten auch std::swap spezialisieren und deine eigene swap-methode aufrufen.
-
ok danke aber das ist noch zu hoch für mich. da muss ich erstmal im Lehrbuch weiter kommen. ich dachte vllt schreibt man in der klasse einfach einen Operator und dazu was passiert wenn man 2 Objekte der klasse mit diesem Operator verbindet.
Naja ich versuch mich mal reinzuarbeiten danke

-
Es ist mir nicht klar, ob du matrix-produkt oder das elementweise-Produkt haben willst (beides wird je nach Sprache mit * notiert). adfasdfs gezeigter Code passt gut zum elementweisen produkt und wird so mit Sicherheit auch beim matrix-produkt funktionieren. Allerdings ist es beim echten Matrixprodukt besser wegen der Probleme mit der Matrixgröße sowie aliasing op = mithilfe von op zu implementieren, und nicht wie üblich umgekehrt. Das spart eine Kopie (du brauchst bei dem hier gezeigten Ansatz immer 2 temporäre Kopien bei Benutzung von op*)
das wird heir ja gemacht. Nur nicht dein Code für a*b sondern a*=b und dann wird a*b mithilfe dieses operators implmentiert mittels:
c=ab
=>
c=a;
c=b;
-
Photon schrieb:
ok danke aber das ist noch zu hoch für mich. da muss ich erstmal im Lehrbuch weiter kommen. ich dachte vllt schreibt man in der klasse einfach einen Operator und dazu was passiert wenn man 2 Objekte der klasse mit diesem Operator verbindet.
Das geht auch. Wo wäre da denn der große Unterschied gegenüber dem, was adfasdf gezeigt hat, dass du das nicht mehr verstehst? Das ist doch das gleiche, wie als Member, bloß eben als freie Funktion.
Der Unterschied zwischen der Implementierung als Memberfunktion und als freie Funktion ist, dass bei der freien Funktion implizite Konvertierungen für den linksseitigen Parameter möglich sind (was man oft möchte!). Für ein paar Feinheiten der Operatorüberladung, die so detailliert wohl nicht in jedem Lehrbuch stehen dürften, siehe den mehrteiligen Magazinartikel, der hier beginnt:
http://www.c-plusplus.net/forum/232010