Matrizenmultiplikation 1D-Array



  • Hallo Zusammen :),

    ich möchte eine Matrixmultiplikation mit eindimensionalen Arrays durchführen.
    Also
    z.B. die Matrix
    1 2
    3 4

    sieht so aus:
    A = {1, 2, 3, 4}

    Ich habe bereits die Addition und Subtraktion erfolgreich gelöst, aber meine Multiplikation liefert noch falsche Ergebnisse 😕
    Meine Matrixmultiplikation sieht folgendermaßen aus:

    int* Mult(Matrix M){
    int* result = new int[m * n];
    
                if (n == M.m) {
                    for (int i = 0; i < n; i++) {
                        for (int j = 0; j < M.m; j++) {
                            for (int k = 0; k < n; k++) {
                                result[k] += matrix[k] * M.matrix[k];
                            }
                        }
                    }
                    return result;
                }
    
                else{
                    cout << "ungültig: Spaltenanzahl stimmt nicht mit Zeilenanzahl überein !" << endl;
                }
    
            }
    

    der Aufruf erfolgt so: A.Mult(A);
    A ist bereits ein Objekt der Klasse Matrix.
    die Funktion Mult(Matrix M) wird in der Klasse Matrix definiert.
    m ist die Zeilenanzahl und n die Spaltenanzahl.

    Kann mir vielleicht jemand helfen, warum hier falsche Ergebnisse rauskommen?
    Bin langsam am verzweifeln 😞

    Schon mal ein großes Danke an euch 😉



  • Hallo

    Matrix-Matrix-Multiplikation sieht so aus. Du gehst durch eine Zeile der linken Matrix und durch eine Spalte der rechten. Dann bildest du Zelle für Zelle das Produkt und summierst diese auf.

    In deinem Code ist ersichtlich, dass du immer nur auf die ersten n (da 0≤k<n) Zellen zugreifst. Hast du dir bereits eine Methode überlegt, wie du die Matrix in einem eindimensionalen, kontinuierlichen Speicher abbilden könntest?

    Letztlich:
    - verwende kein new -> std::vector
    - verwende keine besitzende Zeiger
    - verwende nicht cout um Fehler zu vermitteln -> throw
    - verwende nicht Methoden wie Mult , wenn du auch Operator-Overloading verwenden könntest -> operator*

    LG



  • Fytch schrieb:

    Letztlich:
    - verwende kein new -> std::vector
    - verwende keine besitzende Zeiger
    - verwende nicht cout um Fehler zu vermitteln -> throw
    - verwende nicht Methoden wie Mult , wenn du auch Operator-Overloading verwenden könntest -> operator*

    LG

    leider sind das die meisten unserer Vorgaben.
    Kann man den Codeausschnitt noch verbessern, dass wenigstens die richtigen Ergebnisse erzielt werden?
    Das ganze Programm ist so aufgebaut.

    Ich weiß im Grunde, wie eine Multiplikation funktioniert.
    Das Umsetzen in Code fällt mir schwer, deswegen habe ich ja noch die falschen Ergebnisse 😕



  • Wenn du weißt, wie die Matrizenmultiplikation funktioniert, dann schreib den Algorithmus dafür erstmal in Pseudocode:

    Funktion: Mult(A, B)
        Wenn A.x ungleich B.y Dann
            Fehler
        Sonst
            ...
    

    Wenn du die Matrizenmultiplikation verstanden hast, dann dürfte das kein Problem sein. Und wenn du den Pseudocode hast, dann kannst du den danach recht einfach Zeile für Zeile in C++ übersetzen.



  • genau die Umsetzung ist ja leider mein Problem.
    Ich kann das alles am Blatt rechnen, mich verwirren die verschachtelten for-Schleifen, wann welches Ergebnis in result gespeichert wird..



  • Warum ist das Ergebnis einer Matrixmultiplikation ein int*?



  • Du schreibst Mult als freie Funktion. Woher kommt matrix?
    Warum wird M als value (d.h als Kopie) übergeben?



  • Die Funktion Mult wird in der Klasse Matrix geschrieben.
    matrix ist ein der Daten der Klasse und ist so in definiert: int* matrix;

    die Anweisung A.Add(A); wurde uns so vorgegeben.



  • codie schrieb:

    Ich kann das alles am Blatt rechnen, mich verwirren die verschachtelten for-Schleifen, wann welches Ergebnis in result gespeichert wird..

    Das kenn ich 🙂

    Leider zeigst Du ja nicht, was Matrix ist, oder was m und n sind.
    Zudem musst Du noch die Umrechnung von Zeile/Spalte nach Arrayindex hinfriemeln.

    Schau Dir an wie at aus Zeile/Spalte/Zeilenanzahl einen Index bastelt.
    Die for Schleifen evtl. mit Papier und Bleistift nachspielen?

    // friemelt arrayindex hin
    template<int cols>
    int& at(int* matrix, int row, int col) {
      return matrix[cols*row+col];
    }
    
    int main() {
      // das wikipedia beispiel:
      // https://de.wikipedia.org/wiki/Matrizenmultiplikation#Beispiel
      int a[2*3] = {3,2,1,
    				1,0,2};
      int b[3*2] = {1,2,
    				0,1,
    				4,0};
      int c[2*2] = {};
      for(int i=0; i<2; ++i) // fuer alle Zeilen in c (=as Zeilen)
    	for(int j=0; j<2; ++j) // fuer alle Spalten in c (=bs Spalten)
    	  for(int k=0; k<3; ++k) // fuer as Spalten und bs Zeilen
    		at<2>(c, i, j) += at<3>(a, i, k) * at<2>(b, k, j);
    }
    

Log in to reply