我正在做科学计算的家庭作业,特别是matlab中的Gauss-Seidel和SOR迭代方法,问题在于矩阵给出了意想不到的结果(解决方案不会收敛),而另一个矩阵收敛。
继承人的代码,其中:
这是sor方法的代码:
function [x2,iter] = sor(A,xIni, b, maxIter, tol,w)
x1 = xIni;
x2 = x1;
iter = 0;
i = 0;
j = 0;
n = size(A, 1);
for iter = 1:maxIter,
for i = 1:n
a = w / A(i,i);
x = 0;
for j = 1:i-1
x = x + (A(i,j) * x2(j));
end
for j = i+1:n
x = x + (A(i,j) * x1(j));
end
x2(i) = (a * (b(i) - x)) + ((1 - w) * x1(i));
end
x1 = x2;
if (norm(b - A * x2) < tol);
break;
end
end
以下是Gauss-seidel方法的代码:
function [x, iter] = Gauss(A, xIni, b, maxIter, tol)
x = xIni;
xnew = x;
iter = 0;
i = 0;
j = 0;
n = size(A,1);
for iter = 1:maxIter,
for i = 1:n
a = 1 / A(i,i);
x1 = 0;
x2 = 0;
for j = 1:i-1
x1 = x1 + (A(i,j) * xnew(j));
end
for j = i+1:n
x2 = x2 + (A(i,j) * x(j));
end
xnew(i) = a * (b(i) - x1 - x2);
end
x= xnew;
if ((norm(A*xnew-b)) <= tol);
break;
end
end
对于此输入:
A = [1 2 -2; 1 1 1; 2 2 1];
b = [1; 2; 5];
调用Gauss-Seidel或sor函数时:
[x, iter] = gauss(A, [0; 0; 0], b, 1000, eps)
[x, iter] = sor(A, [0; 0; 0], b, 1000, eps, 1.5)
高斯的输出是:
x =
1.0e+304 *
1.6024
-1.6030
0.0011
iter =
1000
而对于sor来说:
x =
NaN
NaN
NaN
iter =
1000
然而,以下系统能够找到解决方案:
A = [ 4 -1 0 -1 0 0;
-1 4 -1 0 -1 0;
0 -1 4 0 0 -1;
-1 0 0 4 -1 0;
0 -1 0 -1 4 -1;
0 0 -1 0 -1 4 ]
b = [1 0 0 0 0 0]'
解决方案:
[x, iter] = sor(A, [0; 0; 0], b, 1000, eps, 1.5)
x =
0.2948
0.0932
0.0282
0.0861
0.0497
0.0195
iter =
52
方法的行为取决于两个矩阵的条件?因为我注意到第二个矩阵的条件比第一个矩阵好。有什么建议吗?
答案 0 :(得分:4)
来自wiki article on Gauss-Seidel:
只有当矩阵是对角占优的,或对称的和肯定的时,才能保证收敛
由于SOR类似于Gauss-Seidel,我希望SOR能够保持相同的条件,但你可能希望看一下。
你的第一个矩阵肯定不是对角占优或对称的。然而,你的第二个矩阵是对称的和肯定的(因为all(A==A.')
和all(eig(A)>0)
)。
如果您使用Matlab的默认方法(A\b
)作为“真实”解决方案,并绘制每次迭代与“真实”解决方案之间差异的标准,那么您将获得下面的两个图表。很明显,第一个矩阵永远不会收敛,而第二个矩阵在几次迭代后已经产生了可接受的结果。
在在野外应用之前,始终了解算法的局限性。