Lezione del 1 marzo 2007¶
Esempio con una ODE elementare
Implementazione MATLAB del metodo di Eulero esplicito per la equazione di un circuito RL:
File circuito.m
:open:
1%
2% Soluzione esatta e approssimata con il metodo di Eulero
3% della equazione differenziale
4% L di(t)/dt + R i(t) = V
5% i(0) = i0
6%
7% Ingresso:
8% i0 = corrente iniziale
9% V = tensione ai capi del circuito
10% R = resistenza
11% L = induttanza
12% T = tempo finale
13% N = numero di punti di griglia da calcolare
14% restituisce i vettori
15% t(:) = vettore con gli istanti temporali dove la soluzione è calcolata
16% i(:) = andamento della corrente calcolato con il metodo di Eulero
17% e(:) = andamento della corrente con soluzione esatta
18%
19function [t,i,e]=circuito(i0,V,R,L,T,N)
20 t(1) = 0 ;
21 i(1) = i0 ;
22 e(1) = i0 ;
23 h = T/N ;
24 for k=1:N
25 % griglia temporale
26 t(k+1) = t(k) + h;
27 % soluzione approssimata col metodo di Eulero
28 i(k+1) = i(k) + (V-R*i(k))*h/L;
29 % soluzione esatta
30 e(k+1) = i0*exp(-t(k+1)*R/L) ...
31 +(V/R)*(1-exp(-t(k+1)*R/L)) ;
32 end;
33end
Programma driver per verificare il codice:
File test_circuito.m
:open:
1i0 = 1 ;
2V = 10 ;
3R = 1 ;
4L = 2 ;
5T = 10 ;
6N = 30 ;
7[t,i,e] = circuito(i0,V,R,L,T,N);
8hold off ;
9plot(t,i,'.-b');
10hold on ;
11plot(t,e,'-r');
12legend('approssimata','esatta');
Esempio di output:
Metodo di Eulero esplicito
Implementazione MATLAB del metodo di Eulero esplicito:
File Eulero_esplicito.m
:open:
1%
2% Metodo di Collatz o Eulero Migliorato per sistemi di equazioni differenziali
3%
4% Ingresso
5% f = funzione per il sistema y'=f(x,y)
6% x0, y0 = dato iniziale del problema y(x0) = y0
7% xf = estremo superiore dell'intervallo di calcolo [x0,xf]
8% N = numero di intervalli in cui suddividere [x0,xf]
9%
10% Uscita
11% x(:) = vettore soluzione delle 'x'
12% y(:) = vettore soluzione delle 'y'
13%
14function [x,y]=Eulero_esplicito(f,x0,y0,X,N)
15 x(1) = x0;
16 y(1,:) = y0;
17 h = X/N ;
18 for k=1:N
19 % griglia spazio
20 x(k+1) = x(k) + h;
21 % soluzione approssimata col metodo di Eulero
22 y(k+1,:) = y(k,:) + h*feval(f,x(k),y(k,:));
23 end;
24end
Metodo basato sullo sviluppo di Taylor al secondo ordine
ODE per l’esempio considerato:
File test_1_yp.m
:open:
1%
2% Esempio di metodo basato sullo sviluppo di Taylor
3%
4% funzione f(x,y)
5%
6function yp=test_1_yp(x,y)
7 yp = -20.*y+20.*sin(x)+cos(x);
8end
Derivata prima della ODE:
File test_1_ypp.m
:open:
1%
2% Esempio di metodo basato sullo sviluppo di Taylor
3%
4% funzione
5%
6% d f(x,y)
7% -------
8% d x
9%
10function ypp=test_1_ypp(x,y)
11 f = - 20.*y+20.*sin(x)+cos(x);
12 fx = 20.*cos(x)-sin(x);
13 fy = - 20.*onex(size(x)) ;
14 ypp = fx+fy.*f ;
15end
Programma MATLAB che implementa il metodo basato sullo sviluppo di Taylor:
File test_1_taylor.m
:open:
1%
2% Esempio di metodo basato sullo sviluppo di Taylor
3%
4% calcolo della soluzione approssimata
5%
6function [x,y]=test_1_taylor(x0,y0,X,N)
7 x(1) = x0;
8 y(1) = y0;
9 h = X/N ;
10 for k=1:N
11 % griglia spazio
12 x(k+1) = x(k) + h;
13 % soluzione approssimata col metodo basato su Taylor
14 yp = test_1_yp(x(k),y(k)) ;
15 ypp = test_1_ypp(x(k),y(k)) ;
16 y(k+1) = y(k) + h*yp + (h*h/2)*ypp ;
17 end;
18end
Soluzione esatta del problema:
File test_1_esatta.m
:open:
1%
2% Esempio di metodo basato sullo sviluppo di Taylor
3%
4% soluzione esatta
5%
6function y=test_1_esatta(x)
7 y=exp(-20.*x)+sin(x);
8end
Programma driver per verificare il codice:
File test_taylor.m
:open:
1x0 = 0 ;
2y0 = 1 ;
3X = 2 ;
4N = 30 ;
5[x,y]=test_1_taylor(x0,y0,X,N) ;
6hold off ;
7plot(x,y,'.-b');
8hold on ;
9x = [x0:(X-x0)/200:X];
10plot(x,test_1_esatta(x),'-r');
11legend('approssimata','esatta');
Esempio di output:
Metodo al secondo ordine
Implementazione MATLAB del metodo di Collatz:
File Collatz.m
:open:
1%
2% Metodo di Collatz o Eulero Migliorato per sistemi di equazioni differenziali
3%
4% Ingresso
5% f = funzione per il sistema y'=f(x,y)
6% x0, y0 = dato iniziale del problema y(x0) = y0
7% xf = estremo superiore dell'intervallo di calcolo [x0,xf]
8% N = numero di intervalli in cui suddividere [x0,xf]
9%
10% Uscita
11% x(:) = vettore soluzione delle 'x'
12% y(:) = vettore soluzione delle 'y'
13%
14function [x,y]=Collatz(f,x0,y0,xf,N)
15 x(1) = x0;
16 y(1,:) = y0;
17 h = (xf-x0)/N ;
18 for k=1:N
19 % griglia spazio
20 x(k+1) = x(k) + h;
21 % mezzo passo di Eulero
22 % y(k+1/2) = y(k) + (h/2)*f(x(k),y(k))
23 fk = feval(f,x(k),y(k,:));
24 ykh = y(k,:) + (h/2).*fk;
25 % correzione di Collatz
26 % y(k+1) = y(k) + h*f(x(k+1/2),y(k+1/2))
27 fkh = feval(f,x(k) + h/2,ykh);
28 y(k+1,:) = y(k,:) + h.*fkh ;
29 end;
30end
Implementazione MATLAB del metodo di Heun:
File Heun.m
:open:
1%
2% Metodo di Heun per sistemi di equazioni differenziali
3%
4% Ingresso
5% f = funzione per il sistema y'=f(x,y)
6% x0, y0 = dato iniziale del problema y(x0) = y0
7% xf = estremo superiore dell'intervallo di calcolo [x0,xf]
8% N = numero di intervalli in cui suddividere [x0,xf]
9%
10% Uscita
11% x(:) = vettore soluzione delle 'x'
12% y(:) = vettore soluzione delle 'y'
13%
14%
15function [x,y]=Heun(f,x0,y0,xf,N)
16 x(1) = x0 ;
17 y(1,:) = y0 ;
18 h = (xf-x0)/N ;
19 for k=1:N
20 % griglia spazio
21 x(k+1) = x(k) + h;
22 % passo di Eulero
23 % ytilde(k+1) = y(k) + h*f(x(k),y(k))
24 fk = feval(f,x(k),y(k,:));
25 ytilde = y(k,:) + h*fk;
26 % correzione di Heun
27 % y(k+1) = y(k) + (h/2)*(f(x(k),y(k))+f(x(k+1),ytilde(k+1)))
28 fk1 = feval(f,x(k+1),ytilde);
29 y(k+1,:) = y(k,:) + h*(fk+fk1)/2 ;
30 end;
31end
Programma driver per verificare i metodi di Collatz, Heun e Eulero:
File test_multiplo.m
:open:
1x0 = 0 ;
2y0 = 1 ;
3X = 2 ;
4N = 30 ;
5[x,ye] = Eulero_esplicito (@test_1_yp,x0,y0,X,N) ;
6[x,yc] = Collatz (@test_1_yp,x0,y0,X,N) ;
7[x,yh] = Heun (@test_1_yp,x0,y0,X,N) ;
8hold off ;
9plot(x,ye,'.-b');
10hold on ;
11plot(x,yc,'.-k');
12plot(x,yh,'-gs');
13x = [x0:(X-x0)/200:X];
14plot(x,test_1_esatta(x),'-r','LineWidth',2);
15legend('Eulero', ...
16 'Collatz', ...
17 'Heun', ...
18 'Esatta');
Esempio di output:
Esempio per un sistema di ODE
Definizione della ODE:
File cerchio_yp.m
:open:
1%
2% Equazioni per il sistema differenziale
3%
4% x' = y
5% y' = -x
6%
7function Zp=cerchio_yp(t,Z)
8 Zp(1) = Z(2);
9 Zp(2) = -Z(1);
10end
Programma driver per verificare i metodi di Collatz, Heun e Eulero sulla ODE:
File test_cerchio.m
:open:
1x0 = 0 ;
2y0 = 1 ;
3X = 10 ;
4N = 30 ;
5[t,e] = Eulero_esplicito (@cerchio_yp,0,[x0,y0],X,N*2) ;
6[t,c] = Collatz (@cerchio_yp,0,[x0,y0],X*2,N) ;
7[t,h] = Heun (@cerchio_yp,0,[x0,y0],X*2,N) ;
8hold off ;
9plot(e(:,1),e(:,2),'.-b');
10hold on ;
11plot(c(:,1),c(:,2),'.-k');
12plot(h(:,1),h(:,2),'-gs');
13t = [0:0.01:2*pi];
14x = cos(t) ;
15y = sin(t) ;
16plot(x,y,'-r','LineWidth',2);
17legend('Eulero', ...
18 'Collatz', ...
19 'Heun', ...
20 'Esatta');
Esempio di output: