高斯消元法模板--矩阵分解

求解方程组的解向量: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;
}

猜你喜欢

转载自blog.csdn.net/lidengdengter/article/details/81076104