function [z,v,info,k,mis] = bisezione(f_bis,a,b,...
                          criterio_di_arresto_bis,E_bis,kmax,dialogo)
//
// Uso:
//    [ z,v,info,[k,[mis]] ] = bisezione(f_bis,a,b,...
//                criterio_di_arresto_bis,E_bis,kmax,dialogo)
//
//
// Metodo di bisezione.
//
// Approssima uno zero della funzione f_bis (che deve essere continua)
// contenuto nell'intervallo [a,b]. La funzione f_bis deve assumere
// valori non nulli e di segno opposto in a e b.
//
// L'iterazione si arresta quando:
//   (*) il valore di f_bis nel punto medio x_m dell'intervallo
//       considerato è zero;
//   (*) la misura dell'intervallo considerato [a(k),b(k)] è minore di
//       tol, dove:
//         tol = E_bis se criterio_di_arresto_bis = "assoluto" (in tal
//               caso si ha, in teoria, che z approssima uno zero di
//               f_bis con errore assoluto non superiore ad E_bis/2);
//         tol = E_bis * min(abs(a(k)),abs(b(k))) se
//               criterio_di_arresto_bis = "relativo" (in tal caso si
//               ha, in teoria, che z approssima uno zero di f_bis con
//               errore relativo non superiore a E_bis/2).
//               Ha senso usare il criterio di arresto relativo solo se
//               l'intervallo iniziale [a,b] non include zero;
//   (*) la funzione f_bis assume valori del medesimo segno negli
//       estremi a e b;
//   (*) dopo kmax iterazioni (valore suggerito: kmax = 55).
//
// Se dialogo = "loquace", ad ogni ciclo di iterazione la procedura
// stampa il numero di iterazione, l'intervallo corrente, disegna un
// grafico di f_bis su [a,b] su cui viene riportato z (nella finestra
// grafica numero NFG_bis) e comunica l'ampiezza dell'ultimo intervallo
// determinato.
//
// z: approssimazione finale (zero di f_bis oppure punto medio
//    dell'ultimo intervallo generato);
// v: valore di f_bis in z;
// info = 0: individuato valore in cui f_bis si annulla;
//      = 1: la misura dell'ultimo intervallo considerato è minore di
//           tol e la f_bis assume valori non nulli e di segno opposto
//           agli estremi di tale intervallo;
//      = 2: f_bis non assume valori non nulli e di segno opposto agli
//           estremi dell'intervallo iniziale [a,b];
//      = 3: superato il numero massimo consentito di iterazioni;
// k: numero di iterazioni effettuate;
// mis: ampiezza dell'ultimo intervallo determinato.
//
// Se info = 2, si pone z = Nan , v = Nan , k = Nan e mis = Nan.
//
info = -1;
format_bis = " k = %d , [ %16.15e , %16.15e ]\n";
if dialogo == "loquace" then
   ListaFinestre_bis = winsid();
   if length(ListaFinestre_bis) ~= 0 then
                       FinestraCorrente_bis = gcf(); end;
   NFG_bis = 34; // Numero della Finestra Grafica nella quale la
                //  procedura disegna.
   figure_handle_bis = scf(NFG_bis);
   figure_handle_bis.figure_name =...
                       "finestra generata da bisezione.sce (34)";
   x_bis = linspace(a,b,500); end; // ascisse per il disegno finale
k_bis = 0; // contatore delle iterazioni eseguite
if criterio_di_arresto_bis == "relativo" then
       tol = E_bis*min(abs(a),abs(b));
   else tol = E_bis; end;
if f_bis(a) == 0 then info = 0; z = a; v = 0; k = 0; mis = abs(b-a); end;
if f_bis(b) == 0 then info = 0; z = b; v = 0; k = 0; mis = abs(b-a); end;
if (info ~= 0) & (sign(f_bis(a)) == sign(f_bis(b))) then
        info = 2; v = %nan; z = %nan;  k = %nan; mis = %nan; end;
if dialogo == "loquace" then printf(format_bis,k_bis,a,b); end;
// iterazione
while info == -1,
  x_m = (a + b)/2;
  f_m = f_bis(x_m);
  if f_m == 0 then info = 0; z = x_m; v = 0; k = k_bis; mis = abs(b-a); end;
  if (info ~= 0) & abs(b-a) < tol then info = 1; z = x_m; v = f_m; ...
                                       k = k_bis; mis = abs(b-a); end;
  if k_bis>= kmax then info = 3;  z = x_m; v = f_m; ...
                       k = k_bis; mis = abs(b-a); end;
  if info == -1 then k_bis= k_bis+1;
                     if sign(f_m) == sign(f_bis(b)) then b = x_m;
                        else a = x_m; end;
                     if dialogo == "loquace" then
                        printf(format_bis,k_bis,a,b); end;
                     if criterio_di_arresto_bis == "relativo" then
                        tol = E_bis*min(abs(a),abs(b)); end;
  end;
end;
//
ampiezza_bis = abs(b-a); // misura dell'ultimo intervallo considerato.
//
if dialogo == "loquace" then
   clf(); plot(x_bis,f_bis(x_bis)); xgrid(); xlabel("x");
   //
   select info,
     case 0 then 
          printf("\n\n *** Trovato zero\n\n"); plot(z,v,"ro");
          legend("f_bis (x)","(z,v)");
     case 1 then
          printf("\n*** ampiezza ultimo intervallo = %5.4e\n\n",...
             ampiezza_bis); plot(z,v,"ro"); legend("f_bis (x)","(z,v)");
     case 2 then
          printf("\n\n *** ERRORE: f_bis(a) * f_bis(b) > 0\n\n");
     case 3 then
          printf("\n\n *** Superato numero max iterazioni\n");
          printf(" *** ampiezza ultimo intervallo = %5.4e\n\n",...
             ampiezza_bis);
   end;
   if length(ListaFinestre_bis) ~= 0 then
                  scf(FinestraCorrente_bis); end;
end
endfunction
