Frage bezüglich Matrix Multiplikation?



  • Du machst jetzt in der j Schleife noch eine k-Schleife (genau so wie j).

    Die Indizes hast du ja eben richtig hin geschrieben.



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

    So? weil da haut bei mir noch irgendwas nicht ganz hin 😃

    Edit: LOL += vergessen 😃 Ooookay also dann funktioniert es jetzt ja 🙂

    Meine Aufgabe ist es jetzt die Main vernünftig noch hinzubekommen.

    1. Matrix eingeben (klappt)
    2. Nullen zählen (klappt) also ich speichere das zur Zeit als int ab
    3. Matrix mit sich selbst multiplizieren (klappt)
    4. Neue Nullen zählen (klappt) damit ich die gleich unterscheiden kann nenne ich die zaehlen2

    und ab jetzt soll ich solange weiter multiplizieren bis nur noch Nullen kommen, also habe ich eher an eine do while Schleife gedacht. Nach dem Motto

    do
    	{
    		zaehlen1 = null_zaehlen (dim, matrix);
    		multiplizieren (dim, matrix, matrix);
    		zaehlen2 = null_zaehlen (dim, matrix);
    	}
    	while(zaehlen2 > zaehlen1);
    

    Kann das klappen? 😃 Weil es muss noch was rein nach dem Motto wenn zaehlen2 <= zaehlen1 ist DANN soll abgebrochen werden und geschrieben ist nicht nilpotent



  • Ja, kann klappen.

    Verbesserungsvorschlag: Ab dem zweiten Durchlauf kommt für zahlen1 auch nur der Wert von zahlen2 vom vorhergehenden Durchlauf.

    zaehlen2 = null_zaehlen (dim, matrix);
        do
        {   zahlen1 = zahlen2;
            multiplizieren (dim, matrix, matrix);
            zaehlen2 = null_zaehlen (dim, matrix);
        }
        while(zaehlen2 > zaehlen1);
    


  • Wie baue ich in eine Do While Schleife ein Abbruchkriterium ein? Weil jetzt rechnet er fröhlich vor sich hin, aber ich muss ja für den Fall wenn die Nullen pro Multiplikation nicht mehr werden, dann abbrechen und sagen diese Matrix ist Nicht Nilpotent. Aber wenn er ewig weiter rechnet und immer mehr Nullen werden, dann ist sie Nilpotent



  • mehr als 100 Nullen können es nicht werden.

    Die do-while-Schleife wird solange durchlaufen, solange die Bedingung wahr ist.



  • Achsoo und wie gebe ich dann aus ob diese Matrix Nilpotent ist oder nicht? Also bei uns wird das auch noch so vorgegeben:

    Zählen Sie nun die Nullen der eingegebenen Matrix. Multiplizieren Sie die Matrix
    mit sich selbst. Zählen Sie danach die Nullen. Sind die Nullen mehr geworden,
    fahren Sie fort, die Matrix mit sich selbst zu multiplizieren, bis alle Einträge der
    Matrix Nullen sind. Ist das der Fall, ist die Matrix nilpotent. Werden die Nullen
    bei einem Multiplikationsschritt nicht mehr, brechen Sie das Verfahren ab, dann
    ist die Matrix nicht nilpotent.

    Also es muss ja noch eine If Bedinung rein oder verstehe ich das falsch?

    Oder soll ich einen Durchgang "per Hand" machen? dann kann ich ja schon aussagen ob es sich um eine nilpotente Matrix handelt oder nicht und danach erst die Do While Schleife das wäre doch Unsinn...



  • Durch das while(zaehlen2 > zaehlen1); wird die Schleife abgebrochen, wenn keine Nullen mehr dazu gekommen sind.

    Jetzt musst du nur noch überprüfen, ob alle Elemente 0 sind.
    Dazu musst du aber wissen, wieviel Elemente es in der Matrix gibt.



  • for (i = 0; i < dim; i++)
    	{
    		for (j = 0; j < dim; j++)
    		{
    			if (matrix[i][j] == 0)
    			{
    				printf("Die Matrix\n");
    				ausgabe(dim, matrix);
    				printf("ist nilpotent\n");
    			}
    			if (matrix[i][j] != 0)
    			{
    				printf("Die Matrix\n");
    				ausgabe(dim, matrix);
    				printf("ist nicht nilpotent\n");
    			}
    		}
    	}
    

    Also soll ich sowas machen? Wo er jedes Element überprüft? Nur jetzt weil es ja in der Schleife ist und wird immer wieder geprintet.



  • 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).


Anmelden zum Antworten