C语言实现雅克比迭代法求根

C语言实现雅克比迭代法求根

问题描述

设方程组 A x = b Ax = b Ax=b的系数矩阵 A A A非奇异 ,且 a i i ≠ 0 {a_{ii}} \ne 0 aii=0 A A A分裂为: A = D + L + U A = D + L + U A=D+L+U
D = d i a g ( a 11 , a 22 , ⋯ a n n ) D = diag({a_{11}},{a_{22}}, \cdots {a_{nn}}) D=diag(a11,a22,ann), L L L U U U分别是将 A A A对角元素置为 0 0 0的下三角和上三角矩阵,进行一系列转化形成迭代格式可求解方程组。

算法思想

将方程组
∑ i = 1 i = n a i j x i = b i , i = 1 , 2... , n \sum_{i=1}^{i=n}{ {a_{ij}}{x_i}} = {b_i}, {i = 1,2...,n} i=1i=naijxi=bi,i=1,2...,n
乘以 1 a i i \frac{1}{ { {a_{ii}}}} aii1,得到等价方程组
x i = 1 a i i ( b i − ∑ i = 1 i = n b i − a i j x i ) {x_i} = \frac{1}{ { {a_{ii}}}}({b_i} - \sum_{i=1}^{i=n}{b_i}- { {a_{ij}}{x_i}} ) xi=aii1(bii=1i=nbiaijxi)
简记为 x = B x + f x=Bx+f x=Bx+f.
其中, B = I − D − 1 = − D − 1 ( L + U ) , f = D − 1 b {B = I - {D^{-1}}}=-D^{-1}(L+U),f=D^{-1}b B=ID1=D1(L+U),f=D1b
我们称 φ ( x ) = B x + f \varphi (x) = Bx + f φ(x)=Bx+f为迭代函数,任取初始向量 x = x ( 0 ) x = {x^{(0)}} x=x(0),按照 x ( k + 1 ) = B x ( k ) + f {x^{(k + 1)}} = B{x^{(k)}} + f x(k+1)=Bx(k)+f形成的迭代格式,称这种迭代格式为雅克比迭代法。

C语言程序

#include <stdio.h>
#include <stdlib.h>
#include<math.h>
#define MaxSize 100
double A[MaxSize][MaxSize];
double B[MaxSize];
double C[MaxSize][MaxSize];
double D[MaxSize][MaxSize];//储存D逆
double E[MaxSize][MaxSize];//储存-(D-1)*(L+U)
double F[MaxSize];//(D-1)*B
double X[MaxSize];
double X1[MaxSize];
double Y[MaxSize];
#define e 1e-6//10的负6次方
int n;//矩阵尺寸大小
//所有迭代格式X(k+1)=B*X(k)+F,B范数<1,必收敛,B范数>1,未必发散
//雅克比迭代只适用于A[i][i]非0
void InitMatrix()
{
    
    
    int i,j;
    for(i=0;i<n;i++)
     for(j=0;j<n;j++)
     {
    
    
        if(i==j)
        {
    
    
            D[i][j]=1/A[i][i];
            E[i][j]=0;
        }
        if(i<j)
            E[i][j]=A[i][j];
        if(i>j)
            E[i][j]=A[i][j];
     }

}

void Jacobi()
{
    
    
    int i,j,k,r;
    double sum1,sum2,sum4=0;
    for(i=0;i<n;i++)
     for(j=0;j<n;j++)
     {
    
    
        sum1=0;
       for(k=0;k<n;k++)//矩阵运算
       {
    
    
        sum1=sum1+D[i][k]*E[k][j];
       }
       E[i][j]=-sum1;//(D-1)*(L+U)
     }
     //求E的F范数,判断是否收敛
     //E的F范数>1,不一定发散;但是E的F范数<1,一定收敛
     for(i=0;i<n;i++)
        for(j=0;j<n;j++)
         sum4=sum4+pow(E[i][j],2);
     if(sqrt(sum4)<1)
        printf("/*****B矩阵F范数<1,必有数值解!*****/\n");
     else
     printf("/*****B矩阵F范数>1,不一定有数值解!*****/\n");
     for(i=0;i<n;i++)
      {
    
    
          sum2=0;
          for(k=0;k<n;k++)
          {
    
    
              sum2=sum2+D[i][k]*B[k];
          }
          F[i]=sum2;//(D-1)*B
      }
    //X迭代
    for(r=1;r<100;r++)
    {
    
    
        int flag=0;
        double sum3;
        for(i=0;i<n;i++)
            X1[i]=X[i];//储存上一次迭代运算结果,必须在此处储存
        for(i=0;i<n;i++)
        {
    
    
        sum3=0;
        for(k=0;k<n;k++)
        {
    
    
         sum3=sum3+E[i][k]*X1[k];
        }
        X[i]=F[i]+sum3;//更新X[i]
        }
      for(j=0;j<n;j++)
          if(fabs(X[j]-X1[j])<e)//abs整型求绝对值,fabs浮点型求绝对值
            flag++;
     if(flag==n)
     {
    
    
        printf("迭代第%d次满足精度!\n",r);
        break;
     }
      printf("第%d次迭代向量X:\n",r);
     for(i=0;i<n;i++)
        printf("%lf\n",X[i]);
    }

}



void input()
{
    
    
    int i,j;
    printf("请输入系数矩阵A:\n");
    for(i=0;i<n;i++)
        for(j=0;j<n;j++)
        scanf("%lf",&A[i][j]);
    printf("请输入向量B:\n");
    for(i=0;i<n;i++)
        scanf("%lf",&B[i]);
    printf("请输入初始向量X:\n");
    for(i=0;i<n;i++)
        scanf("%lf",&X[i]);
}
void print()
{
    
    
  int i,j;
  printf("方程组的近似解:\n");
  for(i=0;i<n;i++)
    printf("%lf\n",X[i]);
}



int main()
{
    
    
    void InitMatrix();
    void Jacobi();
    void input();
    void print();
    printf("请输入矩阵行数:\n");
    scanf("%d",&n);
    printf("\n");
    input();
    InitMatrix();
    Jacobi();
    print();
    return 0;
}

实验结果

{ x 1 + 2 x 2 − 2 x 3 = 1 x 1 + x 2 + x 3 = 3 2 x 1 + 2 x 2 + x 3 = 5 \begin{cases} { {x_1} + 2{x_2} - 2{x_3} = 1}\\ { {x_1} + {x_2} + {x_3} = 3}\\ {2{x_1} + 2{x_2} + {x_3} = 5} \end{cases} x1+2x22x3=1x1+x2+x3=32x1+2x2+x3=5
初始向量为: x ( 0 ) = ( 0 , 0 , 0 ) T {x^{(0)}} = {(0,0,0)^T} x(0)=(0,0,0)T
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_41982200/article/details/109219340
今日推荐