Lezione del 19/5/2014

Approssimazione zeri di funzione (variabile singola):

File zeri.rb

  1#!/usr/bin/env ruby
  2#-------------------------------------------------------------------------#
  3#  Esercitazioni in Laboratorio per il Corso di                           #
  4#  Fondamenti di Informatica e Calcolo Numerico, AA 2013/2014             #
  5#                                                                         #
  6#  Autori:   Enrico Bertolazzi e Carlos Maximiliano Giorgio Bort          #
  7#            Dipartimento di Ingeneria Industriale, Universita` di Trento #
  8#  Sito web: http://www.ing.unitn.it/~bertolaz/                           #
  9#                                                                         #
 10#  Contatti: enrico.bertolazzi@unitn.it, cm.giorgiobort@unitn.it          #
 11#                                                                         #
 12#  Copyright (c) 2014 E.Bertolazzi e C.M. Giorgio Bort                    #
 13#-------------------------------------------------------------------------#
 14
 15#
 16class NthRooth
 17  def initialize( a, n )
 18    @a = a # numero del quale si vuole la radice quadrata
 19    @n = n # ordine della radice da calcolare
 20  end
 21  
 22  def f(x)
 23    return x**@n-@a
 24  end
 25  
 26  def df(x)
 27    return @n*x**(@n-1)
 28  end
 29end  
 30
 31class SqrtFun < NthRooth
 32  def initialize( a )
 33    super(a,2)
 34  end
 35end
 36
 37class ThirdRooth < NthRooth
 38  def initialize( a )
 39    super(a,3)
 40  end
 41end
 42
 43#class SqrtFun
 44#  def initialize( a )
 45#    @a = a # numero del quale si vuole la radice quadrata
 46#  end
 47#  
 48#  def f(x)
 49#    return x*x-@a
 50#  end
 51#
 52#  def df(x)
 53#    return 2*x
 54#  end
 55#end
 56
 57def err_asymptotic( x, alpha )
 58  for k in 2...x.size do
 59    ek    = (x[k-2]-alpha).abs
 60    ekp1  = (x[k-1]-alpha).abs 
 61    ekp2  = (x[k]  -alpha).abs
 62    p     = Math::log(ekp1/ekp2)/Math::log(ek/ekp1)
 63    puts "k = #{k}, order p = #{p}"
 64  end
 65end
 66
 67def newton( x0, tol, iter_max )
 68  x = [ x0.to_f ] # inizializza iterate
 69  for k in 1..iter_max do
 70    fdf = yield(x.last) # blocco calcola f(x) e df(x) e restituisce [f(x),df(x)]
 71    h = -fdf[0]/fdf[1] # h = - f(x)/df(x)
 72    break if h.abs < tol # interrompo ciclo se passo 
 73                         # piu piccolo della tolleranza
 74    x << x.last+h # x = x + h
 75  end
 76  return x
 77end
 78
 79def secanti( x0, x1, tol, iter_max )
 80  x  = [ x0.to_f, x1.to_f ] # inizializza iterate
 81  f0 = yield(x0)
 82  f1 = yield(x1) 
 83  for k in 1..iter_max do    
 84    h = -f1/((f1-f0)/(x1-x0))
 85    break if h.abs < tol # interrompo ciclo se passo 
 86                         # piu piccolo della tolleranza
 87    x << x.last+h # x = x + h
 88    x0 = x1
 89    x1 = x.last
 90    f0 = f1
 91    f1 = yield(x1)
 92  end
 93  return x
 94end
 95
 96fun = SqrtFun.new 2
 97
 98#x = newton( 2, 1e-10, 10 ){ |x| [fun.f(x),fun.df(x)] }
 99x = newton( 2, 1e-10, 10 ){ |x| [x*x-3,2*x] }
100
101puts "x = #{x}"
102err_asymptotic( x, Math::sqrt(3.0))
103
104x = secanti( 2, 3, 1e-10, 10 ){ |x| x*x-3 }
105
106puts "x = #{x}"
107err_asymptotic( x, Math::sqrt(3.0))