function X=Jacobi(A,b,x0,e) % 线性方程的Jacobi迭代法 % A为系数矩阵n*n;b为右值n*1;x0为初值n*1,默认为全0;e为精度,默认为10^(-6) % BJ为Jacobi迭代矩阵,其基本迭代公式为 X = B*X + g % 编程过程中要用到的几个迭代收敛的充要条件: % 1,BJ的谱半径小于1 % 2,BJ的第一范式或无穷范式小于1 % 3,系数矩阵A是严格对角占优 % 以上三个条件只要满足其中一个即可使此迭代法对任意的初始向量x0都收敛 % % 作者:野渡无人 % 最后修改日期:2008.4.9 % % A=[10 -2 -1;-2 10 -1;-1 -2 5] % b=[3 15 10]' % % >> X=Jacobi(A,b) % 0 0.000000 0.000000 0.000000 % 1 0.300000 1.500000 2.000000 % 2 0.800000 1.760000 2.660000 % 3 0.918000 1.926000 2.864000 % 4 0.971600 1.970000 2.954000 % 5 0.989400 1.989720 2.982320 % 6 0.996176 1.996112 2.993768 % 7 0.998599 1.998612 2.997680 % 8 0.999490 1.999488 2.999165 % 9 0.999814 1.999815 2.999693 % 10 0.999932 1.999932 2.999889 % 11 0.999975 1.999975 2.999959 % 12 0.999991 1.999991 2.999985 % 13 0.999997 1.999997 2.999995 % 14 0.999999 1.999999 2.999998 % 15 1.000000 2.000000 2.999999 % 16 1.000000 2.000000 3.000000 % % X = % % 1.0000 % 2.0000 % 3.0000
[n,m]=size(A);
if n~=m error('请输入方阵'); end
if nargin==3 e=10^(-6); % 如果只输入3个参数,则默认e为10^(-6) end
if nargin==2 e=10^(-6); x0=zeros(n,1); % 如果只输入2个参数,则默认e为10^(-6),x0为全0列向量 end
% 初始化BJ,g,X,flag BJ=zeros(n); g=zeros(n,1); X=zeros(n,1); flag=0; % 用于检验是否满足迭代收敛的几个条件
sn=zeros(n,1); % 用于判别系数A是否为严格对角占优矩阵 for i=1:n tmp=0; for j=1:n tmp=tmp+abs(A(i,j)); end sn(i,1)=abs(2*A(i,i))-tmp; end if min(sn)>0 %fprintf('A为严格对角占优/n'); flag=flag+1; % 满足收敛条件3:系数矩阵A是严格对角占优,即可进行迭代 end
% 求迭代矩阵BJ的子过程 for i=1:n for j=1:n if j==i continue end BJ(i,j)=-A(i,j)/A(i,i); end g(i)=b(i)/A(i,i); end
lamda=eig(BJ); % lamda为BJ的特征值,以向量形式存放 if max(abs(lamda))<1 flag=flag+1; % 满足收敛条件1:BJ的谱半径小于1,即可以进行迭代 end if norm(BJ,1)<1 flag=flag+1; % 满足收敛条件2:BJ的第一范式小于1,即可以进行迭代 end
if norm(BJ,inf)<1 flag=flag+1; % 满足收敛条件2:BJ的无穷范式小于1,即可以进行迭代 end
if flag==0 error('所输入的参数不满足迭代收敛3个条件中的任一个,迭代不能进行!'); end
% 格式化输出迭代初值 l=0; %初始化迭代次数l fprintf('%3d ',l); fprintf(' %f',x0); fprintf('/n');
% 格式化输出第一次迭代值 l=l+1; X=BJ*x0+g;
fprintf('%3d ',l); for i=1:n fprintf(' %f',X(i)); end fprintf('/n');
% 进行迭代并格式化输出结果 while max(abs(X-x0))>e x0=X; X=BJ*x0+g; %max(abs(X-x0)); l=l+1; fprintf('%3d ',l); for i=1:n fprintf(' %f',X(i)); end fprintf('/n'); end