数值分析-解线性方程组-超松弛迭迭代法

用SOR法求解线性方程组,并使用高斯消去法验证算法
image

点击查看代码
#include <stdio.h>
#include <stdlib.h>
/**********************************
    项目名称:超松弛迭代法解线性方程组
    x1  x2  x3  x4   d
    5   1   -1  -2   4
    2   8    1   3   1
    1   -2  -4  -1   6
    -1  3    3   7   -3
************************************/
/*********************************************************
    方程举例:C * x = D
    参数说明:*c:方程组系数矩阵
              *d:方程组右侧列向量
              *x:开始存储方程组位置向量x
              omega:松弛因子
               n:方程阶数
              the:精度要求
**********************************************************/
double SOR(double *c,double *d,double *x,double omega,int n,double the)
{
    int     _t;    //记录迭代次数
    double acc;
    double old[n]; //存储上一次计算结果
    double max;    //每次迭代误差的最大值
    _t  = 0;
    do{
        max = 0;
        acc = 0;
        memset(old, 0, sizeof(old));
        memcpy(old,x,n*sizeof(double));
        for(int i = 0;i < n;i++) //遍历每一行
        {
            acc += d[i];
            for(int j = 0;j < n;j++)
            {
                if(j != i)
                {
                    acc +=  (-1) * x[j] * c[i*n +j];
                }
            }
            x[i] = (1 - omega)*x[i] + omega/c[i*n + i]*acc;
            acc = 0;
        }
        for(int k = 0;k < n;k++) //计算误差
        {
            if(fabs(x[k]-old[k]) > max)
                max = fabs(x[k] - old[k]);
        }
        //printf("迭代第 %d 次计算误差为:%f\n",_t,max);
        _t++;
    }while(max > the);
    for(int i = 0;i < n;i++)
    {
        printf("超松弛迭代法迭代 %d 次后计算结果 X[%d] = %f\n",_t,i,x[i]);
    }
}

/***************************************************
    函数功能:列选主元高斯消去法解线性方程组
    参数说明:a: 二维矩阵
              b: 方程右侧列向量
              x: 未知数列向量
              n: 方程阶数
****************************************************/
int Gauss(double *a, double *b, double *x, int n)
{
	//由于此处A矩阵传递的是一维数组
	//a[i,j]在程序中用a[i*n+j]表示,请注意区分
	int i,j,k,m;
	double l;
	double temp;
	//消去过程
	for(k = 0;k < n-1;k++)
	{
		m = k;
		for (i=k+1;i<n;i++)
			if (fabs(a[m*n+k]) < fabs(a[i*n+k]))
				m=i;
		if(m!=k)
		{
			for (j=k;j<n;j++)
			{
				temp = a[k*n+j];
				a[k*n+j] = a[m*n+j];
				a[m*n+j] = temp;
			}
			temp=b[k];
			b[k]=b[m];
			b[m]=temp;
		}
		//消元过程
		for(i=k+1;i<n;i++)
		{
			if (a[k*n+k]+1.0==1.0)//如果用来消去的元素为零,则退出函数,并返回错误值
				return 0;//0代表错误
			l=a[i*n+k]/a[k*n+k];//计算消去过程中的除数
			for(j=k;j<n;j++)//消去a[i,k],并修改a[i,j]的值
				a[i*n+j]-=l*a[k*n+j];
			b[i]-=l*b[k];//修改b[i]的值
		}
	}
	//回代过程
	for(i=n-1;i>=0;i--)
	{
		x[i]=b[i];
		for(j=i+1;j<n;j++)
		x[i]-=x[j]*a[i*n+j];
		x[i]/=a[i*n+i];
	}
	for(int i = 0;i< n;i++)
    {
        printf("列选主元高斯消去法计算结果:x(%d) = %f\n",i,x[i]);
    }
	return 1;//1代表能正确求出结果
}
int main()
{
    double omega;
    double X[4] = {0,0,0,0}; //初值与中间值
    double C[4][4] =
     {5,   1,   -1,  -2,
      2,   8,    1,   3,
      1,   -2,  -4,  -1,
     -1,   3,    2,   7};
    double D[4] = {4,1,6,-3};
    SOR(C,D,X,1.15,4,0.00001); /*超松弛迭代法*/
    printf("\n");
    Gauss(C,D,X,4);  /*高斯消去法验证*/
    printf("计算完成!\n");
    return 0;
}


posted @ 2022-02-17 22:48  相对维度  阅读(77)  评论(0)    收藏  举报