Frage bezüglich Matrix Multiplikation?
-
Mach doch mal ein
ausgabe(dim, erg);
in Zeile 95.Und für die Matrizenmultiplikation brauchst du auch drei ineinader verschachtelte Schleifen.
-
Jo hab jetzt erst mal die erg Matrix mit 0 initialisiert jetzt weiß ich woher die Negativen Zahlen kamen
Ja klar weiß ich wie man "auf Papier" mit Matritzen rechnet
Also Zeile mal Spalte, d.h. A11*A11+ A12*A21 + A13*A31 Also einmal die erste Zeile mit den der ersten Spalte von der anderen Matrix (in diesem Fall muss die Matrix mit sich selbst multipliziert werden).
Das heißt meine erste For Schleife mit i ist für die Zeilen, die läuft einen weiter, wenn alle in Elemente in der zweiten For Schleife mit j also Spalten durchgearbeitet wurden.
Wenn ich jetzt eine dritte For Schleife reinschreibe was kommt denn da rein? (Blöd Frage ich weiß, kann mir das nur grade nicht vorstellen momentan) Es müsste ja irgendwas mit erg[i][j] = matrix1[i][k] dieses k muss immer einen weiter gerechnet werden * matrix [k][j] und hier müsste man ja das k immer höher rechnen aber das j bleiben. Oder nicht?
-
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 zaehlen2und 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 zaehlen2Wieviel 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.