Programm zur Matrixmultiplikation, brauche Hilfe!



  • Hallo,

    ich wurschtel mich grad durch ein kleines Programm welches eine beliebige Anzahl an Matrizen beliebiger Größe einlesen und miteinander multiplizieren soll. Ich arbeite momentan noch am Grundprinzip, deshalb habe ich noch nicht die Überprüfungen bezüglich genügend Speicher (bei malloc usw.) bzw. ob die Matrizen multiplizierbar sind etc. eingebaut.

    Das Hauptproblem momentan ist, dass ich nicht genau weiß, wie ich die Funktionen usw. verbinden soll, damit er auch das tut was ich will. Bis jetzt funktioniert das Einlesen bzw. Anzeigen der Matrizen wunderbar, aber die Multiplikation wird nicht ausgeführt.
    Das Hauptproblem ist wahscheinlich, dass die Matrizen in einer Unterfunktion erstellt werden, dann aber nicht richtig gespeichert und übergeben werden. Da komm ich jetzt nicht weiter (nach ettlichem Probieren hab ich jetzt die Übergabe der Parameter von "Multiplikation();" rausgelöscht, war nur noch wirrwarr)

    #include <stdio.h>
    #include <stdlib.h>
    
    int matrix(int tmp);
    int Ausgabe(int zeile, int spalte, int **matrix);
    int Multiplikation(int b, int d);
    
    /* Aktuelles Problem: Die Multiplikation wird nicht ausgeführt, Matrizen A und B erstellen
    um Multiplikation zu ermöglichen!*/
    
    int main()
    {
        int anzahl=0;
        int tmp=0;
        int a=0,b=0,c=0,d=0;
    
        printf("\tMatrixMultiplikation v.1.0\n\n");
    
        printf("Wie viele Matrizen? ");
        scanf("%i",&anzahl)
    
        for(tmp=0; tmp<anzahl;tmp++) //erstellte Matrizen werden nicht gespeichert?!
        {                            //mit Pointern arbeiten?
            matrix(tmp);
        }
    
        Multiplikation(); //Wie die Übergabe strukturieren?
    
        system("PAUSE");
        return 0;
    
    }
    
    int matrix(int tmp)
    {
        char z=(tmp+65);
        int i=0;
        int y=0;
    
        int spalte=0;
        int zeile=0;
    
        int **matrix;
    
        printf("Zeilen %c:",z);
        scanf("%i",&zeile);
        getchar();
    
        printf("\nSpalten %c:",z);
        scanf("%i",&spalte);
        getchar();
    
        matrix = (int**) malloc(zeile * sizeof(int*));
    
        for (i=0; i<zeile; i++)
        {
            matrix[i] = (int*) malloc(spalte * sizeof(int));
        }
    
        printf("Werte bitte zeilenweise eingeben!\n");
    
        for (i=0; i<zeile; i++)
        {
            printf("\nZeile %i:",(i+1));
    
            for (y=0; y<spalte; y++)
            {
            scanf("%i",&matrix[i][y]);
            }
        }
    
        Ausgabe(zeile, spalte, matrix);
    
        return 0;
    }
    
    int Ausgabe(int zeile, int spalte, int **matrix)
    {
        int i=0;
        int y=0;
    
        for (i=0; i<zeile; i++)
        {
            printf("\nZeile %i:",(i+1));
    
            for (y=0; y<spalte; y++)
            {
            printf("( %i )",matrix[i][y]);
            }
        }
    return;
    }
    
    int Multiplikation(int a,int b, int d)  // Wird momentan nicht ausgeführt bzw. angezeigt!
    {
        int i=0, j=0, k=0, z=0, temp=0;
        int *ptr = &z;
    
        C[a][d];
    
        for(j=0; j<d; j++)
        {
            for(k=0; k<b; k++)
            {
                temp = A[i][k]*B[k][j];
                *ptr += temp;
                printf("\nz: %i\n",z);
             }
        C[i][j] = z;
        z = 0;
        printf("\nFERTIG!\n");
        }
    
    printf("\nErgebnisMatrix C:\n");
    
    for(i=0; i<a; i++)
        {
            printf("\n");
            for(j=0; j<d; j++)
            {
                printf("( %i )",C[i][j]);
            }
    
        }
    }
    

    Vielen Dank im Voraus, bin über jede Hilfe sehr erfreut!

    Grüße



  • Das ist ja ein grausamer Code...
    Dass du überhaupt den Code kompilieren hast können verwundert mich ein bisschen.
    Da hat es ja noch etliche Fehler, wie nicht deklarierte Arrays, Falsche Parameter bei Funktionsaufrufen etc.



  • dann wär ich dir sehr dankbar wenn du mir die fehler ein wenig genauer aufzeigen könntest...ich bin autodidakt und über jeden hilfreichen hinweis dankbar...



  • #define READ_MATRIX_FROM_FILE   1
    #define READ_MATRIX_FROM_STRING 2
    #define READ_MATRIX_FROM_STDIN  0
    
    typedef struct _lolo_matrix{
    	int *data;
    	int rows;
    	int cols;
    }lolo_matrix;
    
    void plotMatrix(lolo_matrix m){
    	int cols;
    	while(m.rows--){
    		cols = m.cols;
    		while(cols--){
    			printf("%5d",*m.data++);
    		}
    		printf("\n");
    	}
    }
    
    lolo_matrix readMatrix(lolo_matrix matrix, void *f, int type){
    	int n = matrix.rows * matrix.cols,nn;
    	int *r;
    	if(matrix.data)
    		free(matrix.data);
    	matrix.data = malloc(sizeof(*matrix.data)*n);
    	r=matrix.data;
    	if(r){
    		switch(type){
    			case 0:
    				f = stdin;
    			case 1:
    				while(n--){
    					fscanf((FILE*)f,"%d",r++);
    				}
    			break;
    			case 2:
    				while(n--){
    					sscanf((char*)f,"%d%n",r++,&nn);
    					f+=nn;
    				}
    			break;
    		}
    	}
    	return matrix;
    }
    
    lolo_matrix matrixMultiply(lolo_matrix a,lolo_matrix b){
    	lolo_matrix c;
    	int l,ll,lll,cache;
    	int *aa,*bb,*cc,*bDataCache = b.data,*cDataCache;
    	c.cols = a.rows;
    	c.rows = b.cols;
    	c.data = malloc(sizeof(*c.data)*c.cols*c.rows);
    
    	if(c.data){
    		cDataCache = c.data;
    		lll = a.rows;
    		while(lll--){
    			ll = a.cols;
    			while(ll--){
    				l = c.cols;
    				cc = c.data-1;
    				aa = a.data++;
    				bb = b.data;
    				b.data+=b.cols;
    				cache = *aa;
    				while(l--){
    					*++cc += cache * *bb++;
    				}
    			}
    			b.data = bDataCache;
    			c.data += c.cols;
    		}
    		c.data = cDataCache;
    	}
    	return c;
    }
    
    int main(void) {
    	char *ma = "1  2  3\n"
                       "4  5  6\n";
    
    	char *mb = "6 -1\n"
                       "3  2\n"
                       "0 -3\n";
    
    	lolo_matrix matrixA;
    	matrixA.rows = 2;
    	matrixA.cols = 3;
    	matrixA.data = 0;
    
    	lolo_matrix matrixB;
    	matrixB.rows = 3;
    	matrixB.cols = 2;
    	matrixB.data = 0;
    
    	lolo_matrix matrixC;
    
    	matrixA = readMatrix(matrixA,ma,READ_MATRIX_FROM_STRING);
    	matrixB = readMatrix(matrixB,mb,READ_MATRIX_FROM_STRING);
    	matrixC = matrixMultiply(matrixA,matrixB);
    	plotMatrix(matrixC);
    	return 0;
    }
    

    habs nur mit den 2 test datensätzen versucht, kpl. ob das mit anderen auch klappt 😕

    lg lolo



  • oO z.65

    cache = *a.data++;
    

    dafür in z.52 aa raus und z.68 löschen

    da sind wie immer sicher noch mehr so schnitzer drin 🤡



  • na super, nächster bug, kann ich ja gleich die ghostbusters holen...
    z.53,54

    c.cols = b.cols;
        c.rows = a.rows;
    statt
        c.cols = a.rows;
        c.rows = b.cols;
    

    @chmbw schau dir doch mal das snippet an, da geht mir bei dir noch ne 3. schleife ab, hab den code aus dem rr forum kopiert und das const raus gemacht...

    #include <stdio.h>
    
    #define  n 3
    int main(void){
      int i,h,j;
      int m1[][n] = { {1,2,3}, {4,5,6}, {7,8,9} };
      int m2[][n] = { {1,2,3}, {4,5,6}, {7,8,9} };
      int m3[n][n];
    
      // zeilen in m1 und m3
      for(i=0; i < n; ++i)
      {
        // spalten in m3 und m2
        for(h=0; h < n; ++h)
        {
          int pre = 0;
          // spalte in m1; zeile in m2
          for(j=0; j < n; ++j)
          {
            pre += m1[i][j] * m2[j][h];
          }
          m3[i][h] = pre;
        }
      }
    
      for(i=0; i < n; ++i)
      {
        // spalten in m3 und m2
        for(h=0; h < n; ++h)
        {
          printf("%5d",m3[i][h]);
        }
        printf("\n");
      }
    
      return 0;
    }
    

    für die übergabe und rückgabe verwendest du am besten structuren hoffe das hilft etwas, btw. scheint so als würde dem compiler der code aus meinem letzten post nicht so gut gefallen, da kann man leider nix machen... 😉

    lg lolo



  • Hallo,

    mich hat gerade wieder die Coderitis gepackt. Hier hast du also noch eine Anregung, wie so etwas aussehen kann:

    #include <stdio.h>
    #include <stdlib.h>
    #include <assert.h>
    
    typedef struct matrix Matrix;
    
    struct matrix {
    	unsigned z, s; // Anzahl der Zeilen und der Spalten.
    	double* m; // Alternativ: double** m;
    };
    
    void cb() { // clear buffer, Eingabepuffer leeren.
    	int c = 0;
    
    	while ( c = getchar() != '\n' && c != EOF ) {};
    }
    
    void matrizen_freigabe ( Matrix** matrizen, unsigned n ) {
    	unsigned i = 0;
    
    	if ( matrizen == NULL ) return;
    	for ( i = 0; i < n; i++ )
    		free ( matrizen[i]->m ), free ( matrizen[i] );
    	free ( matrizen );
    }
    
    Matrix* neue_matrix ( unsigned z, unsigned s ) {
    	Matrix*	neu = calloc ( 1, sizeof ( *neu ) );
    
    	if ( neu == NULL ) return NULL;
    	if ( NULL == ( neu->m = malloc ( z*s*sizeof(double))))
    		free ( neu ), neu = NULL;
    	else
    		neu->z = z, neu->s = s;
    	return neu;
    }
    // Ergebnis = A * B
    int multiplikation ( Matrix* Ergebnis, Matrix* A, Matrix* B ) {
    	unsigned s, z;
    
    	assert ( A->z == B->z && A->s == B->s );
    	assert ( Ergebnis->z == A->z  &&  Ergebnis->s == A->s );
    	for ( z = 0; z < A->z; z++ ) {
    		for ( s = 0; s < A->s; s++ ) {
    			// Eventuell Wertebereichüberschreitung prüfen und 
    // bei Überschreitung 1 zurückgeben ...
    			Ergebnis->m[z*Ergebnis->s+s] = A->m[z*A->s+s] * B->m[z*B->s+s];
    		}
    	}
    	return 0;
    }
    
    int matrix_eingabe_dimension ( unsigned* z, unsigned* s, unsigned* n ) {
    	int ret = 0;
    
    	printf ( "Zeilen, Spalten, Anzahl: " );
    	ret = scanf ( "%u %u %u", z, s, n );
    	cb();
    	if ( ret != 3 ) 
    		return 1; // Fehler.
    	return 0; // Ok.
    }
    
    int matrix_eingabe_werte ( Matrix* M ) {
    	unsigned z = 0, s = 0;
    
    	for ( z = 0; z < M->z; z++ ) {
    			printf ( "Zeile %u von %u\n", z+1, M->z );
    			for ( s = 0; s < M->s; s++ ) {
    				printf ( "Wert %u von %u: ", s+1, M->s );
    				if ( 1 != scanf ( "%lf", &M->m[z*M->s+s] ))
    					return 1; // Fehler.
    			}
    		}
    	return 0;
    }
    
    int matrix_anzeige ( Matrix* M ) {
    	unsigned z, s;
    	for ( z = 0; z < M->z; z++ ) {
    		for ( s = 0; s < M->s; s++ ) {
    			printf ( "%lf ", M->m[z*M->s+s] );		
    		}
    		puts("");
    	}
    	return 0;
    }
    
    int eret ( char* s ) {
    	if ( s != NULL ) fprintf ( stderr, "%s\n", s );
    	return 1;
    }
    
    int main() {
    	Matrix** matrizen = NULL; // Zeigerarray, 'Container' für die Matrien.
    	Matrix* Ergebnis = NULL;
    	unsigned z = 0, s = 0, n = 0, i = 0;
    
    	if ( matrix_eingabe_dimension ( &z, &s, &n ))
    		return eret ( "Fehler in der Eingabe!" );
    
    	if ( n == 0 ) return 0;
    
    	if ( NULL == ( matrizen = calloc ( n, sizeof(Matrix*))))
    		return eret ( "Speichermangel!" );
    
    	for ( i = 0; i < n; i++ ) {
    		if ( NULL == ( matrizen[i] = neue_matrix ( z, s )))
    			return eret ( "Speichermangel!" );
    	}
    
    	for ( i = 0; i < n; i++ ) {
    		printf ( "Matrix Nr. %u ************************************ \n", i+1 );
    		if ( matrix_eingabe_werte ( matrizen[i] )) {
    			matrizen_freigabe ( matrizen, n );
    			return eret ( "Fehler in der Eingabe!" );
    		}
    	}
    	puts ( "Anzeige der eingegebenen Matrizen ..." );
    	for ( i = 0; i < n; i++ ) {
    		printf ( "Matrix Nr. %u ************************************ \n", i+1 );
    		matrix_anzeige ( matrizen[i] );
    	}
    
    	if ( NULL == ( Ergebnis = neue_matrix ( z, s ))) {
    		matrizen_freigabe ( matrizen, n );
    		return eret ( "Speichermangel!" );
    	}
    
    	if ( n == 1 ) matrix_anzeige ( matrizen[0] );
    	if ( n >= 2 ) multiplikation ( Ergebnis, matrizen[0], matrizen[1] );
    	if ( n > 2 ) {
    		for ( i = 2; i < n; i++ )
    			multiplikation ( Ergebnis, Ergebnis, matrizen[i] );
    	}
    
    	puts ( "Ergebnis der Multiplikation ..." );
    	matrix_anzeige ( Ergebnis );
    
    	matrizen_freigabe ( matrizen, n );
    	free ( Ergebnis->m );
    	free ( Ergebnis );
    	return 0; 
    }
    

    Gruß,
    B.B.



  • bist du dir sicher das die

    int multiplikation ( Matrix* Ergebnis, Matrix* A, Matrix* B )
    

    stimmt, denke das wär doch eher die addition 😕

    lg lolo



  • noobLolo schrieb:

    bist du dir sicher das die

    int multiplikation ( Matrix* Ergebnis, Matrix* A, Matrix* B )
    

    stimmt, denke das wär doch eher die addition 😕

    lg lolo

    Stimmt, der Inhalt dieser Funktion ist noch ein bisschen verbesserungsbedürftig.



  • Peinlich, peinlich ... ist schon ne Weile her, das ich Matrizenrechnung hatte.
    Naja, jetzt mal ohne das Eingabegedöns, die korrigierte Funktion und ein bisschen Initialisierung drum herum, das Zeigerarray macht auch nicht mehr so den Sinn:

    #include <stdio.h>
    #include <stdlib.h>
    #include <assert.h>
    
    typedef struct matrix Matrix;
    
    struct matrix {
    	unsigned z, s; // Anzahl der Zeilen und der Spalten.
    	double* m; // Alternativ: double** m;
    };
    
    // E = A * B
    void multiplikation ( Matrix* E, Matrix* A, Matrix* B ) {
    	unsigned s, z, k;
    	assert ( A->s == B->z );
    	for ( z = 0; z < A->z; z++ ) 
    		for ( s = 0; s < B->s; s++ )
    			for ( k = 0; k<A->s; k++ )
    					E->m[z*E->s+s] += A->m[z*A->s+k] * B->m[k*B->s+s]; 
    }
    
    int matrix_anzeige ( Matrix* M ) {
    	unsigned z, s;
    	for ( z = 0; z < M->z; z++ ) {
    		for ( s = 0; s < M->s; s++ ) {
    			printf ( "%8.3lf ", M->m[z*M->s+s] );		
    		}
    		puts("");
    	}
    	return 0;
    }
    
    int eret ( char* s ) {
    	if ( s != NULL ) fprintf ( stderr, "%s\n", s );
    	return 1;
    }
    
    int main() {
    	int z, s, k;
    	Matrix A = {0}, B = {0}, E = {0};
    	double a[] = { 1.0, 5, 2, 3 }, b[] = { 4, 1, 2, 1, 0, 3 }; // Diese Eingabe 
    	A.m = &a, B.m = &b,	A.z = 2, A.s = 2, B.z = 2, B.s = 3; // ist simuliert ;)
    
    	E.m = calloc ( A.z * B.s, sizeof( *E.m ) );
    	if ( E.m == NULL ) return eret ( "Speichermangel!" );
    	E.z = A.z, E.s = B.s;
    
    	multiplikation ( &E, &A, &B );
    	matrix_anzeige ( &E );
    
    	free ( E.m );
    	return 0;
    }
    

    Gruß,
    B.B.



  • habt vielen vielen dank für die klasse antworten! ich werde mich da jetzt mal durchwurschteln 😉


Anmelden zum Antworten