%SOR:逐次超松弛迭代法
%本函数只能求解当A为n*n的矩阵
%2010-10-21
function x=SOR(A,b,w)
tic;
if nargin==2
w=1.23;%默认松弛因子w=1.23
end
if w<0
error('MATLAB:SOR:Argument w:should be larger than 0',...
'recomanded range is 0<w<2 .See SOR.');
end
t=size(A);%获取A的行列
n=t(1);
D=zeros(n,n);
L=zeros(n,n);
U=zeros(n,n);%初始化三个矩阵
x1=zeros(n,1);
x2=zeros(n,1);%初始结果矩阵
%获取三个矩阵D,L,U
for i=1:n
for j=1:n
if i>j
L(i,j)=A(i,j);
elseif i<j
U(i,j)=A(i,j);
else
D(i,j)=A(i,j);
end
end
end
G=-inv(D/w+L)*((1-1/w)*D+U);%计算迭代矩阵
%计算迭代矩阵的谱半径,即绝对值最大的特征值
rho=max(abs(eig(G)));
%rho就是G的谱半径
if rho>1 %谱半径大于1,迭代不收敛……
error('MATLAB:SOR:the Iteration Matrix may not be Astringent.See SOR.');
end
fid=fopen('SOR-Output.txt','w');%用文件保存每次迭代结果
y=1;%y代表迭代深度
while 1 %matlab中没有do-while循环,可用break跳出
for i=1:n
temp1=0;
for j=1:i-1
temp1=temp1+A(i,j)*x2(j)/A(i,i);
end
temp2=0;
for j=i+1:n
temp2=temp2+A(i,j)*x1(j)/A(i,i);
end
x2(i)=w*(b(i)/A(i,i)-temp1-temp2-(1-1/w)*x1(i));
end
fprintf(fid,'%d\t',y);
for z=1:n %将数据写入文件
fprintf(fid,'%2.8f\t',x2(z));
end
fprintf(fid,'\r\n');%输出完一次结果,换行
if norm(x2-x1)<1e-10
break;%迭代结束
end
x1=x2; %继续下一轮迭代
y=y+1;
end
x=x2;%返回计算结果
fclose(fid);%关闭文件
toc;