function [x, flag, k, rez]  = gaussseidel0( A, b, x0, max_it, rez_01, tol )
% Funkcija gaussseidel0 rjesava sustav A*x = b u kojem je A n-puta-n matrica
% za koju se pretpostavlja da je strogo dijagonalno dominantna ili
% ireducibilno dijagonalno dominantna. Sama funkcija ne provjerava to
% svojstvo - odgovornost je na funkciji koja poziva gaussseidel0.
% PMF-Matematicki odjel
% Numericka analiza 1 (Zlatko Drmac)
%
% Ulazni parametri:
% =================
% A      :: n-puta-n strogo dijagonalno dominantna ili ireducibilno dijagonalno
%           dominantna matrica
% b      :: n-puta-1 vektor, desna strana sustava jednadzbi.
% x0     :: n-puta-1 vektor, pocetna iteracija
% max_it :: prirodan broj, maksimalni dozvoljeni broj iteracija
% rez_01 :: 0 ili 1, definira tip reziduala:
%           rez_01 = 0 :   rezidual = || b - A*x || / ||b||
%           rez_01 = 1 :   rezidual = || b - A*x || / ( ||A||*||x|| + ||b|| )
% tol    :: prag tolerancije za rezidual
%           ako je rezidual manji od tol, x je prihvacen kao aproksimacija
%           rjesenja i iteracije prestaju.
%
% Izlazni parametri:
% ==================
% x    :: n-puta-1 vektor, 
%         ako je flag = 0, x je aproksimacija rjesenja i zadovoljava 
%         kriterij zaustavljanja (rezidual dovoljno mali)
%         ako je flag = 1, x je vektor izracunat u zadnjoj (k=max_it)
%         iteraciji.
% flag :: ako je flag = 0, izracunati x je zadovolji kriterij
%         zaustavljanja, inace nije.
% k    :: indeks zadnje iteracije
% rez  :: rez(1:k) sadrzi vrijednosti reziduala svih iteracija, tj. sadrzi
%         povijest konvergencije.
%

n       = max(size(A)) ;
b2norm  = norm(b)      ;
Anorm   = norm(A,'fro')*rez_01 ;

flag = 0 ;

if b2norm == 0
    x = zeros(n,1) ;
    k = 1          ;
    rez(1) = 0     ;
    return
end

k = 1 ;
x = x0 ;
rez(1) = norm(b - A*x0) / (Anorm*norm(x0)+b2norm) ;

if ( rez(1) < tol ) return, end

for k = 2 : max_it
%   ..    
%   .. jedan korak Gauss-Seidelove metode    
    for i = 1 : n
        x(i) = ( b(i) - ( A(i,1:n)*x(1:n) - A(i,i)*x(i) ) ) / A(i,i) ;   
    end
%   ..
%   .. pripadni rezidual pospremljen u vektor za 'post festum' analizu
    rez(k) = norm(b-A*x) / (Anorm*norm(x)+b2norm) ;
%   ..
%   .. ako je rezidual manji od zadanog praga, prihvacamo x kao dobru
%   aproksimaciju rjesenja.
    if ( rez(k) <= tol ), break, end 
% 
end
% .. zavrsio maksimalni broj iteracija. Ako ni tada nije zadovoljen
% kriterij zaustavljanja, podigni zastavicu.

if ( rez(k) > tol ) flag = 1; end;
