function [aa,bb,wres,flag]=bisezione(f,a,b,toll,maxit)

% Algoritmo di bisezione, con criterio di arresto sul residuo pesato e
% ampiezza dell'intervallo.
%
% Dati di ingresso:
% f: funzione (inline function)
% a: estremo sinistro
% b: estremo destro
% toll: tolleranza richiesta per il test del residuo pesato
% maxit: massimo indice dell'iterata permesso
%
% Dati di uscita:
% aa: sequenza degli estremi di sinistra degli intervalli [a_k,b_k], 
%     immagazzinata in vettore colonna;
% bb: sequenza degli estremi di destra degli intervalli [a_k,b_k],
%     immagazzinata in vettore colonna;
% wres: sequenza dei residui pesati,immagazzinata in vettore colonna;
% flag: 0 processo terminato correttamente, 
%     1 processo non terminato correttamente.

if b < a, s=b; b=a; a=s; end % Aggiusta errori utente.
flag=0;  fa=feval(f,a); fb=feval(f,b);  aa=[a]; bb=[b]; wres=[];

% hp. bisezione non soddisfatte (uscita con errore).
if fa*fb > 0, flag=1; return; end 
% zero all'estremo iniziale "a"  (uscita con successo).
if fa == 0, aa=[a]; bb=[a]; return; end % a sol.
% zero all'estremo iniziale "b"   (uscita con successo).
if fb == 0, aa=[b]; bb=[b]; return; end % b sol.

for k=1:maxit   % iterazioni bisezione
    c=(a+b)/2;  fc=feval(f,c); % punto medio di [a_k,b_k]
    w=(b-a)/(fb-fa); % peso "w".
    wres(k)=abs(fc*w);  % residuo pesato.
    % uscita per raggiungimento risultato.
    if (wres(k)<toll) |(fc==0) 
        aa(k+1)=c; bb(k+1)=c; return;% OK exit.
    end 
    % determinazione intervallo [a_{k+1},b_{k+1}]
    if fc*fa > 0 % "c" sostituisce "a"
        aa(k+1)=c; bb(k+1)=b; a=c; fa=fc; % aggiorna aa,bb,a,fa
    else % "c" sostituisce "b"
        aa(k+1)=a; bb(k+1)=c; b=c; fb=fc; % aggiorna aa,bb,a,fa
    end 
end

flag=1; % raggiunto questo punto, si sono fatte troppe iterazioni
