Gauss-Seidel代码没有收敛于解决方案

时间:2014-02-10 13:49:59

标签: matlab matrix octave matrix-multiplication

我无法使用Gauss-Seidel算法获得收敛值

以下是代码:

A = [12 3   -5  2
     1  6   3   1
     3  7   13  -1
     -1 2   -1  7];

b = [2
    -3
    10
    -11];


ep = 1e-8;

[m, n] = size(A);
[n, p] = size(b);
x = zeros(n, 1001);

x(:, 1) = []


for k=0:1000

    ka = k + 1;

    if ka == 1001
       break;
    end

    xnew = zeros(n,1);

    for i=1:n

       sum = 0;

       j = 1;
       while j < i
          s1 = s1 + A(i,j) * x(j, ka + 1);
          j = j + 1;
       end

       j = i + 1;
       while j <= n
           sum = sum + A(i,j) * x(j, ka);
           j = j + 1;
       end

       xnew(i) = (b(i) - sum) / A(i, i);

       % if result is within error bounds exit loop
       if norm(b - A * xnew, 2) < ep * norm(b, 2)
          'ending'
          break
       end
    end

    x(:,ka + 1) = xnew;
end

我无法让A * xnew收敛于b我做错了什么?

我已尝试多次运行此更改语法,但我不断获取远离的值。

谢谢! 加布

1 个答案:

答案 0 :(得分:0)

您的代码基本上存在两个问题:

(1)您正在使用两个不同的变量“sum”和“s1”。我用mySum替换了它。顺便说一句,不要使用“sum”,因为有一个带有这个名字的matlab函数。

(2)我认为更新x时也存在问题;

我解决了这个问题,我也尝试改进你的代码:

(1)你不需要保存所有“x”;

(2)当你不知道你需要多少次迭代时,最好使用“while”而不是a。

(3)为了保持工作空间,一般使用“全部清除”和“全部关闭”是件好事。有时旧的计算可能会产生错误。例如,当您使用具有不同大小和相同名称的矩阵时。

(4)最好使用点/逗号分隔矩阵的行

您仍然可以改进此代码:

(1)你可以测试A是否是正方形,并且它是否满足使用这种数值方法所需的条件:是正定的还是对角占优的。

clear all
close all

A = [12 3   -5  2;
     1  6   3   1;
     3  7   13  -1;
     -1 2   -1  7];

b = [2;
    -3;
    10;
    -11];


ep = 1e-8;

n = length(b); % Note this method only works for A(n,n)



xNew=zeros(n,1);
xOld=zeros(n,1);

leave=false;

while(~leave)

    xOld=xNew;

     for i=1:n

       mySum = 0;    

       j = i + 1;
       while j <= n
           mySum = mySum + A(i,j) * xOld(j,1);
           j = j + 1;
       end

       j = 1;
       while j < i
          mySum = mySum + A(i,j) * xNew(j,1);
          j = j + 1;
       end

       mySum=b(i,1)-mySum;
       xNew(i,1) = mySum / A(i, i);
    end

      if (norm(b - A * xNew, 2) < ep * norm(b, 2))
          disp('ending');
          leave=true;
      end

    xOld = xNew;
end

xNew