Zum Inhalt springen

Probleme mit Multiplikation


Empfohlene Beiträge

Geschrieben

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];

Geschrieben

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.

Geschrieben

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.

Geschrieben
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.

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.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...