⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 practice4-2.cpp

📁 使用:Gauss消元
💻 CPP
字号:
#include <algorithm>
using namespace std;
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <time.h>

const int maxn = 500 + 10;
const int n = 500;

double mat[maxn][maxn], b[maxn], x[maxn]; //储存系数矩阵mat、常数向量b以及解向量x

//高斯消元法
void GaussElimination(double _mat[maxn][maxn], double b[maxn], double x[maxn])
{
	double mat[maxn][maxn];
	int i,j,k; //将矩阵和b向量粘合,成为n*(n+1)的矩阵方便运算
	for (i=1; i<=n; i++)
	{
		for (j=1; j<=n; j++)
			mat[i][j] = _mat[i][j];
		mat[i][n+1] = b[i];
	}
	for (i=1; i<=n; i++) //对每一列消元
	{
		for (j=i+1; j<=n; j++) //使用第i行对第i+1..n行进行消元
		{
			double pp = -mat[j][i] / mat[i][i];
			for (k=i; k<=n+1; k++)
				mat[j][k] += mat[i][k] * pp;
		}
	}
	for (i=n; i>=1; i--) //倒推求出x的解
	{
		for (j=i+1; j<=n; j++)
			mat[i][n+1] -= mat[i][j] * x[j];
		x[i] = mat[i][n+1] / mat[i][i];
	}
}

//列主元的高斯消元法
void GaussEliminationImprove(double _mat[maxn][maxn], double b[maxn], double x[maxn])
{
	double mat[maxn][maxn];
	int i,j,k; //将矩阵和b向量粘合,成为n*(n+1)的矩阵方便运算
	for (i=1; i<=n; i++)
	{
		for (j=1; j<=n; j++)
			mat[i][j] = _mat[i][j];
		mat[i][n+1] = b[i];
	}
	for (i=1; i<=n; i++) //对每一列消元
	{
		double maxp = 0; int dir; //选择合适的列主元(绝对值最大项)
		for (j=i; j<=n; j++)
			if (fabs(mat[j][i])>maxp)
				maxp = fabs(mat[j][i]), dir = j;
		for (j=i; j<=n+1; j++)
			swap(mat[i][j], mat[dir][j]);

		for (j=i+1; j<=n; j++) //使用第i行对第i+1..n行进行消元
		{
			double pp = -mat[j][i] / mat[i][i];
			for (k=i; k<=n+1; k++)
				mat[j][k] += mat[i][k] * pp;
		}
	}
	for (i=n; i>=1; i--) //倒推求出x的解
	{
		for (j=i+1; j<=n; j++)
			mat[i][n+1] -= mat[i][j] * x[j];
		x[i] = mat[i][n+1] / mat[i][i];
	}
}

// Cholesky分解法
double l[maxn][maxn];
void CholeskyDecomposition(double a[maxn][maxn], double b[maxn], double x[maxn])
{
	int i,j,k;
	for (j=1; j<=n; j++) //根据公式计算l矩阵
	{
		l[j][j] = a[j][j];
		for (k=1; k<j; k++)
			l[j][j] -= l[j][k]*l[j][k];
		l[j][j] = sqrt(l[j][j]);
		for (i=j+1; i<=n; i++)
		{
			l[i][j] = a[i][j];
			for (k=1; k<j; k++)
				l[i][j] -= l[i][k]*l[j][k];
			l[i][j] /= l[j][j];
		}
	}
	double y[maxn]; //根据Ly=b求解y
	for (i=1; i<=n; i++)
	{
		y[i] = b[i];
		for (k=1; k<i; k++)
			y[i] -= l[i][k]*y[k];
		y[i] /= l[i][i];
	}
	for (i=n; i>=1; i--)  //根据L^Tx=y求解x
	{
		x[i] = y[i];
		for (k=i+1; k<=n; k++)
			x[i] -= l[k][i]*x[k];
		x[i] /= l[i][i];
	}
}

double t[maxn][maxn], d[maxn];
void CholeskyDecompositionImprove(double a[maxn][maxn], double b[maxn], double x[maxn])
{
	int i,j,k;
	d[1] = a[1][1];
	for (i=2; i<=n; i++) //根据公式分解A=LDL^T
	{
		for (j=1; j<i; j++)
		{
			t[i][j] = a[i][j];
			for (k=1; k<j; k++)
				t[i][j] -= t[i][k]*l[j][k];
			l[i][j] = t[i][j]/d[j];
		}
		d[i] = a[i][i];
		for (k=1; k<i; k++)
			d[i] -= t[i][k]*l[i][k];
	}
	double y[maxn];
	for (i=1; i<=n; i++) //根据Ly=b求解y
	{
		y[i] = b[i];
		for (k=1; k<i; k++)
			y[i] -= l[i][k]*y[k];
	}
	for (i=n; i>=1; i--)  //根据L^Tx=y求解x
	{
		x[i] = y[i]/d[i];
		for (k=i+1; k<=n; k++)
			x[i] -= l[k][i]*x[k];
	}
}

int main()
{
	int i,j;
	for (i=1; i<=n; i++) //给矩阵初始值
		for (j=1; j<=n; j++)
			mat[i][j] = 1.0/(i+j-1);
	for (int i=1; i<=n; i++)
	{
		b[i] = 0;
		for (j=1; j<=n; j++)
			b[i] += mat[i][j];
	}
	clock_t st;
	
	st = clock();
	GaussElimination(mat, b, x);
	printf("%.8lf\n",(double)(clock()-st)/CLOCKS_PER_SEC);

	st = clock();
	GaussEliminationImprove(mat, b, x);
	printf("%.8lf\n",(double)(clock()-st)/CLOCKS_PER_SEC);

	st = clock();
	CholeskyDecomposition(mat, b, x);
	printf("%.8lf\n",(double)(clock()-st)/CLOCKS_PER_SEC);

	st = clock();
	CholeskyDecompositionImprove(mat, b, x);
	printf("%.8lf\n",(double)(clock()-st)/CLOCKS_PER_SEC);
	/*for (i=1; i<=n; i++)
		printf("%.10lf\n",fabs(x[i]-1));*/
	return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -