% Metoda zlateho rezu 06

funkce='-2*sin(x) + sin(2*x) - 2*sin(3*x)/3';     % ucelova funkce
a=1; b=3;                             % krajni hodnoty intervalu I=[a,b] 

fplot(funkce,[a,b],'r')    % graf funkce
line([2.356,2.356],[-3.185,-2.585])      % vyznaceni skutecneho minima
hold on;

disp(' '); % vlozi prazdny radek na vystupni obrazovku

% vypis na obrazovku

disp(sprintf('Je zadana funkce f=%s a interval [a,b]=[%f,%f].',funkce,a,b));
disp(sprintf('Nasim cilem je najit minimum funkce f s presnosti 0,0001.'));

disp(' '); % vlozi prazdny radek na vystupni obrazovku

r=((5^(0.5))-1)/2;          % rez r

i=0;         % promenna urcena k pocitani iteraci
chyba=1;     % "mira presnosti" - jak presny bude vysledek


% cyklus skonci ve chvili, kdy bude dosazeno pozadovane presnosti
% nebo kdyz pocet kroku dosahne hodnoty 20 (oboji je mozne zvolit libovolne)

 while (chyba>0.0001) & (i<20)

    c = a + (1-r)*(b-a);       % body urcene rezem intervalu
    d = a + r*(b-a);           

    x=c; 
    fc = eval(funkce);         % funkcni hodnota v bode c
    x=d;
    fd = eval(funkce);         % funkcni hodnota v bode d
    
    if (fd<fc)  a=c;           % novy interval bude [c,b]
         else   b=d;           % novy interval bude [a,d]
    end                          


    % vyznaceni "smrstovani" puvodniho intervalu [a,b]
    % omezeni na i<20 je kvuli prehlednosti obrazku
    
    % vyznaceni aproximace minima
    line([x,x],[eval(funkce)-0.02*i,eval(funkce)+0.02*i])
    

    chyba=(b-a)/2;            % chybu urcuje rozdil funkcnich hodnot
    i=i+1;                    % konci cyklus, zvysime citac iteraci


    % vypis informaci o krocich vypoctu na obrazovku

    disp(sprintf('%d. krok: c=%f, d=%f, f(c)=%f, f(d)=%f.',i,c,d,fc,fd));   
    disp(sprintf('          [a,b]=[%f, %f]. ',a,b));
    disp(' '); % vlozi prazdny radek na vystupni obrazovku
keyboard;

end  % zde konci while-cyklus (cyklus kroku vypoctu)


x=(a+b)/2;  % konecna aproximace jako stred konecneho intervalu

% vypis konecneho vysledku na obrazovku

disp(sprintf('Priblizne reseni: x=%f s presnosti %f.',x,chyba));   
disp(sprintf('Hodnota minima: f(x)=%f. ',eval(funkce))); 
 
 
