用Matlab写的雅各比i和高斯塞德尔以及SOR迭代法

因为不会使用Matlab,所以希望程序一点错误也不要有。最佳答案还会有追加分。

1. 用雅克比迭代法和高斯--赛德尔迭代法求解下列方程组,取迭代初值[0;0;0]。
(1) 编程求解,并与用数学软件求解的结果对比。
(2) 考察迭代法的收敛性,若均收敛,对比两种方法的收敛速度。

解:源程序:
①雅克比迭代法:建立函数文件jacobi.m
function [n,x]=jacobi(A,b,X,nm,w)
%用雅克比迭代法求解方程组Ax=b
%输入:A为方程组的系数矩阵,b为方程组右端的列向量,X为迭代初值构成的列向量,nm为最大迭代次数,w为误差精度
%输出:x为求得的方程组的解构成的列向量,n为迭代次数
n=1;
m=length(A);
D=diag(diag(A)); %令A=D-L-U,计算矩阵D
L=tril(-A)+D; %令A=D-L-U,计算矩阵L
U=triu(-A)+D; %令A=D-L-U,计算矩阵U
M=inv(D)*(L+U); %计算迭代矩阵
g=inv(D)*b; %计算迭代格式中的常数项
%下面是迭代过程
while n<=nm
x=M*X+g; %用迭代格式进行迭代
if norm(x-X,2)<w
disp('迭代次数为');n
disp('方程组的解为');x
return;
%上面:达到精度要求就结束程序,输出迭代次数和方程组的解
end
X=x;n=n+1;
end
%下面:如果达到最大迭代次数仍不收敛,输出警告语句及迭代的最终结果(并不是方程组的解)
disp('在最大迭代次数内不收敛!');
disp('最大迭代次数后的结果为');x
②高斯赛德尔迭代法:建立函数文件gaussseidel.m
function [n,x]=gaussseidel(A,b,X,nm,w)
%用高斯-赛德尔迭代法求解方程组Ax=b
%输入:A为方程组的系数矩阵,b为方程组右端的列向量,X为迭代初值构成的列向量,nm为最大迭代次数,w为误差精度
%输出:x为求得的方程组的解构成的列向量,n为迭代次数
n=1;
m=length(A);
I=eye(m); %生成m*m阶的单位矩阵
D=diag(diag(A)); %令A=D-L-U,计算矩阵D
L=tril(-A)+D; %令A=D-L-U,计算矩阵L
U=triu(-A)+D; %令A=D-L-U,计算矩阵U
M=inv(D-L)*U; %计算迭代矩阵
g=inv(I-inv(D)*L)*(inv(D)*b); %计算迭代格式中的常数项
%下面是迭代过程
while n<=nm
x=M*X+g; %用迭代格式进行迭代
if norm(x-X,2)<w
disp('迭代次数为');n
disp('方程组的解为');x
return;
%上面:达到精度要求就结束程序,输出迭代次数和方程组的解
end
X=x;n=n+1;
end
%下面:如果达到最大迭代次数仍不收敛,输出警告语句及迭代的最终结果(并不是方程组的解)
disp('在最大迭代次数内不收敛!');
disp('最大迭代次数后的结果为');x
运行过程及结果:
①雅克比迭代法的运行过程及结果为:
>> A=[10,3,1;2,-11,3;1,3,12];
b=[2;-5;4];
X=[0;0;0];
nm=50;
w=10^-6;
>> jacobi(A,b,X,nm,w)
迭代次数为
n =
14
方程组的解为
x =
0.0254
0.5144
0.2026
②高斯赛德尔迭代法的运行过程及结果为:
>> A=[10,3,1;2,-11,3;1,3,12];
b=[2;-5;4];
X=[0;0;0];
nm=50;
w=10^-6;
>> gaussseidel(A,b,X,nm,w)
迭代次数为
n =
6
方程组的解为
x =
0.0254
0.5144
0.2026
③用matlab中的A\b命令的运行过程及结果如下:
>> A=[10,3,1;2,-11,3;1,3,12];
b=[2;-5;4];
>> A\b
ans =
0.0254
0.5144
0.2026
(1)由运行结果可知,编程得到的方程组的解为[0.0254;0.5144;0.2026]。而用matlab中的A\b命令求出的方程组的解为[0.0254;0.5144;0.2026],完全一致。
(2)由运行过程可知,两种方法均收敛,雅克比迭代次数为14,高斯赛德尔迭代次数为6,说明后者的迭代速度比前者快。

2.用超松弛迭代法求解方程组,分别取松弛因子 ,取迭代初值[0;0;0],迭代30次或满足 时停止计算。
(1) 编程求解,并与用数学软件求解的结果对比。
(2) 考察迭代是否收敛,若收敛,松弛因子取何值时收敛最快,与有关定理的结论对照,看结果是否一致。

解:源程序:
①超松弛迭代法:建立函数文件sor22.m
function [n,x]=sor22(A,b,X,nm,w,ww)
%用超松弛迭代法求解方程组Ax=b
%输入:A为方程组的系数矩阵,b为方程组右端的列向量,X为迭代初值构成的列向量,nm为最大迭代次数,w为误差精度,ww为松弛因子
%输出:x为求得的方程组的解构成的列向量,n为迭代次数
n=1;
m=length(A);
D=diag(diag(A)); %令A=D-L-U,计算矩阵D
L=tril(-A)+D; %令A=D-L-U,计算矩阵L
U=triu(-A)+D; %令A=D-L-U,计算矩阵U
M=inv(D-ww*L)*((1-ww)*D+ww*U); %计算迭代矩阵
g=ww*inv(D-ww*L)*b; %计算迭代格式中的常数项
%下面是迭代过程
while n<=nm
x=M*X+g; %用迭代格式进行迭代
if norm(x-X,'inf')<w
disp('迭代次数为');n
disp('方程组的解为');x
return;
%上面:达到精度要求就结束程序,输出迭代次数和方程组的解
end
X=x;n=n+1;
end
%下面:如果达到最大迭代次数仍不收敛,输出警告语句及迭代的最终结果(并不是方程组的解)
disp('在最大迭代次数内不收敛!');
disp('最大迭代次数后的结果为');x
②向后超松弛迭代法:建立函数文件sorxh22.m
function [n,x]=sorxh22(A,b,X,nm,w,ww)
%用向后超松弛迭代法求解方程组Ax=b
%输入:A为方程组的系数矩阵,b为方程组右端的列向量,X为迭代初值构成的列向量,nm为最大迭代次数,w为误差精度,ww为松弛因子
%输出:x为求得的方程组的解构成的列向量,n为迭代次数
n=1;
m=length(A);
D=diag(diag(A)); %令A=D-L-U,计算矩阵D
L=tril(-A)+D; %令A=D-L-U,计算矩阵L
U=triu(-A)+D; %令A=D-L-U,计算矩阵U
M=inv(D-ww*U)*((1-ww)*D+ww*L); %计算矩阵迭代矩阵
g=ww*inv(D-ww*U)*b; %计算迭代格式中的常数项
%下面是迭代过程
while n<=nm
x=M*X+g; %用迭代格式进行迭代
if norm(x-X,'inf')<w
disp('迭代次数为');n
disp('方程组的解为');x
return;
%上面:达到精度要求就结束程序,输出迭代次数和方程组的解
end
X=x;n=n+1;
end
%下面:如果达到最大迭代次数仍不收敛,输出警告语句及迭代的最终结果(并不是方程组的解)
disp('在最大迭代次数内不收敛!');
disp('最大迭代次数后的结果为');x
③对称超松弛迭代法:建立函数文件ssor22.m
function [n,x]=ssor22(A,b,X,nm,w,ww)
%用对称超松弛迭代法求解方程组Ax=b
%输入:A为方程组的系数矩阵,b为方程组右端的列向量,X为迭代初值构成的列向量,nm为最大迭代次数,w为误差精度,ww为松弛因子
%输出:x为求得的方程组的解构成的列向量,n为迭代次数
n=1;
m=length(A);
I=eye(m); %生成m*m阶的单位矩阵
D=diag(diag(A)); %令A=D-L-U,计算矩阵D
L=tril(-A)+D; %令A=D-L-U,计算矩阵L
U=triu(-A)+D; %令A=D-L-U,计算矩阵U
%下面计算迭代矩阵和迭代格式中的常数项
M=inv(D-ww*U)*((1-ww)*D+ww*L)*inv(D-ww*L)*((1-ww)*D+ww*U); g=ww*inv(D-ww*U)*(I+((1-ww)*D+ww*L)*inv(D-ww*L))*b;
%下面是迭代过程
while n<=nm
x=M*X+g; %用迭代格式进行迭代
if norm(x-X,'inf')<w
disp('迭代次数为');n
disp('方程组的解为');x
return;
%上面:达到精度要求就结束程序,输出迭代次数和方程组的解
end
X=x;n=n+1;
end
%下面:如果达到最大迭代次数仍不收敛,输出警告语句及迭代的最终结果(并不是方程组的解)
disp('在最大迭代次数内不收敛!');
disp('最大迭代次数后的结果为');x
温馨提示:答案为网友推荐,仅供参考
第1个回答  2011-05-13
可以参考MATLAB语言常用算法程序集
SOR迭代法AX=b
function [x,n]=SOR(A,b,x0,w,eps,M)
if nargin==4
eps= 1.0e-6;
M = 200;
elseif nargin<4
error
return
elseif nargin ==5
M = 200;
end

if(w<=0 || w>=2)
error;
return;
end

D=diag(diag(A)); %求A的对角矩阵
L=-tril(A,-1); %求A的下三角阵
U=-triu(A,1); %求A的上三角阵
B=inv(D-L*w)*((1-w)*D+w*U);
f=w*inv((D-L*w))*b;
x=B*x0+f;
n=1; %迭代次数

while norm(x-x0)>=eps
x0=x;
x =B*x0+f;
n=n+1;
if(n>=M)
disp('Warning: 迭代次数太多,可能不收敛!');
return;
end
end
块雅克比迭代法求线性方程组Ax=b的解
function [x,N]= BJ(A,b,x0,d,eps,M)
if nargin==4
eps= 1.0e-6;
M = 10000;
elseif nargin<4
error
return
elseif nargin ==5
M = 10000; %参数的默认值
end

NS = size(A);
n = NS(1,1);
if(sum(d) ~= n)
disp('分块错误!');
return;
end
bnum = length(d);
bs = ones(bnum,1);
for i=1:(bnum-1)
bs(i+1,1)=sum(d(1:i))+1;
%获得对角线上每个分块矩阵元素索引的起始值
end

DB = zeros(n,n);
for i=1:bnum
endb = bs(i,1)+d(i,1)-1;
DB(bs(i,1):endb,bs(i,1):endb)=A(bs(i,1):endb,bs(i,1):endb);
%求A的对角分块矩阵
end
for i=1:bnum
endb = bs(i,1)+d(i,1)-1;
invDB(bs(i,1):endb,bs(i,1):endb)=inv(DB(bs(i,1):endb,bs(i,1):endb));
%求A的对角分块矩阵的逆矩阵
end

N = 0;
tol = 1;
while tol>=eps
x = invDB*(DB-A)*x0+invDB*b; %由于LB+DB=DB-A
N = N+1; %迭代步数
tol = norm(x-x0); %前后两步迭代结果的误差
x0 = x;
if(N>=M)
disp('Warning: 迭代次数太多,可能不收敛!');
return;
end
end
高斯-赛德尔迭代法求线性方程组Ax=b的解
function [x,N]= BJ(A,b,x0,d,eps,M)
if nargin==4
eps= 1.0e-6;
M = 10000;
elseif nargin<4
error
return
elseif nargin ==5
M = 10000; %参数的默认值
end

NS = size(A);
n = NS(1,1);
if(sum(d) ~= n)
disp('分块错误!');
return;
end
bnum = length(d);
bs = ones(bnum,1);
for i=1:(bnum-1)
bs(i+1,1)=sum(d(1:i))+1;
%获得对角线上每个分块矩阵元素索引的起始值
end

DB = zeros(n,n);
for i=1:bnum
endb = bs(i,1)+d(i,1)-1;
DB(bs(i,1):endb,bs(i,1):endb)=A(bs(i,1):endb,bs(i,1):endb);
%求A的对角分块矩阵
end
for i=1:bnum
endb = bs(i,1)+d(i,1)-1;
invDB(bs(i,1):endb,bs(i,1):endb)=inv(DB(bs(i,1):endb,bs(i,1):endb));
%求A的对角分块矩阵的逆矩阵
end

N = 0;
tol = 1;
while tol>=eps
x = invDB*(DB-A)*x0+invDB*b; %由于LB+DB=DB-A
N = N+1; %迭代步数
tol = norm(x-x0); %前后两步迭代结果的误差
x0 = x;
if(N>=M)
disp('Warning: 迭代次数太多,可能不收敛!');
return;
end
end
第2个回答  2011-05-16
诶呀,我这学期正好在学~可是都没去上课~
相似回答