You are on page 1of 6

5 Soluzioni numeriche di equazioni differenziali

5.1 Metodo di Eulero per la soluzione approssimata di equazioni diffe-


renziali del primo ordine in forma normale
Dato un problema di Cauchy (
y ′ = f (t, y)
y (t0 ) = y0 ,
il metodo di Eulero serve per trovarne una soluzione approssimata su un intervallo dato [t0 , t0 + T ]
e consiste nell’approssimare il grafico della soluzione con le sue rette tangenti in una successione di
intervalli in cui viene suddiviso l’intervallo di interesse [t0 , t0 + T ]. Sia quindi N il numero totale
T
di intervalli e h = N > 0 l’ampiezza del singolo intervallino in cui suddivideremo [t0 , t0 + T ]. Più
h verrà scelto piccolo (e quindi N grande) e più l’approssimazione risulterà precisa, però dovremo
compiere un numero maggiore di passi per determinare la soluzione approssimata sull’intervallo
di interesse.
I punti in cui si calcolano i valori approssimati della funzione sono ti = t0 + hi, per cui
ti+1 = ti + h. I valori approssimati sono calcolati sulle rette tangenti: y (t0 ) = y0 è un dato del
problema di Cauchy, y (t1 ) è approssimato da

y (t1 ) ≈ y1 = y0 + hy ′ (t0 ) = y0 + hf (t0 , y0 ) ,

y (t2 ) è approssimato da

y (t2 ) ≈ y (t1 ) + hy ′ (t1 ) = y (t1 ) + hf (t1 , y (t1 )) ≈ y2 = y1 + hf (t1 , y1 ) .

Dato il punto (ti , yi ) possiamo trovare il successivo tramite il semplice algoritmo


(
ti+1 = ti + h
yi+1 = yi + hf (ti , yi ) .

Un miglioramento a questo algoritmo può essere ottenuto nel seguente modo, invece di usare
la derivata in ti , usiamo una media della derivata in ti e ti+1 usando il valore ui+1 = yi + hf (ti , yi )
per approssimare yi+1 nel calcolo della derivata in ti+1 . Otteniamo quindi il seguente algoritmo
di Eulero migliorato: 
ti+1 = ti + h

ui+1 = yi + hf (ti , yi )
yi+1 = yi + h f (ti ,yi )+f2(ti+1 ,ui+1 ) .

Nei seguenti grafici è rappresentata la soluzione esatta del problema di Cauchy


(
y ′ = te−t y
y(0) = 1

data da y(t) = e1−(t+1)e in nero e le approssimazioni numeriche ottenute con il metodo di Eulero
−t

(in verde) e il metodo di Eulero migliorato (in blu) relativi a vari valori del parametro h > 0.

47
3

2.5

1.5
y

0.5

0
0 1 2 3 4 5 6 7 8
t

Figura 0.54: Grafico della soluzione esatta

2.5

1.5
y

0.5

0
0 1 2 3 4 5 6 7 8
t

Figura 0.55: Grafico della soluzione esatta e delle due approssimazioni numeriche con h = 4

48
3

2.5

1.5
y

0.5

0
0 1 2 3 4 5 6 7 8
t

Figura 0.56: Grafico della soluzione esatta e delle due approssimazioni numeriche con h = 2

2.5

1.5
y

0.5

0
0 1 2 3 4 5 6 7 8
t

Figura 0.57: Grafico della soluzione esatta e delle due approssimazioni numeriche con h = 1

49
3

2.5

1.5
y

0.5

0
0 1 2 3 4 5 6 7 8
t

Figura 0.58: Grafico della soluzione esatta e delle due approssimazioni numeriche con h = 0.5

2.5

1.5
y

0.5

0
0 1 2 3 4 5 6 7 8
t

Figura 0.59: Grafico della soluzione esatta e delle due approssimazioni numeriche con h = 0.1

50
3

2.5

1.5
y

0.5

0
0 1 2 3 4 5 6 7 8
t

Figura 0.60: Grafico della soluzione esatta e delle due approssimazioni numeriche con h = 0.01

I grafici sono stati ottenuti con il seguente programma in Python.

#! /usr/bin/env python
# -*- coding: utf-8 -*-
#
from math import *
import Gnuplot, Gnuplot.funcutils
import numpy

# inizializza il grafico e fissa la lunghezza


# degli assi e le proporzioni
g = Gnuplot.Gnuplot()
g(’set xrange [0:8]’)
g(’set yrange [0:3]’)
g(’set size ratio 1.0/1.33’)
g(’set clip’)
g(’unset key; set hidden3d’)
g(’set termoption enhanced’)
g(’set xlabel "t"’)
g(’set ylabel "y"’)
g(’set parametric’)
g(’set trange [0:8]’)

# comando per disegnare la soluzione esatta


exactgraph = ’t,exp(1-exp(-t)*(t+1))’
# disegna il grafico della soluzione esatta in nero
g.plot(Gnuplot.Func(exactgraph,with_="lines lt 1 lc rgb ’black’ lw 1"))

# funzione che definisce l’equazione differenziale


def f(t,y):
return t * exp(-t) * y

51
# estremo superiore dell’intervallo di integrazione
T = 8.
# dati iniziali
t0 = 0
y0 = 1

# chiede il valore dell’ampiezza degli intervallini


while True:
h = float(raw_input("h= "))
if h <=0:
break

# numero di passi
n = int(T / h) + 1

# vettori in cui inserire i valori di t e y


t = numpy.zeros(n,float)
y = numpy.zeros(n,float)

# i primi valori sono i dati iniziali del problema di Cauchy


t[0] = t0
y[0] = y0

# ALGORITMO DI EULERO
for i in range(n-1):
t[i+1] = t[i] + h
y[i+1] = y[i] + h * f(t[i],y[i])

# EULERO MIGLIORATO

# vettori in cui inserire i valori di t e y e u


tm = numpy.zeros(n,float)
um = numpy.zeros(n,float)
ym = numpy.zeros(n,float)

# i primi valori sono i dati iniziali del problema di Cauchy


tm[0] = t0
ym[0] = y0

# ALGORITMO DI EULERO MIGLIORATO


for i in range(n-1):
tm[i+1] = tm[i] + h
um[i+1] = ym[i] + h * f(tm[i],ym[i])
ym[i+1] = ym[i] + h * (f(tm[i],ym[i]) + f(tm[i+1],um[i+1])) / 2.

# disegna la soluzione esatta e le approssimazioni con i due algoritmi


g.plot(Gnuplot.Func(exactgraph,with_="lines lt 1 lc rgb ’black’ lw 1"),\
Gnuplot.Data(t,y, with_="lines lt 1 lc rgb ’green’ lw 2"),\
Gnuplot.Data(tm,ym, with_="lines lt 1 lc rgb ’blue’ lw 2"))

52

You might also like