Lag Geschrieben 28. Dezember 2006 Geschrieben 28. Dezember 2006 Hallo allerseits, ich hoffe sehr ihr könnt mir weiterhelfen, da ich selbst das Problem trotz mehrere Anläufe nicht in den Griff bekomme. Die Aufgabe: Ziel ist es zwei Matrizen ( aus den Dateien matrix1.dat und matrix2.dat ) auslesen und diese auszugeben. Anschließend sollen die beiden miteinander multipliziert werden und anschließend wieder ausgegeben werden. Das auslesen und ausgeben funktioniert, jedoch finde ich keine Lösung für das multiplizieren zweier beliebiger Matritzen. Ich hoffe da könnt ihr mir weiterhelfen. Es folgt der Code: ( Das in diesem Fall 3 3 am Anfang gibt Zeilen und Spaltenzahl der Matrix an, das Programm soll jedoch auch für beliebe Matrizen funktionieren ) Matrix1.dat 3 3 8 2 1 3 4 2 9 2 5 Matrix2.dat 3 3 3 0 0 0 3 0 0 0 3 Das Programm: #include <stdio.h> #include <stdlib.h> int ReadMatrix(char *datei, struct matrix *); void printMatrix(FILE *fp, struct matrix); int MultiplyMatrix(struct matrix, struct matrix, struct matrix *); double *allocate_matrix(int nrow, int ncol); struct matrix /** Definition der Struktur Matrix ****/ { int nrow; int ncol; double *mat; }; int main(void) { int ret; struct matrix matrix1, matrix2, matrix3; ret = ReadMatrix("matrix1.dat", &matrix1); // Matrix einlesen if (ret < 0) return(ret); else { printf("Matrix 1: \n"); printMatrix(stdout, matrix1); } ret = ReadMatrix("matrix2.dat", &matrix2); // Einlesen der 2. Matrix if (ret < 0) return(ret); else { printf("Matrix 2: \n"); printMatrix(stdout, matrix2); } ret = MultiplyMatrix(matrix1, matrix2, &matrix3); // Matrixmultiplikation // Ausgabe der Multiplikation if (ret == -1) printf("Dimensionierungsfehler bei Zeilen und Spalten! \n\n"); else if (ret == -2) printf("Kann Speicher nicht allokieren ! \n\n"); else { printf("Matrix der Multiplikation: \n"); printMatrix(stdout, matrix3); } free(matrix1.mat); // Freigeben von belegtem Speicherplatz free(matrix2.mat); free(matrix3.mat); return(0); } int ReadMatrix(char *datei, struct matrix *m) { FILE *fp; int row, col; if ( (fp = fopen( datei, "r" )) == NULL ) { printf("\n%s konnte nicht geoeffnet werden.\n", "matrix1.dat"); fclose(fp); } else { fprintf(stdout, "\nKein Fehler beim Oeffnen \n"); fscanf(fp, "%d %d", &m->nrow, &m->ncol); m->mat = allocate_matrix(m->nrow,m->ncol); int x=0,i,j; for(i=1;i<=m->nrow;i++) for(j=0;j<m->ncol;j++) fscanf(fp,"%d",&m->mat[x++]); } return(0); } void printMatrix(FILE *fp, struct matrix m){ int i=0,j=0,x=0; for (i=0; i<m.ncol; i++) for (j=0; j<m.nrow; j++) { fprintf(fp, "%d ", m.mat[x++]); if(!(x % m.ncol)) fprintf(fp, "\n"); } } int MultiplyMatrix(struct matrix m1, struct matrix m2, struct matrix *m) { // Hier fehlt mir der Code zum multiplizieren der Matrix return 0; } double *allocate_matrix(int nrow, int ncol) /* Allokieren von Speicherplatz für eine Matrix mit Komponenten vom Typ double */ { int i, j; double *m; /* Allokiere Zeiger auf Matrixelemente */ m=(double *) malloc(nrow*ncol*sizeof(double)); if (!m) return 0; // Initialisiere als Einheitsmatrix for(i=0; i<nrow; i++) for(j=0; j<ncol; j++) { if (i == j) m[i+nrow*j] = 1.0; else m[i+nrow*j] = 0.0; } /* Return Zeiger auf Feld von Zeigern zu Zeilen */ return m; } Fehlgeschlagene Entwürfe für MultiplyMatrix: if(m1.ncol != m2.ncol || m1.ncol != m2.ncol) return -1; if(!(m->mat = allocate_matrix(m1.nrow,m1.ncol))) return -2; m->ncol = m1.ncol; m->nrow = m1.nrow; int i=1,j=1,x=0; /* int tmat1[m1.nrow][m1.ncol]; int tmat2[m1.nrow][m1.ncol]; for(i=1;i<=m1.nrow;i++){ for(j=1;j<=m1.ncol;j++){ tmat1[i-1][j-1] =m1.mat[((i-1)*m1.nrow +j) -1]; tmat2[i-1][j-1] =m2.mat[((i-1)*m1.nrow +j) -1]; } } printf("\t\t m1.nrow: %i; m1.ncol: %i \n",m1.nrow,m1.ncol); */ const int ix = m1.nrow; int tmat[ix][ix]; Zitieren
Klotzkopp Geschrieben 28. Dezember 2006 Geschrieben 28. Dezember 2006 Weißt du denn, wie man zwei Matrizen multipliziert? Ganz allgemein mathematisch, nicht in C? Zitieren
Bubble Geschrieben 28. Dezember 2006 Geschrieben 28. Dezember 2006 Die Rechenregel mit Beispiel findet Du z.B. in der Wikipedia oder in einer Formelsammlung. Diese Berechnungsvorschrift musst Du nun einfach in C umsetzen. Wichtig ist nur, dass die Spaltenzahl der linken Matrix gleich der Zeilenzahl der rechten Matrix ist, völlig beliebig dürfen die Matrizen also nicht sein. Zitieren
Lag Geschrieben 28. Dezember 2006 Autor Geschrieben 28. Dezember 2006 In Mathe ist das kein Problem. Ich hab für nen voriges Projekt auch 2 3X3 Matrizen miteinander multipliziert. for (i=0; i<3; i++) { for (j=0; j<3; j++) { for (n=0; n<3; n++) { m[j]=m[j] + m1[n]*m2[n][j]; } } } Das funktioniert hier jedoch nicht, wieso genau bin ich nicht sicher. Meines Wissens stehen die Werte jedoch nicht in Zeilen sondern einfach alle am Stück im Speicher. Ich bekomms leider halt nicht hin. Zitieren
Bubble Geschrieben 29. Dezember 2006 Geschrieben 29. Dezember 2006 Meines Wissens stehen die Werte jedoch nicht in Zeilen sondern einfach alle am Stück im Speicher. Ich bekomms leider halt nicht hin. Klar stehen die Werte im Speicher hintereinander. Zeile für Zeile. Bei der Ausgabe musstest Du das doch auch schon berücksichtigen. Überlege Dir doch zuerst, wie Du auf ein bestimmtes Element einer Matrix zugreifen kannst und schreibe dafür eine Funktion. Eine mögliche Funktion könnte (ungetestet) so aussehen (davon ausgehend, dass die Nummerierung der Zeilen und Spalten bei 0 und nicht bei 1 beginnt): double HoleMatrixEintrag(struct matrix *m, int Zeile, int Spalte) { return m->mat[(Zeile * m->ncol) + Spalte]; } Hierbei holst Du einen Wert aus einer Matrix, deren Inhalt zeilenweise direkt hintereinander im Speicher abgeklegt wurde, so dass Du genau wie bei einem Array darauf zugreifen kannst. Du musst aus der Zeilen- und Spaltenangabe nur den richtigen Index berechnen und diesen dann für den Zugriff verwenden. Zum Setzen von Einträgen (also für eine Funktion SetztMatrixEintrag) kannst Du analog vorgehen. Jetzt kannst Du Deine Multiplikationsfunktion mit Hilfe dieser beiden Hilfsfunktionen schreiben, die gleiche Methode direkt einbauen (ohne Funktionsaufrufe) oder durch die Verwendung von Pointern versuchen, die Anzahl der für die Zugriffe nötigen Operationen zu reduzieren. Zitieren
Lag Geschrieben 30. Dezember 2006 Autor Geschrieben 30. Dezember 2006 Funzt nun. Vielen Dank Zitieren
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.