雅各比到高斯 - 赛德尔

时间:2014-11-23 07:56:23

标签: matlab numerical-methods

我需要将我的Jacobi代码重构为Gauss-Seidel。我尝试了很多东西但到目前为止还没有任何工作。这是我当前的代码。如何将此代码更改为Gauss-Seidel需要做什么?

function z=jacobi(A,B)
C=A; D=B; [N N]=size(A);
for i=1:N
    C(i,:)=-C(i,:)/A(i,i);
    C(i,i)=0;
    D(i)=D(i)/A(i,i);
end
x=zeros(N,1);
y=C*x+D;
m=0;
while(norm(x-y)>0.00000001 && m<100)
    x=y;
    y=C*x+D;
    m=m+1;
end
z=y;
end

2 个答案:

答案 0 :(得分:0)

Jacobi求解器和Gauss-Seidel求解器之间的区别在于,当您在当前迭代中求解变量x_i的解时,需要使用先前变量的信息(x_1, x_2, ..., x_{i-1})作为当前变量x_i的解决方案的一部分。对于Jacobi,您只是使用前面的迭代解决方案来制定当前的解决方案。对于Gauss-Seidel,对于您求解的每个变量,必须使用从当前迭代计算的先前变量的解决方案作为您关注的变量的解决方案的一部分。

因此,对于您特定版本的代码(尽管不是最佳的......),您只需要添加一个for循环,我们一次一个地解决每个变量,然后继续这个信息转化为其他变量。这必须在while循环中完成,因为您正在进行迭代。

因此:

function z=gaussseidel(A,B) %// Change the function name
C=A; D=B; [N N]=size(A);
for i=1:N
    C(i,:)=-C(i,:)/A(i,i);
    C(i,i)=0;
    D(i)=D(i)/A(i,i);
end
x=zeros(N,1);
y=C*x+D;
m=0;
while(norm(x-y)>0.00000001 && m<100)
    x=y;
    %// Change here
    for idx = 1 : N
        if idx == 1 %// Case where we are solving for the first variable
            y(idx) = C(idx,:)*x + D(idx);
        else %// Everything else
            y(idx) = C(idx,1:idx-1)*y(1:idx-1) + C(idx,idx:end)*x(idx:end) + D(idx);
        end
    end
    m=m+1;
end
z=y;
end

仔细查看代码。如果我们正在计算第一个变量,那么我们还没有任何新信息,因此我们只需使用上一次迭代中的所有先前信息更新解决方案。一旦我们通过这一点,那么我们使用从第一个变量到我们计算点的当前迭代计算的变量,然后使用其余的变量来计算解。


如果你愿意,还有另一种计算Jacobi和Gauss-Seidel的方法,你可以在这里看一下这篇文章:Jacobi iteration doesn't end。这段代码最初是为Jacobi编写的,我提供了修改它以使其成为Gauss-Seidel。

祝你好运!

答案 1 :(得分:0)

重组代码的另一个版本。 顺便说一句,这段代码并不比jacobi代码快,但是在较少的迭代中找到了解决方案。

function [z,m]=seidel(A,B)
C=A; D=B; [N N]=size(A);
for i=1:N
 C(i,:)=-C(i,:)/A(i,i);
 C(i,i)=0;
 D(i)=D(i)/A(i,i);
end
x=zeros(N,1);
m=0;
while (m<100)
 t=x;
 m=m+1;
 for j=1:N
   y(j)=C(j,:)*x+D(j);
   x(j)=y(j);
 end
 if(norm(x-t)<0.00000001)
    break;
 end
end
z=y';
end