function X = conjgrad(A,b,P,max1,tol)

% CONJGRAD  resava sistem linearnih jednacina Ax=b metodom konjugovanih
% gradijenata
%
% Poziv funkcije: x = conjgrad(A,b,P,max1,tol)
%
% Argumenti funkcije su :
%   A - simetricna matrica dimenzije NxN
%   B - vektor desne strane dimenzije Nx1
%   P - vektor dimenzije Nx1, pocetna aproksimacija (X0)
%   max1 - maksimalan broj iteracija
%   tol - proizvoljan argument - tolerancija za resenje. Ukoliko se ne
%   navede, podrazumevana vrednost mu je 1e-5
%
% Funkcija vraca:
%   vektor X dimenzije Nx1 - aproksimacija resnja sistema Ax=B 
%
% Autor : Zorica Drazic
% Verzija : 1.0
% Datum : 4.10.2009.
%


% ukoliko nije prosledjena vrednost za toleranciju resenja, postavljamo je
% na podrazumevanu vrednost 1e-5
    if nargin<5
        tol=1e-5;
    end
    
    % racunamo r0=Ax0-b
    r=A*P-b;
    % u pocetnoj iteraciji p0=r0
    p=r;
    % lamda =<r0,p0>/<Ap0,p0>
    lamda=(r'*p)/((A*p)'*p);
    % racunamo sledeci clan x1=x0-lamda*p0
    % oznake:
    % X = X(n+1) - dobijem u (n+1)-oj iteraciji
    % P = X(n) - dobijem u (n+1)-oj iteraciji
    X=P-lamda*p;
    
    % za svaku narednu iteraciju racunamo r,p,X
    for k=1:max1
        P=X;
        r=A*P-b;
        % ukoliko je postignuta odgovarajuca tacnost, prekidamo iterativni
        % postupak i vracamo rezultat
        if(norm(r)<tol)
            disp('Broj potrebnih iteracija: ');
            disp(k);
            return
        end
        % Mi = <Ap(n),r(n+1)> / <A*p(n),p(n)>
        M=(A*p)'*r/((A*p)'*p);
        % p(n) = r(n) - Mi*p(n-1)
        p=r-M*p;
        lamda=(p'*r)/((A*p)'*p);
        X=P-lamda*p;
    end

       
% ukoliko za max1 iteracija nije postignuta odgovarajuca tacnost:
error('Za zadati broj iteracija nije postignuta odgovarajuca tacnost.');
   
