Gauß'sches Eliminationsverfahren in C aufbauend auf der LR Zerlegung
-
Hallo,
ich möchte gerne das Gauß'sche Eliminationsverfahren in C programmieren.
Mein Programm gibt auch keine Fehlermeldungen mehr aus, aber, wenn ich es starte, kommt die Fehlermeldung "Segmentation fault".
(Das Programm baut auf http://www.c-plusplus.net/forum/289873 auf)Das ist mein Programm:
#include <iostream> #include <stdio.h> #include <math.h> #include <stdlib.h> typedef double *PVector; typedef double **PMatrix; PVector TVector_Create(int n){ return (PVector) calloc(n, sizeof(double)); } PMatrix TMatrix_Create(int m, int n){ PMatrix A; int i; A = (PMatrix) malloc(m * sizeof(PVector)); for ( i=0; i<m; i=i+1 ) A[i] = TVector_Create(n); return A; } PVector readVector(int n) { int i; PVector v = TVector_Create(n); for(i = 0; i < n; i++){ printf("Geben Sie v %d ein\n", i+1); scanf("%lf", &v[i]); fflush(stdin); } return v; } PMatrix readMatrix(int m, int n) { int i,j; PMatrix A = TMatrix_Create(m, n); for(i = 0; i < m; i++) { for(j = 0; j < n; j++){ printf("Geben Sie A %d %d ein\n", i+1, j+1); scanf("%lf", &A[i][j]); fflush(stdin); } } return A; } void writeVector(PVector v, int n) { int i; printf("("); for(i = 0; i < n; i++) { printf("%f,", v[i]); } printf(")\n"); } void writeMatrix(PMatrix A,int m, int n) { int i, j; printf("("); for(i = 0; i < n; i++) { for(j = 0; j < m; j++) { printf("%f,", A[i][j]); } printf(")\n"); } } //LR-Zerlegung void LRZerlegung(PMatrix A, int m, int n) { int i, k, j; for(i = 0; i < n; i++) { // Bestimmen von R for(j = i; j < m; j++) { for(k = 0; k< i-1; k++){ A[i][j]-= A[i][k] * A[k][j]; } } // Bestimmen von L for(j = i+1; j<m; j++){ for (k = 0; k < i-1; k++){ A[j][i] -= A[j][k] * A[k][i]; } A[j][i] /= A[i][i]; } } } int main(void){ int i, j, k, n, m; PMatrix A; PVector b; //Eingabe der Dimension printf("Geben Sie n an\n"); scanf("%d",&n); fflush(stdin); printf("Geben Sie m an\n"); scanf("%d",&m); fflush(stdin); //Eingabe: Matrix A A = readMatrix(n, m); //Eingabe: b b = readVector(n); //LR Zerlegung LRZerlegung(A, m, n); //Gauss-Elimination for (k = 0; k<n-1; k++) { if (A[k][k] == 0) { return 0; } else { for (i = k+1; i<n; i++){ A[i][k]= A[i][k]/A[k][k]; for (j=k+1; j<m; j++){ A[i][j]=A[i][j] - A[k][j]* A[i][k]; b[i]= b[i] - b[k]*A[i][k]; } } } } //Linksdreieckssystem Ly = b lösen durch Vorwärtseinsetzen b[0]= b[0]/A[0][0]; for (i=1; i<n; i++) { for (j = 0; j<i-1; j++) { b[i]=b[i]-A[i][j]*b[j]; } } //Rechtsdreieckssystem Rx = y lösen durch Rückwärtseinsetzen. b[n]= b[n]/A[n][n]; for (i=n-1; i>=0; i--) { for (j = i+1; j<m; j++) { b[i]=b[i]-A[i][j]*b[j]; b[i]= b[i]/A[i][i]; } } writeVector(b, n); return 0; }
Kann mir da jemand weiter helfen?
Vielen Dank!
-
1. Arrays gehen immer noch bei 0 los! Zähl mal nach, welchen Index dann das letzte Element hat.
2. Lern mal, einen Debugger zu benutzen. Das ist Grundwissen für die Programmierung und damit findet man solche Fehler sofort!
3. fflush(stdin) löst undefiniertes Verhalten aus, außer auf einem gewissen Compiler von Microsoft.
4. iostream? WTF?
-
Okay, das letzte Element hat nicht den Index n sondern n-1.
Ich hab jetzt alle fflush(stdin) auskommentiert.
#include <iostream> wurde automatisch hingeschrieben. Habe ich jetzt auch gelöscht.
Das Programm rechnet jetzt zwar, aber es liefert leider nicht das richtige Erbenis
-
Ich hab jetzt noch mal die Matrix A ausgeben lassen.
Die wird richtig berechnet.
Der Vektor beim Vorwärtseinsetzen ist leider schon falsch.
Ich probiere mal den Fehler zu finden.
-
Das Programm läuft jetzt.
Der fertige Code ist:int main(void){ int i, j, k, n, m; PMatrix A; PVector b; //Eingabe der Dimension printf("Geben Sie n an\n"); scanf("%d",&n); //fflush(stdin); printf("Geben Sie m an\n"); scanf("%d",&m); //fflush(stdin); //Eingabe: Matrix A A = readMatrix(n, m); //Eingabe: b b = readVector(n); //LR Zerlegung //LRZerlegung(A, m, n); //Gauss-Elimination for (k = 0; k<n; k++) { if (A[k][k] == 0) { return 0; } else { for (i = k+1; i<n; i++){ A[i][k]= A[i][k]/A[k][k]; for (j=k+1; j<m; j++){ A[i][j]=A[i][j] - A[k][j]* A[i][k]; } b[i]= b[i] - b[k]*A[i][k]; } } } //Linksdreieckssystem Ly = b lösen durch Vorwärtseinsetzen //b[0]= b[0]/A[0][0]; //for (i=1; i<n; i++) { // for (j = 0; j<i-1; j++) { // b[i]=b[i]-A[i][j]*b[j]; // } //} //Rechtsdreieckssystem Rx = y lösen durch Rückwärtseinsetzen. b[n-1]= b[n-1]/A[n-1][n-1]; for (i=n-2; i>=0; i--) { for (j = i+1; j<m; j++) { b[i]=b[i]-A[i][j]*b[j]; } b[i]= b[i]/A[i][i]; } writeVector(b, n); writeMatrix(A, m, n); return 0; }
Das Problem war, dass das Vorwärtseinsetzen schon in der Gauss-Elimination gemacht wurde und ich ein paar mal die Klammern für die for-Schleifen zu spät gesetzt hab, usw.
Vielen Dank für die Hilfe!