CALCOLO NUMERICO
a.a. 2010/2011
Prof. Giulio Giunta
Il corso è una introduzione alle metodologie generali, alle tecniche e alle competenze operative legate allo
sviluppo e all’analisi di algoritmi e software nel campo del calcolo scientifico. Il corso contiene una
introduzione al linguaggio MATLAB, che viene utilizzato per lo sviluppo del software nelle attività di
Laboratorio.
Programma dettagliato
Testi consigliati
A.QUARTERONI, C. SALERI: “Introduzione al Calcolo Scientifico”, II Ed., Springer, 2004.
A.MURLI: “Matematica Numerica: metodi, algoritmi e software". Liguori, 2007.
W.J. PALM - “MATLAB per l’ingegneria” - McGraw Hill Italia, 2001.
Corso di Calcolo Numerico
CdL Informatica,
Calcolo Numerico e Matematica Applicata
CdL SNeA - 6 CFU
modalità esame:
orale con prova Matlab (40%)+ 2 Prove
intercorso (40%) + 2 HomeWork (20%)
Prof. Giulio GIUNTA
giulio.giunta@uniparthenope.it
Orario ricevimento:
lunedì, ore 14:00 – 16:00, stanza 420,
quarto piano Nord
Orario ricevimento:
martedì, ore 16:00 – 18:00, LabMNCP,
quarto piano Nord
Materiale didattico
presentazioni multimediali con registrazione audio, slide
delle lezioni e delle esercitazioni di Laboratorio (.pps, .pdf),
sintesi delle lezioni (.pdf, e-book), programmi Matlab (.m),
quiz di autovalutazione, esercizi, tutte le vecchie prove di
esame:
sulla piattaforma di e-learning
testi utili:
A. Murli
Matematica numerica: metodi, algoritmi e software
Liguori Editore, 2007
A. Quarteroni, F. Saleri
Introduzione al Calcolo Scientifico
Springer Italia, 2000
Attività di Laboratorio
calcolo scientifico
informatica
schema del processo di risoluzione di un problema
nel calcolo scientifico
problema applicativo
modello matematico
modello numerico
algoritmo
software
strumenti di sviluppo (nel corso)
il WEB
calcolo scientifico
http://www.netlib.org
http://www.nhse.org/
http://math.nist.gov/
http://math.nist.gov/MatrixMarket/
http://gams.nist.gov/
MATLAB
http://www.mathworks.com
OCTAVE
versione 3.8.x
158
Prerequisiti
Esempio: dati 10 numeri, memorizzati in un vettore vet,
calcolare il massimo e la sua posizione
66 10
Esempio: risolvere gli esempi precedenti usando le
function Matlab
>> vet = [31 14 28 5 -12 32 -25 19 0 66];
>> somma = sum(vet);
somma =
158
>> mas = max(vet);
mas =
66
>> [mas indmas] = max(vet);
mas =
66
indmas =
10
Esempio: costruzione e uso di function utente
function risultato = piugrande(x,y)
if x > y
risultato = x;
else
risultato = y;
end
>> a = piugrande(7,8)
a =
8
>> p = -73*8; q = exp(2.1);
>> b = piugrande(p,q)
b =
8.1662
sistema aritmetico di un computer
(ma anche di un tablet, di uno smartphone, etc.)
rappresentazione posizionale
notazione scientifica
rappresentazione a precisione finita
base 2
rappresentazione posizionale
425.76
1 2
4 10 2 10 5 10 7 10 6 10
2 1 0
notazione scientifica
4.2576 10 2
in posizione fissa
notazione scientifica
esponente
4.2576 10 2
mantissa
m b e base
(fissa)
ordine di grandezza
0.0000076
notazione scientifica:
6
7.6 10
evita di visualizzare/memorizzare
gli zeri non significativi
(ovvero gli zeri “in testa”)
il massimo numero di cifre per rappresentare
la mantissa e l’esponente è fissato
rappresentazione finita
rappresentazione normalizzata,
a precisione finita (base 2)
limitazioni su m e su e:
m è compreso tra 1 e 2, (1<=m <2)
(normalizzazione)
e è un intero con al più E cifre binarie,
ovvero e è compreso tra 0 e 2E-1,
(range finito)
m ha al più t cifre binarie (precisione finita)
i numeri rappresentati in memoria sono detti
numeri floating point (fp)
Nel 1985 lo
IEEE Standards Board and the American
National Standards Institute
ha adottato lo ANSI/IEEE Standard 754-1985
per l’aritmetica floating-point
(intervallo rappresentabile)
- (2-2 ) 2 ,- 2
-23 127 -126
2 -126
,(2-2 ) 2
-23 127
(intervallo rappresentabile)
- (2-2 ) 2 ,- 2
-52 1023 -1022
2
-1022
, (2-2 ) 2
-52 1023
Aritmetica standard IEEE
il segno è rappresentato con un bit,
che vale 0 per positivo e 1 per negativo
la base dell’esponente è 2
l’esponente (memorizzato) è 127+e in
singola precisione, 1023+e in doppia
precisione
il primo bit della mantissa, che è sempre 1,
non viene memorizzato esplicitamente;
ovvero, il campo mantissa contiene solo
la frazione (la parte frazionaria della
mantissa)
singola precisione
00100001 00000000
11000000 00001000
11000000 00001000
frazione
00000000 10000000
00000000 00000000
1.0000000 00000000 00000000x2-126
(è il più piccolo numero rappresentabile;
l’esponente = 0 è riservato per situazioni eccezionali)
00000000 00000000
00000000 00000000
00000000 00000000
frazione
doppia precisione
segno esponente frazione
00000000 00010000
00000000 00000000
00000000 00000000
52
00000000 00000001 2
frazione
overflow: numeri troppo grandi, in valore assoluto
underflow: numeri troppo piccoli, in valore assoluto
o o
v intervallo rappresentabile v
e 0 e
r r
f f
l l
o o
underflow
w w
intervallo rappresentabile (range): unione degli intervalli dei
numeri che possono essere rappresentati, eventualmente in
modo approssimato, attraverso arrotondamento della mantissa
alla precisione del sistema
intervallo rappresentabile
0
numeri fp
massima accuratezza
numeri fp
x y = arrotondamento( x y)
rappresentazione del risultato
“vero” con mantissa arrotondata
operazione fp alla precisione del sistema (t bit)
Aritmetica standard IEEE
massima accuratezza
00000000 00000000
00000000 00000000
00000000 00000000
00000000 00000000
00000000 00000000
#include <stdio.h>
void main()
{
int cont; float uno,sum,numero;
numero = 1.0F;
uno = 1.0F;
cont = 0;
sum = uno+numero;
while(sum>uno)
{
numero = numero/2; cont++;
sum = uno+numero;
}
numero = numero*2;
printf(“numero= %16.8e \n numero
divisioni= %d\n",numero,cont);
}
numero = 1.19209290e-7
numero divisioni= 24
output
0 1
numero fp
successivo di
1
#include <stdio.h>
void main()
{
int cont; double numero,uno,sum;
numero = 1.0;
uno = 1.0;
cont = 0;
sum = uno+numero;
while(sum>uno)
{
numero = numero/2; cont++;
sum = uno+numero;
}
numero = numero*2;
printf(“numero= %24.16e \n numero
divisioni= %d\n",numero,cont);
}
% Script Epsilon – Esperimento esistenza
% epsilon macchina
format long
numero = 1.0;
uno = 1.0;
cont = 0;
sum = uno + numero;
while sum > uno
numero = numero/2; cont = cont + 1;
sum = uno + numero;
end
numero = numero*2;
sprintf(‘numero = %24.16e \n numero
divisioni= %d\n",numero,cont);
format
numero= 2.2204460492503131e-016
numero divisioni= 53
output
mantissa e
1.0 21
1 . 0 0 0 0 + 0 0 0 0 1
1.0 2-2 1 . 0 0 0 0 - 0 0 0 1 0
incolonnamento
1.0 21 1 . 0 0 0 0 + 0 0 0 0 1
1.0 2-2 0 . 0 0 1 0 + 0 0 0 0 1
somma 1 . 0 0 1 0 + 0 0 0 0 1
errore assoluto ed errore relativo
sia dato un numero x e una sua approssimazione a
se x e a hanno la stessa
errore assoluto di a parte intera e le stesse
prime m cifre della parte
Eass x a frazionaria, allora
m
Eass x a 10
se x e a hanno le stesse
errore relativo di a
prime m cifre significative,
xa allora xa
Erel Erel 10 m
x x
le cifre significative di un numero sono le cifre della sua
mantissa esclusi gli eventuali “zeri in testa”
errore assoluto ed errore relativo
non è strettamente
sia dato un numero x e una sua
VERO
approssimazione a
se Eass x a 10 m
errore assoluto di a
allora x e a hanno la
Eass x a stessa parte intera e le
stesse prime m cifre della
parte frazionaria
+1.000… 0× 2 0
0011 1111 1111 0000 ..0000
00111111 11110000
00000000 00000000
00000000 00000000
00000000 00000000
e = esponente memorizzato - 1023=1023-1023= 0
in Matlab eps è la distanza tra il numero 1 e
il numero fp successivo a 1
eps
0 1
epsMacchina eps/2
» format hex
0 0000 9 1001
» 1+eps
ans = 1 0001 10 (a) 1010
2 0010 1
3ff0000000000001 11 (b) 1011
» 1+eps/2 3 0011
4 0100 12 (c) 1100
ans =
5 0101 13 (d) 1101
3ff0000000000000
>> 1+eps/2+eps/2 6 0110 14 (e) 1110
ans = 7 0111 15 (f) 1111
3ff0000000000000 8 1000
» 1+2^(-52)
ans =
3ff0000000000001 1
» 1+2^(-53)
ans =
3ff0000000000000
» format hex
» 1+(eps/2+eps/2)
ans =
3ff0000000000001
» 1+(eps/2+eps/4)
ans =
3ff0000000000001
» 1+(eps/2+eps/10)
ans =
3ff0000000000001
epsMacchina
=
numero fp successivo a eps/2
» max=(2-2^(-52))*2^1023
max =
1.797693134862316e+308
» realmax il più grande numero rappresentabile
realmax =
1.797693134862316e+308
» 2*max
ans =
Inf
» max+1
1 è minore di eps*max
ans =
1.797693134862316e+308
» max+eps*max
ans =
Inf
la somma fp tra 1.0 e un qualunque numero fp
minore di epsMacchina
fornisce come risultato 1.0,
ovvero l’operazione di addizione fp, a differenza
della operazione di addizione usuale, ammette
elementi neutri diversi da zero
questa proprietà vale solo
nella somma con 1 ?
fissato un numero x, esistono numeri fp y che
sommati a x, mediante addizione fp, forniscono
un risultato uguale a x ?
y : x y x y
x y x 1
x
y y
1Å = 1 solo se < epsMacchina
x x
y Î éë0, x × epsMacchina ) Þ x Å y = x
risolvere: f x 0
r : f r 0
r è detto:
soluzione dell’equazione
radice dell’equazione
zero della funzione f
il problema della risoluzione dell’equazione:
wx vx
è equivalente al problema :
f x 0
se si pone:
f x wx vx
wx
oppure
f x 1 , v x 0
v x
f x 0 la funzione può avere più zeri
f x 0 la funzione può avere zeri multipli
x. 2-2*x+1
1.5
0.5
-0.5
-0.5 0 0.5 1 1.5 2 2.5
f x 0 la funzione può avere zeri multipli
x. 3-3*x. 2+3*x-1
1.5
0.5
-0.5
-1
-1.5
-0.5 0 0.5 1 1.5 2 2.5
f x 0 problema poco sensibile a errori sulla funzione
(problema ben condizionato)
1.5
0.5
-0.5
-0.5 0 0.5 1 1.5 2 2.5
f x 0 problema molto sensibile a errori sulla funzione
(problema mal condizionato)
1.5
0.5
-0.5
-0.5 0 0.5 1 1.5 2 2.5
TEOREMA: non sempre è possibile esprimere
la soluzione r di una equazione mediante una
formula chiusa
Evariste Galois
(1811-1832):
approssimazione di r:
generare, mediante una formula ricorrente,
una successione di approssimazioni
x0 , x1 , , xk ,
che converge alla soluzione r
xk r errk xk r 0
formula ricorrente algoritmo iterativo
condizioni:
f(x) è una funzione continua in [a,b]
f(x) cambia segno in [a,b] f a f b 0
a0 a b0 b m0
a0 b0
2
f a0 f m0 0
vero falso
a1 , b1 a0 , m0 a1 , b1 m0 , b0
al passo k: ak , bk contiene la radice
metodo di bisezione input: • f(x)
•aeb
a0 a b0 b m0
a0 b0
2
segno f a0 segno f m0
vero falso
a1 , b1 a0 , m0 a1 , b1 m0 , b0
al passo k: ak , bk contiene la radice
al passo k: ak , bk contiene la radice
l’approssimazione al passo k è:
mk
ak bk
2
1 1
errk r mk bk ak ek ek ek 1
2 2
k
1
ek e0
2
k 1
1
ek b a
2
andamento dell’errore di approssimazione
1
r m0 e0 ba
2
2
1
r m1 e1 b a
2
3
1
r m2 e2 b a
2
101 23.3
“3 o 4” passi per “guadagnare” una cifra in base 10 corretta
(l’errore viene moltiplicato per 10-1)
richiami
il contenuto informativo (in bit) di un numero n
è
log 2 n
k : ek
r mk
k 1
1
k: b a
2
1
k 1
k 1
b a 2
b a
2
b a
k 1 log 2 k 1 log 2
b a
b a
k log 2 1
il minimo k intero che verifica la disuguaglianza è
ba
k log 2 1
il minimo k tale che l’errore di approssimazione sia
minore di una accuratezza prefissata è
ba
k log 2 1
ba
T = numero di passi per numero di
valutazioni di f a ogni passo
function radice=bisezione(funzione,a,b,delta_ass)
% risoluzione dell'equazione f(x)=0 mediante % %
il metodo di bisezione.
% input:
% funzione puntatore (handle) alla
% function che definisce f(x)
% a,b estremi di un intervallo tale
% che f(a)*f(b)<=0
% delta_ass reale non negativo; il massimo
% errore assoluto richiesto sul
% risultato
% output:
% radice il punto medio dell'intervallo
% [ak,bk] tale che
% f(ak)*f(bk)<=0
% |bk-ak|<=delta+eps*max(|ak|,|bk|)
%
ak = a; bk = b;
fak = funzione(ak);
fbk = funzione(bk);
while abs(bk-ak)>delta_ass+eps*max(abs(ak),abs(bk))
pmediok = (ak+bk)/2; criterio
fpmediok = funzione(pmediok);
di
if sign(fak)~ = sign(fpmediok)
%la radice e' nell'intervallo [ak,pmediok] arresto
bk = pmediok;
fbk = fpmediok;
else
%la radice e' nell'intervallo [pmediok,bk]
ak = pmediok;
fak = fpmediok;
end
disp([ak,bk,abs(ak-bk)])
end
radice = (ak+bk)/2;
criterio di arresto
f xk 0
?
ans =
0.99951171875000
>> bisezione(@f2,0,12,0.001)
estremo sinistro estremo destro ampiezza interv.
0 6 6
0 3 3
0 1.50000000000000 1.50000000000000
0.75000000000000 1.50000000000000 0.75000000000000
1.12500000000000 1.50000000000000 0.37500000000000
1.31250000000000 1.50000000000000 0.18750000000000
1.31250000000000 1.40625000000000 0.09375000000000
1.31250000000000 1.35937500000000 0.04687500000000
1.33593750000000 1.35937500000000 0.02343750000000
1.34765625000000 1.35937500000000 0.01171875000000
1.34765625000000 1.35351562500000 0.00585937500000
1.35058593750000 1.35351562500000 0.00292968750000
1.35058593750000 1.35205078125000 0.00146484375000
1.35058593750000 1.35131835937500 0.00073242187500
ans =
1.35095214843750
function radice=bisez_ric(funzione,a,b,delta_ass)
% risoluzione dell'equazione f(x)=0 mediante
% bisezione con approccio ricorsivo.
% input:
% funzione puntatore (handle) alla
% function che definisce f(x)
% a,b estremi di un intervallo tale che
% f(a)*f(b)<=0
% delta_ass reale non negativo; il massimo
% errore assoluto richiesto
% sul risultato
% output:
% radice il punto medio dell'intervallo
% [ak,bk] tale che
% f(ak)*f(bk)<=0
% bk-ak|<=delta+eps*max(|ak|,|bk|)
%
disp([a,b,abs(a-b)])
if abs(b-a)<=delta_ass+eps*max(abs(a),abs(b))
% istanza banale
radice = (a+b)/2;
else
% autoattivazioni
fa = funzione(a);
pmedio = (a+b)/2;
fpmedio = funzione(pmedio);
if sign(fa) ~= sign(fpmedio)
%la radice e' nell'intervallo [a,pmedio]
radice=bisez_ric(funzione,a,pmedio,delta_ass);
else
%la radice e' nell'intervallo [pmedio,b]
radice=bisez_ric(funzione,pmedio,b,delta_ass);
end
end
>> bisez_ric(@f2,0,12,0.001)
estremo sinistro estremo destro ampiezza interv.
0 12 12
0 6 6
0 3 3
0 1.50000000000000 1.50000000000000
0.75000000000000 1.50000000000000 0.75000000000000
1.12500000000000 1.50000000000000 0.37500000000000
1.31250000000000 1.50000000000000 0.18750000000000
1.31250000000000 1.40625000000000 0.09375000000000
1.31250000000000 1.35937500000000 0.04687500000000
1.33593750000000 1.35937500000000 0.02343750000000
1.34765625000000 1.35937500000000 0.01171875000000
1.34765625000000 1.35351562500000 0.00585937500000
1.35058593750000 1.35351562500000 0.00292968750000
1.35058593750000 1.35205078125000 0.00146484375000
1.35058593750000 1.35131835937500 0.00073242187500
ans =
1.35095214843750
il metodo di bisezione usa solo l’informazione
sul segno della f(x)
DOMANDA:
esistono metodi con maggiore rapidità di
convergenza?
metodo di Newton
xk 1 xk
f xk
f xk
metodo di Newton
f xk
xk 1 xk
f xk
requisiti per l’applicabilità:
f(x) e f’(x) devono essere note
x0 deve essere noto
f xk
xk 1 xk ck ck
f xk
function radice =
Newton(funzione,derivata,xiniz,delta_ass,kmax)
% risoluzione dell'equazione f(x)=0
% mediante metodo di Newton
% input:
% funzione puntatore (handle) alla
% function che definisce f(x)
% derivata puntatore (handle) alla
% function che definisce f'(x)
% xiniz approssimazione iniziale della
% soluzione
% delta_ass reale non negativo; il massimo
% errore assoluto richiesto
% sul risultato
% kmax intero, massimo numero di
% iterazioni
% output:
% radice approssimazione della radice
xk = xiniz;
k = 1;
fxk = funzione(xk);
fprimoxk = derivata(xk);
correzionek = -fxk/fprimoxk;
disp([xk,abs(correzionek)])
while
abs(correzionek)>delta_ass+eps*abs(xk)&k<=kmax
xk = xk+correzionek; criterio
fxk = funzione(xk);
di
fprimoxk = derivata(xk);
correzionek = -fxk/fprimoxk; arresto
k = k+1;
disp([xk,abs(correzionek)])
end
radice = xk;
>> Newton(@f2,@f2primo,2,0.001,20)
approssimazione correzione
2.00000000000000 0.39583333333333
1.60416666666667 0.19917236039527
1.40499430627140 0.05078276632164
1.35421153994975 0.00300135531660
1.35121018463315 0.00001002971444
ans =
1.35121018463315
ans =
1.35131820165736
zoom
zoom
interpretazione del metodo di Newton come
risoluzione di una successione di problemi lineari
(zero di una funzione lineare)
y f xk f xk x xk
la soluzione di t(x)=0 è:
0 f xk f xk x xk
f xk f xk
xk x xk 1 xk
f xk f xk
il metodo di Newton non converge sempre
(metodo locale)
f b
f b
a b
f a
f a
il metodo di Newton non converge sempre
(metodo locale)
xk 1 r c xk r
2
errk 1 c errk 2
nel caso di zeri
non multipli
errk xk r xk 1 xk ck
sviluppo di Taylor, arrestato al primo ordine:
2
f xk f xk 1 f
0 r xk r xk 2
f xk f xk 2 f xk
f xk 1 f
xk r r xk 2
f xk 2 f xk
1 f 1 f
r xk 1 r xk 2
errk 1 errk 2
2 f xk 2 f xk
errk 1 1 f xk errk 1 1 f r
xk r lim c
errk 2
2 f xk k err
k
2
2 f r
il metodo di Newton non converge sempre
(metodo locale)
PERICOLO! PERICOLO!
PERICOLO! PERICOLO!
xk 1 xk
stime
dell’errore assoluto
f xk
f xk
Complessità di tempo del metodo di Newton
b a = numero di passi
T
moltiplicato per
due valutazioni di function ( f e f’ )
metodo delle secanti
xk 1
xk xk 1
metodo delle secanti
xk 1xk
metodo delle secanti
xk 1
xk xk 1
f xk
xk 1 xk ck ck
pk
metodo delle secanti
f xk f xk 1
pendenza della retta (secante) pk
xk xk 1
xk 1 xk ck f xk
ck
pk
f xk
xk 1 xk
f xk f xk 1
xk xk 1
metodo delle secanti
xk 1 xk
xk 1
metodo delle secanti
xk xk 1 xk 1
function radice =
Secanti(funzione,xiniz,xiniz1,delta_ass,kmax)
% risoluzione dell'equazione f(x)=0
% mediante metodo delle Secanti
% input:
% funzione puntatore (handle) alla
% function che definisce f(x)
% xiniz prima approssimazione iniziale
% della soluzione
% xiniz1 seconda approssimazione iniziale
% della soluzione
% delta_ass reale non negativo; il massimo
% errore assoluto richiesto
% sul risultato
% kmax intero, massimo numero di
% iterazioni
% output:
% radice approssimazione della radice
xk = xiniz; xk1 = xiniz1;
k = 1;
fxk = funzione(xk); fxk1 = funzione(xk1);
pxk = (fxk-fxk1)/(xk-xk1);
correzionek = -fxk/pxk;
disp([xk,abs(correzionek)])
while
abs(correzionek)>delta_ass+eps*abs(xk)&k<=kmax
xk1 = xk; fxk1 = fxk; criterio
xk = xk + correzionek;
fxk = funzione(xk);
di
pxk = (fxk-fxk1)/(xk-xk1); arresto
correzionek = -fxk/pxk;
k = k+1;
disp([xk,abs(correzionek)])
end
radice = xk;
il metodo delle secanti non converge sempre
(metodo locale)
il metodo delle secanti ha rapidità di
convergenza superlineare
xk 1 r C xk r
1.618
r = fzero(funzione,xiniz)
r = fzero(funzione,[estremo_sin,estremo_des])
metodi ibridi
xk
a xk 1 b
intervallo successivo
xk
a xk 1 b
function radice = NewtonGlobale(funzione,derivata,
a,b,delta_ass,res_ass,kmax)
% risoluzione dell'equazione f(x)=0 mediante metodo
% ibrido Newton-bisezione
% input:
% funzione puntatore (handle) alla function
% che definisce f(x)
% derivata puntatore (handle) alla function
% che definisce f'(x)
% a estremo sinistro di un intervallo
% che contiene la soluzione
% b estremo destro di un intervallo
% che contiene la soluzione
% delta_ass reale non negativo; il massimo
% errore assoluto sul risultato
% res_ass reale non negativo; il massimo
% residuo assoluto sul risultato
% kmax intero, massimo numero di iterazioni
% output:
% radice approssimazione della soluzione
fa = funzione(a); fb = funzione(b);
if fa*fb>0
disp(' Intervallo non contenente la soluzione')
return
end
x = (a+b)/2;
fx = funzione(x);
fpx = derivata(x);
disp(sprintf('%20.15f %20.15f %20.15f',a,x,b))
k = 1;
while abs(a-b) > delta_ass+eps*max(abs(a),abs(b))
& (abs(fx) > res_ass) & k <= kmax
%[a,b] contiene una radice e x = a o x = b.
if appross_in_ab(x,fx,fpx,a,b)
% si effettua un passo di Newton
disp('Newton'); x = x-fx/fpx;
else
%si effettua un passo di Bisezione
disp('Bisezione'); x = (a+b)/2;
end %end if
fx = funzione(x);
fpx = derivata(x);
k = k+1;
if fa*fx<=0
% radice in [a,x]
b = x;
fb = fx;
else
% radice in [x,b]
a = x;
fa = fx;
end
disp(sprintf('%20.15f %20.15f %20.15f',a,x,b))
end %end while
radice = x;
function ok = appross_in_ab(x,fx,fpx,a,b)
% determina l'appartenenza dell'approssimazione di un
% passo di Newton o selle Secanti all'intervallo [a,b].
% E’ usata da NewtonGlobale, SecantiGlobale
% input
% x approssimazione corrente della radice
% fx valore di f in x.
% fpx valore di f'(o di una sua approssimazione) in x
% a,b [a,b] intervallo che contiene la radice
% output
% ok 1 se la approssimazione di Newton/Secanti
% x - fx/fpx appartiene a [a,b]
% 0 ALTRIMENTI
mi = min([a b]); ma = max([a b]); a=mi; b=ma;
ok = (a <= x-fx/fpx) && (x-x/fpx <= b);
end
function radice =
SecantiGlobale(funzione,a,b,delta_ass,res_ass,kmax)
% risoluzione dell'equazione f(x)=0 mediante metodo
% ibrido Secanti-bisezione
% input:
% funzione puntatore (handle) alla function
% che definisce f(x)
% a estremo sinistro di un intervallo
% che contiene la soluzione
% b estremo destro di un intervallo
% che contiene la soluzione
% delta_ass reale non negativo; il massimo
% errore assoluto sul risultato
% res_ass reale non negativo; il massimo
% residuo assoluto sul risultato
% kmax intero, massimo numero di iterazioni
% output:
% radice approssimazione della soluzione
fa = funzione(a); fb = funzione(b);
if fa*fb>0
disp(' Intervallo non contenente la soluzione')
return
end
x = (a+b)/2; fx = funzione(x);
px = (fx-fa)/(x-a);
disp(sprintf('%20.15f %20.15f %20.15f',a,x,b))
k = 1;
while(abs(a-b) > delta_ass+eps*max(abs(a),abs(b))
& (abs(fx) > res_ass) & k <= kmax)
%[a,b] contiene una radice e x = a o x = b.
if appross_in_ab(x,fx,px,a,b)
% si effettua un passo di Secanti
disp('Secanti'); xprec = x; x = x-fx/px;
else
%si effettua un passo di Bisezione
disp('Bisezione'); xprec = x; x = (a+b)/2;
end %end if
fxprec = fx;
fx = funzione(x);
px = (fx-fxprec)/(x-xprec);
k = k+1;
if fa*fx<=0
% radice in [a,x]
b = x;
fb = fx;
else
% radice in [x,b]
a = x;
fa = fx;
end
disp(sprintf('%20.15f %20.15f %20.15f',a,x,b))
end % end while
radice = x;
Problema del punto fisso
p è un punto fisso di g
x g x
problema del punto fisso
x g x p: p g p
x1 g x0 x2 g x1
x3 g x2 x4 g x3
x5 g x4
metodo del punto fisso
xk 1 g xk
g
funzione di
iterazione
contrazione in I: g v g q c v q , c 1, v, q I
metodo del punto fisso
xk 1 g xk
se g è derivabile e ha derivata minore di 1 (in
valore assoluto) in p, allora il metodo del punto
fisso converge a p , scegliendo x0 vicino a p
errk 1 xk 1 p errk 1 xk 1 p g xk g p
g xk g p g k xk p
teorema del Valor Medio k tra xk e p
metodo del punto fisso
xk 1 g xk
errk 1 g xk g p g xk g p g k xk p
g k c 1 ,k 1
e allora
errk 1 c errk c err0
k
cioè errk 0, k
metodo del punto fisso
xk 1 g xk
errk 1 c errk , c 1
la velocità di convergenza è (generalmente) lineare
con costante di proporzionalità c
c g p
al diminuire di c
aumenta la velocità di convergenza
>> pp-g(pp)
ans =
-2.076420934749024e-006
function y=g(x)
% g(x)= 2*(1-exp(-x)+1);
y=2*(1-exp(-x)+1);
problema del punto fisso e
risoluzione di una equazione
f x 0 il problema di risoluzione
di una equazione può
essere trasformato in un
problema di punto fisso
x f x x
equivalente
(ovvero, che hanno la
stessa soluzione)
funzione di
iterazione g
problema del punto fisso e
risoluzione di una equazione
esempio f x x 3sin x 0
4
x 3sin x x x
4
funzione di
iterazione g
function y=g(x)
y=x.^4-3*sin(x)+x;
>> pp=PFisso(@g,xiniz,0.0001,20)
pp è soluzione di x 3sin x x x
4
pp è soluzione di x 3sin x 0
4
problema del punto fisso e
risoluzione di una equazione
esempio
f x x x 2 0 r 2
2
x 2 x
2 g x x 2
2 diverge g 2 4
2 2
1 x g x 1 converge
x x
x2 2 x2 2 g 2 0
x g x converge
2x 1 2x 1
p2
punto fisso e analisi dei metodi iterativi
xk 1 g xk
un metodo iterativo
può essere visto come metodo di punto fisso
f xk
es.: metodo di Newton xk 1 xk
f xk
f f f f f f f r f r
g 1 g r 0
f f 2 f r
2 2
convergenza quadratica
Lezioni 2 e 2bis - “ f(x) = 0, risoluzione di una equazione ” in sintesi: punti fondamentali da ricordare.
Il problema f(x)=0
Il problema è detto “risoluzione di una equazione” oppure ”determinazione di uno zero di una
funzione”. Ci siamo occupati solo di soluzioni che sono numeri reali, e non del caso più generale in cui le
soluzioni possono essere numeri complessi.
Un numero r è una soluzione del problema f(x) = 0 se si ha che f(r) = 0.
Il problema può ammettere nessuna soluzione, una o più soluzioni, o anche infinite soluzioni, a seconda
della natura della f e del dominio a cui si è interessati.
Gli algoritmi (metodi) che abbiamo trattato permettono di determinare una sola soluzione alla volta.
Quindi, se il problema ammette più soluzioni, l’algoritmo deve essere eseguito tante volte quante sono
le soluzioni che si vogliono calcolare.
I dati che devono essere noti sono: la funzione f e poi una informazione che consente di localizzare una
soluzione. Tale informazione può essere un intervallo (incluso nel dominio di f) che contiene la
soluzione o un numero che rappresenta una approssimazione iniziale della soluzione. In genere, la
localizzazione avviene esaminando il grafico della f o usando altre informazioni sul problema. Si ricorda
che la f si ritiene nota se si conosce la sua espressione esplicita (per es. f(x)=sin(3x)/(1+(log(x2))2) ),
oppure se si ha un programma che consente di calcolare il valore di f(x) per qualunque valore fissato x.
Un importante aspetto teorico del problema f(x) = 0 è che, anche se esiste una soluzione, può non
esistere una formula (chiusa) per calcolarla. Si ricorda che per formula chiusa si intende una formula
che contiene un numero finito di operazioni aritmetiche e di valutazioni di funzioni elementari. Un
esempio in tal senso è dato dal teorema di Ruffini-Abel-Galois che afferma l’impossibilità di esprimere
mediante formula chiusa (che coinvolga i coefficienti del polinomio) gli zeri di un qualunque polinomio
di grado maggiore o uguale di 5: per esempio, non esiste una formula per risolvere 3x5-8x4-x+1=0.
Ne consegue che un algoritmo per risolvere il problema f(x) = 0 deve necessariamente essere di tipo
iterativo. Un algoritmo iterativo è in grado di generare una successione che, sotto opportune ipotesi,
converge alla soluzione del problema. E’ chiaro che un algoritmo iterativo deve contenere un criterio di
arresto che stabilisce le condizioni che si devono verificare per terminare, a un certo passo p, il
processo iterativo, in modo che il p-simo elemento della successione (detto approssimazione al passo p)
sia una approssimazione soddisfacente della soluzione (ovvero del limite della successione).
Le due caratteristiche principali di un algoritmo iterativo sono la convergenza, e la velocità di
convergenza. Analizzare la convergenza significa stabilire le condizioni affinché l’algoritmo generi una
successione che converge alla soluzione. Determinare la velocità di convergenza di un algoritmo
iterativo significa determinare la legge che indica di quanto si riduce l’errore (tra l’approssimazione e la
soluzione) dopo aver eseguito un passo di iterazione.
Metodo di bisezione
Il metodo di bisezione è un algoritmo iterativo globale e a velocità di convergenza lineare che risolve il
problema f(x) = 0; è utilizzabile se f è una funzione continua e se si conosce un intervallo che contiene la
soluzione e ai cui estremi la f assume valori di segno opposto. Con globale si intende che l’algoritmo è
sempre convergente (quando è applicabile!). Con velocità di convergenza lineare si intende che l’errore
si riduce di un fattore costante a ogni passo di iterazione.
L’algoritmo è basato sull’approccio detto divide et impera, che riduce progressivamente (dimezzandolo
a ogni passo) l’intervallo che contiene la soluzione.
A ogni passo p, si ha un intervallo che contiene la soluzione: il punto medio dell’intervallo è
l’approssimazione della soluzione e la semi-ampiezza dell’intervallo è la stima dell’errore tra tale
approssimazione e la soluzione. Il fatto che l’errore si dimezza a ogni passo di iterazione implica che se
al passo p l’errore 2-s (cioè l’approssimazione ha s cifre della parte frazionaria corrette) allora al passo
successivo p+1 l’errore sarà 2-1 2-s = 2-s-1, ovvero la nuova approssimazione avrà un bit corretto in più
rispetto all’approssimazione precedente. Poiché sono necessari al più 4 bit per rappresentare i numeri
della base 10 (0,1,2,…8,9), dopo quattro passi di iterazione la nuova approssimazione avrà una cifra (in
base 10) corretta in più.
L’intestazione di una function Matlab per l’algoritmo di bisezione ha la seguente forma:
function radice = bisezione(funzione,a,b,delta_ass)
si noti che il primo argomento di input deve essere l’handle alla function Matlab che implementa la
funzione f, il secondo e il terzo sono gli estremi dell’intervallo iniziale, l’ultimo argomento è
l’accuratezza che si vuole sul risultato da calcolare (restituito in radice), ovvero |r - radice|<
delta_ass.
Il nucleo della function è costituito dalla struttura ripetitiva che realizza il processo iterativo:
while abs(bk-ak)>delta_ass + eps*max(abs(ak),abs(bk))
pmediok = (ak+bk)/2;
fpmediok = funzione(pmediok);
if sign(fak) ~ = sign(fpmediok)
% la radice è nell'intervallo [ak, pmediok]
bk = pmediok;
fbk = fpmediok;
else
% la radice è nell'intervallo [pmediok, bk]
ak = pmediok;
fak = fpmediok;
end
end
2 2
grafico di sin(3*x)./(1+(log(x.)).
0.6
0.4
0.2
-0.2
-0.4
-0.6
-0.8
0.5 1 1.5
ris è una approssimazione (1.047197818756104) della soluzione (1.047197551196598) con 6 cifre della
Metodo di Newton
Il metodo di Newton è un algoritmo iterativo locale e a velocità di convergenza quadratica che risolve il
problema f(x) = 0; è utilizzabile se f è una funzione continua e derivabile (con derivata nota) e se si
conosce una buona (ricordare il corrispondente teorema) approssimazione iniziale della soluzione.
Con locale si intende che l’algoritmo non è sempre convergente e che la convergenza dipende da come
si sceglie la condizione iniziale. Con velocità di convergenza quadratica si intende che, a ogni passo di
iterazione, l’errore relativo si riduce diventando il (proporzionale al) quadrato dell’errore precedente
(si ricorda che gli errori sono del tipo 10-s e che (10-s)2 = 10-2s ).
L’algoritmo è basato sull’idea di approssimare linearmente la f, a ogni passo p di iterazione, con la retta
tangente alla f nel punto (xp, f(xp)), il cui coefficiente angolare1 è f’(xp), e di considerare lo zero di tale
retta come approssimazione dello zero di f.
1
Il coefficiente angolare, o pendenza, di una retta è la tangente dell’angolo tra la retta e la direzione positiva
dell’asse x.
Se chiamiamo xp l’approssimazione al passo p, allora effettuando un altro passo di iterazione si ottiene
la nuova approssimazione xp+1 data da xp+1 = xp - cp , dove cp è la lunghezza del cateto sull’asse delle x del
triangolo rettangolo che ha per vertici (xp ,0), (xp , f( xp ) ) e il punto di intersezione della retta tangente
con l’asse delle x. La lunghezza di tale cateto, in virtù del noto teorema sui cateti del triangolo
rettangolo e della interpretazione geometrica della derivata di una funzione in un punto, è f(xp) /f’(xp).
Il fatto che l’errore diventi a ogni passo di iterazione il quadrato dell’errore al passo precedente implica
che se al passo p l’errore 10-s (cioè l’approssimazione ha s cifre della parte frazionaria corrette) allora al
passo successivo p+1 l’errore sarà (10-t )2 = 10-2t, ovvero la nuova approssimazione avrà il doppio delle
cifre corrette rispetto all’approssimazione precedente. Si noti che se l’approssimazione iniziale x0 ha
una cifra corretta (errore dell’ordine di 10-1), allora dopo 4 passi di iterazione si avrà una nuova
approssimazione con 16 cifre (in base 10) corrette, ovvero tutte le cifre memorizzabile nella
rappresentazione f-p.
L’intestazione di una function Matlab per l’algoritmo di Newton ha la seguente forma:
function radice = Newton(funzione,derivata,xiniz,delta_ass,kmax)
si noti che i primi due argomenti di input devono essere l’handle alla function Matlab che implementa
la funzione f e l’handle alla function Matlab che implementa la funzione f’, cioè la derivata di f, il terzo
argomento è l’approssimazione iniziale, il quarto argomento è l’accuratezza che si vuole sul risultato da
calcolare (restituito in radice), ovvero |r - radice|< delta_ass, e l’ultimo è il massimo numero di
iterazioni consentito (serve per evitare che l’algoritmo vada in loop nel caso di non convergenza).
Il nucleo della function è costituito dalla struttura ripetitiva che realizza il processo iterativo:
while abs(correzionek) > delta_ass + eps*abs(xk) & k <= kmax
xk = xk + correzionek;
fxk = funzione(xk);
fprimoxk = derivata(xk);
correzionek = -fxk/fprimoxk;
k = k+1;
end
2
L’espressione della derivata della funzione f può essere determinata a mano, con un po’ di attenzione e di
tempo, ma può essere ottenuta ricorrendo al servizio funtool di Matlab. Basta digitare funtool nella
finestra comandi, poi scrivere l’espressione di f nel primo campo della finestra centrale e cliccare sul tasto df/dx,
ottenendo l’espressione della derivata di f nella stessa finestra (con il suo grafico visualizzato nella finestra di
sinistra). Bisogna fare attenzione al fatto che funtool opera in notazione matematica pura e non in notazione
Matlab: non bisogna usare le operazioni .*, ./, .^ ma sempre *,/,^.
2 2
grafico di sin(3*x)./(1+(log(x.)). grafico della derivata di sin(3*x)./(1+(log(x.2)).2
0.6 1.5
1
0.4
0.5
0.2
0
0 -0.5
-0.2 -1
-1.5
-0.4
-2
-0.6
-2.5
-0.8 -3
0.5 1 1.5 0.5 1 1.5
ris è una approssimazione (1.047197258345557) della soluzione (1.047197551196598) con 6 cifre della
parte frazionaria corrette. L’algoritmo ha effettuato 4 passi di iterazione. Si noti la maggiore velocità di
convergenza rispetto all’algoritmo di bisezione (4 vs. 20 iterazioni, per ottenere approssimazioni con 6
cifre frazionarie corrette).
Il residuo dell’approssimazione ris è immediatamente calcolabile valutando la f in ris:
>> residuo = f(ris)
residuo =
8.711421187216681e-007
Si noti che il residuo è un numero dello stesso ordine dell’accuratezza richiesta (1e-6) , ed è una
approssimazione di 0 con 6 cifre corrette.
E’ importante osservare che se si prende un’approssimazione iniziale più lontana dalla soluzione, per
esempio 0.7, l’algoritmo di Newton non converge alla soluzione desiderata. Provare a giustificare
qualitativamente questo fatto analizzando il grafico della f.
Infine, ricordare che l’algoritmo di Newton ha una velocità di convergenza minore se la soluzione del
problema è uno zero multiplo della f (ovvero uno zero anche per la funzione f’, derivata di f).
parte frazionaria corrette. L’algoritmo ha effettuato 5 passi di iterazione. Si noti che la velocità di
convergenza è maggiore di quella dell’algoritmo di bisezione e minore dell’algoritmo di Newton (5 vs.
20, e 5 vs. 4 iterazioni, rispettivamente, per ottenere approssimazioni con 6 cifre frazionarie corrette).
Il residuo dell’approssimazione ris è immediatamente calcolabile valutando la f in ris:
>> residuo = f(ris)
residuo =
-6.465308752413356e-009
Si noti che il residuo è un numero di un paio di ordini minore dell’accuratezza richiesta (1e-6) , ed è una
approssimazione di 0 con 6 cifre corrette.
E’ importante osservare che se si prendono due approssimazioni iniziali più lontane dalla soluzione, per
esempio 0.7 e 0.8, l’algoritmo delle secanti non converge alla soluzione desiderata. Provare a
giustificare qualitativamente questo fatto analizzando il grafico della f.
Metodi ibridi
I metodi ibridi combinano in un unico algoritmo un metodo globale e uno (o più) metodi locali.
L’obiettivo è di ottenere un algoritmo globale con velocità di convergenza superlineare.
Considerando per esempio un metodo ibrido basato su bisezione e Newton, l’algoritmo a ogni passo
determina sia l’approssimazione della bisezione sia l’approssimazione di Newton. Se l’approssimazione
di Newton appartiene al nuovo intervallo di bisezione, allora l’approssimazione di Newton diventa la
nuova approssimazione dell’algoritmo. Si noti che l’appartenenza all’intervallo di bisezione è una
ragionevole garanzia della convergenza del metodo di Newton. Altrimenti, la nuova approssimazione
dell’algoritmo è quella della bisezione.
L’algoritmo implementato nella function Matlab fzero è un algoritmo ibrido.
L’algoritmo combina il metodo di bisezione, il metodo delle secanti e un terzo metodo detto
interpolazione quadratica inversa, che sarà discusso più avanti nel Corso.
La function fzero ha due parametri di input: il primo è l’handle alla function Matlab che implementa
la funzione f; il secondo argomento può essere uno scalare o un vettore; se è uno scalare, allora è una
approssimazione iniziale della soluzione; se è un vettore, allora deve avere due componenti che sono
l’estremo sinistro e l’estremo destro di un intervallo che contiene la soluzione.
Per esempio, se si vuole risolvere sin(3x)/(1+(log(x2))2) = 0 in [0.5, 1.5], si procede così:
>> f = @(x) sin(3*x)./(1+(log(x.^2)).^2);
>> ris = fzero(f,0.7) % appross. iniziale 0.7
ris =
1.047197551196598 % in format long
ris è una approssimazione della soluzione (1.047197551196598) con tutte le cifre corrette. Si noti la
110
100
90
80
70
60
50
40
30
20
0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1
120
110
100
90
80
70
60
50
40
30
20
0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1
Massimi di una funzione
determinazione di punti di
massimo locale di una funzione
f (x )
18
16
14
12
10
0
0 0.2 0.4 0.6 0.8 1 1.2 1.4
0
-2 − f (x )
-4
-6
-8
-10
-12
-14
-16
-18
-20
0 0.2 0.4 0.6 0.8 1 1.2 1.4
f(x) derivabile
f ′ ( xk )
x k +1 = xk −
f ′′ ( xk )
x_minimo = Newton(@d1,@d2,xiniz,delta,kmax)
q ′( x k ) = f ′( xk )
q ′′( x k ) = f ′′( x k )
considerando come approssimazione successiva
del minimo di f il minimo del polinomio q
18
16
x.^2+0.45*(sin(2*x)).^2;
14
12
10
0
-4 -3 -2 -1 0 1 2 3 4
20
15
10
polinomio q xk = 2.2
-5
-4 -3 -2 -1 0 1 2 3 4
xk +1 = −1.128
metodo di Newton per la minimizzazione: f ′ ( xk )
x k +1 = xk −
risoluzione di f ’(x) = 0 f ′′ ( x k )
q (x k )= f (x k )
sviluppo di Taylor di f
q ′ (x k )= f ′ (x k )
attorno a xk arrestato al
q ′′ ( x k ) = f ′′ ( x k )
secondo ordine:
c2
f ( xk + c ) = f ( xk ) + c ⋅ f ′ ( xk ) + ⋅ f ′′ ( xk ) + O c
2
3
( )
min f (x ) = min f (xk + c ) c2
≈ min f ( xk ) + c ⋅ f ′ ( xk ) + ⋅ f ′′ ( xk )
x c c
2
è una funzione
della variabile c
d c2
f ( xk ) + c ⋅ f ′( xk ) + ⋅ f ′′( xk ) = 0
dc 2
metodo di Newton per la minimizzazione: f ′ ( xk )
x k +1 = xk −
risoluzione di f ’(x) = 0 f ′′ ( x k )
q (x k )= f (x k )
sviluppo di Taylor di f
q ′ (x k )= f ′ (x k )
attorno a xk arrestato al
q ′′ ( x k ) = f ′′ ( x k )
secondo ordine:
f ( x k ) − f ( x k −1 ) f ( x k −1 ) − f ( x k − 2 )
−
x k − x k −1 x k −1 − x k − 2
f (x k ) ≈ p 2 k =
′′
x k − x k −1
metodo di minimizzazione di Newton varianti
approssimazione della derivata prima e seconda
(con differenze finite)
~
xk +1 = xk + ck
f ( x k ) − f ( x k −1 )
f ′( x k ) ≈ p k =
f ′( x k ) x k − x k −1
ck = −
f ′′( x k ) f ′′( x k ) ≈ p 2 k =
f ( x k ) − f ( x k −1 )
−
f ( x k −1 ) − f ( x k − 2 )
(x k − x k −1 )2 (x k − x k −1 )(x k −1 − x k − 2 )
p k − p k −1
f ′′( x k ) ≈ p 2 k =
( x k − x k −1 )
~ pk
ck = −
p2k
metodo di minimizzazione di Newton varianti
determinazione (a ogni passo k) del minimo del
polinomio di secondo grado interpolante
su xk , xk-1, xk-2
20
15
10
-5
-4
xk-3− 2 -2 x-1k +1 0 1
x k2 3 xk −1 4
metodo di minimizzazione di Newton varianti
metodi damped (il parametro αk è scelto a ogni
passo in modo tale da evitare che la nuova
approssimazione sia troppo lontana dalla
precedente)
xk +1 = xk + α k ck
f ( xk +1 ) < f ( xk )
calcolo di minimi di una funzione di una variabile in Matlab
(ottimizzazione non vincolata)
x = fminbnd(@mia_fun,estremo_sin,estremo_des)
f = @(x) 2+(x-pi).^2;
x = fminbnd(f,1.2,5.1)
approssimazione
iniziale
metodo del gradiente discendente (steepest descent)
passo
approssimazione
successivo
iniziale
metodo del gradiente discendente (steepest descent)
approssimazione
nuova
iniziale
derivata
passo
successivo
metodo del gradiente discendente (steepest descent)
approssimazione
iniziale
passo
successivo
metodo del gradiente discendente (steepest descent)
approssimazione
iniziale
metodo del gradiente discendente (steepest descent)
xk +1 = xk − α ⋅ f ′( xk )
per esempio: α = 0.1
xk +1 = xk + ck
a ogni passo l’approssimazione della soluzione
viene corretta con una quantità proporzionale
all’opposto del valore della derivata
(valutata in quel punto di approssimazione)
difficoltà: criterio di arresto
criterio per
arrestare il metodo
iterativo
difficoltà: funzione non convessa
approssimazione
iniziale buona
difficoltà: funzione non convessa
approssimazione
iniziale cattiva
approssimazione
iniziale buona
funzione convessa
x
funzione convessa
funzione non convessa
funzione concava
f convessa concavità verso l’alto
f concava concavità verso il basso
Definizione
presi due qualunque punti
A e B dell’insieme, allora
ogni punto sulla retta che
passa per A e B
appartiene all’insieme. insieme convesso
λ A + (1 − λ ) B, 0 ≤ λ ≤1
appartiene all’insieme
insiemi convessi
Definizione
presi due qualunque punti
A e B dell’insieme, allora
ogni punto sulla retta che
passa per A e B
insieme non
appartiene all’insieme.
convesso
λ A + (1 − λ ) B, 0 ≤ λ ≤1
appartiene all’insieme
funzioni e insiemi convessi
funzione convessa
min f ( x )
funzione convessa
x
f è una funzione convessa,
definita su insiemi convessi
definizione:
definizione:
una funzione f(x)
una funzione f(x) èè unimodale
unimodale in in [[a,b
a,b],], se
se esiste
esiste
un
un unico numero pp in
unico numero in [a,b]
[a,b] tale
tale che
che
f(x)
f(x) èè strettamente
strettamente decrescente in [[a,p
decrescente in a,p]] ed
ed èè
strettamente
strettamente crescente in [[p,b
crescente in p,b]]
calcolo del minimo di una
funzione unimodale
metodo
metodo della
della ricerca
ricerca di
di Fibonacci
Fibonacci
(Fibonacci
(Fibonacci search)
search)
metodo
metodo della
della ricerca
ricerca Aurea
Aurea
(Golden
(Golden search)
search)
calcolo del minimo di una
funzione unimodale
riduzione di un intervallo che racchiude uno zero
di una funzione continua
16
x.^2+0.45*(sin(2*x)).^2;
14
0
-4 -3 -2 -1 0 1 2 3 4
a c d b
18
16
x.^2+0.45*(sin(2*x)).^2;
14
0
-4 -3 -2 -1 0 1 2 3 4
a c d b
function
function risris == fminrand(f,a,b,delta_ass)
fminrand(f,a,b,delta_ass)
%% minimizzazione
minimizzazione di di f,
f, unimodale
unimodale in
in a,b;
a,b;
%% l'approssimazione
l'approssimazione ha ha accuratezza
accuratezza delta_ass
delta_ass
if
if abs(b-a)
abs(b-a) << delta_ass
delta_ass
ris
ris =(a+b)/2;
=(a+b)/2;
else
else
r1
r1 == aa +(b-a)*rand(1,1);
+(b-a)*rand(1,1);
r2
r2 == aa +(b-a)*rand(1,1);
+(b-a)*rand(1,1);
cc == min([r1,r2]);
min([r1,r2]);
dd == max([r1,r2]);
max([r1,r2]);
fc
fc == f(c);
f(c); fdfd == f(d);
f(d);
if
if fc
fc <=<= fd
fd
bb == d;
d;
else
else
aa == c;
c;
end
end
ris
ris == fminrand(f,a,b,delta_ass);
fminrand(f,a,b,delta_ass);
end
end
function
function risris == fminrand1(f,a,b,delta_ass)
fminrand1(f,a,b,delta_ass)
%% minimizzazione
minimizzazione di di f,
f, unimodale
unimodale in
in a,b;
a,b;
%% l'approssimazione
l'approssimazione ha ha accuratezza
accuratezza delta_ass
delta_ass
if
if abs(b-a)
abs(b-a) << delta_ass
delta_ass
ris
ris =(a+b)/2;
=(a+b)/2;
else
else
rr == 0.5*rand;
0.5*rand;
cc == aa +(b-a)*r;
+(b-a)*r;
dd == aa +(b-a)*(1-r);
+(b-a)*(1-r);
fc
fc == f(c);
f(c); fdfd == f(d);
f(d);
if
if fc
fc <=<= fd
fd
bb == d;
d;
else
else
aa == c;
c;
end
end
ris
ris == fminrand1(f,a,b,delta_ass);
fminrand1(f,a,b,delta_ass);
end
end
18
criterio per la scelta di c e d
16
4
il punto c o il punto d deve essere un
punto già considerato al passo precedente
2
0
-4 -3 -2 -1 0 1 2 3 4
a c d b
Metodo della ricerca di Fibonacci (Fibonacci search)
si sceglie un intero N
si considerano i numeri di Fibonacci
fibonacci(N), fibonacci(N-1), fibonacci (N-2), …,
fibonacci(2), fibonacci(1)
primo passo (l’intervallo che contiene la soluzione è [a,b])
c = a + fibonacci (N-2)/fibonacci (N) *(b-a)
d = a + fibonacci (N-1)/fibonacci (N) *(b-a)
se f(c) < f(d) il nuovo intervallo è [a,d]
se f(c) ≥ f(d) il nuovo intervallo è [c,b]
secondo passo (l’intervallo è chiamato ancora [a,b])
c = a + fibonacci (N-3)/fibonacci (N-1) *(b-a)
d = a + fibonacci (N-2)/fibonacci (N-1) *(b-a)
si sceglie il nuovo intervallo
e così via, fino al passo N-simo
Metodo della ricerca di Fibonacci (Fibonacci search)
(b − a ) FN −1
numeri di Fibonacci
FN
Metodo della ricerca di Fibonacci (Fibonacci search)
(b − a ) FN −1 FN − 2
(b − a )1 − = (b − a )
FN − FN − 2
FN FN FN
Metodo della ricerca di Fibonacci (Fibonacci search)
FN − FN − 2
(b − a ) FN −1
(b − a ) = (b − a )
FN −1
FN FN FN
Metodo della ricerca di Fibonacci (Fibonacci search)
[b − a] FN −1 FN − 2 FN −3 F2 F1
⋯ [b − a] 1
FN FN −1 FN − 2 F3 F2 FN
Metodo della ricerca di Fibonacci (Fibonacci search)
[b − a] 1
FN
δ
sezione aurea (golden section)
Metodo della ricerca di Fibonacci (Fibonacci search)
c = a + [b − a ] , d = a + [b − a ]
FN − 2 FN −1
FN FN
supponiamo che il nuovo intervallo sia [a,d]
= a + [d − a ] = a + [b − a ]
FN − 2 FN −1 FN − 2
d nuovo =c
FN −1 FN FN −1
Fn
lim =ϕ 1.6180….
sezione aurea
(golden section)
n →∞ F
n −1
Fn −1 1
lim = ≡ ϕ −1 0.6180….
n →∞ F
n ϕ
Fibonacci search
primo passo (l’intervallo che contiene la soluzione è [a,b])
c = a + fibonacci (N-2)/fibonacci (N) *(b-a)
d = a + fibonacci (N-1)/fibonacci (N) *(b-a)
ϕ -1
Golden search
Fn
lim =ϕ 1.6180….
sezione aurea
(golden section)
n →∞ F
n −1
Fn −1 1
lim = ≡ ϕ −1 0.6180….
n →∞ F
n ϕ
Fibonacci search
primo passo (l’intervallo che contiene la soluzione è [a,b])
c = a + fibonacci (N-2)/fibonacci (N) *(b-a)
d = a + fibonacci (N-1)/fibonacci (N) *(b-a)
Golden search Fn −1 1
lim = ≡ ϕ −1
n →∞ F
n ϕ
Fn − 2 Fn − Fn −1 Fn −1
= = 1−
Fn Fn Fn
= 1 − (ϕ − 1) = 2 − ϕ
Fn − 2
lim 0.3819...
n →∞ F
n
Fibonacci search
primo passo (l’intervallo che contiene la soluzione è [a,b])
c = a + fibonacci (N-2)/fibonacci (N) *(b-a)
d = a + fibonacci (N-1)/fibonacci (N) *(b-a)
2-ϕ
Golden search Fn −1 1
lim = ≡ ϕ −1
n →∞ F
n ϕ
Fn − 2 Fn − Fn −1 Fn −1
= = 1−
Fn Fn Fn
= 1 − (ϕ − 1) = 2 − ϕ
Fn − 2
lim 0.3819...
n →∞ F
n
Golden search
primo passo (l’intervallo che contiene la soluzione è [a,b])
c = a + (2-phi) *(b-a)
d = a + (phi-1) *(b-a)
Golden search
c = a + (b − a )(2 − ϕ ) , d = a + (b − a )(ϕ − 1)
(ϕ − 1)2 = (ϕ − 1) = 1 − 1 = 1 − (ϕ − 1) = 2 − ϕ
ϕ ϕ
function fminrand
metodo di ricerca di Fibonacci
Golden search
function Matlab fminbnd
( ( ))
f (x ) = exp sin x 2 4
+ x + 3 sin exp −
1
1+ x
3.7
3.6
3.5
3.4
3.3
3.2
1.8 1.85 1.9 1.95 2 2.05 2.1 2.15 2.2 2.25
Ripetere l’esercizio osservando, dal grafico della funzione
f, che questa ammette vari minimi locali.
Trovare il minimo:
• nell’intervallo [-1,1]
• nell’intervallo [-2.85,3.75]
Usare:
variante di Newton con differenze finite
3 passi del metodo del gradiente discendente
function Matlab fminbnd
20
18 ( ( ))
f ( x ) = exp sin x 2
+ x + 3 sin exp −
4
1
16
1+ x
14
12
10
0
-5 -4 -3 -2 -1 0 1 2 3 4 5
Lezioni 3 - “ min f(x), determinazione del minimo di una funzione” in sintesi: punti fondamentali da
ricordare.
1
L’espressione della derivata della funzione f può essere determinata a mano, con un po’ di attenzione e di
tempo, ma può essere ottenuta ricorrendo al servizio funtool di Matlab. Basta digitare funtool nella
finestra comandi, poi scrivere l’espressione di f nel primo campo della finestra centrale e cliccare sul tasto df/dx,
ottenendo l’espressione della derivata di f nella stessa finestra (con il suo grafico visualizzato nella finestra di
>> fsecondo = @(x) -(3*cos(2*x) - 4*sin(2*x))./exp(x); %derivata seconda
calcolata con funtool
>> g = linspace(-3, 0, 200);
>> figure(1), plot(g, f(g)), grid
>> title(‘grafico di -exp(-x)*sin(2*x-pi/2)’)
>> figure(2), plot(g, fprimo(g)), grid
>> title(‘grafico della derivata di -exp(-x)*sin(2*x-pi/2)’)
5
15
0
10 -5
-10
5
-15
0 -20
-25
-5
-30
-10 -35
-3 -2.5 -2 -1.5 -1 -0.5 0 -3 -2.5 -2 -1.5 -1 -0.5 0
fminbnd
La function Matlab fminbnd calcola il punto di minimo di una funzione.
La function fminbnd ha tre parametri di input: il primo è l’handle alla function Matlab che implementa
la funzione f; il secondo e il terzo argomento sono, rispettivamente, l’estremo sinistro e l’estremo
destro di un intervallo che contiene la soluzione.
Per esempio, se si vuole risolvere min -exp(-x)*sin(2*x-pi/2), in [-2.5,1], con 14 cifre della parte
frazionaria corrette, si procede così:
>> f = @(x) -exp(-x).*sin(2*x-pi/2);
>> xminimo = fminbnd(f,-2.5,-1,optimset(‘TolX’,1e-14)) % delta è 1e-4
xminimo =
-1.802620131175508 % in format long
sinistra). Bisogna fare attenzione al fatto che funtool opera in notazione matematica pura e non in notazione
Matlab: non bisogna usare le operazioni .*, ./, .^ ma sempre *,/,^.
L’accuratezza richiesta è posta per default uguale a 1e-4. Il comando Matlab optimset consente di
visualizzare le opzioni di chiamata a fminbnd:
>> options = optimset('fminbnd')
mentre
>> options = optimset(options,'TolX',1e-14)
modifica il valore di default dell’accuratezza richiesta, portandola a 1e-14.
Si noti che è possibile modificare il valore di Tolx solo per una chiamata, usando la optimset come
quarto argomento di chiamata della function fminbnd (fminbnd(f,-2.5,-
1,optimset(‘TolX’,1e-14))).