economia news e media viaggi informatica internet salute e benessere int rattenimento e spettacolo sport tempo libero istruzio ne e formazione arte cultura scienza

Il Sondaggio

Quale versione del fortran utilizzi?

Guarda i risultati

Algoritmi

L'algoritmo della Secante

A cura di Giuseppe Ciaburro

Pubblicato il 24/08/2001

Algoritmo della Secante per il calcolo degli zeri di una funzione.

Il metodo che qui si propone, detto metodo della secante, tende a risolvere e eliminare la difficoltà del calcolo della derivata prima necessaria nell'applicazione del metodo di Newton senza rinunciare del tutto al miglioramento della velocità convergenza che tale metodo introduce.

  Ipotesi:
Sia f(x) una funzione continua e monotona nell'intervallo chiuso e limitato [a,b] e tale da che esista un punto z di tale intervallo in cui sia f(z)=0;
  Tesi:
Se x0 e
x1 sono punti appartenenti ad [a,b]   allora la seguente operazione
x2 = x1 - f(x1) (x1 - x0)  / ( f(x1) - f(x0) )

quando venga ripetuta più volte, crea una successione di punti xn che converge rapidamente a z.

L'ipotesi assicura che esiste almeno un punto z in cui é f(z)=0; inoltre la funzione è strettamente monotona nell'intervallo [a,b] per cui comunque si scelgano, in esso, due punti distinti x0 e x1 sarà sempre vero che f(x1)-f(x0) è diverso da zero. 

Si consideri, allora la secante passante per i due punti curva, di ascissa x0 e x1, che hanno coordinate P0(x0 ,f( x0))  e  P1(x1 ,f( x1)).
La retta passante per il punto P0 e P1 ha equazione  y-f(
x1) = m(x-f( x1)) dove per semplicità si è posto m=[f( x1)-f( x0)]/( x1- x0)
L'intersezione della retta  secante P0P1 con l'asse x può considerarsi una buona approssimazione della soluzione z; pertanto posto y=0 nella precedente equazione si ha, in analogia a quanto ottenuto nel metodo di Newton,   x2 = x1 - f(x1)/m

dove sostituendo 1/m= (x1 - x0)  / ( f(x1) - f(x0) ) si ottiene, infine, 
x2 = x1 - f(x1) (x1 - x0)  / ( f(x1) - f(x0) )

Poichè la retta  secante P0P1 può considerarsi una buona approssimazione della retta t, tangente in P1 alla curva di equazione y=f(x) quando P1 --> P0 si può notare che il metodo qui ottenuto non è altro che il metodo di Newton nel quale alla derivata prima f'(x1) si è sostituita una espressione approssimata e cioè il rapporto incrementale m=[f( x1)-f( x0)]/( x1- x0)
Per questo, il metodo della secante ha una convergenza di ordine quasi quadratico (si può dimostrare che è di ordine 1/2+forSecante1.gif
 (981 byte)/2 = 1,618)
Pertanto, il procedimento consente di ridurre  l'ampiezza dell'errore, ad ogni iterazione, in maniera che si possa assumere e2
=  k e11,618. La convergenza non è esattamente come nel metodo di Newton, ma il metodo presenta il grande vantaggio di non richiedere il calcolo della derivata prima.

 

Il  metodo della secante secondo Steffensen        

É stato precedentemente accennato alla velocità di convergenza del metodo della secante che è di ordine 1,618; il metodo di Steffensen consente di accelerare la convergenza del metodo della secante portandola alla stessa velocità del metodo di Newton senza un aggravio eccessivo in termini di costo del calcolo.

Facendo riferimento alla formula della secante
x2 = x1 - f(x1) (x1 - x0)  / ( f(x1) - f(x0) )
si assuma che nell'intorno di x0 sia lecito porre f(x1) = (x1 - x0) da cui x0 = x1 -f(x1) . In tal caso la formula della secante precedentemente scritta, assume la forma seguente che prende il nome di formula di Steffensen:
x2 = x1 - f(x1)² / ( f(x1) - f(x1 -f(x1))

Più frequentemente la stessa formula viene usata sotto la forma seguente:
x2 = x1 - f(x1)² / (  f(x1 + f(x1)) - f(x1) )
che è giustificata dal fatto che nella prima forma il denominatore è semplicemente l'incremento della funzione nell'intorno sinistro di
x1 mentre nella seconda forma, l'incremento della funzione viene calcolato nell'intorno destro dello stesso punto. 

Le formule appena scritte partono con un solo punto x1, come la formula di Newton, ma richiedono, ad ogni iterazione, il calcolo sia dell'incremento h= f(x1) che della   f(x1 + f(x1)) = f(x1+h).
La dimostrazione che la convergenza delle formule precedenti è quadratica la si ottiene facilmente quando si riscriva la formula di Steffensen con le posizioni precedenti:
x2 = x1 - f(x1) h / (  f(x1 + h) - f(x1) )  = x1 - f(x1)/ m 
dove è stato posto
m =  (  f(x1 + h) - f(x1) )/h ; sviluppando  f(x1 + h)   in serie di Taylor intorno a x1 si ottiene
f(x1+ h)= f(x1)+f'(x1)h+ f"(x1)h² /2+O(h²)
da cui si deduce:
(f(x1+ h)- f(x1))/h=f'(x1)+ f"(x1)h /2+O(h²)
si ha, cioè

m=f'(x1)[1+ f"(x1)h /2f'(x1)+O(h²)] = f'(x1)/[1- f"(x1)h /2f'(x1)+O(h²)].
Sostituendo, infine, nella
  
x2 = x1 - f(x1)/ m=x1 - f(x1)/f'(x1)*[1- f"(x1)h /2f'(x1)+O(h²)] 
da cui, ricordando che
h= f(x1) , si può scrivere 
x2 = x1- f(x1)/f'(x1)+ f"(x1)h² /2f'(x1)²+O(h³)
Qui  si riconosce l'espressione dell'errore della formula di Newton. Pertanto la formula di Steffensen ha la stessa convergenza della formula di Newton.      

Di seguito è riportato il codice in fortran 90 che impllementa l'algoritmo della secante per il calcolo degli zeri di una funzione.

 

!Programma in fortran 90 per il calcolo
!degli zeri di una funzione con il metodo
!della secante
      program main
      real :: a = 1.0, b = -1.0
      integer :: m = 8
      interface
      function f(x)
      real, intent(in) :: x
      end function
      end interface

      call secant(f,a,b,m)
      end program main

      subroutine secant(f,a,b,m)
      real, intent(in) :: a,b
      integer, intent(in) :: m
      real :: fa, fb, temp
      integer :: n
      interface
      function f(x)
      real, intent(in) :: x
      end function f
      end interface

      fa = f(a)
      fb = f(b)
      if (abs(fa) >  abs(fb)) then
         temp = a
         a = b
         b = temp
         temp = fa
         fa = fb
         fb = temp
      end if
      print *,"    n        x(n)         f(x(n))"
      print *," 1 ", b, fb
      print *," 0 ", a, fa	
      do n = 2,m
         if (abs(fa) >  abs(fb)) then
            temp = a
            a = b
            b = temp
            temp = fa
            fa = fb
            fb = temp
         end if
         temp = (b - a)/(fb - fa)
  	 b = a
	 fb = fa
         a = a - fa*temp
         fa = f(a)
         print *,n,a,fa
      end do   
      end subroutine secant

      real function f(x)
      real, intent(in) :: x
      f = x**5 + x**3 + 3.0
      end function

Vuoi essere aggiornato sulle novità della guida?

Feed RSS XML vostro feed RSS