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

    用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 @   相对维度  阅读(55)  评论(0编辑  收藏  举报
    编辑推荐:
    · 如何编写易于单元测试的代码
    · 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
    · .NET Core 中如何实现缓存的预热?
    · 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
    · AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
    阅读排行:
    · 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
    · 地球OL攻略 —— 某应届生求职总结
    · 周边上新:园子的第一款马克杯温暖上架
    · 提示词工程——AI应用必不可少的技术
    · Open-Sora 2.0 重磅开源!
    点击右上角即可分享
    微信分享提示