gpt4 book ai didi

C程序使用高斯消元法和偏旋转法求解线性代数方程组

转载 作者:太空宇宙 更新时间:2023-11-04 02:51:45 24 4
gpt4 key购买 nike

我有一个 C 程序(如下),它使用高斯消元法和偏轴法来求解线性代数方程组。我的 friend 告诉我,我应该重写它。他告诉我用 0 而不是 1 开始循环 for。不幸的是,我不再与他联系,所以他无法向我解释为什么他的解决方案更好。我试图为 for 重写这些循环,但程序无法正常工作。也许只需要重写这些循环中的一部分而不是全部。你能给我解释一下这个问题吗(我希望这个程序是完美的)?

线性代数方程组看起来像 A*X=B。该程序从文件 matrix.txt 中读取输入。

#include<stdio.h>
#include<stdlib.h>
#include<math.h>

typedef double **Matrix;
typedef double *Row;
typedef double *Col;
typedef double Elem;

Matrix allocate_matrix(int n);
Col allocate_col(int n);
Row allocate_row(int n);
void free_matrix(Matrix M, int n);

void pivot_partial(Matrix A, Col S,Col B, int n);
void forward_elimination(Matrix A,Col B,int n);
Col back_substitution(Matrix A, Col B, int n);
Col scale_factor(Matrix A,int n);
void gauss(Matrix A, Col B, int n);

void swap_rows(Row *r1, Row*r2);
void print_matrix(Matrix M, int n, char * name);
void print_col(Col C, int n, char *name);
void print_row(Row R, int n, char *name);

int main(int argc, char *argv[])
{
FILE *ifp;
int n,i,j;
Matrix A;
Col B;
if(argc < 2)
{
printf("\nInput filename not passed \n");
exit(1);
}

ifp = fopen(argv[1],"r");

if(ifp == NULL)
{
printf("\nCould not open file %s\n",argv[1]);
exit(1);
}
fscanf(ifp,"%i",&n);
printf("A * X = B\n");
printf("\nDimension(A) = %i\n",n);

A = allocate_matrix(n);
for( i = 1; i <= n; ++i)
for(j = 1; j <= n; ++j)
fscanf(ifp,"%lf", &A[i][j]);

B = allocate_col(n);

for(j = 1; j <= n; ++j)
fscanf(ifp,"%lf",&B[j]);
fclose(ifp);


print_matrix(A,n,"A");
print_col(B,n,"B");

gauss(A,B,n);

free_matrix(A,n);
free(B + 1);

getchar();
return 0;
}

void print_matrix(Matrix M, int n, char * name)
{
int i,j;
printf("\n[%s] = ",name);
printf("\n\n");
for(i = 1; i <= n; i++)
{
for(j = 1; j <= n; ++j)
printf("%6lG ",M[i][j]);
printf("\n");
}
}

void print_col(Col C, int n, char * name)
{
int j;
printf("\n[%s] = ",name);
printf("\n\n");
for(j = 1; j <= n; ++j)
printf("%6lg\n",C[j]);

}

void print_row(Row R, int n, char * name)
{
int i;
printf("\n[%s] = ",name);
for(i = 1; i <= n; ++i)
printf("%6lg ",R[i]);
printf("\n");
}

Matrix allocate_matrix(int n)
{
Matrix A;
int i,j;
A = malloc(n * sizeof(Row));
if(!A)
{
printf("\nError : Could not allocate
memory for matrix\n");
exit(1);
}
--A;

for(i = 1; i <= n; ++i)
{
A[i] = malloc(n * sizeof(Elem));
if(!A[i])
{
printf("\nError : Could not allocate
memory for matrix\n");
exit(1);
}
--A[i];
}
return A;
}

void free_matrix(Matrix M, int n)
{
int i;
for(i = 1; i <= n; ++i)
free(M[i] + 1);
free(M + 1);
}

Col allocate_col(int n)
{
Col B;

B = malloc(n * sizeof(Elem));

if(!B)
{
printf("\nError : could not allocate
memory\n");
exit(1);
}
--B;
return B;
}

Row allocate_row(int n)
{
Row B;
B = malloc(n * sizeof(Elem));
if(!B)
{
printf("\nError : could not allocate
memory\n");
exit(1);
}
--B;
return B;
}

Col scale_factor(Matrix A, int n)
{
int i,j;
Col S ;
S = allocate_col(n);

for(i = 1; i <= n; ++i)
{
S[i] = A[i][1];
for(j = 2; j <= n; ++j)
{
if(S[i] < fabs(A[i][j]))
S[i] = fabs(A[i][j]);
}

}
return S;

}

void pivot_partial(Matrix A, Col S,Col B, int n)
{
int i,j;
Elem temp;
for(j = 1; j <= n; ++j)
{
for(i = j + 1; i <= n; ++i)
{
if(S[i] == 0)
{
if(B[i] == 0)
printf("\nSystem doesnt
have a unique solution");
else
printf("\nSystem is
inconsistent");
exit(1);
}
if(fabs(A[i][j]/S[i])>fabs(A[j][j]/S[j]))
{
swap_rows(&A[i],&A[j]);
temp = B[i];
B[i] = B[j];
B[j] = temp;
}
}

if(A[j][j] == 0)
{
printf("\nSingular System Detected\n");
exit(1);
}
}

}

void swap_rows(Row *r1, Row*r2)
{
Row temp;
temp = *r1;
*r1 = *r2;
*r2 = temp;
}

void forward_elimination(Matrix A,Col B,int n)
{
int i,j,k;
double m;

for(k = 1; k <= n-1; ++k)
{
for(i = k + 1; i <= n; ++i)
{
m = A[i][k] / A[k][k];
for(j = k + 1; j <= n; ++j)
{
A[i][j] -= m * A[k][j];
if(i == j && A[i][j] == 0)
{
printf("\nSingular
system detected");
exit(1);
}
}
B[i] -= m * B[k];
}
}
}

Col back_substitution(Matrix A, Col B, int n)
{
int i,j;
Elem sum;
Col X = allocate_col(n);
X[n] = B[n]/A[n][n];
for(i = n - 1; i >= 1; --i)
{
sum = 0;
for(j = i + 1; j <= n; ++j)
sum += A[i][j] * X[j];
X[i] = (B[i] - sum) / A[i][i];
}
return X;
}

void gauss(Matrix A, Col B, int n)
{
int i,j;
Col S, X;
S = scale_factor(A,n);
pivot_partial(A,S,B,n);
forward_elimination(A,B,n);
X = back_substitution(A,B,n);
print_col(X,n,"X");

free(S + 1);
free(X + 1);
}

最佳答案

C 中的数组自然从 0 开始索引,而不是 1。所以如果你有 a[5],你有五个槽:a[0]、a[1]、a[2]、a[3]、 [4].所以数组 a 的“第一个”元素在 a[0] 中。

你用一个技巧解决了这个问题。在分配函数中,递减从 malloc 返回的指针。这具有将阵列槽移动一个的效果。所以 a[1] 所指的现在是获取 a[0] 中的内容。这允许您使用从 1 开始到 n 的 for 循环。

虽然现有代码可能在任何普通系统和编译器上都能正常工作,但它不是标准 C。这可能是您 friend 重写代码的意思。如果要更改它,请删除分配函数中的指针递减,然后将 for 循环更改为从 0 到 n-1,而不是从 1 到 n。

for (i=0; i < n; i++)

不是从1到n的for循环,你得仔细检查逻辑是否正确。请记住,最低的数组元素是 0,最大的是 n-1。

关于C程序使用高斯消元法和偏旋转法求解线性代数方程组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21408006/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com