雅可比迭代并未结束

时间:2014-07-14 06:53:13

标签: matlab numerical-methods numerical numerical-analysis

我试图在MATLAB中实现Jacobi迭代,但我无法使其收敛。我已经在网上和其他地方查找了用于比较的工作代码但是我找不到任何与我的代码类似的东西并且仍然有效。这就是我所拥有的:

function x = Jacobi(A,b,tol,maxiter)

n = size(A,1);
xp = zeros(n,1); 
x = zeros(n,1); 
k=0; % number of steps

while(k<=maxiter)
    k=k+1;

    for i=1:n
       xp(i) = 1/A(i,i)*(b(i) - A(i,1:i-1)*x(1:i-1) - A(i,i+1:n)*x(i+1:n));
    end

    err = norm(A*xp-b);

    if(err<tol)
        x=xp;
        break;
    end

    x=xp;

end

无论我用什么A和b,这都会爆炸。这可能是我忽略的一个小错误,但如果有人能够解释错误是什么,我将非常感激,因为这应该是正确的但在实践中并非如此。

3 个答案:

答案 0 :(得分:7)

您的代码是正确的。它可能似乎不起作用的原因是因为您在使用Jacobi迭代时指定可能不收敛的系统。

具体而言(感谢@Saraubh),如果您的矩阵A 严格 diagonally dominant,此方法将会收敛。换句话说,对于矩阵中的每一行i,行j处的所有列i的绝对求和,i处的对角线系数必须<强比对角线本身更少。换句话说:

blah

但是,有些系统会与Jacobi会聚,即使这种情况不满意,但在尝试将Jacobi用于您的系统之前,您应该将其作为一般规则使用。如果你使用Gauss-Seidel,它实际上更稳定。唯一的区别是您正在重新使用x的解决方案,并在向下进行时将其提供给其他变量。要制作这个Gauss-Seidel,您所要做的就是更改for循环中的一个字符。改变它:

xp(i) = 1/A(i,i)*(b(i) - A(i,1:i-1)*x(1:i-1) - A(i,i+1:n)*x(i+1:n));

对此:

xp(i) = 1/A(i,i)*(b(i) - A(i,1:i-1)*xp(1:i-1) - A(i,i+1:n)*x(i+1:n));
                                    **HERE**

以下是我将向您展示的两个例子:

  1. 我们指定一个雅可比不会聚的系统,但有一个解决方案。该系统对角占优势。
  2. 我们指定一个由雅可比收敛的系统。具体而言,该系统是对角占优势的。

  3. 示例#1

    A = [1 2 2 3; -1 4 2 7; 3 1 6 0; 1 0 3 4];
    b = [0;1;-1;2];
    x = Jacobi(A, b, 0.001, 40)
    xtrue = A \ b
    
    x =
    
    1.0e+09 *
    
    4.1567
    0.8382
    1.2380
    1.0983
    
    xtrue =
    
    -0.1979
    -0.7187
     0.0521
     0.5104
    

    现在,如果我使用Gauss-Seidel解决方案,这就是我得到的:

    x =
    
    -0.1988
    -0.7190
    0.0526
    0.5103
    

    哇!虽然系统不是对角占优势,但它可以为Gauss-Seidel而非雅可比收敛,我可能会对此有一个解释,我稍后会提供。

    示例#2

    A = [10 -1 2 0; -1 -11 -1 3; 2 -1 10 -1; 0 3 -1 8];
    b = [6;25;-11;15];
    x = Jacobi(A, b, 0.001, 40);
    xtrue = A \ b
    
    x =
    
    0.6729
    -1.5936
    -1.1612
    2.3275
    
    xtrue =
    
    0.6729
    -1.5936
    -1.1612
    2.3274
    

    这是我用Gauss-Seidel得到的:

    x =
    
    0.6729
    -1.5936
    -1.1612
    2.3274
    

    这两者肯定会收敛,而且系统是对角占优势的。


    因此,您的代码存在 nothing 错误。您只是指定使用Jacobi解决无法的系统。最好将Gauss-Seidel用于围绕这种求解的迭代方法。原因是因为您立即使用当前迭代中的信息并将其传播到其余变量。雅可比不这样做,这就是为什么它更快地分化的原因。对于Jacobi,您可以看到Example#1未能收敛,而Example#2则收敛。 Gauss-Seidel融合了两者。事实上,当它们两者融合时,它们都非常接近真正的解决方案。

    同样,您需要确保您的系统具有对角占优势,因此您可以保证收敛。没有执行这条规则......好吧......你将承担风险,因为它可能会或可能不会收敛。

    祝你好运!

答案 1 :(得分:1)

虽然这并没有指出代码中的问题,但我相信您正在寻找Numerical Methods: Jacobi File Exchange Submission

%JACOBI   Jacobi iteration for solving a linear system.
% Sample call
%   [X,dX] = jacobi(A,B,P,delta,max1)
%   [X,dX,Z] = jacobi(A,B,P,delta,max1)

它似乎正是你所描述的。

答案 2 :(得分:0)

正如其他人所指出的那样,并非所有系统都使用雅可比方法收敛,但他们没有指出为什么?实际上只有一小部分系统与Jacobi方法汇合。

收敛标准是“一行中所有系数(非对角线)之和”必须小于“该行中对角线位置处的系数”。所有行都必须满足此标准。您可以在以下网址了解详情:Jacobi Method Convergence

在决定使用Jacobi方法之前,您必须查看数值方法是否满足此标准。 Gauss-Seidel方法具有稍微宽松的收敛标准,允许您将其用于大多数有限差分型数值方法。