Calculer le facteur déterminant matrice avec pivotement partiel Gauss en C
-
27-10-2019 - |
Question
Je suis en train de faire une simple application de la console en C qui calcule le déterminant d'une matrice en utilisant la méthode d'élimination de pivotement partielle Gauss. Les 2 problèmes que j'ai sont les suivants: - quelqu'un m'a dit qu'il ya certaines matrice-es qui ne fonctionnent pas avec cette méthode (mathématiquement parlant), après avoir lu des articles sur google, je ne pouvais pas trouver ce qui est ce cas particulier -. Après beaucoup de tests j'ai découvert que mon programme ne fonctionne pas pour certaines matrice-es, après 2 jours de « gaspiller » l'édition de temps et défaisant, je ne pouvais pas trouver le problème
Tout type d'améliorations sont les bienvenues. Je commence par C.
#include<stdio.h>
#include<cstdlib>
#include<math.h>
#include<conio.h>
#include<windows.h>
// calculate biggest element on column
int indice_max(int dim, int col, float coloana[20][20]) {
float max = 0;
int indice;
for(int i = 1; i <= dim; i++)
if(fabs(max) < fabs(coloana[i][col])) {
max = coloana[i][col];
indice = i;
}
return indice;
}
// permute 2 lines
void permutare_linie(int linie1, int linie2, int dim, float matrice[20][20]) {
float aux;
for(int i = 1; i <= dim; i++) {
aux = matrice[linie1][i];
matrice[linie1][i] = matrice[linie2][i];
matrice[linie2][i] = aux;
}
}
// print matrix
void afisare_matrice(int dimensiune, float matrice[20][20], int lpiv) {
for(int i = 1; i<= dimensiune; i++) {
for(int j = 1; j <= dimensiune; j++) {
if(i == lpiv)
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), BACKGROUND_GREEN);
else
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE );
printf("%4.2f ", matrice[i][j]);
}
printf("\n");
}
}
void main(void) {
float matrice[20][20];
int dimensiune ;
float rezultat = 1;
float pivot;
int lpiv;
int cpiv;
int optiune;
while(1) {
// MENU
printf("ALEGET OPTIUNEA:\n");
printf("1) Calculate matrix determinant\n");
printf("2) Exit\n");
scanf("%d", &optiune);
if(optiune == 1) {
// Read determinant dimension
printf("Matrix dimension:");
scanf("%d", &dimensiune);
// Read determinant
for(int i = 1; i <= dimensiune; i++)
for(int j = 1; j <= dimensiune; j++) {
printf("M[%d][%d]=", i, j);
scanf("%f", &matrice[i][j]);
}
// pivot initial coords
lpiv = 1;
cpiv = 1;
printf("\n----- Entered Matrix -----\n\n");
afisare_matrice(dimensiune, matrice, 0);
printf("\n");
for(int pas = 1; pas <= dimensiune - 1; pas++) {
if(fabs(matrice[lpiv][cpiv]) > fabs(matrice[indice_max(dimensiune, cpiv, matrice)][cpiv])) {
permutare_linie(lpiv, indice_max(dimensiune, cpiv, matrice), dimensiune, matrice);
rezultat = -(rezultat);
}
pivot = matrice[lpiv][cpiv];
for(int inm = 1; inm <= dimensiune; inm++) {
matrice[lpiv][inm] = matrice[lpiv][inm] / pivot;
}
rezultat *= fabs(pivot);
// transform matrix to a superior triangular
for(int l = lpiv+1; l <= dimensiune; l++)
for(int c=cpiv+1; c <= dimensiune; c++) {
matrice[l][c] -= matrice[l][cpiv] * matrice[lpiv][c] / matrice[lpiv][cpiv];
}
for(int i = lpiv + 1; i <= dimensiune; i++)
matrice[i][cpiv] = 0;
// afisam rezultat / pas
printf("----- Step %d -----\n\n", pas);
afisare_matrice(dimensiune, matrice, lpiv);
printf("\nResult after step %d : %4.2f\n\n", pas, rezultat);
lpiv++;
cpiv++;
}
// final result
rezultat = rezultat * matrice[dimensiune][dimensiune];
printf("----- REZULTAT FINAL -----\n\n");
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED | FOREGROUND_INTENSITY);
printf("Rezultat = %4.2f\nRezultat rotunjit:%4.0f\n\n", rezultat, floorf(rezultat * 100 + 0.5) / 100);
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE );
}
else {
exit(0);
}
}
}
La solution
Votre code fait une division:
matrice[lpiv][inm] = matrice[lpiv][inm] / pivot;
Si elle arrive à diviser par zéro, une erreur se produit. Je suppose que cela se produira pour la matrice zéro.
Il semble que votre code est en train d'essayer d'inverser la matrice, ne calcule pas seulement le facteur déterminant.