13.11.2014 Views

0.1 Programmi MATLAB

0.1 Programmi MATLAB

0.1 Programmi MATLAB

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

<strong>0.1</strong>. PROGRAMMI <strong>MATLAB</strong> 1<br />

<strong>0.1</strong> <strong>Programmi</strong> <strong>MATLAB</strong><br />

Concludiamo questa Appendice, riportando alcuni programmi scritti in linguaggio<br />

<strong>MATLAB</strong>, relativi ad algoritmi visti nei capitoli del Testo. Il lettore<br />

è incoraggiato, oltre che a provarli, a modificarli per ottenere delle versioni<br />

più generali.<br />

1. Capitolo 2: Metodo di Bisezione<br />

function [xs,scarto,iter,x] = bisezione(fname, a, b, toll, nmax)<br />

% Metodo di bisezione per calcolare la radice di una equazione f(x)=0.<br />

%<br />

% Sintassi:<br />

% [xs,scarto,iter,x] = bisezione(fname,a,b,toll)<br />

%<br />

% fname : stringa che contiene il nome della funzione f(x)<br />

% a,b : definiscono l’intervallo [a,b], f(a)f(b) 0<br />

% la funzione assume in entrambi gli estremi dell’intervallo [a,b]<br />

% valori dello stesso segno.<br />

disp(’L’’intervallo iniziale non e’’ accettabile’)<br />

iter = []; x = []; xs = [];<br />

else


2<br />

end<br />

% inizio il ciclo iterativo<br />

iter = 0;<br />

while ( scarto>=toll & iter


<strong>0.1</strong>. PROGRAMMI <strong>MATLAB</strong> 3<br />

2. Capitolo 2: Metodo di Newton-Raphson<br />

function[xs,x,scarti,rapp,M]=N_Raphson(fname,f1name,f2name,x0,toll,maxi)<br />

% Metodo di Newton-Raphson per calcolare la radice di una equazione<br />

% non lineare f(x)=0 mediante costruzione di una successione<br />

% {x(k)} convergente alla radice x ( x(0) stima iniziale assegnata ).<br />

% Caso della radice semplice.<br />

% Modificare il codice nel caso di radici multiple.<br />

%<br />

% Sintassi<br />

% [xs,x,scarti,rapp,M]=N_Raphson(fname,f1name,f2name,x0,toll,maxi)<br />

%<br />

% fname : stringa che contiene il nome della funzione f(x)<br />

% f1name: stringa che contiene il nome della derivata prima f’(x)<br />

% f2name: stringa che contiene il nome della derivata seconda f’’(x)<br />

% x0 : approssimazione iniziale della radice<br />

% toll : criterio di arresto (sullo scarto) | x(k+1)-x(k) | < toll<br />

% maxi : numero massimo di iterazioni<br />

% xs : approssimazione finale della radice<br />

% x : successione x(k) convergente a x, t.c. f(x)=0<br />

% scarti: vettore degli scarti d(k), k=1,....<br />

% rapp : stime della costante asintotica M attraverso gli scarti<br />

% M : stima finale di M usando la f’’(x) e la f’(x)<br />

%<br />

%%%%%%%%%%%%%%%%%%%% ESEMPIO %%%%%%%%%%%%%%%%%<br />

%fname = inline(’x- exp(-x) -0.5*cos(x)’);<br />

%f1name = inline(’1+exp(-x) +0.5*sin(x)’);<br />

%f2name = inline(’- exp(-x) +0.5*cos(x)’);<br />

%<br />

%x0 = 0.5;<br />

%toll = 1.e-06;<br />

%maxi = 50;<br />

%<br />

%[xs,x,scarti,rapp,M]=N_Raphson(fname,f1name,f2name,x0,toll,maxi)<br />

%%%%%%%%%%%%%%%% FINE ESEMPIO %%%%%%%%%%%%%%%%<br />

scarti0 = 1.0e5;<br />

x(1) = x0;<br />

fxk = feval(fname,x0);<br />

f1xk = feval(f1name,x0);<br />

k = 0;<br />

scarto = 2*toll;<br />

while ( scarto >= toll & k < maxi )


4<br />

% calcolo una nuova stima della radice<br />

k = k+1;<br />

x(k+1) = x(k)-fxk/f1xk ;<br />

scarti(k) = abs(fxk/f1xk);<br />

rapp(k) = scarti(k)/scarti0^2;<br />

fxk = feval(fname,x(k+1));<br />

f1xk = feval(f1name,x(k+1));<br />

scarto = abs(x(k+1)-x(k));<br />

if abs(f1xk) < toll*abs(fxk)<br />

% derivata prima troppo piccola ==> esco dalla routine<br />

error(’La derivata f’’(x(%d)) e’’ nulla’,k);<br />

end<br />

scarti0 = scarti(k);<br />

end<br />

xs = x(k+1);<br />

f1xk = feval(f1name,xs);<br />

f2xk = feval(f2name,xs);<br />

M = 0.5*abs(f2xk/f1xk);


<strong>0.1</strong>. PROGRAMMI <strong>MATLAB</strong> 5<br />

Il seguente script (mainNewton.m) illustra come richiamare un sottoprogramma<br />

(la function N Raphson.m, vedi esempio 2), da un programma principale<br />

(main). Esso fa uso del Symbolic Math Tool di <strong>MATLAB</strong>.<br />

In particolare, usa la funzione diff per calcolare derivate di funzioni, utile nel<br />

caso del metodo di Newton-Raphson.<br />

2’. Capitolo 2: Metodo di Newton-Raphson<br />

% mainNewton: script di chiamata (programma main)<br />

% alla function N_Raphson.m<br />

%<br />

% Usa la funzione ‘‘diff’’ del Symbolic Math Tool,<br />

% per calcolare derivate di funzioni.<br />

% Nell’esempio, la derivata di: ’x - exp(-x) - 0.5*cos(x)’<br />

%<br />

% sym: costruisce variabili simboliche<br />

% char: crea stringhe di caratteri<br />

%<br />

func = sym(’x- exp(-x) -0.5*cos(x)’);<br />

dfunc = diff(func);<br />

d2func = diff(dfunc);<br />

% creazione delle funzioni di input<br />

fname = inline(char(func));<br />

f1name = inline(char(dfunc));<br />

f2name = inline(char(d2func));<br />

% parametri di input<br />

x0 = 0.5;<br />

toll = 1.e-06;<br />

maxi = 50;<br />

% chiamata della function N_Raphson.m<br />

[xs,x,scarti,rapp,M]=N_Raphson(fname,f1name,f2name,x0,toll,maxi)


6<br />

3. Capitolo 2: Metodo di Punto fisso<br />

function [xs, x, scarto, rapp, n] = pfisso(gname,x0,toll,nmax)<br />

% Metodo di punto fisso per calcolare la radice della equazione<br />

% f(x)=0, opportunamente riscritta come x = g(x).<br />

%<br />

% Sintassi:<br />

% [xs, x, scarto, rapp, n]= pfisso(gname, x0, toll, nmax)<br />

%<br />

% gname : stringa che contiene il nome della funzione g(x)<br />

% x0 : approssimazione iniziale della radice<br />

% toll : tolleranza associata al criterio di arresto (sullo scarto)<br />

% nmax : numero massimo di iterazioni<br />

% xs : approssimazione finale della radice<br />

% x : vettore delle iterate (approssimazioni della radice)<br />

% scarto: scarto |x(n)-x(n-1)|<br />

% rapp : stima finale della costante asintotica tramite gli scarti<br />

% n : numero di iterazioni impiegate per arrivare a convergenza<br />

% : (esclusa quella iniziale)<br />

%%%%%%%%%%%%%%%%% ESEMPIO %%%%%%%%%%%%%%%%%%%%<br />

% gname = inline(’(x+1).^(1/3)’);<br />

% x0 = 0.5;<br />

% toll = 1.e-6;<br />

% nmax = 100;<br />

% [xs, x, scarto, rapp, n] = pfisso(gname, x0, toll, nmax)<br />

%%%%%%%%%%%%%%%% FINE ESEMPIO %%%%%%%%%%%%%%%%<br />

scarto0 = 1.0e5;<br />

scarto = 2*toll;<br />

x = zeros(nmax);<br />

x(1) = x0;<br />

n = 1;<br />

while ( scarto > toll & n < nmax )<br />

% calcolo della iterata (n+1)-esima<br />

n = n + 1;<br />

x(n) = feval(gname, x0);<br />

scarto = abs( x(n)-x0 );<br />

rapp = scarto/scarto0;<br />

x0 = x(n);<br />

scarto0 = scarto;<br />

end<br />

xs = x(n);<br />

x = x(1:n);<br />

n = n-1;


<strong>0.1</strong>. PROGRAMMI <strong>MATLAB</strong> 7<br />

4. Capitolo 3: Metodi iterativi per sistemi lineari<br />

*****************************************************************<br />

% function seidel.m<br />

*****************************************************************<br />

Soluzione di un sistema lineare mediante il metodo iterativo di Gauss-Seidel. Si<br />

veda alla fine della sezione ??.<br />

Per esercizio, si modifichi la function seidel.m modo da implementare i metodi di<br />

Jacobi ed SOR.


8<br />

5. Capitolo 5: Polinomio di interpolazione di Newton<br />

function [fx0, F] = interp_newton(m, x, fx, x0, n)<br />

% Input: numero m di nodi, loro ascisse x, ordinate fx,<br />

% il punto x0, grado n del polinomio interpolante: n=[0,...,m-1].<br />

% Output: tabella delle differenze divise F e<br />

% valore fx0 del polinomio interpolante di Newton in x0<br />

%<br />

% Sintassi:<br />

% [fx0, F]=interp_newton(m, x, fx, x0, n);<br />

%<br />

%%%%%%%%%%%%%%%%% ESEMPIO %%%%%%%%%%%%%%%%%<br />

%<br />

% m=5; n=4; x0=0.31;<br />

% x = [-4 -1 0 2 5 ];<br />

% fx = [1245 33 5 9 1335];<br />

% [fx0, F]=interp_newton(m, x, fx, x0, n);<br />

% Si ottiene: fx0 = 1.1154<br />

% F =<br />

% 1245 -404 94 -14 3<br />

% 0 33 -28 10 13<br />

% 0 0 5 2 88<br />

% 0 0 0 9 442<br />

% 0 0 0 0 1335<br />

%<br />

%%%%%%%%%%%%%%%% FINE ESEMPIO %%%%%%%%%%%%%%%%<br />

% Porre la variabile di stampa = 1 (uno) per avere una stampa a<br />

% video della tabella F delle differenze divise e del valore fx0<br />

% del polinomio interpolante nel punto x0.<br />

stampa = 1;<br />

%<br />

% Costruzione della tabella delle differenze divise<br />

% (in una matrice F triangolare superiore).<br />

F = zeros(m);<br />

for i=1:1:m<br />

F(i,i)=fx(i);<br />

end<br />

for j=2:1:m<br />

for i=(j-1):(-1):1<br />

F(i,j)=(F((i+1),j)-F(i,(j-1)))/(x(j)-x(i));<br />

end<br />

end<br />

%


<strong>0.1</strong>. PROGRAMMI <strong>MATLAB</strong> 9<br />

% Vettore PROD (di grado m)=[1,(x0-x(1)),....(x0-x(m-1)].<br />

prod(1)=1;<br />

for j=2:1:m<br />

prod(j)=(x0-x(j-1))*prod(j-1);<br />

end<br />

fx0=fx(1);<br />

for j=2:1:(n+1)<br />

fx0=fx0+F(1,j)*prod(j);<br />

end<br />

%<br />

if stampa<br />

% eventuale stampa dei risultati ottenuti<br />

disp([’m= ’,num2str(m), ’ n= ’, num2str(n)])<br />

disp(’ ’)<br />

disp(’tabella delle differenze divise F=’)<br />

disp(’ ’)<br />

disp(F)<br />

disp([’valore del polinomio di grado n=’,num2str(n),’,fx0=’,num2str(fx0)])<br />

end


10<br />

6. Capitolo 6: Metodo di integrazione di Romberg<br />

% mainRomberg: script di chiamata (programma main) alla function<br />

% romb.m (integrazione di Romberg).<br />

% romb.m chiama a sua volta la function trap.m<br />

%<br />

% Esempi test tratti dal Testo, cap. 6.<br />

% funzione da integrare<br />

% fname = inline( ’log(x)’ );<br />

% estremi di integrazione<br />

% a = 1;<br />

% b = 2;<br />

% funzione da integrare<br />

fname = inline( ’log(1+x.^4)’ );<br />

% estremi di integrazione<br />

a = 0;<br />

b = 4;<br />

% numero (massimo) di sottointervalli n = 2^m<br />

m = 7;<br />

% chiamata alla function di integrazione romb.m<br />

[I, Idiag, tab] = romb(fname, a, b, m);<br />

% stampa della tabella su file di testo: risRomberg.txt<br />

fid = fopen(’risRomberg.txt’,’w’);<br />

for i = 1:m+1<br />

fprintf(fid,’%5i’,i);<br />

for j=1:i<br />

fprintf(fid,’%12.8f’,tab(i,j));<br />

end<br />

fprintf(fid,’\r\n’);<br />

end<br />

fclose(fid);<br />

% grafico della diagonale e della 1 ◦ colonna<br />

plot(1:m+1,Idiag,’r’, 1:m+1,tab(:,1),’b’ )<br />

hold on<br />

plot(1:m+1,Idiag,’rs’, 1:m+1,tab(:,1),’bs’)<br />

legend(’Romberg’,’trapezi’ )<br />

grid on<br />

hold off


<strong>0.1</strong>. PROGRAMMI <strong>MATLAB</strong> 11<br />

romb.m: quadratura mediante la formula di Romberg<br />

function [I, Idiag, tab] = romb(fname, a, b, m)<br />

%<br />

% Sottoprogrammi chiamati: trap.m<br />

%<br />

% Sintassi:<br />

% [I,Idiag,tab] = romb(fname, a, b, m)<br />

% calcola un’approssimazione dell’integrale della funzione fname<br />

% sull’intervallo [a,b] mediante la formula di integrazione<br />

% di Romberg. Il numero massimo di sottointervalli<br />

% in cui è suddiviso l’intervallo [a,b] è 2^m, m >= 0.<br />

% I e’ la migliore approssimazione disponibile per<br />

% l’integrale, tab e’ una matrice (m+1)x(m+1) che contiene<br />

% la tabella delle approssimazioni di Romberg, Idiag e’ un<br />

% vettore di dimensione (m+1) che contiene la diagonale di tab.<br />

% Gli elementi della matrice tab che non sono calcolati nella<br />

% approssimazione di Romberg contengono dei NaN.<br />

% inizializzazione della tabella<br />

tab = NaN*ones(m+1);<br />

idiag = zeros(m+1,1);<br />

% calcolo della prima colonna della tabella<br />

n = 1;<br />

for i = 1:m+1<br />

I = trap(fname,a,b,n);<br />

tab(i,1) = I;<br />

n = 2*n;<br />

end<br />

Idiag(1) = tab(1,1);<br />

% calcolo delle successive righe della tabella<br />

for h = 2:m+1<br />

for k = 2:h<br />

tab(h,k) = ( 4^(k-1)*tab(h,k-1)-tab(h-1,k-1) )/(4^(k-1)-1);<br />

end<br />

Idiag(h) = tab(h,h);<br />

end<br />

% migliore approssimazione disponibile per l’integrale<br />

I = Idiag(m);


12<br />

trap.m: quadratura mediante la formula dei trapezi<br />

function I = trap(fname, a, b, m)<br />

%<br />

% Sintassi:<br />

% I = trap(fname, a, b, m)<br />

% Calcola una approssimazione dell’integrale della funzione<br />

% fname sull’intervallo [a,b]<br />

% mediante la formula di integrazione dei trapezi composta.<br />

% Usa (m + 1) punti equispaziati in [a,b].<br />

h = (b-a)/m;<br />

xk = linspace(a,b,m+1);<br />

fxk = feval(fname,xk);<br />

I = h*( 0.5*fxk(1) + sum(fxk(2:m)) + 0.5*fxk(m+1));


<strong>0.1</strong>. PROGRAMMI <strong>MATLAB</strong> 13<br />

7. Capitolo 7: Metodo di integrazione di Eulero<br />

*****************************************************************<br />

% function euler.m<br />

% sottoprogramma chiamato: eulero.m<br />

*****************************************************************<br />

Metodo di integrazione di un’equazione differenziale, mediante il metodo di Eulero<br />

in avanti. Si veda l’ultimo esempio riportato in sezione ??.<br />

Per esercizio, implementare altri metodi di integrazione (Eulero indietro, trapezi,<br />

punto medio, ecc...), modificando la subfunction chiamata eulero.m.

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!