% zad 7.43.

% Funkcional
f   = inline('x.^2 + y.^2 + x.*y', 'x', 'y');
% Prvi izvodi - potrebni za gradijent
fx  = inline('2*x+y', 'x', 'y'); 
fy  = inline('2*y+x','x', 'y');
% Drugi izvodi - potrebni sa Hessian
fxx = inline('2', 'x', 'y'); 
fxy = inline('1', 'x', 'y'); 
fyx = inline('1', 'x', 'y'); 
fyy = inline('2', 'x', 'y');

% Pocetna iteracija i tacnost
x0 = 1; 
y0 = 2; 
epsilon = 1e-6;

% Postavljamo vrednost tekuce iteracije na pocetnu
x = x0;  
y = y0;

while(1)  
   % Pamtimo vrednosti prethodne iteracije
   xp = x; 
   yp = y;
   
   % Izracunavamo vektor gradijenta u tekucoj tacki
   d = -[feval(fx, x, y) feval(fy, x, y)];
   
    % Izracunavamo vrednost Hessiana u tekucoj tacki
    H = [feval(fxx, x, y) feval(fxy, x, y);...
         feval(fyx, x, y) feval(fyy, x, y)];

    % Ukoliko tekuca tacka nije stacionarna izracunavamo koeficijenat lambda
    % koji odredjuje "koliko dugo" je potrebno spustati se u pravcu d 
    if (~isequal(d,[0 0]))
        lambda = d*d'/(d*H*d');
    else
        % Ukoliko je tacka stacionarna, nasli smo lokalni minimum
        break;
    end
    
    % Izracunavamo vrednost nove tacke
    x = x + lambda*d(1); 
    y = y + lambda*d(2); 
    
    % Ukoliko je postignuta zeljena tacnost prekidamo iterativni postupak
    if (abs(x-xp)<epsilon & abs(y-yp)<epsilon)
        break;    
    end    
end

disp('Minimum funkcije je u tackama:');
disp('x=');
disp(x);
disp('y=');
disp(y);

