数值分析-解线性方程组-超松弛迭迭代法
用SOR法求解线性方程组,并使用高斯消去法验证算法
点击查看代码
#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;
}
本文来自博客园,作者:相对维度,转载请注明原文链接:https://www.cnblogs.com/wangjirui/articles/15906763.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!