Aldrich Taylor
Aldrich Taylor

Reputation: 141

Gauss-Seidel Method in MATLAB

I am trying to implement the Gauss-Seidel method in MATLAB. But there are two major mistakes in my code, and I could not fix them:

  1. My code converges very well on small matrices, but it never converges on large matrices.

  2. The code makes redundant iterations. How can I prevent from redundant iterations?

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);

Upvotes: 2

Views: 11150

Answers (2)

Lutz Lehmann
Lutz Lehmann

Reputation: 25992

First off, a generality. The Gauß-Seidel and Jacobi methods only apply to diagonally dominant matrices, not generic random ones. So to get correct test examples, you need to actually constructively ensure that condition, for instance via

A = rand(N,N)+N*eye(N)

or similar.

Else the method will diverge towards infinity in some or all components.


Now to some other strangeness in your implementation. What does

if(abs(x(i)-xold(j))<0.001)

mean? Note that this instruction is outside the loops where i and j are the iteration variables, so potentially, the index values are undefined. By inertia they will accidentally both have the value N, so this criterion makes at least a little sense.

What you want to test is some norm of the difference of the vectors as a whole, thus using sum(abs(x-xold))/N or max(abs(x-xold)). On the right side you might want to multiply with the same norm construction applied to x so that the test is for the relative error, taking the scale of the problem into account.


By the instructions in the given code, you are implementing the Jacobi iteration, computing all the updates first and then advancing the iteration vector. For the Gauß-Seidel variant you would need to replace the single components in-place, so that newly computed values are immediately used.


Also, you could shorten/simplify the inner loop

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)

or even shorter using the language features of 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)

Upvotes: 2

ragib777
ragib777

Reputation: 61

%Gauss-seidal method for three equations
clc;
x1=0;
x2=0;
x3=0;
m=input('Enter number of iteration');
for i=1:1:m
    x1(i+1)=(-0.01-0.52*x2(i)-x3(i))/0.3
    x2(i+1)=0.67-1.9*x3(i)-0.5*x1(i+1)
    x3(i+1)=(0.44-0.1*x1(i+1)-0.3*x2(i+1))/0.5
    er1=abs((x1(i+1)-x1(i))/x1(i+1))*100
    er2=abs((x2(i+1)-x2(i))/x2(i+1))*100
    er3=abs((x3(i+1)-x3(i))/x3(i+1))*100

    if er1<=0.01
       er2<=0.01
       er3<=0.01
        break;
    end
end

Upvotes: 0

Related Questions