% Metoda bisekce 04

funkce='x + 3/(x^2)';      % ucelova funkce        
DER='1-6/(x^3)';           % derivace ucelove funkce
a=0.5; b=3;                % krajni hodnoty intervalu I=[a,b] 
x=(a+b)/2;                 % aproximace bude vzdy stred intervalu [a,b]

p = linspace(a,b);                       % vykreslovany interval
q = (p.^(1)) + 3*(p.^(-2));              % predpis funkce
plot(p,q,'r')                            % vykresleni funkce   
line([1.817,1.817],[2.529,2.926])        % vyznaceni skutecneho minima


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

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


% zakladni WHILE-cyklus (cyklus jednotlivych kroku) konci ve chvili
% dosazeni pozadovane presnosti, ci pokud citac iteraci dosahne hodnoty 15

while ((chyba>0.0001) & (i<15))
    
   i=i+1;  % zvyseni poctu iteraci     
   
   
   DERx=eval(DER);      % hodnota derivace funkce f v bode x
     
   disp(sprintf('%d. krok: a=%f, b=%f, x=%f, df(x)=%f => ',i,a,b,x,DERx));
   
   if     (DERx<0)  a=x;   % b=b;
   elseif (DERx>0)  b=x;   % a=a;    
   else             i=17;  % mame minimum, konec while-cyklu
   end
          
       
   disp(sprintf('        => novy interval bude: [a,b]=[%f, %f]',a,b));
   
   
   xx=x;   % ulozeni stare hodnoty x (posledni aproximace)
  
   % vyznaceni zmenseni intervalu [a,b]
   % omezeni na i<20 je kvuli prehlednosti obrazku
   
   if (i<20)
       p = linspace(a,b);
       q2 = (p.^(1)) + 3*(p.^(-2)) - 0.3*i;    
       hold on;
   end

    % podmineny prikaz zakresluje "smrstovani" dvema barvami (modra, cerna),
    % aby byly lepe rozlisene jednotlive kroky

    if (mod(i,2) == 0) plot(p,q2,'b')
            else       plot(p,q2,'k')
    end      
        
   x=(a+b)/2;  
  
   chyba = (b-a)/2;     % chyba jako rozdil poslednich dvou aproximaci
  
  
   disp(' '); % vlozi prazdny radek na vystupni obrazovku     
 keyboard;
 
  
end % konec while-cyklu (cyklu kroku vypoctu, radky 29-74)


% Vypis informaci o vypocitanem reseni v zavislosti na tom,
% jestli jsme nahodou "netrefili" minimum presne

if (i==17)
      disp(sprintf('Presne reseni: x=%f.',x));
      disp(sprintf('Hodnota minima: f(x)=%f.' ,eval(funkce)));
      
else  
   
disp(sprintf('Priblizne reseni: x=%f s presnosti %f.',x,chyba));
disp(sprintf('Hodnota minima: f(x)=%f. ',eval(funkce)));
   
end