数值分析4-解线性方程组的雅可比迭代法,高斯-塞德尔法的matlab程序

代码块1:雅可比迭代法:

clear;
clc;
fprintf('雅可比迭代法解线性方程组:\n')
n=input('请输入系数矩阵A的阶数:n=');
A=input('请输入系数矩阵A:A=');
b1=input('请输入结果向量b1:b1=');%b为行向量,计算时需要转置
x1=input('请输入初始向量x1:x1=');%x1为行向量,计算时需要转置
eps=input('请输入停止精度要求:eps=');
%产生分裂矩阵A=D-L-U
for i=1:n
    for j=1:n
        if i==j
            D(i,j)=A(i,j);
        else D(i,j)=0;
        end%生成矩阵D,存储A的对角元素
        if i>j
            L(i,j)=-A(i,j);
        else L(i,j)=0;
        end%生成矩阵L,存储A的下三角元素
        if i<j
            U(i,j)=-A(i,j);
        else U(i,j)=0;
        end%生成矩阵U,存储A的上三角元素
    end
end
D1=inv(D);%矩阵D的逆矩阵记作D1
B=D1*(L+U);% B=D\(L+U)可能运算更快一些,B为迭代矩阵;
f=D1*b1';%f为行向量
k=2;
xk=B*x1'+f;%xk为列向量,储存时需要转置
x=[x1;xk'];%按行存储
bk=A*xk;%bk为列向量,储存时需要转置
b=[b1;bk'];%按行存储
while max(abs(x(k,:)-x(k-1,:))) > (eps/2)%
    if k>1000||max(abs(eig(B)))>1%如果迭代矩阵B的谱半径大于1,则迭代不收敛
        error('迭代失败!可能是迭代精度过高或迭代矩阵谱半径大于1的缘故,迭代矩阵谱半径为:%0.8f\n',max(abs(eig(B))))
    else
        k=k+1;%第一次为k=3
        xk=B*x(k-1,:)'+f;%x(k-1,:)为x矩阵的第k-1行的行元素
        x=[x;xk'];%第一次后x矩阵为33列;
        bk=A*xk;
        b=[b;bk'];
    end
end
fprintf('经过%d次迭代,方程组的根的近似解为:',k-1)
disp(vpa(x(k,:),8));%输出矩阵第k行的所有元素
fprintf('雅可比迭代法迭代矩阵的谱半径为:%0.8f\n',max(abs(eig(B))))

代码块2:高斯-塞德尔迭代法

clear;
clc;
fprintf('Gauss_Seidel迭代法解线性方程组:\n')
n=input('请输入系数矩阵A的阶数:n=');
A=input('请输入系数矩阵A:A=');
b1=input('请输入结果向量b1:b1=');%b为行向量,计算时需要转置
x1=input('请输入初始向量x1:x1=');%x1为行向量,计算时需要转置
eps=input('请输入停止精度要求:eps=');
for i=1:n
    for j=1:n
        if i==j
            D(i,j)=A(i,j);
        else D(i,j)=0;
        end%生成矩阵D
        if i>j
            L(i,j)=-A(i,j);
        else L(i,j)=0;
        end%生成矩阵L
        if i<j
            U(i,j)=-A(i,j);
        else U(i,j)=0;
        end%生成矩阵U
    end
end
D1=inv(D-L);%矩阵(D-L)的逆矩阵记作D1。与雅可比迭代相比,仅仅此处发生变化
B=D1*U;%
f=D1*b1';%f为行向量
k=2;
xk=B*x1'+f;%xk为列向量,储存时需要转置
x=[x1;xk'];
bk=A*xk;
b=[b1;bk'];
while max(abs(x(k,:)-x(k-1,:)))>eps/2%
    if k>500||max(abs(eig(B)))>1%如果迭代矩阵B的谱半径大于1,则迭代不收敛
        error('迭代失败!可能是迭代精度过高或迭代矩阵谱半径大于1的缘故,迭代矩阵谱半径为:%0.8f\n',max(abs(eig(B))))
    else
        k=k+1;%第一次为k=3
        xk=B*x(k-1,:)'+f;%x(k-1,:)为X矩阵的第k-1行的行元素
        x=[x;xk'];%第一次后X矩阵为33列;
        bk=A*xk;
        b=[b;bk'];
    end
end
%vpa(x,8)
fprintf('经过%d次迭代,方程组的根的近似解为:\n',k-1)
disp(vpa(x(k,:),8));
fprintf('Gauss_Seidel迭代法迭代矩阵的谱半径为:%0.8f\n',max(abs(eig(B))))

1,分裂矩阵A=D-L-U与A=LU三角分解不同,不要混淆概念
2,不同的迭代方法有着不同的迭代矩阵B,因此他们的谱半径不相等,当谱半径大于1时,迭代不收敛,无法得到精确解
3,Jacobi迭代和gauss-seidel迭代代码绝大多数都是一样的,仅仅几行不同,他们原理一致,但是化迭代格式的时候高斯赛德尔用了新产生的数据,所以会更精确一些,收敛阶更高

你可能感兴趣的:(数值分析-matlab程序,matlab,算法,线性代数,矩阵)