求解方程组的解向量:Ax=b,
令 A=LU; //求解L矩阵和U矩阵可以利用一般高斯消元法,也可以用直接法
则 LUx=b;
令 y=Ux;
则 Ly=b;
所以根据L矩阵和b向量,可求出y向量,再根据y向量和U矩阵求解x向量即可
#include<cstdio>
#include<cmath>
using namespace std;
const int N=100;
double a[N][N],b[N];
double set0_cal(double a[N][N],int k,int j){ //求u[][]的求和部分
double sum=0;
for(int i=1;i<=k-1;i++)
sum+=a[k][i]*a[i][j];
return sum;
}
double set_cal(double a[N][N],int i,int k){ //求l[][]的求和部分
double sum=0;
for(int j=1;j<=k-1;j++)
sum+=a[i][j]*a[j][k];
return sum;
}
double get0_cal(double a[N][N],double y[N],int k){ //求y[][]的求和部分
double sum=0;
for(int j=1;j<=k-1;j++)
sum+=a[k][j]*y[j];
return sum;
}
double get_cal(double a[N][N],double x[N],int k,int n){ //求x[][]的求和部分
double sum=0;
for(int j=k+1;j<=n;j++)
sum+=a[k][j]*x[j];
return sum;
}
void LU(int n,double a[N][N],double b[N]){
double y[N],x[N];
for(int i=2;i<=n;i++) //LU矩阵分解
a[i][1]=a[i][1]/a[1][1];
for(int k=2;k<=n;k++){
for(int j=k;j<=n;j++)
a[k][j]=a[k][j]-set0_cal(a,k,j);
for(int i=k+1;i<=n;i++)
a[i][k]=(a[i][k]-set_cal(a,i,k))/a[k][k];
}
printf("a[][]=\n"); //输出验证
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++)
printf("%lf ",a[i][j]);
printf("\n");
}
for(int k=1;k<=n;k++) //求解y,ly=b
y[k]=b[k]-get0_cal(a,y,k);
for(int k=n;k>=1;k--) //求解x,ux=y
x[k]=(y[k]-get_cal(a,x,k,n))/a[k][k];
for(int k=2;k<=n;k++)
for(int j=k;j<=n;j++)
a[k][j]=a[k][j]-set0_cal(a,k,j);
//output
printf("\n");
for(int i=1;i<=n;i++)
printf("Y%d:%lf%c",i,y[i],i==n?'\n':'\t');
printf("\n");
for(int i=1;i<=n;i++)
printf("X%d:%lf%c",i,x[i],i==n?'\n':'\t');
}
int main(){
int n=1;
while(true){
printf("n=");
scanf("%d",&n);
if(n==0) break;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
scanf("%lf",&a[i][j]);
for(int i=1;i<=n;i++)
scanf("%lf",&b[i]);
printf("\n");
LU(n,a,b);
}
return 0;
}