Frage bezüglich Matrix Multiplikation?



  • Wie stellst du fest, wieviel Nullen die Matrix hat?
    Mit null_zaehlen. Das Ergebnis hast du dann in zaehlen2

    Wieviel Nullen kann sie maximal haben?
    15 Sekunden Zeit:
    [dallidallimusik] ...............[/dallidallimusik]

    zaehlen2 = null_zaehlen (dim, matrix);
        do
        {   zahlen1 = zahlen2;
            multiplizieren (dim, matrix, matrix);
            zaehlen2 = null_zaehlen (dim, matrix);
        }
        while(zaehlen2 > zaehlen1);
    
        if (zaehlen2 == MAXIMAL_ANZAHL_NULLEN_IN_MATRIX)
          printf("Die Matrix ist nilpotent\n");
    


  • Erstmal vielen Danke bis hierhin Dirk hast mir eine Menge weitergeholfen, aber ich glaube ich stell jetzt eine sau blöde Frage 😃 Ich kenne doch gar nicht die Anzahl der maximalen Nullen, denn die ist ja Dimensions abhängig (2x2 Matrix 4, 3x3 Matrix 9, usw.) Also muss man ja noch vorher definieren, wie viele denn Maximal sind und am besten mit irgendner Schleife ja hoch rechnen lassen je nach Dimension oder nicht?

    int maxNullen = 0;
    for (i = 1; i < dim; i++)
    {
        maxNullen += i*(i+1);
    }
    

    Und dann kann ich doch erst wie ind einem Beispiel die If Bedinung einbauen oder nicht? 🙂 Ich hoffe das klappt 😃



  • ES KLAPPT HURRA Danke schön!! 😃 🙂 Sag mal Dirk kannst du mir noch einen Gefallen tun und nur auf einen anderen Code rüber gucken, um zu sagen wo genau mein Fehler liegt 🙂

    #include<stdio.h>
    #include<math.h>
    
    int main (void)
    {
    	int a, b, c;
    	double diskri,erg1, erg2;
    
    	printf("\nProgramm zur Berechnung der Losungen");
    	printf("einer quadratischen Gleichung der Form ax^2+bx+c=0");
    
    	printf("\n\nBitte geben Sie a ein!");
    	scanf("%d", &a);
    	printf("\n\nBitte geben Sie b ein!");
    	scanf("%d", &b);
    	printf("\n\nBitte geben Sie c ein!");
    	scanf("%d", &c);
    
    	(a != 0) ? diskri = ((b*b)-( 4*a*c)) : printf("\nDas ist keine quadratische Gleichung!!!\n\n");
    
    	printf("\n\n%d, %d, %f, %f\n\n", (b*b), (4*a*c), diskri, sqrt(diskri));
    
    	if (diskri > 0)
    	{
    		erg1 = (((-1)*b)+sqrt(diskri) / (2*a));
    		erg2 = (((-1)*b)-sqrt(diskri) / (2*a));
    
    		printf("\n\nDie quadratische Gleichung hat die reellen Losungen x1=%f und x2=%f", erg1, erg2);
    	}
    
    	if (diskri < 0)
    	{
    		erg1 = (((-1)*b) + sqrt(-diskri) / (2*a));
    		erg2 = (((-1)*b) - sqrt(-diskri) / (2*a));
    
    		printf("\n\nDie quadratische Gleichung hat die komplexen Losungen x1=-2+2i und x2=-2-2i.", erg1, erg2);
    	}
    
    	if (diskri == 0)
    	{
    		erg1 = (((-1)*b) / (2*a));
    		printf("\n\nDie quadratische Gleichung hat nur die eine reelle Losung x=%f\n\n", erg1);
    	}
    	return 0;
    }
    

    Mein Problem bei dieser Aufgabe ist (abc Formel implemntieren), dass der Compiler durchgehend meckert und die Diskrimininante unbedingt double sein muss. Ich glaube da passieren mir die Fehler, denn wenn ich mir vor den Rechnung alles ausprinte stehen die Zahlen völlig richtig da.

    Also z.B. a=1 b=4 c=-5, dann ist ja b*b 16, 4*a*c = -20 und diskri = 36 also kommt er zur ersten If Anweisung diskri > 0 und rechnet -4+sqrt(36) / 2 sein Ergebnis ist aber -1 warum auch immer denn eigentlich steht doch -4+6=2 / 2 = 1 aber positiv.



  • Keine Schleife. Direkt berechnen.

    Du hast das alles so schön hin geschrieben.

    Wo steht die Dimension der Matrix?
    Wie berechnest du damit die Anzahl der Elemente?



  • Zu deiner quadratischen Gleichung.

    Was ist 1+2*3 ?

    Wenn deine Antwort keine Primzahl ist, darfst du weiter überlegen.



  • aaaaaaaaachsoo LOL dim*dim ist dann die Anzahl der Elemente und dann nur noch abfragen ob die alle 0 sind. Oh man das ist dann auch klar 😃

    max_nullen = dim * dim;
    if (zaehlen2 == max_nullen)
    	{
    		printf("Die Matrix\n\n");
    		ausgabe(dim, matrix);
    		printf("\nist nilotent\n");
    	}
    
    	if (zaehlen2 != max_nullen)
    	{
    		printf("Die Matrix\n\n");
    		ausgabe(dim, matrix);
    		printf("\nist nicht nilpotent\n");
    	}
    

    So sieht das aus, aber jetzt plötzlich stimmt das nicht mehr 😞 also in unserer Aufgabenbeschreibung haben wir zwei Matritzen die 0 1 1 / 0 0 1 / 0 0 0 die sollte nilpotent sein. Und die zweite 0 0 0 / 0 0 1 / 0 1 0 sollte nicht nilpotent sein... Bei mir werden beide als nicht nilpotent angezeigt 😃

    Zur quadratischen Gleichung: wie 1+2*3 ist ja Punkt vor Strich also 2*3=6 und 1+6 = 7 🙂 und alles habe ich doch ordentlich geklammert, dass sowieso nichts zu schnell ausgerechnet wird oder inwiefern meintest du das jetzt?



  • saschokkk schrieb:

    aaaaaaaaachsoo LOL dim*dim ist dann die Anzahl der Elemente und dann nur noch abfragen ob die alle 0 sind. Oh man das ist dann auch klar 😃

    printf("Die Matrix\n\n");
      ausgabe(dim, matrix);
      if (zaehlen2 == dim * dim)
        printf("\nist nilpotent\n");
      else // nur ein else. Was soll denn sonst anderes sein?
        printf("\nist nicht nilpotent\n");
    	}
    

    saschokkk schrieb:

    Zur quadratischen Gleichung: wie 1+2*3 ist ja Punkt vor Strich also 2*3=6 und 1+6 = 7 🙂 und alles habe ich doch ordentlich geklammert, dass sowieso nichts zu schnell ausgerechnet wird oder inwiefern meintest du das jetzt?

    Du rechnest falsch:

    -4+sqrt(36) / 2 = -4+6/2 = -4+3 = -1
                          ^ das must du zuerst rechnen  (da steht zwar ein Strich, ist aber als Punktrechnung gemeint)
    


  • Das lustige ist jetzt noch kurz zur Matrix ich verstehe ganz genau was du meinst, es wird mir aber trotzdem nicht richtig angezeigt 😞 Hier einmal der gesamte Code, kannst du den einmal durch compilieren? 😞

    Einmal mit Matrix A=
    (0 1 1)
    (0 0 1)
    (0 0 0)
    ist nilpotent
    Und mit Matrix B=
    (0 0 0)
    (0 0 1)
    (0 1 0)
    ist nicht nilpotent

    #include<stdio.h>
    #include<stdlib.h>
    
    void eingabe(int dim, float matrix[10][10]);
    void ausgabe(int dim, float matrix[10][10]);
    int null_zaehlen (int dim, float f_matrix[10][10]);
    void multiplizieren (int dim, float matrix1[10][10], float matrix2[10][10]);
    void kopieren (int dim, float f_matrix1[10][10], float f_matrix2[10][10]);
    
    int main (void)
    {
    	int i = 0, j = 0, dim, zaehlen1, zaehlen2, max_nullen;
    	float matrix[10][10];
    	float matrix2[10][10];
    
    	printf("Bitte geben Sie die Dimension der quadratischen Matrix ein (maximal 10)!\n");
    	scanf("%d", &dim);
    
    	eingabe(dim, matrix);
    
    	zaehlen2 = null_zaehlen (dim, matrix);
    	do
    	{   
    		zaehlen1 = zaehlen2;
    		multiplizieren (dim, matrix, matrix);
    		zaehlen2 = null_zaehlen (dim, matrix);
    	}
    	while(zaehlen2 > zaehlen1);
    	//kopieren(dim, matrix, matrix2);
    
    	printf("Die Matrix\n\n");
    	ausgabe(dim, matrix);
    	if (zaehlen2 == dim * dim)
    		printf("\nist nilpotent\n");
    	else 
    		printf("\nist nicht nilpotent\n");
    
    	return 0;
    }
    
    void eingabe(int dim, int matrix[10][10])
    {
    	int i, j;
    
    	for(i=0;i<dim;i++)
    		for(j=0;j<dim;j++)
    		{
    			printf("Bitte geben Sie das Element [%d][%d] ein!\n\n",i+1,j+1);
    			scanf("%f", &matrix[i][j]);
    		} 
    }
    
    void ausgabe(int dim, float f_matrix[10][10])
    {
    	int i, j;
    	for (i= 0 ; i < dim; i++)
    	{
    		printf("|");
    		for (j = 0 ; j < dim; j++)
    		{
    			printf("%3.f", f_matrix[i][j]);			
    		}
    		printf("|\n");
    	}
    	printf("\n");
    }
    
    int null_zaehlen (int dim, float f_matrix[10][10])
    {
    	int i, j, zaehler = 0;
    
    	for (i = 0; i < dim; i++)
    	{
    		for(j = 0; j < dim; j++)
    		{
    			if ( f_matrix[i][j] == 0)
    				zaehler++;
    		}
    	}
    	return zaehler;
    }
    
    void multiplizieren (int dim, float matrix1[10][10], float matrix2[10][10])
    {
    	int i, j, k;
    	float erg[10][10] = {0};
    	//ausgabe(dim, erg);
    	for (i = 0; i < dim; i++)
    	{
    		for (j = 0; j < dim; j++)
    		{
    			for (k = 0; k < dim; k++)
    			{
    				erg[i][j] += matrix1[i][k] * matrix2[k][j];
    			}
    		}
    	}
    	printf("\n");
    	//ausgabe(dim, erg);
    }
    
    void kopieren (int dim, float f_matrix1[10][10], float f_matrix2[10][10])
    {
    	int i, j;
    
    	for (i = 0; i < dim; i++)
    	{
    		for (j = 0; j < dim; j++)
    		{
    			f_matrix2[i][j] = f_matrix1[i][j];
    		}
    	}
    	//ausgabe(dim, f_matrix1);    //nur zum überprüfen ob es die gleichen sind
    	//ausgabe(dim, f_matrix2);
    }
    

    Also das ist ganz merkwürdig...

    Zur quadratischen Gleichung danke schön 🙂 Schön blind gewesen 😃



  • Ich glaub ich weiß auch wo der Fehler liegt ich multipliziere ja schön die Matrix mit sich selbst, aber das wird ja da gar nicht reingespeichert... das wird ja nur in erg aus der Multiplikationsfunktion gespeichert. Und da wir noch keine Pointer gemacht haben, kann ich ja gar nicht die Matrix zurück geben an die Main Lol...

    Also bleibt mir ja nichts anderes übrig als die global zu definieren? Wobei immer wieder betont wurde wie hässlich und schlecht das ist...



  • Mit erg hast du natürlich recht.

    Aaaaber mit

    saschokkk schrieb:

    Und da wir noch keine Pointer gemacht haben, kann ich ja gar nicht die Matrix zurück geben an die Main Lol...

    liegst du komplett falsch.
    Arrays werden immer als Pointer an Funktionen übergeben.

    Du kannst in multiplizieren noch kopieren aufrufen (erg nach matrix) oder
    multiplizieren umändern:

    void multiplizieren  (int dim, float matrix1[10][10], float matrix2[10][10], float erg[10][10]);
    

    Probier es aus

    C-Style ist zwar, das Ergebnis als ersten Paramter zu nehmen, da es dann mehr nach erg = mat1 * mat2 aussieht.



  • Ich meine im Vorlesungsstoff einen Pointer an sich kennen wir noch nicht, es gab nur eine Vorlesung über Arrays und das wars, dann kam eine über Sortier Algorhitmen und der Vorlesungsschluss, diese Aufgabe hier ist eine alte Klausuraufgabe, da ich grade dabei bin als Übung alle möglichen durch zu programmieren.

    Also das mit Kopieren klingt für mich am sinnvollsten, denn sonst würde man auch nirgendswo die Funktion brauchen 🙂

    Also sieht dann meine multiplizieren Funktion so aus?

    void multiplizieren (int dim, float matrix[10][10], float matrix2[10][10])
    {
    	int i, j, k;
    	float erg[10][10] = {0};
    	for (i = 0; i < dim; i++)
    	{
    		for (j = 0; j < dim; j++)
    		{
    			for (k = 0; k < dim; k++)
    			{
    				erg[i][j] += matrix[i][k] * matrix2[k][j];
    			}
    		}
    	}
    	printf("\n");
    	ausgabe(dim, erg);
    	kopieren(dim, erg, matrix);
    }
    

    Edit: Sauber es läuft ich kopiere jetzt einfach in die matrix[10][10] das rein und es klappt, nur habe ich wiederum damit ein Problemchen 😃 wenn ich per If Anweisung die damalige Matirx printen möchte, also die Matrix ... ist nilpotent dann steht das eine 0 Matrix weil wir ja die multiplizierte dort hin kopiert haben 😃 wie kann man das noch lösen? ^^



  • So nutzt du doch auch die "Rückgabe" von Arrays.
    Dann kannst du doch auch gleich erg in die Parameterliste packen.

    So vermeidest du das Überschreiben von deinen Matrizen.

    Sonst musst du die Matrix vorher sichern (in eine andere Matrix kopieren).



  • Ich versteh das nicht... Nirgendswo ist mehr ein kopieren drin, nirgendswo wird was überschrieben oder so trotzdem jetzt wenn ich wie bei dir gezeigt, erg[10][10] in die Funktion reinpacke wird matrix am Ende des Programmes überschrieben...

    #include<stdio.h>
    #include<stdlib.h>
    
    void eingabe(int dim, float matrix[10][10]);
    void ausgabe(int dim, float matrix[10][10]);
    int null_zaehlen (int dim, float f_matrix[10][10]);
    void multiplizieren (int dim, float matrix1[10][10], float matrix2[10][10]);
    void kopieren (int dim, float f_matrix1[10][10], float f_matrix2[10][10]);
    
    int main (void)
    {
    	int i = 0, j = 0, dim, zaehlen1, zaehlen2, max_nullen;
    	float matrix[10][10];
    	float matrix2[10][10] = {0};
    
    	printf("Bitte geben Sie die Dimension der quadratischen Matrix ein (maximal 10)!\n");
    	scanf("%d", &dim);
    
    	eingabe(dim, matrix);
    	zaehlen2 = null_zaehlen(dim, matrix);
    	do
    	{   
    		zaehlen1 = zaehlen2;
    		multiplizieren (dim, matrix, matrix);
    		zaehlen2 = null_zaehlen (dim, matrix);
    	}
    	while(zaehlen2 > zaehlen1);
    	printf("Die Matrix\n\n");
    	ausgabe(dim, matrix);
    	if (zaehlen2 == dim * dim)
    		printf("\nist nilpotent\n");
    	else 
    		printf("\nist nicht nilpotent\n");
    
    	return 0;
    }
    
    void eingabe(int dim, int matrix[10][10])
    {
    	int i, j;
    
    	for(i=0;i<dim;i++)
    		for(j=0;j<dim;j++)
    		{
    			printf("Bitte geben Sie das Element [%d][%d] ein!\n\n",i+1,j+1);
    			scanf("%f", &matrix[i][j]);
    		} 
    }
    
    void ausgabe(int dim, float f_matrix[10][10])
    {
    	int i, j;
    	for (i= 0 ; i < dim; i++)
    	{
    		printf("|");
    		for (j = 0 ; j < dim; j++)
    		{
    			printf("%3.f", f_matrix[i][j]);			
    		}
    		printf("|\n");
    	}
    	printf("\n");
    }
    
    int null_zaehlen (int dim, float f_matrix[10][10])
    {
    	int i, j, zaehler = 0;
    
    	for (i = 0; i < dim; i++)
    	{
    		for(j = 0; j < dim; j++)
    		{
    			if ( f_matrix[i][j] == 0)
    				zaehler++;
    		}
    	}
    	return zaehler;
    }
    
    void multiplizieren (int dim, float matrix1[10][10], float matrix2[10][10], float erg[10][10])
    {
    	int i, j, k;
    	float erg[10][10] = {0};
    	for (i = 0; i < dim; i++)
    	{
    		for (j = 0; j < dim; j++)
    		{
    			for (k = 0; k < dim; k++)
    			{
    				erg[i][j] += matrix1[i][k] * matrix2[k][j];
    			}
    		}
    	}
    	printf("\n");
    	//ausgabe(dim, erg);
    }
    
    void kopieren (int dim, float f_matrix1[10][10], float f_matrix2[10][10])
    {
    	int i, j;
    
    	for (i = 0; i < dim; i++)
    	{
    		for (j = 0; j < dim; j++)
    		{
    			f_matrix2[i][j] = f_matrix1[i][j];
    		}
    	}
    	//ausgabe(dim, f_matrix1);    //nur zum überprüfen ob es die gleichen sind
    	//ausgabe(dim, f_matrix2);
    }
    

    Was mache ich denn jetzt noch falsch??



  • Wieviel Paramter erwartet multiplizieren=
    Mit wie vielen rufst du es auf?

    Wo steht dann das Ergebnis drin?



  • Aber jetzt meckert er rum in der Main, dass erg nicht definiert ist? Muss ich jetzt int main (erg[10][10] schreiben? Es ist ja nicht so das ich faul bin und nur die Lösungen haben will, ich verstehe einfach von der Logik dass nicht wie ich dieses erg reinbekomme.

    WAS will ich jetzt machen damit es richtig passiert? Bitte einmal zwei Sätze, vielleicht schaff ich es dann selbst zu implementieren?

    Also der Prototyp oben in der Funktion ist angepasst, die Unterfunktion hat erg in der Parameterliste. Aber halt wenn ich die Funktion in der Main Aufrufe meckert er rum, dass kein erg definiert ist. Oder soll ich erg IN der main noch einmal definieren? Dann hat es ja ganz bestimmt nicht den ausgerechneten Wert, sondern ein ganz neuen... Also ich habe keinen blassen Schimmer...



  • Der Auruf von multiplizieren muss zur Definition von der Funktion passen.
    Der vierte Paramter muss nicht erg heissen. Du kannst dafür auch matrix2 nehmen.

    Weil die Frage auch kommt:
    Das Ergebnis steht dann in matrix2. Damit es dann wieder in in der Schleife multiplizieren kannst, muss es wieder nach matrix2.

    Aber du brauchst ja noch eine Kopie von deiner Originalmatrix.

    float matrix_org[10][10];  // Originalmatrix zur Eingabe
        float matrix[10][10];  // zum rechnen
        float erg[10][10] = {0};  //für das Ergebnis
    
        printf("Bitte geben Sie die Dimension der quadratischen Matrix ein (maximal 10)!\n");
        scanf("%d", &dim);
    
        eingabe(dim, matrix_org);  
        kopiere(dim, matrix_org, matrix);  //
        zaehlen2 = null_zaehlen(dim, matrix);
        do
        {  
            zaehlen1 = zaehlen2;
            multiplizieren (dim, matrix, matrix, erg);
            zaehlen2 = null_zaehlen (dim, erg);
            kopiere(dim, erg, matrix);
    
        }
        while(zaehlen2 > zaehlen1);
        printf("Die Matrix\n\n");
        ausgabe(dim, matrix_org);
    
    void multiplizieren (int dim, float matrix1[10][10], float matrix2[10][10], float erg[10][10])
    {
        float erg[10][10] = {0}; // Das ist jetzt falsch, da erg ja schon in der Paramterliste steht.
    

    Trotzdem musst du erg irgendwie auf 0 bekommen.
    Dazu wandelst du die Funktion eingabe etwas ab:

    void loeschen(int dim, float matrix[10][10])
    {
        int i, j;
    
        for(i=0;i<dim;i++)
            for(j=0;j<dim;j++)
            {
               matrix[ i][j] = 0;
            }
    }
    

    ⚠ Schau dir den Typ von matrix bei eingabe (Zeile 38) nochmal an.



  • Danke es klappt! 🙂 Auch für die Geduld 😃


Anmelden zum Antworten