C语言中部分旋转高斯矩阵行列式的计算
我正在尝试用C语言制作一个简单的控制台应用程序,它将使用高斯部分旋转消去法计算矩阵的行列式。我遇到的两个问题是: -有人告诉我,有些矩阵E不能用这种方法工作(从数学上讲),在阅读了谷歌的文章后,我找不到那个特例是什么 -经过大量的测试,我发现我的程序对一些矩阵E不起作用,经过两天的“浪费”时间编辑和撤销,我没有发现问题 任何类型的改进都非常受欢迎。我只是从C开始C语言中部分旋转高斯矩阵行列式的计算,c,matrix,partial,gaussian,determinants,C,Matrix,Partial,Gaussian,Determinants,我正在尝试用C语言制作一个简单的控制台应用程序,它将使用高斯部分旋转消去法计算矩阵的行列式。我遇到的两个问题是: -有人告诉我,有些矩阵E不能用这种方法工作(从数学上讲),在阅读了谷歌的文章后,我找不到那个特例是什么 -经过大量的测试,我发现我的程序对一些矩阵E不起作用,经过两天的“浪费”时间编辑和撤销,我没有发现问题 任何类型的改进都非常受欢迎。我只是从C开始 #include<stdio.h> #include<cstdlib> #include<math.h&
#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);
}
}
}
#包括
#包括
#包括
#包括
#包括
//计算列上的最大元素
内部标识最大值(内部尺寸、内部颜色、浮动色[20][20]){
浮动最大值=0;
int-indice;
对于(int i=1;i您的代码进行了一些划分:
matrice[lpiv][inm] = matrice[lpiv][inm] / pivot;
如果它正好被零除,就会发生错误。我想这会发生在零矩阵上
看起来你的代码实际上是在尝试反转矩阵,而不仅仅是计算行列式。好吧,去图书馆找一本关于数值方法的书,比如数值方法,负担和公平,如果我没有弄错的话,看看他们的高斯消除的C实现,HTHIt在不可逆的方阵称为奇异矩阵或退化矩阵。当且仅当其行列式为0时,方阵才是奇异矩阵。奇异矩阵很少见,因为如果你选择一个随机方阵,它几乎肯定不会是奇异的。"甚至不需要去图书馆!看看第二章:@user786653你的解释是当矩阵不可逆时。奇异矩阵是当它的行列式为0时,但我需要计算行列式,看看它是否为0。网络上有这个过程的代码示例,但它们的步骤与我的大学教授不同正在做。请看@anatolygs的答案,一个奇异矩阵在某个点上会有一个零列,不需要显式计算行列式。当然,我认为对角线上的一个元素是0,但在将矩阵转换为上三角元素的操作完成后,我认为它们可能是0。谢谢。我认为我还有另一个问题。我正在搜索整个列上的max元素,而不仅仅是在轴下面。