我正在尝试在 MATLAB 中实现 Gauss-Seidel 方法。但我的代码中有两个重大错误,我无法修复它们:
我的代码在小矩阵上收敛得很好,但在大矩阵上却从不收敛。
代码进行了冗余迭代。如何防止冗余迭代?
Gauss-Seidel Method on wikipedia .
N=5;
A=rand(N,N);
b=rand(N,1);
x = zeros(N,1);
sum = 0;
xold = x;
tic
for n_iter=1:1000
for i = 1:N
for j = 1:N
if (j ~= i)
sum = sum + (A(i,j)/A(i,i)) * xold(j);
else
continue;
end
end
x(i) = -sum + b(i)/A(i,i);
sum = 0;
end
if(abs(x(i)-xold(j))<0.001)
break;
end
xold = x;
end
gs_time=toc;
prompt1='Gauss-Seidel Method Time';
prompt2='x Matrix';
disp(prompt2);
disp(x);
disp(prompt1);
disp(gs_time);
最佳答案
首先,概括一下。 Gauß-Seidel 和 Jacobi 方法仅适用于对角占优矩阵,不适用于一般随机矩阵。因此,为了获得正确的测试示例,您需要实际建设性地确保该条件,例如通过
A = rand(N,N)+N*eye(N)
或类似的。
Else the method will diverge towards infinity in some or all components.
现在来看看您的实现中的其他一些奇怪之处。是什么意思
if(abs(x(i)-xold(j))<0.001)
是什么意思?请注意,该指令位于循环外部,其中 i
和 j
是迭代变量,因此索引值可能未定义。由于惯性,它们会意外地同时具有值 N
,因此这个标准至少有一点意义。
您想要测试的是整个向量差异的一些范数,因此使用 sum(abs(x-xold))/N
或 max(abs(x -xold))
。在右侧,您可能需要乘以应用于 x
的相同范数构造,以便测试相对误差,同时考虑到问题的规模。
根据给定代码中的指令,您将实现雅可比迭代,首先计算所有更新,然后推进迭代向量。对于 Gauß-Seidel 变体,您需要就地替换单个组件,以便立即使用新计算的值。
此外,您可以缩短/简化内部循环
xold = x;
for i = 1:N
sum = b(i);
for j = 1:N
if (j ~= i)
sum = sum - A(i,j) * x(j);
end
end
x(i) = sum/A(i,i);
end
err = norm(x-xold)
使用 matlab 的语言功能甚至更短
xold = x
for i = 1:N
J = [1:(i-1) (i+1):N];
x(i) = ( b(i) - A(i,J)*x(J) )/A(i,i);
end
err = norm(x-xold)
关于matlab - MATLAB 中的高斯-赛德尔法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42012733/