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))