2015-02-11 48 views
0

我似乎无法找到修复我的无限循环。我编写了一个Jacobi求解器来求解一个线性方程组。雅可比求解器进入无限循环

这里是我的代码:

function [x, i] = Jacobi(A, b, x0, TOL) 
[m n] = size(A); 
i = 0; 
x = [0;0;0]; 
while (true) 
    i =1; 

    for r=1:m 
     sum = 0; 
     for c=1:n 
      if r~=c 
       sum = sum + A(r,c)*x(c); 
      else 
       x(r) = (-sum + b(r))/A(r,c); 
      end  
      x(r) = (-sum + b(r))/A(r,c); 
xxx end          xxx 
    end 
    if abs(norm(x) - norm(x0)) < TOL; 
     break 
    end 
    x0 = x; 
    i = i + 1; 
end 

当我终止它在该行与XXX结束代码

+1

你怎么知道它是无限的? 'A'的大小是多少?当用循环遍历矩阵时,Matlab出了名的慢。如果可以的话,最好是将工作向量化。 – 2015-02-11 00:20:55

+1

A是3x3。我认为这不应该花很长时间 – user3681755 2015-02-11 00:22:03

+0

你的循环没有达到break语句。它可能是'if abs(norm(x) - norm(x0)) 2015-02-11 00:40:23

回答

1

之所以你的代码不工作是因为你的if语句的逻辑在您的for循环中。具体而言,您需要累积特定行的所有值,其中不是首先属于该行的对角线。一旦完成,你然后执行分工。您还需要确保按照A的对角线系数除以您所关注的那一行,这对应于您正在尝试解决的x的组件。您还需要在循环开始时删除i=1语句。您每次都重置i

换句话说:

function [x, i] = Jacobi(A, b, x0, TOL) 
[m n] = size(A); 
i = 0; 
x = [0;0;0]; 
while (true) 
    for r=1:m 
     sum = 0; 
     for c=1:n 
      if r==c %// NEW 
       continue; 
      end 
      sum = sum + A(r,c)*x(c); %// NEW 
     end          
     x(r) = (-sum + b(r))/A(r,r); %// CHANGE 
    end 
    if abs(norm(x) - norm(x0)) < TOL; 
     break 
    end 
    x0 = x; 
    i = i + 1; 
end 

实施例使用:

A = [6 1 1; 1 5 3; 0 2 4] 
b = [1 2 3].'; 
[x,i] = Jacobi(A, b, [0;0;0], 1e-10) 

x = 

    0.048780487792648 
    -0.085365853612062 
    0.792682926806031 


i = 

    20 

这意味着它需要20次迭代来实现与公差1e-10的溶液。与MATLAB内置的逆比较:

x2 = A \ b 

x2 = 

    0.048780487804878 
    -0.085365853658537 
    0.792682926829268 

正如你所看到的,我指定的1e-10的公差,这意味着我们保证有准确的10位小数。我们当然可以看到雅可比给我们的东西和MATLAB给我们内置的东西之间的10位小数精度。