Matrix invertieren c++ mit algorithmus
-
warum invertiert mir das Programm keine matrix bzw zeigt es nicht an?
der Fehler muss an der Berechnung liegen...
es erstellt die Matrix, zeigt sie an und fragt auch nach der richtigen eingabe der matrix, nur die inverse berechnet es nicht....#include "stdafx.h" #include <cmath> #include "windows.h" float matrix[20][20]; float invmatrix[20][20]; int main() { int n = 1; //Dimension der Matrix int iFehler = 0; //Fehlermerker int iNochmal = 0;//Wiederholen oder beenden int iRichtig = 0;//Überprüfung Matrix richtig int i; //Zeilen Matrix int j;//Spalten Matrix int k; int z;//Zeilenwechsel float A[20][20];//Speichermatrix (array) printf("------------------------------------ \n MATRIZEN INVERTIEREN \n------------------------------------ \n"); do { iFehler = 0; printf("\n Dies ist ein Programm zum invertieren von Matrizen \n"); printf("\n Gib dafuer bitte eine Dimension n (fuer eine quadratische Matrix) zwischen 2 und 10 ein:\n n="); scanf_s("%i", &n); //Dimension der Matrix erfassen if (n< 2 || n > 10) { iFehler = 1; printf("Fehler! Deine eingegebene Dimension ist nicht zwischen 2 und 10! \n \nNochmal? \n \n 1. Ja \n 2.Nein \n --> "); scanf_s("%i", &iNochmal); } //if Fehlerschleife falsche Dimension if (iFehler == 0) { printf(" \nGib nun zeilenweise die Matrix ein, die du invertieren willst und bestätige jedes Element mit Enter! \n", n, n); //Eingabe der Matrix for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { scanf_s("%f", &matrix[i][j]); }//for j }//for i printf("\nDeine Matrix lautet [%i][%i]... \n", n, n); for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { printf("\t%g", matrix[i][j]); }//for j printf("\n\n"); }//for i printf("\n Ist deine Matrix richtig?\n \n 1. Ja \n 2. Nein \n"); scanf_s("%i",&iRichtig); if (iRichtig == 1) { printf("\n Nun wird deine inverse Matrix berechnet:\n"); // Gauß-Algorithmus. for (k = 0; k < n - 1; k++) { // Zeilen vertauschen, falls das Pivotelement eine Null ist if (A[k][k] == 0) { for (i = k + 1; i < n; ++i) { if (A[i][k] != 0) { z<n, 2 * n>(A, k, i); break; } else if (i == n - 1) return false; // Es gibt kein Element != 0 } } // Einträge unter dem Pivotelement eliminieren for (i = k + 1; i < n; ++i) { double p = A[i][k] / A[k][k]; for (j = k; j < 2 * n; ++j) A[i][j] -= A[k][j] * p; } } // Determinante der Matrix berechnen double det = 1; for (k = 0; k < n; k++) det *= A[k][k]; if (det == 0)// Determinante ist =0 -> Matrix nicht invertierbar printf("Die Matrix ist nicht invertierbar"); return false; // Jordan-Teil des Algorithmus durchführen for (k = n - 1; k > 0; k--) { for (int i = k - 1; i >= 0; i--) { double p = A[i][k] / A[k][k]; for (j = k; j < 2 * n; j++) A[i][j] -= A[k][j] * p; } } // Einträge in der linker Matrix auf 1 normieren und in invmatrix schreiben for (i = 0; i < n; i++) { const double f = A[i][i]; for (j = n; j < 2 * n; j++) invmatrix[i][j - n] = A[i][j] / f; } printf("\nDeine inverse Matrix lautet [%i][%i]... \n", n, n);//inverse Matrix ausgeben for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { printf("\t%g", invmatrix[i][j-n]); }//for j printf("\n\n"); }//for i }//if Berechnung inverse Matrix printf("\n \nNochmal? \n \n 1. Ja \n 2. Nein \n "); scanf_s("%i", &iNochmal); } //if Nur weiterrechnen wenn Eingabe richtig } while (iNochmal == 1); //while if (iNochmal == 2) { printf("\n---------------------------------- \n Vielen Dank und auf Wiedersehen! \n---------------------------------- \n \n Beende Anwendung..."); Sleep(1500); return 0; }// if int iWait;//Warteschleife scanf_s("%i", &iWait); return 0; }
-
Benutze einen Debugger!
for (j = n; j < 2 * n; j++) invmatrix[i][j - n] = A[i][j] / f;
Du hast eine n*n Matrix, lässt den Index aber von n bis 2*n laufen?
float A[20][20];//Speichermatrix (array)
Die Größe des Arrays ist fest, dann aber kann man die eigentliche Größe eingeben?
Ich sehe irgendwie keinen Fetzen C++ in deinem Programm.
-
hmm.. ja leider hab ich da auch nicht so den plan von muss es nur leider machen..
hast du vielleicht einen alternativen quellcode für den Algorithmus zur Berechnung der inversen Matrix?
-
z<n, 2 * n>(A, k, i);
was soll diese Zeile bewirken?
-
Zeilen vertauschen, falls das Pivotelement eine Null ist
z<n, 2 * n>(A, k, i);
-
JJc schrieb:
hast du vielleicht einen alternativen quellcode für den Algorithmus zur Berechnung der inversen Matrix?
Klar
// Returns the inverse of matrix `M`. function matrix_invert(M){ // I use Guassian Elimination to calculate the inverse: // (1) 'augment' the matrix (left) by the identity (on the right) // (2) Turn the matrix on the left into the identity by elemetry row ops // (3) The matrix on the right is the inverse (was the identity matrix) // There are 3 elemtary row ops: (I combine b and c in my code) // (a) Swap 2 rows // (b) Multiply a row by a scalar // (c) Add 2 rows //if the matrix isn't square: exit (error) if(M.length !== M[0].length){return;} //create the identity matrix (I), and a copy (C) of the original var i=0, ii=0, j=0, dim=M.length, e=0, t=0; var I = [], C = []; for(i=0; i<dim; i+=1){ // Create the row I[I.length]=[]; C[C.length]=[]; for(j=0; j<dim; j+=1){ //if we're on the diagonal, put a 1 (for identity) if(i==j){ I[i][j] = 1; } else{ I[i][j] = 0; } // Also, make the copy of the original C[i][j] = M[i][j]; } } // Perform elementary row operations for(i=0; i<dim; i+=1){ // get the element e on the diagonal e = C[i][i]; // if we have a 0 on the diagonal (we'll need to swap with a lower row) if(e==0){ //look through every row below the i'th row for(ii=i+1; ii<dim; ii+=1){ //if the ii'th row has a non-0 in the i'th col if(C[ii][i] != 0){ //it would make the diagonal have a non-0 so swap it for(j=0; j<dim; j++){ e = C[i][j]; //temp store i'th row C[i][j] = C[ii][j];//replace i'th row by ii'th C[ii][j] = e; //repace ii'th by temp e = I[i][j]; //temp store i'th row I[i][j] = I[ii][j];//replace i'th row by ii'th I[ii][j] = e; //repace ii'th by temp } //don't bother checking other rows since we've swapped break; } } //get the new diagonal e = C[i][i]; //if it's still 0, not invertable (error) if(e==0){return} } // Scale this row down by e (so we have a 1 on the diagonal) for(j=0; j<dim; j++){ C[i][j] = C[i][j]/e; //apply to original matrix I[i][j] = I[i][j]/e; //apply to identity } // Subtract this row (scaled appropriately for each row) from ALL of // the other rows so that there will be 0's in this column in the // rows above and below this one for(ii=0; ii<dim; ii++){ // Only apply to other rows (we want a 1 on the diagonal) if(ii==i){continue;} // We want to change this element to 0 e = C[ii][i]; // Subtract (the row above(or below) scaled by e) from (the // current row) but start at the i'th column and assume all the // stuff left of diagonal is 0 (which it should be if we made this // algorithm correctly) for(j=0; j<dim; j++){ C[ii][j] -= e*C[i][j]; //apply to original matrix I[ii][j] -= e*I[i][j]; //apply to identity } } } //we've done all operations, C should be the identity //matrix I should be the inverse: return I; }
Hier geklaut: http://blog.acipo.com/matrix-inversion-in-javascript/
-
var i=0, ii=0, j=0, dim=M.length, e=0, t=0; var I = [], C = [];
sind Klassen oder ? die darf ich nicht verwenden
-
das hier ist die aufgabe
soll zuerst die Dimension n eingegeben werden, dann zeilenweise die Matrix. Die
einzelnen Spaltenelemente sollen durch ein Leerzeichen getrennt werden.
Bevor die Rechnung beginnt, soll die Matrix auf dem Bildschirm angezeigt werden und
der Anwender bestätigen, ob die Eingabe richtig war oder ob die Eingabe wiederholt
werden soll.
Jetzt wird die Matrix invertiert. Stellt sich dabei heraus, daß die Matrix singulär ist (d.h.,
nicht invertierbar), soll das Programm nicht abstürzen, sondern eine Meldung
ausgeben.
Weiterhin soll ein Textfile erzeugt werden, in dem die Matrix und – so existent – die
inverse Matrix gespeichert sind. Existiert die inverse Matrix nicht, soll es auch im
Textfile eine Meldung geben.
Ob Sie die Inverse über Determinanten oder über Gauss berechnen, bleibt Ihnen
überlassen und ist gleichwertig.ich bekomm es nur leider nicht hin
-
JJc schrieb:
ich bekomm es nur leider nicht hin
Tja, also hier wird dir (hoffentlich) keiner deine Hausaufgaben liefern.
JJc schrieb:
var i=0, ii=0, j=0, dim=M.length, e=0, t=0; var I = [], C = [];
sind Klassen oder ? die darf ich nicht verwenden
Naja, es ist Javascript. Man müsste es schon für C++ anpassen.
-
JJc schrieb:
for (j = 0; j < n; j++) { printf("\t%g", invmatrix[i][j-n]); }//for j
j ist immer kleiner als n. Somit hast du einen negativen Index.
Das kommt nicht gut.Benutze eigenen Funktionen.
Für die Eingabe, Ausgabe, Berechnung, ....Dann brauchst du z.B die Matrixausgabe nur einmal machen und kannst sie sehr leich prüfen.
Auch ist es übersichtlicher, wenn du die Eingabe wiederholen willst.
-
JJc schrieb:
Zeilen vertauschen, falls das Pivotelement eine Null ist
z<n, 2 * n>(A, k, i);
Das ist allerdings sehr weit von dem entfernt, was diese Zeile tatsächlich tut: effektiv nichts.
z,n,k und i sind ints, A ist ein float[20][20]-Array.
Es wird daher folgendes gemacht:
1. z wird mit n bzgl. kleiner-als Verglichen, das Ergebnis wird verworfen
2. die Ausdrücke A und k (die nichts weiter tun) werden ausgewertet und das Ergebnis verworfen
3. Der Wert 2*n wird mit dem Wert i größer-als verglichen, das Ergebnis wird verworfen.
Die Zeile verändert also weder den Zustand eines Objektes, noch wird der Wert des Ausdruckes in irgendeiner Weise verwendet.