雅可比迭代和高斯赛德迭代的比较

实验要求:

分别用雅可比算法和高斯-塞德尔算法求解给定的线性方程组

函数接口定义:

int Jacobi( int n, double a[][MAX_SIZE], double b[], double x[], double TOL, int MAXN );

int Gauss_Seidel( int n, double a[][MAX_SIZE], double b[], double x[], double TOL, int MAXN );

两函数的接口定义是一致的:n为矩阵a的维数,MAX_SIZE是由裁判程序定义的矩阵最大维数,b是方程组中的常向量,x传入叠代初始向量,求得的解将存储在x中返回;TOL是需要达到的精度上限,MAXN是叠代最大次数。函数的返回值为整数,有以下4种可能:

  • -2:若迭代算法不收敛。这里判断不收敛的根据是当的某个分量值超出了最大区间[-bound, bound],其中bound是由裁判程序定义的常数;
  • -1:若矩阵有一列全为0,则方程组没有唯一解;
  • 0:若算法经过MAXN次叠代后还没有达到精度要求;
  • K:若算法经过K次叠代达到了精度要求。这时求得的解存储在x中。

这里必须注意到,如我们在第五章中讨论过的,在两种算法的公式中,A的对角元aii都出现在分母上,所以为了算法的稳定,我们必须采取措施使得对角元的绝对值尽可能大。因为叠代中A不改变,所以我们可以事先调整好A的对角元。

不同的调整策略可能导致不同的收敛性,本书裁判程序要求的调整策略是:对每

个aii,首先向下扫描该列元素(包括aii)中绝对值最大的那个元,若该元不为0,则通过行交换将该元换到aii的位置。若该元为0,则向上扫描该列元素中绝对值最大的那个元,若该元不为0,则将该元所在行的全部元加到第i行。

实验算法

雅可比迭代:

雅可比迭代和高斯赛德迭代的比较_第1张图片

雅可比迭代和高斯赛德迭代的比较_第2张图片

高斯赛德迭代:

雅可比迭代和高斯赛德迭代的比较_第3张图片

即在雅可比迭代的基础上,在计算用已经算出来的替换

可能会获得更好的收敛效果。

实验代码

#include
#include

#define MAX_SIZE 100 /* 矩阵最大维数 */
#define MAX_length 1000
#define bound pow(2, 127) /* 判断叠代发散的边界值 */
#define ZERO 0.000000001 /* 当一个正数小于ZERO就认为该数是0 */
/*做对角元变换,求系数矩阵B和常数项量f*/
double max(double a,double b)
{
    if(a>b)
      return a;
    else
      return b;
}
int maix(double a[][MAX_SIZE],double b[],double L[][MAX_SIZE],int n)
{
    int i,k,m;
    double t,tmp;
    for(i=0;it)
          {
              t=fabs(a[k][i]);
              m=k;
          }
        if(t!=0)
        {
           if(m!=i)
           {
            for(k=0;kt)
          {
              t=fabs(a[k][i]);
              m=k;
          }
          if(t==0)
            return 1;
          else
             {
               for(k=0;k=-bound&&s<=bound)
              xm[m][i]=s;
          else
             return -2;
          e=max(fabs(xm[m][i]-xm[m-1][i]),e);
      }
      /*printf("x%d=",m);
      for(i=0;iMAXN)
        break;
    }
    if(m<=MAXN)
    {
      for(i=0;i=-bound&&s<=bound)
             xm[m][i]=s;
          else
             return -2;
          e=max(fabs(xm[m][i]-xm[m-1][i]),e);
      }
      /*printf("x%d=",m);
      for(i=0;iMAXN)
        break;
    }
    if(m<=MAXN)
    {
      for(i=0;i

 

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(c/cpp)