Introduzione ad attivit`a di laboratorio di Calcolo Scientifico con
Transcript
Introduzione ad attivit`a di laboratorio di Calcolo Scientifico con
Introduzione ad attività di laboratorio di Calcolo Scientifico con OCTAVE per insegnanti delle scuole superiori Luca Bonaventura MOX - Modellistica e Calcolo Scientifico Dipartimento di Matematica ’Francesco Brioschi’ Politecnico di Milano [email protected] Anno Accademico 2008-09 2 3 Sol. numerica Sol. esatta 2.5 2 1.5 1 0 0.5 ....be wise, discretize! Mark Kac 1 1.5 2 Introduzione Lo scopo di queste note è quello di fornire una guida allo svolgimento di attività didattiche di Calcolo Scientifico in laboratorio informatico mediante l’utilizzo di un software scientifico avanzato. Non vi è pretesa di completezza né di esaustività per quanto riguarda la presentazione teorica dei metodi utilizzati, per cui si può fare riferimento a numerosi testi universitari. In particolare, una presentazione più completa dei metodi introdotti può essere trovata ad esempio nei testi [2], [6], [8] mentre una ampia panoramica sugli algoritmi di calcolo scientifico e sui relativi problemi di implementazioneè presentata in [4]. Per i necessari richiami di Analisi Matematica si può far riferimento ai manuali [1],[3], [5]. I temi affrontati sono comunque tutti contenuti nei programmi previsti per gli istituti che applicano il Piano Nazionale per l’Informatica. Più in dettaglio, si presenteranno, a livello introduttivo, alcuni aspetti dei seguenti argomenti: • uso didattico del software scientifico OCTAVE • calcolo approssimato di costanti e funzioni fondamentali • simulazione di variabili aleatorie • calcolo numerico di zeri di funzioni • calcolo numerico di integrali definiti • soluzione numerica di equazioni differenziali ordinarie. L’impostazione delle note consiste nella presentazione di alcuni brevi richiami teorici alla problematica e ai metodi numerici considerati, come introduzione ad una sessione di esercitazione specificamente finalizzata alla implementazione dei metodi stessi. L’obbiettivo didattico del corso che si riassume in queste note consiste 3 4 • nel favorire lo sviluppo da parte del docente di una capacità autonoma di utilizzo dello strumento informatico, che consenta di predisporre la traccia di esercitazioni al calcolatore da svolgere con gli allievi; • nel fornire esempi di implementazioni che possono essere utilizzati nel contesto di esercitazioni al calcolatore. Per la redazione di questa dispensa si è utilizzato in parte materiale relativo all’attività di laboratorio didattico nell’ambito del corso di Analisi Matematica e Geometria tenuto dalla prof.ssa Clelia Marchionna nel corso di Laurea in Ingegneria Ambientale del Politecnico di Milano e nel corso di Calcolo Numerico tenuto dal prof. Riccardo Sacco nel corso di Laurea in Ingegneria Civile del Politecnico di Milano fino al 2006. Si ringraziano la prof.ssa Marchionna ed il prof. Sacco per avere permesso di utilizzarlo. Si ringrazia inoltre la prof.ssa Cristina Turrini per i numerosi consigli forniti nella fase di preparazione del materiale e tutti i docenti che hanno partecipato al corso ’Analisi Numerica’ del II semestre dell’a.a. 2008-09 della SILSIS - Milano per le segnalazioni di errori e imprecisioni nelle stesure preliminari di queste note. Indice Introduzione 3 1 Il software OCTAVE 1.1 Comandi in linea . . . . . . . . . . . . . . 1.2 Vettori e operazioni sui vettori . . . . . . . 1.3 Grafici di funzioni . . . . . . . . . . . . . . 1.4 Scripts di OCTAVE . . . . . . . . . . . . . 1.5 Definizione di funzioni in OCTAVE . . . . 1.6 Istruzioni di programmazione in OCTAVE 2 Numeri reali e calcolo approssimato 2.1 Concetti di errore assoluto e relativo 2.2 Numeri interi e reali . . . . . . . . . 2.3 Divisione e radice quadrata . . . . . 2.4 Calcolo di costanti fondamentali . . . 2.5 Calcolo di funzioni fondamentali . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 8 11 14 15 18 19 . . . . . 23 23 25 29 32 33 3 Statistica e campioni casuali 37 3.1 Elementi di statistica descrittiva . . . . . . . . . . . . . . . . . 37 3.2 Numeri pseudocasuali . . . . . . . . . . . . . . . . . . . . . . . 40 3.3 Teoremi asintotici . . . . . . . . . . . . . . . . . . . . . . . . . 42 4 Equazioni nonlineari 4.1 Metodo di bisezione . . . . . . . . . . . . . . . . . . . . . . . . 4.2 Metodo di Newton e le sue varianti . . . . . . . . . . . . . . . 4.3 Metodo del punto fisso . . . . . . . . . . . . . . . . . . . . . . 5 45 47 48 51 6 INDICE 5 Integrali 53 5.1 Alcuni metodi di integrazione numerica . . . . . . . . . . . . . 54 5.2 Semplice tecnica di stima dell’errore . . . . . . . . . . . . . . . 57 6 Equazioni differenziali 6.1 Discretizzazione delle ODE: il metodo di Eulero . . . 6.2 Misure dell’ errore nella soluzione numerica di ODE . 6.3 Discretizzazione delle ODE: altri metodi ad un passo 6.4 Stabilità numerica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59 60 61 63 66 7 Appendice A 7.1 Calcolo approssimato di π . . . . . . . . . . . . . . . . . 7.2 Generatore lineare congruente di numeri pseudocasuali . 7.3 Teorema del limite centrale . . . . . . . . . . . . . . . . . 7.4 Metodo di bisezione . . . . . . . . . . . . . . . . . . . . . 7.5 Metodo dei trapezi con controllo sulla tolleranza d’errore 7.6 Metodo di Eulero in avanti per ODE . . . . . . . . . . . 7.7 Solutore lsode per ODE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69 69 70 72 73 75 77 79 . . . . Capitolo 1 Il software OCTAVE OCTAVE è un programma per il calcolo scientifico non coperto da licenza (free software). Una documentazione completa su tale software può essere reperita sul sito web http://www.octave.org, insieme agli eseguibili del programma per vari sistemi operativi. OCTAVE costituisce uno strumento particolarmente interessante perché riproduce di fatto le funzionalità di un sottoinsieme del software MATLAB, sviluppato dalla azienda Mathworks e coperto da licenza, si veda il sito http://www.mathworks.com. L’uso sempre più ampio di MATLAB in ambito scientifico e ingegneristico rende OCTAVE molto indicato per fornire agevolmente anche a studenti delle scuole superiori un primo approccio con uno strumento moderno di calcolo scientifico. Si deve però tenere presente che OCTAVE riproduce solo le funzionalità base di MATLAB. In particolare, la grafica non è supportata direttamente. Per poter utilizzare le funzioni grafiche di OCTAVE è necessario disporre anche del software grafico GNUPLOT, anche esso disponibile senza licenza per molti sistemi operativi, si veda il sito http://www.gnuplot.info. Nel resto di questa sezione saranno introdotti i principali comandi di OCTAVE ed alcuni elementi di programmazione con tale software, allo scopo di disporre degli strumenti necessari per implementare gli algoritmi numerici che saranno considerati in seguito. Tutti i comandi utilizzati si riferiscono alla versione OCTAVE 3.0.1 e la funzionalità dell’implementazione è stata verificata, per quanto possibile, nella versione di OCTAVE per il sistema operativo LINUX. 7 8 1.1 CAPITOLO 1. IL SOFTWARE OCTAVE Comandi in linea Nella modalità più semplice, OCTAVE può essere utilizzato introducendo comandi in linea dalla finestra principale del programma. Dopo il prompt dei comandi >> è possibile digitare semplici operazioni aritmetiche come >> 7+5 ottenendo come risultato ans= 12 Tale risultato può essere poi assegnato come valore ad una variabile il cui nome può essere scelto arbitrariamente, tenendo conto che il programma distingue lettere maiuscole dalle minuscole: >> a= 7+5 fornisce come risultato a= 12 mentre >> A= 7-5 fornisce come risultato A= 2 Il valore di una variabile (che sia stata già definita) può essere visualizzato semplicemente digitando il suo nome: >> A A= 2 >> a a= 12 OCTAVE permette di lavorare sia con numeri interi che numeri reali. Alcune costanti reali di uso comune sono predefinite, ad esempio >> pi ans= 3.1416 I numeri reali vengono rappresentati in OCTAVE utilizzando fino a 16 cifre significative. Per default, come visto nell’esempio precedente, si visualizzano 9 1.1. COMANDI IN LINEA solo 4 cifre dopo la virgola. Per visualizzare il valore completo di una variabile reale si deve utilizzare il comando format. In particolare con il comando >> format long si ottiene >> pi ans= 3.141592653589793 oppure >> e ans= 2.71828182845905 Se si vuole conoscere più in dettaglio la sintassi del comando format (o di un qualsiasi altro comando OCTAVE) si possono utilizzare i comandi help e doc. Digitando >> help format si ottengono direttamente nella finestra principale di OCTAVE una sintesi delle finalità e della sintassi del comando. Digitando invece >> doc format viene visualizzata invece la voce del manuale di OCTAVE corrispondente al comando stesso, che è in generale più completa e dettagliata rispetto a quanto fornito dal comando help. Le variabili intere e reali possono essere utilizzate in calcoli in cui intervengano tutte le operazioni aritmetiche. Un sommario della sintassi delle prinicipali operazioni aritmetiche in OCTAVE è riportato nella tavola 1.1. Si noti che se si vuole svolgere una operazione senza farne visualizzare il risultato, è sufficiente terminare la riga di comando con il simbolo ; di punto e virgola, come si vede dall’esempio Simbolo + * / \ ˆ Operazione Somma Sottrazione Moltiplicazione Divisione Divisione inversa Elevazione a potenza Sintassi a+b a-b a*b a/b a \ b aˆb Tabella 1.1: Principali operazioni aritmetiche in OCTAVE. 10 CAPITOLO 1. IL SOFTWARE OCTAVE Funzione Radice quadrata Logaritmo naturale Logaritmo in base 2 Coseno Seno Tangente Cos. iperbolico Seno iperbolico Tang. iperbolica Sintassi sqrt(x) log(x) log2(x) cos(x) sin(x) tan(x) cosh(x) sinh(x) tanh(x) Funzione Esponenziale di base e Logaritmo in base 10 Valore assoluto Arcocoseno Arcoseno Arcotangente Arcocos. iperbolico Arcoseno iperb. Arcotang. iperbolica Sintassi exp(x) log10(x) abs(x) acos(x) asin(x) atan(x) acosh(x) asinh(x) atanh(x) Tabella 1.2: Principali funzioni matematiche in OCTAVE. >> a= 7+10; In OCTAVE sono anche predefinite le principali funzioni dell’Analisi Matematica. Un riassunto dei nomi (che utilizzano le convenzioni anglosassoni) e della sintassi delle prinicipali funzioni matematiche in OCTAVE è riportato nella tavola 1.2. Esercizio Calcolare con OCTAVE le seguenti espressioni: a) 45 − 122 + 56 = 16505; b) 3 · 52 = 1.5; 10 + 5 · 8 c) e5 − 1 = 12.5188; ln 4 + e2 + 3 d) r e) 3 sin 2 3 ln 5 = 0.7171; 2 + e2 π 3 2 − cos 3 π 4 = 0.0122; 1.2. VETTORI E OPERAZIONI SUI VETTORI Comando clc clear clear elenco variabili who whos 11 Azione Cancella contenuto della finestra Cancella valori immagazzinati in tutte le variabili definite Cancella valori immagazzinati nelle variabili dell’elenco Elenca le variabili presenti in memoria Elenca le variabili, il loro tipo e la memoria occupata. Tabella 1.3: Principali comandi in linea OCTAVE. f) arcsin − 23 = 0.1765. sin π3 − 5 Esercizio Porre x = 3, y = −2 e valutare con OCTAVE le seguenti espressioni: a) xy 3 = −4.8; x−y b) 2x ln (|y| + 1) − y ln (x + 2) = 9.8105; c) arctan y x d) cos (x + y) + exy = 0.5428. p − sin2 (x |y|) = −1.3831; Vari comandi possono poi essere utili nel corso di una sessione di lavoro. I principali sono riportati nella tabella 1.3. 1.2 Vettori e operazioni sui vettori Sebbene finora si siano considerate solo variabili scalari, OCTAVE in realtà può naturalmente operare con tabelle di numeri (matrici) formate da un certo numero di righe e colonne. In queste esercitazioni ci si limiterà a introdurre e utilizzare vettori, ovvero tabelle di numeri costituite da una sola riga o colonna, e denominate corrispondentemente vettori riga e vettori colonna. Un vettore riga si definisce con il comando 12 CAPITOLO 1. IL SOFTWARE OCTAVE >> x=[1 2 3] x= 1 2 3 mentre un vettore colonna si definisce con il comando >> y=[3 ; 2 ; 1] y= 3 2 1 L’operazione di trasposizione, denotata da un apice apposto dopo la variabile vettoriale, trasforma un vettore riga in un vettore colonna e viceversa >> z=y’ z= 3 2 1 Esercizio Definire in OCTAVE i seguenti vettori a) y=[2 7 12] b) y= -1 -2 3 Con il comando [n:p:m] si genera un vettore riga avente come primo elemento n e come elementi successivi i numeri n + p, n + 2p, . . . , fino ad arrivare al massimo valore ≤ m se p > 0 o al minimo valore ≥ m se p < 0. Ad esempio: >> x=[1:3:8] genera il vettore x=[1 4 7], mentre >> y=[10:-3:3] genera il vettore y=[10 7 4]. Se il passo p viene omesso, il programma assume per default che sia uguale a 1; ad esempio, il comando 1.2. VETTORI E OPERAZIONI SUI VETTORI Operazione Prodotto con scalare Somma di vettori Differenza di vettori Prodotto di vettori Potenza di vettori Operandi k scalare, x vettore x, y vettori x, y vettori x, y vettori x vettore, k scalare Sintassi k*x x+y x-y x.*y x.^k 13 Descrizione Moltiplica elementi di x per k Somma elementi di uguale indice. Sottrae elementi di uguale indice. Moltiplica elementi di uguale indice. Eleva elementi di x a potenza k. Tabella 1.4: Principali operazioni vettoriali in OCTAVE. Sintassi zeros(1,n) ones(1,n) size(x) sum(x) norm(x) Descrizione Definisce vettore riga con n elementi 0 Definisce vettore riga con n elementi 1 Calcola n. di righe e colonne di x Calcola la somma degli elementi di x Calcola la norma euclidea di x Tabella 1.5: Principali funzioni vettoriali in OCTAVE. >> [2:5] genera il vettore >> [2 3 4 5]. Esercizio a) Generare il vettore riga dei numeri pari compresi tra 0 e 21. b) Creare un vettore con gli stessi elementi del precedente in ordine inverso (dall’ultimo al primo). Le variabili vettoriali possono essere utilizzate in calcoli in cui intervengano tutte le operazioni aritmetiche, che vengono effettuate su tutti gli elementi dei vettori considerati. Se si eseguono operazioni su vettori, questi devono essere tutti della stessa lunghezza e dello stesso tipo (riga o colonna). Un sommario della sintassi delle principali operazioni aritmetiche su vettori in OCTAVE è riportato nella tavola 1.4. Si noti che alcune operazioni sono indicate dallo stesso operatore usato per le operazioni tra scalari, mentre per altre è necessario far precedere l’operatore da un punto (operazioni puntate). Vi sono inoltre una serie di utili comandi con cui è possibile generare particolari vettori o calcolare grandezze associate al vettore dato, elencati nella tabella 1.5. 14 CAPITOLO 1. IL SOFTWARE OCTAVE Comando grid on grid off title(’stringa’) xlabel(’stringa’) ylabel(’stringa’) axis([xmin,xmax,ymin,ymax]) hold on hold off clf figure figure(n) print Azione Visualizza una griglia di riferimento sul grafico Cancella la griglia di riferimento Visualizza il titolo del grafico Visualizza una scritta sull’asse orizzontale Visualizza una scritta sull’asse verticale Imposta intervalli delle ascisse e delle ordinate Mantiene i grafici della finestra grafica attiva Disattiva la modalità hold on Cancella il contenuto della finestra grafica attiva Apre una nuova finestra grafica Rende attiva la finestra grafica di numero progressivo n Salva il contenuto della finestra grafica attiva in un file Tabella 1.6: Principali comandi grafici. 1.3 Grafici di funzioni Dati due vettori riga x = [x1 , ..., xn ] e y = [y1 , ...yn ] della stessa dimensione, il comando >> plot(x,y) apre una finestra nella quale i punti del piano cartesiano di coordinate (xi , yi) con i = 1, 2, . . . , n vengono raccordati con segmenti di retta. Esempio Disegnare la spezzata poligonale che congiunge i 4 punti A = (0, 1) , B = (1, 0), C = (2, 1), D = (3, −2) : >> x=[0 1 2 3]; >> y=[1 0 1 -2]; >> plot(x,y) Il comando plot supporta vari argomenti opzionali con i quali si possono variare alcune caratteristiche del grafico risultante; si utilizzi il comando help plot per visualizzare le opzioni consentite. Sono inoltre disponibili i numerosi comandi per modificare l’aspetto del grafico, riassunti nella tabella 1.6. Esempio Disegnare il grafico della funzione y = x3 − 3x2 + 2x − 1 nel’intervallo [−3, 3] campionando la x con passo h = 0.1 e facendo comparire il titolo Grafico di 1.4. SCRIPTS DI OCTAVE 15 xˆ3-3*xˆ2+2*x-1 e la legenda della curva y=xˆ3-3*xˆ2+2*x-1 : >> x=[-3:.1:3]; >> y=x.^3-3*x.^2+2*x-1; >> plot(x,y) >> title(’Grafico di x^3-3*x^2+2*x-1’) >> legend(’y=x^3-3*x^2+2*x-1’) Si osservi che la moltiplicazione va sempre indicata e che deve essere usata la sintassi vettoriale delle operazioni puntate. Il risultato di questa sequenza di comandi è visibile nella figura 1.1. Esercizio Tracciare con OCTAVE i grafici delle seguenti funzioni negli intervalli indicati: √ a) y = x2 + 1, x ∈ [−10, 10] b) y = xex , x ∈ [−3, 4] c) y = sin(x) x ∈ [−2π, 2π] d) y = sin(2x + π/3) x ∈ [−2π, 2π] e) y = sin2 (x) x ∈ [−2π, 2π] f) y = x2 sin(x) x ∈ [−2π, 2π] g) y = sin(x)/x x ∈ [−2π, 2π]. 1.4 Scripts di OCTAVE OCTAVE può essere utilizzato, come si è visto, in modalità interattiva, ma questo può risultare poco conveniente qualora sia necessario impartire lunghe sequenze di comandi per ottenere un certo risultato. Per ovviare a questo problema, è possibile far eseguire a OCTAVE liste di comandi precedentemente preparate in un opportuno file. Un file di questo tipo è denominato m-file e consiste di un file di testo il cui nome abbia l’estensione .m e che sia salvato nella stessa directory in cui ci si colloca per eseguirlo, o in una directory il cui path sia presente nella lista di indirizzi a cui OCTAVE accede 16 CAPITOLO 1. IL SOFTWARE OCTAVE Grafico di x3-3*x2+2*x-1 3 2 y=x -3*x +2*x-1 0 -10 -20 -30 -40 -50 -60 -3 -2 -1 0 1 2 3 Figura 1.1: Grafico della funzione y = x3 − 3x2 + 2x − 1 ottenuto con le istruzioni OCTAVE di questa sezione automaticamente. Tale tipo di file può essere creato con un qualsiasi editor di testi. Se il programma è stato configurato opportunamente, digitando il comando edit viene richiamato da OCTAVE un editor di testo. Un esempio di contenuto di un file vectors.m che assegna un valore a dei vettori ed effettua su di essi delle operazioni è il seguente: % Header di commento sul file vectors.m % Creato il xx.yy.zz da AA.BB % Calcola la somma di due vettori x=[2 3 4]; y=[4 3 2]; z= ones(1,3)+x+y Esercizio Creare uno script che calcoli la lunghezza di una circonferenza di raggio R e l’area del cerchio inscritto. Un altro esempio di è quello di un file graph.m che permette di tracciare il grafico di una funzione con alcune modifiche alla modalità grafica di default: 1.4. SCRIPTS DI OCTAVE 17 % Header di commento sul file graph.m % Creato il xx.yy.zz da AA.BB % Traccia il grafico di x^3-3*x^2+2*x+1 x=[-3.:0.1:3.]; y=x.^3-3*x.^2+2*x+1; plot(x,y,’r’) grid on title(’Grafico di x^3-3x^2+2x+1’) xlabel(’x’) ylabel(’y’) Un esempio più elaborato è quello di un file potenzepari.m che permette di tracciare il grafico di alcune potenze pari di x: % Header di commento sul file potenzepari.m % Creato il xx.yy.zz da AA.BB % Traccia il grafico delle potenze pari con esponente da 2 a 10 figure(1) clf hold on x=[-4.:0.1:4.]; for k=2:2:10 y=x.^k; plot(x,y) end grid on axis([-4 4 0 10]) title(’Potenze pari di x’) Esercizio Creare uno script che tracci su di un’unica finestra grafica il grafico di cos (3x), sin (4x), 2 cos (3x) − 3 sin (4x) rispettivamente in rosso, verde e nero, con il titolo Polinomi trigonometrici. Ripetere l’esercizio con i grafici tutti dello stesso colore e in un’ unica finestra. 18 CAPITOLO 1. IL SOFTWARE OCTAVE Esercizio Creare uno script che tracci su di un’unica finestra grafica il grafico di sin(10x) e−x x 2 calcolata: a) nei punti xi = i0.1, i = 0, . . . , 10 rappresentando i valori della funzione con cerchietti rossi b) nei punti xi = i0.01, i = 0, . . . , 100 rappresentando i valori della funzione con una linea continua blu. 1.5 Definizione di funzioni in OCTAVE A differenza degli script, che sono successioni di comandi che OCTAVE esegue (se sono sintatticamente corretti) come se fossero composti sulla linea di comando l’uno dopo l’altro, le funzioni necessitano una serie di argomenti che devono essere esplicitamente assegnati al momento in cui la funzione stessa viene richiamata. Anche le funzioni devono essere definite in appositi files con estensione .m che devono trovarsi nella stessa directory da cui vengono richiamate, in una directory il cui nome completo sia stato inserito nel search path di OCTAVE. Tale file deve contenere il testo della funzione stessa, che deve avere lo stesso nome del file. Ad esempio, il file fun.m con il seguente contenuto: function y=fun(x) y=x^2; end definisce una implementazione della funzione reale di variabile reale y = x2 . La funzione fun può essere richiamata da OCTAVE nel modo seguente: c=fun(3) c= 9 Analogamente possono essere definite funzioni a valori vettoriali e ad argomenti vettoriali. Ad esempio,la funzione vfun definita da: function y=vfun(x) y(1)=x(1)+x(2)^2-x(3); y(2)=x(2)+sin(x(3)); 1.6. ISTRUZIONI DI PROGRAMMAZIONE IN OCTAVE 19 y(3)=-exp(x(1))+2*x(2)-x(3)^4; end costituisce una implementazione OCTAVE della funzione vettoriale y = f(x) dove y, x ∈ R3 e y1 = f1 (x1 , x2 , x3 ) = x1 + x22 − x3 y2 = f2 (x1 , x2 , x3 ) = x2 + sin (x3 ) y2 = f3 (x1 , x2 , x3 ) = −ex1 + 2x2 − x43 . Si tenga presente che il risultato della funzione vfun definisce un vettore riga. Infatti, ad esempio, sia che si sia definito x=[0 1 2] o x=[0; 1; 2], si ha >> vfun(x) ans = -1.0000 1.9093 -15.0000 Se fosse necessario ottenere come risultato un vettore colonna, la funzione può essere modificata nel modo seguente: function y=vfun(x) y(1)=x(1)+x(2)^2-x(3); y(2)=x(2)+sin(x(3)); y(3)=-exp(x(1))+2*x(2)-x(3)^4; y=y’; end 1.6 Istruzioni di programmazione in OCTAVE Nell’ambito degli scripts e delle funzioni di OCTAVE possono essere usate una serie di istruzioni tipiche dei principali linguaggi di programmazione. Si richiama qui solo brevemente la sintassi degli operatori di confronto e dei comandi disp, for, if, break e continue. Gli operatori di confronto presenti in OCTAVE sono riassunti nella tabella 1.7. Le espressioni in cui sono presenti operatori di confronto vengono usualmente racchiuse da parentesi per evidenziare il fatto che l’intera espressione restituisce un unico valore. Ad esempio ha senso digitare il comando >> (3>2)+(pi<e) 20 Sintassi x==y x!=y x =y x>y x>= y x<y x<=y CAPITOLO 1. IL SOFTWARE OCTAVE Vero Vero Vero Vero Vero Vero Vero (1) (1) (1) (1) (1) (1) (1) Valore se x = y, se x 6= y, se x 6= y, se x > y, se x ≥ y, se x < y, se x ≤ y, restuito falso (0) altrimenti falso (0) altrimenti falso (0) altrimenti falso (0) altrimenti falso (0) altrimenti falso (0) altrimenti falso (0) altrimenti Tabella 1.7: Operatori di confronto in OCTAVE. ans = 1 Il comando disp permette di far visualizzare una stringa di caratteri, come nell’esempio seguente >> disp(’Hello World’) Hello World Il comando for permette di eseguire dei cicli di operazioni ripetute, che possono essere funzioni di un indice discreto. Un esempio è il seguente a=pi; for i = 1:10 b= a*i+e end I valori dell’indice possono essere considerati anche in ordine decrescente a=pi; for i = 10:-1:1 b= a*i+e end o possono assumere valori non consecutivi a=10; for i = 1:3:20 b= i+a end Il comando if permette di eseguire comandi condizionatamente alla verità di una espressione. Ad esempio, eseguendo il seguente blocco if x = 1; if (x == 1) disp (’one’); elseif (x == 2) disp (’two’); else 1.6. ISTRUZIONI DI PROGRAMMAZIONE IN OCTAVE 21 disp (’not one or two’); endif verrà visualizzata la scritta one. Il comando break permette di uscire da un ciclo o da un blocco if, facendo continuare l’esecuzione dello script dalla prima linea di comandi successiva all’end o endif. Nel caso di un ciclo, questo implica che dopo l’esecuzione di break il ciclo viene definitivamente interrotto. Il comando continue invece permette di saltare tutte le istruzioni successive fino alla fine del ciclo o del blocco if in cui si trova. Nel caso di un ciclo, questo implica che dopo l’esecuzione di continue il ciclo viene ripreso per il valore successivo dell’indice. Esercizio Implementare lo script for i=1:10 i if (i<=5) disp(’primi 5’) continue elseif(i>6) break endif disp(’finito’) end e verificare l’effetto dei comandi break e continue. Esercizio Modificare lo script inserendo alternativamente i comandi a) break b) continue dopo il comando endif. Interpretare i risultati. Esercizio Utilizzando la funzione mod, predisporre uno script che consenta di determinare tutti i numeri interi minori di 12345 che sono multipli di 17. 22 CAPITOLO 1. IL SOFTWARE OCTAVE Esercizio Implementare in OCTAVE la sommatoria dei quadrati dei primi n numeri interi n X Sn = i2 . i=1 k Effettuare il calcolo per n = 10 , k = 1, . . . , 6 sommando gli addendi in ordine a) crescente e b) decrescente. Confrontare in entrambi casi il risultato con la formula n(n + 1)(2n + 1) Sn = . 6 Capitolo 2 Rappresentazione dei numeri reali e calcolo approssimato di costanti e funzioni fondamentali In questa sezione si richiamano il concetto di errore assoluto e relativo e le principali problematiche relative alla rappresentazione in OCTAVE (e in qualsiasi altro ambiente di lavoro utilizzato nel calcolo scientifico) dei numeri interi e reali. Si introducono inoltre esempi di semplici algoritmi iterativi che implementano metodi di approssimazione per operazioni aritmetiche, costanti fondamentali dell’Analisi Matematica e funzioni di variabile reale. Lo scopo è quello di • evidenziare gli aspetti che più caratterizzano l’aritmetica dei numeri reali di precisione finita implementata nei calcolatori (e utilizzata anche nel calcolo manuale non simbolico) rispetto a quella di precisione infinita, che si utilizza nell’algebra e nell’analisi quando si effettuano operazioni con simboli che rappresentano numeri reali • introdurre il concetto di approssimazione mediante un algoritmo iterativo. 2.1 Concetti di errore assoluto e relativo Si supponga di considerare un numero reale α, che rappresenti il valore esatto di una quantità di interesse (ad esempio una costante numerica o il valore 23 24 CAPITOLO 2. NUMERI REALI E CALCOLO APPROSSIMATO assunto da una funzione in corrispondenza di un valore assegnato della variabile indipendente). In pratica, tale quantità non potrà quasi mai essere calcolata esattamente, ma solo con procedure approssimate. Inoltre, i calcoli numerici effettuati con un numero finito di cifre decimali introdurranno ulteriori errori. Indicata quindi con e αapprox la concreta approssimazione numerica della quantità di interesse, si possono introdurre due definizioni che permettono di precisare il concetto di errore commesso nell’approssimazione: Definizione Si definisce errore assoluto commesso nella approssimazione di α con il valore αapprox la quantità Eabs = |α − αapprox |. Definizione Si definisce errore relativo commeso nella approssimazione di α con il valore αapprox la quantità |α − αapprox | Erel = . |α| Sono immediate le seguenti considerazioni: • l’errore relativo è definibile solo per α 6= 0; • a parità di errore relativo, si può commettere un errore assoluto più o meno grande a seconda del valore di α; • nel caso che α sia una grandezza fisica, l’errore relativo è un numero adimensionale, indipendente dalle unità di misura utilizzate; • tali quantità possono solo essere stimate, poiché la conoscenza del loro valore esatto equivale alla conoscenza dell’esatto valore di α, che in generale è ignoto. Nella maggior parte delle applicazioni, l’errore relativo è l’unica misura della bontà dell’approssimazione che abbia senso cercare di minimizzare o di mantenere al di sotto di una tolleranza d’errore fissata. Tentare infatti di 2.2. NUMERI INTERI E REALI 25 rispettare una tolleranza d’errore indipendentemente dall’ordine di grandezza della quantità da approssimare può avere come conseguenza l’esecuzione di una gran mole di calcoli che non migliorano l’effettiva accuratezza dell’approssimazione. 2.2 Rappresentazione dei numeri interi e reali: precisione macchina Le operazioni aritmetiche implementate in qualsiasi calcolatore utilizzano delle particolari rappresentazioni degli insiemi numerici che hanno rilevanti implicazioni per il calcolo scientifico. L’insieme dei numeri interi è rappresentato esattamente, fino ad un massimo numero intero che può essere visualizzato con il comando intmax. Tale numero varia a seconda del numero di bit utilizzati per la rappresentazione degli interi. Il più grande dei valori di intmax si ottiene nel caso di interi a 64 bit senza segno e può essere visualizzato digitando >> intmax(’uint64’) ans = 18446744073709551615 Analogamente, le operazioni di addizione, sottrazione e moltiplicazione effettuate con numeri interi sono esatte, nell’ambito dei numeri interi che OCTAVE riesce a rappresentare. I numeri reali, che per l’assioma di completezza sono interpretabili come completamento dell’insieme dei numeri razionali (si veda ad esempio [5] o qualsiasi testo di analisi matematica di buon livello), non possono essere rappresentati in modo esatto, in quanto definiti in generale da una operazione di limite. Di fatto,i numeri reali irrazionali e ancora di più quelli trascendenti (ovvero tali che non siano soluzioni di equazioni algebriche a coefficienti razionali) sono simboli che rappresentano una quantità di informazione infinita. È pertanto abbastanza ovvio che solo un opportuno sottoinsieme di numeri razionali può essere rappresentato in un calcolatore. Il sottoinsieme generalmente utilizzato è costituito da quelli che possono essere descritti nella cosidetta rappresentazione a virgola mobile, noti anche con la definizione anglosassone di numeri reali floating point. Una descrizione completa della struttura di tali numeri può essere trovata nei testi [2], [6], qui ci si limiterà a riassumere alcune particolari caratteristiche di rappresentazione: • i numeri reali rappresentati sono tutti più piccoli in valore assolu- 26 CAPITOLO 2. NUMERI REALI E CALCOLO APPROSSIMATO to di un valore massimo, che può essere visualizzato con il comando realmax: su macchine con architettura a 64 bit tale valore è pari a 1.79769313486232 ∗ 10308 . • lo zero non appartiene a tale insieme e tutti i numeri reali rappresentati sono più grandi in valore assoluto di un valore minimo, che può essere visualizzato con il comando realmin: su macchine con architettura a 64 bit tale valore è pari a 2.22507385850720 ∗ 10−308 ; • i numeri rappresentati non sono uniformemente distribuiti sull’intervallo compreso tra -realmax e realmax, ma sono molto più densi in prossimità dello zero (che pure, come si è detto, non appartiene a tale insieme) e progressivamente sempre più radi mentre ci si avvicina a realmax. Come si vede, tale rappresentazione, che di fatto è per vari motivi la più efficace considerando i vincoli imposti dall’architettura dei calcolatori, costringe a considerare per il calcolo un insieme numerico con caratteristiche apparentemente assai diverse da quelle che si associano usualmente ai numeri reali. Dal punto di vista pratico, la principale conseguenza dell’uso di questo insieme numerico consiste nel fatto che tutte le operazioni con i numeri reali floating point, e la divisione tra interi (che fornisce un risultato reale) sono approssimate ed affette dal cosidetto errore di arrotondamento (round off error) dell’ordine di 10−16 . La misura esatta di questo tipo di errore è fornita dal cosidetto epsilon macchina o zero macchina, una costante dipendente dall’hardware e il cui valore può essere visualizzato utilizzando il comando OCTAVE eps come nell’esempio seguente >>eps ans=2.22044604925031e-16 Si può dimostrare che l’errore relativo nella rappresentazione floating point di qualsiasi numero reale è dell’ordine di grandezza dello zero macchina. Questo garantisce che, in proporzione al valore assoluto del numero considerato, l’errore commesso è uniformemente limitato. Questa approssimazione non causa errori significativi nella maggior parte dei calcoli, ma va comunque tenuto presente che i risultati ottenuti sono corretti solo a meno di un errore di grandezza eps. In particolare, se si combinano quantità diverse di molti ordini di grandezza si possono avere dei problemi. Ad esempio, sebbene la costante eps non sia zero, si ha >> 1+eps 2.2. NUMERI INTERI E REALI 27 ans= 1.000000000000000 L’errore dipende anche dall’ordine con cui vengono eseguite le operazioni. Ad esempio sia >> a=10ˆ-15; allora >> (10+a-10)/a ans = 1.7764 che è sbagliato, mentre >> (10-10+a)/a ans = 1 è corretto. Esercizio Ripetere le operazioni degli esempi precedenti ponendo a=eps. Una delle operazioni che possono creare più problemi quando si opera con numeri reali floating point è la sottrazione di due numeri la cui differenza è molto piccola (ovvero, di un ordine di grandezza vicino a quello dello zero macchina). Ad esempio se si calcola 1.1122334455667878 − 1.1122334455667788, il cui valore esatto è 9 ∗ 10−15 , si ottiene il risultato >>a=1.1122334455667878-1.1122334455667788 a = 8.88178419700125e-15 Tale risultato non è di per sé drammaticamente sbagliato (l’errore, come si può vedere, è sulla sedicesima cifra decimale, il che è coerente con il valore dello zero macchina). Ma se tale risultato viene utilizzato in ulteriori calcoli, si può ottenere una amplificazione significativa dell’errore iniziale. Se ad esempio si calcola semplicemente >>b=1.1122334455667788+a b=1.11223344556679 si vede che si ha ora un errore sulla quattordicesima cifra decimale, ovvero due ordini di grandezza più grande dell’errore iniziale. Questa amplificazione è il risultato della cosidetta cancellazione di cifre significative: nell’operazione eseguita nell’esempio, tutte le cifre decimali meno affette dall’errore di troncamento di fatto scompaiono, e il risultato consiste solo di cifre decimali su cui l’errore di troncamento ha un effetto significativo. Un caso di notissima formula algebrica che può portare a cancellazione 28 CAPITOLO 2. NUMERI REALI E CALCOLO APPROSSIMATO di cifre significative se utilizzata in aritmetica di precisione finita è la formula risolutiva per la soluzione di una equazione algebrica di secondo grado. Scrivendo tale equazione come ax2 + bx + c = 0, la formula si scrive come è noto √ √ b2 − 4ac −b − b2 − 4ac x+ = x− = (2.1) 2a 2a Qualora si abbia a che fare con valori di a, c per cui sia 4ac ≈ 0 e sia b > 0, se la prima radice viene calcolata dalla formula 2.1 si calcola di fatto la differenza di due numeri molto vicini in valore assoluto. Nel caso che sia b < 0, lo stesso si verifica per la seconda radice. Per evitare la cancellazione, si può utilizzare la formula algebricamente equivalente −b + √ b + sign(b) b2 − 4ac q=− 2 x+ = q a x− = c q (2.2) in cui però non si calcolano differenze tra numeri vicini in valore assoluto. sign indica qui la funzione segno, che assume valore 1 per valori positivi dell’argomento e -1 per valori negativi. Esercizio Risolvere l’equazione 10l x2 − (1 + 10l+m )x + 10m = 0 per differenti valori interi di l, m implementando in OCTAVE le formule 2.1,2.2. Confrontare i risultati con le soluzioni esatte x± = 10m , 10−l . (Suggerimento: si utilizzino valori negativi di l, m.) Un altro caso un cui l’approssimazione dei reali con numeri reali floating point può portare ad una amplificazione dell’errore di arrotondamento è quello in cui si eseguano un numero molto elevato di operazioni, come nel caso dei metodi numerici per l’approssimazione degli integrali definiti e delle soluzioni di equazioni differenziali ordinarie. Esempi di queste problematiche saranno illustrati nei capitoli dedicati a tali argomenti. Si può concludere questa sezione con la considerazione che in generale, in tutti calcoli eseguiti con aritmetica floating point, non è pensabile raggiungere una precisione maggiore dello zero macchina. Poiché almeno una lieve propagazione dell’errore di arrotondamento alle ultime cifre decimali deve essere prevista anche nei calcoli più semplici, nelle approssimazioni fatte al 2.3. DIVISIONE E RADICE QUADRATA 29 calcolatore non ha senso imporre una tolleranza d’errore minore o uguale allo zero macchina. Come può essere verificato empiricamente sugli algoritmi presentati nelle prossime sezioni, le tolleranze d’errore che possono essere realisticamente imposte per ottenere risultati in pratica devono essere almeno un ordine di grandezza maggiori dello zero macchina. Come regola empirica, si può assumere quella di considerare come minima tolleranza d’errore praticamente utilizzabile un numero dell’ordine di grandezza di 100*eps. 2.3 Algoritmi iterativi per la divisione e la estrazione di radice quadrata Mentre le operazioni di somma algebrica e moltiplicazione tra numeri reali sono usualmente implementate in appositi circuiti hardware, la divisione deve essere in generale effettuata riconducendosi a somme e moltiplicazioni. Per questo motivo, tale operazione è in generale di esecuzione più lenta della somma e della moltiplicazione (in alcune implementazioni, la differenza di velocità di esecuzione arrivava in passato fino a 20 volte). Per questo motivo, se si devono effettuare dei calcoli in cui si ripete più volte la divisione per un numero fissato, è opportuno precalcolare l’inverso di tale numero e sostituire la divisione con la moltiplicazione per tale inverso. In molti calcolatori, la divisione viene implementata mediante un algoritmo iterativo, che calcola il valore dell’inverso di un numero reale mediante approssimazioni successive. Tale algoritmo può essere definito nel modo seguente. Si sceglie un valore iniziale z0 e si definisce una successione zi iterativamente come zi+1 = zi (2 − xzi ) i = 0, . . . , n (2.3) La convergenza di tale algoritmo verrà studiata teoricamente nel capitolo dedicato alla soluzione numerica di equazioni nonlineari. In generale, si può dimostrare che, per scelte opportune del valore iniziale z0 che dipendono da x, si ha limi→∞ zi = 1/x, per cui una buona approssimazione di 1/x si ottiene considerando zn con n sufficientemente alto. 30 CAPITOLO 2. NUMERI REALI E CALCOLO APPROSSIMATO Esercizio Implementare l’algoritmo 2.3 in OCTAVE e calcolare i reciproci di a) 2, b) √ 2, c) π, d) e utilizzando come valore iniziale z0 = 0.1. Esercizio Verificare empiricamente se vi è convergenza di tale algoritmo ai reciproci dei valori sopra assegnati nel caso di diversi valori di z0 . Esercizio Verificare empiricamente che si ha sempre convergenza per x ∈ (0.1, 1) se si prende z0 = 1.5. Esercizio Utilizzando i comandi OCTAVE tic e toc, predisporre uno script che consenta di confrontare il costo computazionale della divisione per un numero reale con quello della moltiplicazione per il suo inverso. Algoritmi analoghi possono essere utilizzati per approssimare la radice quadrata di un numero reale positivo. Un algoritmo piuttosto noto è il seguente: si sceglie un valore iniziale z0 e si definisce una successione zi iterativamente come zi+1 = 1 x zi + . 2 zi (2.4) La convergenza di tale algoritmo verrà studiata teoricamente nel capitolo dedicato alla soluzione numerica di equazioni nonlineari. In generale, si può dimostrare che, per scelte opportune del valore iniziale z0 che dipendono da √ √ x, si ha limi→∞ zi = x, per cui una buona approssimazione di x si ottiene considerando zn con n sufficientemente alto. Esercizio Implementare l’algoritmo 2.4 in OCTAVE e calcolare le radici quadrate di a) 2, b) π, c) e utilizzando come valore iniziale z0 = 0.1. 2.3. DIVISIONE E RADICE QUADRATA 31 Esercizio Verificare empiricamente se vi è convergenza di tale algoritmo alle radici quadrate dei valori sopra assegnati nel caso di diversi valori di z0 . Esercizio Verificare empiricamente che si ha sempre convergenza per x ∈ (0.1, 1) se si prende z0 = 0.1. Come si può verificare empiricamente, tale algoritmo ha buone proprietà di convergenza. Esso implica però la necessità di effettuare una divisione ad ogni passo iterativo, il che, come si è discusso in precedenza, richiede in realtà l’utilizzo di una ulteriore procedura iterativa che può essere più lenta della moltiplicazione. Esistono pertanto algoritmi iterativi più efficienti che approssimano la radice quadrata utilizzando solo somme e moltiplicazioni. Un esempio è il seguente zi (3 − xzi2 ). (2.5) 2 La convergenza di tale algoritmo verrà studiata teoricamente nel capitolo dedicato alla soluzione numerica di equazioni nonlineari. In generale, si può dimostrare che, per scelte√opportune del valore iniziale z0 che dipendono √ da x, si ha limi→∞ zi = 1/ x, per cui una buona approssimazione di x si ottiene considerando xzn con n sufficientemente alto. zi+1 = Esercizio Implementare l’algoritmo 2.5 in OCTAVE e ripetere gli esercizi precedenti. Esercizio Confrontare la velocità di convergenza degli algoritmi 2.4 e 2.5. Esercizio Utilizzando i comandi OCTAVE tic e toc, predisporre uno script che consenta di confrontare il costo computazionale degli algoritmi 2.4 e 2.5 per ottenere delle soluzioni di pari accuratezza. 32 CAPITOLO 2. NUMERI REALI E CALCOLO APPROSSIMATO Esercizio Implementare gli algoritmi sopra introdotti in modo da terminare le iterazioni una volta raggiunta una tolleranza d’errore fissata. Utilizzare valori della tolleranza pari a ǫ = 10−6 , 10−10 , 10−14 , 10−18. 2.4 Calcolo di costanti fondamentali Alcune costanti fondamentali dell’analisi matematica, come e e π, sono in realtà numeri trascendenti, ovvero tali da non essere gli zeri di nessun polinomio a coefficienti razionali. La determinazione di tali costanti può essere ottenuta solo mediante procedure approssimate. Esse si basano su limiti notevoli studiati in Analisi Matematica o su espansioni in serie di opportune funzioni. Ad esempio, per il calcolo rispettivamente di e e π si possono utilizzare le successioni 1 i zi = 1 + i = 1, . . . , n i zi = 4 i X (−1)k+1 k=1 2k − 1 i = 1, . . . , n (2.6) (2.7) La prima è derivata da un limite notevole, mentre la seconda è ottenuta dalla relazione arctan(1) = π/4 e dalla espansione in serie dell’arcotangente (si vedano ad esempio [1],[3],[5]). Esercizio Implementare gli algoritmi 2.6, 2.7 in OCTAVE e verificarne la convergenza utilizzando come riferimento i valori predefiniti di e, π. Questi algoritmi non sono però particolarmente efficienti. Sebbene questo aspetto non sia di grande rilevanza pratica per il calcolo di costanti che possono essere precalcolate una volta sola alla precisione richiesta, essi non sono i più indicati se si volesse ad esempio, utilizzando una rappresentazione più accurata dei numeri reali, effettuare il calcolo di tale costanti con un numero molto elevato di cifre decimali. Per il calcolo di e può essere ad esempio utilizzata la espressione in serie di potenze della funzione esponenziale, ottenendo la successione 2.5. CALCOLO DI FUNZIONI FONDAMENTALI i X 1 i = 1, . . . , n. zi = k! 33 (2.8) k=0 Per il calcolo π può √ essere invece √ utilizzato l’algoritmo definito in modo √ seguente. Si pone x0 = 2, z0 = 2 + 2, y0 = x0 e per i > 0 si definiscano le successioni 1 √ 1 xi+1 = xi + √ 2 xi xi+1 + 1 zi+1 = zi yi + 1 √ yi xi+1 + √x1i+1 yi+1 = i = 1, . . . , n yi + 1 Si può dimostrare che limi→∞ zi = π. Tale algoritmo è un esempio di quelli che vengono utilizzati per calcolare la costante π con una precisione molto elevata (milioni di cifre decimali esatte!). Una discussione degli algoritmi necessari a tale scopo e delle modalità di implementazione di una aritmetica a precisione arbitraria può essere trovata in [4]. Esercizio Implementare gli algoritmi 2.8, 2.9 in OCTAVE e verificarne la migliore convergenza rispetto agli algoritmi 2.6, 2.7 utilizzando come riferimento i valori predefiniti di e, π. Utilizzare la funzione OCTAVE factorial per calcolare i!. Esercizio Implementare gli algoritmi sopra introdotti in modo da terminare le iterazioni una volta raggiunta una tolleranza d’errore fissata. Utilizzare valori della tolleranza pari a ǫ = 10−6 , 10−10 , 10−14 , 10−18 . 2.5 Calcolo di funzioni fondamentali Molte delle principali funzioni dell’Analisi Matematica sono funzioni analitiche che possono essere approssimate, in linea di principio in modo infinitamente preciso, mediante sviluppi in serie di Taylor su intervalli più o 34 CAPITOLO 2. NUMERI REALI E CALCOLO APPROSSIMATO meno ampi della retta reale (si veda ad esempio [1],[3]). Anche qualora la serie di Taylor non sia convergente, se la funzione è sufficientemente regolare una approssimazione la formula di Taylor permette di approssimarla almeno localmente mediante polinomi, che possono essere calcolati utilizzando solo operazioni implementate nell’ hardware di qualsiasi calcolatore. exp x = lim n→∞ sin x = lim n→∞ n X xi i=0 i! x ∈ (−∞, +∞) n X (−1)i x2i+1 cos x = lim i=0 n→∞ n X (−1)i x2i i=0 ln x = lim − n→∞ x ∈ (−∞, +∞) (2i + 1)! (2i)! x ∈ (−∞, +∞) n X (1 − x)i i=1 i! x ∈ (0, 2) (2.9) (2.10) (2.11) (2.12) Esercizio Calcolare l’approssimazione di e2 utilizzando la serie di Taylor 2.9 troncata al a) quinto b) decimo c) ventesimo termine. Calcolare in ogni caso l’errore relativo commesso. Esercizio Calcolare l’approssimazione di sin π/4 utilizzando la serie di Taylor 2.10 troncata al a) quinto b) decimo c) ventesimo termine. Calcolare in ogni caso l’errore relativo commesso. Esercizio Calcolare l’approssimazione di cos π/4 utilizzando la serie di Taylor 2.11 troncata al a) quinto b) decimo c) ventesimo termine. Calcolare in ogni caso l’errore relativo commesso. 2.5. CALCOLO DI FUNZIONI FONDAMENTALI 35 Esercizio Calcolare l’approssimazione di ln 1/e utilizzando la serie di Taylor 2.12 troncata al a) quinto b) decimo c) ventesimo termine. Calcolare in ogni caso l’errore relativo commesso. Esercizio Studiare empiricamente la convergenza dell’approssimazione di ln x per x → 2 utilizzando la serie di Taylor 2.12. Esercizio Fare il grafico di ciascuna delle approssimazioni sopra introdotte su di un opportuno intervallo e confrontarlo con il grafico della funzione approssimata al variare del numero di termini considerati nella serie. 36 CAPITOLO 2. NUMERI REALI E CALCOLO APPROSSIMATO Capitolo 3 Statistica descrittiva e simulazione di campioni casuali In questo capitolo si introducono alcune delle istruzioni OCTAVE che permettono di effettuare semplici analisi dei dati, di simulare campioni casuali estratti dalle principali distribuzioni di probabilità e di realizzare esperimenti numerici che illustrino empiricamente il significato concreto della legge dei grandi numeri e del teorema del limite centrale. Non vi è alcuna pretesa di introdurre compiutamente i relativi concetti teorici, per cui si può far riferimento a vari testi di statistica e probabilità (si veda ad esempio [7]). L’obbiettivo didattico è piuttosto quello di utilizzare lo strumento informatico per riprodurre in modo sintetico campioni anche di grandi dimensioni a cui applicare i concetti sopra riassunti. Inoltre, l’uso di generatori di numeri pseudocasuali permette di presentare il comportamento asintotico della media campionaria nel limite di un grande numero di prove ripetute indipendenti come un fatto sperimentale, la cui evidenza si impone al di là di giustificazioni teoriche non accessibili a studenti di scuole superiori. 3.1 Elementi di statistica descrittiva Un insieme di valori X = {xi , i = 1, . . . , n} viene chiamato campione se si ritiene che si tratti di valori assunti da una variabile in occasione di diversi rilevamenti. Una delle ipotesi fondamentali per l’applicazione delle usuali stime statistiche è che tali rilevamenti si possano considerare indipendenti, e che la variabile di cui si rileva il valore abbia caratteristiche statisticamente 37 38 CAPITOLO 3. STATISTICA E CAMPIONI CASUALI costanti, ovvero che nel campione siano presenti valori variabili, ma distribuiti secondi una distribuzione di probabilità costante al ripetersi dei rilevamenti. La media campionaria, o media empirica del campione X si definisce come n 1X xi X̄ = n i=1 (3.1) e misura un valore aggregato rappresentativo dell’andamento collettivo dei singoli valori del campione. La varianza campionaria, o varianza empirica, si definisce come n σX2 = X 1 (xi − X̄ )2 (n − 1) i=1 (3.2) Si definisce scarto quadratico medio del campione la quantità σX , ovvero la radice quadrata della varianza del campione. Tali grandezze misurano la dispersione dei valori presenti nel campione attorno al valore medio rappresentato da X¯ . La presenza del fattore n − 1, invece di n, a denominatore, si spiega sulla base di considerazioni statistiche sulla mancanza di bias degli stimatori cosı̀ottenuti (si veda ad esempio [7]). Nel limite di un campione di grandi dimensioni possono essere utilizzate anche formule equivalenti in cui il fattore n − 1 sia sostituito da n, senza rilevanti effetti sul valore calcolato. In OCTAVE tali stimatori possono essere calcolati mediante le funzioni predefinite mean, var e std. Se ad esempio si definisce un campione mediante il vettore x=[-2 -1 0 1 2], si può verificare che si ottengono i valori >> media=mean(x) media=0 >> varianza=var(x) varianza=2.500 >>sqm=std(x) sqm=1.5811 Se ad esempio si modifica il campione in x=[-5 -1 0 1 5], si nota che il valore della media resta pari a zero, data la distribuzione simmetrica dei dati rispetto al valore centrale, ma che sia la varianza che lo scarto quadratico medio aumentano, dal momento che i valori presenti nel campione che sono più lontani dal valore medio sono aumentati in valore assoluto. Considerando invece un campione come x=[-5 -1 0 1 7], si nota che il valore della media campionaria è ora un numero positivo. 3.1. ELEMENTI DI STATISTICA DESCRITTIVA 39 Esercizio Calcolare media, varianza e scarto quadratico medio del campione x=[-1.495588 0.028352 1.076889 -2.259395 -0.138782 1.804042 1.838150 -1.626259 0.430469 -1.316373]. Uno strumento molto utile per analizzare graficamente l’andamento di un campione è l’istogramma, ovvero un grafico a barre che mostra la numerosità nel campione di alcuni insiemi assegnati e a intersezione nulla di valori possibili della variabile rilevata, che congiuntamente ricoprono tutto l’intervallo dei valori effettivamente presenti nel campione. In OCTAVE è possibile visualizzare istogrammi utilizzando il comando hist. Se si definisce ad esempio x= [-2 -2 0 1 1 1 5 6 6 8 8 8 12], il comando hist(x) visualizza l’istogramma relativo a dieci classi di uguale ampiezza comprese tra il valore −2 e il valore 12. Se si volesse visualizzare l’istogramma relativo a m classi di eguale ampiezza che coprano lo stesso intervallo, si dovrebbe utilizzare il comando hist(x,m), mentre digitando hist(x,m,1) si ottiene la visualizzazione delle frequenze relative di ciascuna classe rispetto all’insieme delle classi date, ovvero la numerosità di ciascuna classe viene normalizzata con la numerosità complessiva del campione. In questo modo si ottiene una rappresentazione della cosidetta distribuzione empirica del campione relativamente alle classi assegnate. Utilizzando il comando con la sintassi [f,c]=hist(x,m,1) si ottengono come risultato, invece del grafico, i valori numerici delle frequenze relative, immagazzinati nel vettore f, e dei centri delle classi utilizzate, immagazzinati nel vettore c. A partire da tali vettori, l’istogramma può essere visualizzato anche utilizzando il comando bar(c,f). Esercizio Definito il vettore x=[-pi:0.01:pi], denominare y,z rispettivamente i valori assunti dalle funzioni sin x e exp x2 in corrispondenza di tale vettore. Visualizzare l’istogramma non normalizzato di y e z utilizzando a) 10 classi di valori di uguale ampiezza b) 20 classi di valori di uguale ampiezza. Visualizzare i relativi istogrammi normalizzati. Stimare la frequenza con cui nel vettore y compaiono valori compresi tra 0.4 e 0.6 e quella con cui nel vettore z compaiono valori compresi tra 0.2 e 0.3. 40 3.2 CAPITOLO 3. STATISTICA E CAMPIONI CASUALI Generatori di numeri pseudocasuali e distribuzioni di probabilità in OCTAVE È in generale molto complesso, se non impossibile, dare una definizione precisa di evento casuale. Di fatto, la maggior parte degli esempi canonici di eventi casuali (monete, dadi, estrazioni da urne, ecc.) consiste di fenomeni perfettamente spiegabili in modo deterministico e che non si distinguono concettualmente dagli esempi canonici di determinismo classico: ad esempio la traiettoria di una moneta lanciata per giocare a testa o croce è calcolabile con grande precisione utilizzando le stesse leggi della dinamica che permettono di prevedere il moto dei pianeti o di mettere in orbita satelliti artificiali. La differenza sostanziale è piuttosto nella nostra ignoranza relativa alle condizioni iniziali del sistema considerato: mentre la forza applicata per mettere in orbita un satellite viene calcolata con precisione in base al peso del vettore spaziale e all’orbita da raggiungere, di solito si tira una moneta senza misurarne il peso e applicando una forza che non viene quantificata. Poiché, sia nel caso della moneta che nel caso del satellite, vi è una fortissima dipendenza dell’effettiva posizione ad un istante successivo al lancio dai valori iniziali di posizione, velocità e forze applicate, in assenza di tali informazioni l’esito del lancio diventa praticamente non prevedibile. L’usuale modello probabilistico per il lancio di una moneta non è altro che un modello semplificato, in cui ci si limita a considerare come eventi d’interesse, invece della traiettoria della moneta, i soli esito del lancio (testa o croce), per cui si stimano delle probabilità mediante una statistica sui risultati di esperimenti ripetuti. La tecnica utilizzata per simulare al calcolatore successioni di numeri casuali, o meglio, secondo la dizione più corretta, di numeri pseudocasuali, si basa anche essa su un principio simile. Si utilizzano infatti algoritmi perfettamente deterministici per ottenere una successione di numeri che abbia opportune proprietà statistiche. La successione numerica ottenuta dipende univocamente dal valore iniziale assegnato, quindi, per ottenere successioni diverse è necessario utilizzare valori iniziali differenti. La tecnica più comune alla base dei generatori di numeri pseudocasuali è quella del generatore lineare congruente. L’idea di tale algoritmo è quella di produrre una successione di numeri interi partendo da un valore intero iniziale x0 detto seme e generando i valori successivi calcolando ricorsivamente xn+1 = pxn + q mod m, (3.3) 3.2. NUMERI PSEUDOCASUALI 41 dove p, q, m sono a loro volta numeri interi. Si ottiene in questo modo una successione di numeri interi compresi tra 0 e m − 1, che per opportune e particolari scelte di p, q, m porta ad una distribuzione approssimativamente uniforme dei valori xn , nel senso che su un campione X con n sufficientemente grande la frequenza di ciascun valore tra 0 e m − 1 è approssimativamente di 1/m. Si deve notare che la qualità di tale approssimazione dipende in modo essenziale dalla scelta dei parametri p, q, m, che deve essere effettuata sulla base di considerazioni piuttosto complesse. In generale, ponendo numeri privi di particolari caratteristiche non si ottengono successioni che siano distribuite in modo quasi uniforme. Si può dimostrare che le successioni prodotte da tali algoritmi sono in realtà periodiche, per cui i valori ottenuti si ripeteranno da un certo punto in poi e non potranno più essere considerati indipendenti tra loro. Per scelte opportune dei parametri p, q, m si ottengono però dei periodi molto grandi, per cui i campioni di lunghezza inferiore al periodo possono essere considerati composti di valori statisticamente indipendenti tra di loro. Se i numeri interi ottenuti con questa procedura vengono divisi per m, si ottiene una approssimazione della distribuzione uniforme sull’intervallo (0, 1), ovvero i numeri reali cosı̀ottenuti possono essere interpretati come valori scelti a caso su questo intervallo. Un esempio di implementazione OCTAVE di un generatore lineare congruente è contenuto nella funzione ran0.m riportata in appendice. Tale funzione può essere utilizzata come mostrato nel seguente script ii=21234389; n=100; x=zeros(n,1); for i=1:n [y,ii]=ran0(ii); x(i,1)=y; end Il valore iniziale, per le caratteristiche dei parametri scelti in ran0, deve essere di almeno 6 cifre. La funzione ran0 restituisce un numero reale y distribuito in modo approssimativamente uniforme su (0, 1) ed un numero intero ii, che deve essere utilizzato come argomento nella successiva chiamata della funzione stessa. Per comodità, i numeri pseudocasuali prodotti dalla funzione vengono immagazzinati nel vettore x, che può essere poi analizzato statisticamente, per verificare ad esempio che la media campionaria è approssimativamente pari a 0.5. In OCTAVE, un vettore di numeri pseudocasuali distribuiti in modo ap- 42 CAPITOLO 3. STATISTICA E CAMPIONI CASUALI prossimativamente uniforme su (0, 1) può essere prodotto anche direttamente utilizzando il comando rand. Tale comando implementa un generatore simile a quello sopra descritto, che viene inizializzato di volta in volta con un valore differente del seme, derivato dallo stato dell’orologio interno del sistema operativo del calcolatore. Per questo motivo con il comando rand vengono prodotti ad ogni chiamata numeri pseudocasuali diversi. Sono inoltre predefiniti comandi che permettono di produrre sequenze di numeri pseudocasuali con distribuzione approssimativamente gaussiana standard (randn) ed esponenziale di parametro 1 (rande). 3.3 Simulazione al calcolatore della legge dei grandi numeri e del teorema del limite centrale I due teoremi limite fondamentali del calcolo delle probabilità, ovvero la legge dei grandi numeri ed il teorema del limite centrale, costituiscono la base della statistica classica. Questi importanti risultati teorici possono essere enunciati in modo sufficientemente rigoroso e preciso come segue Teorema (Legge dei grandi numeri) Dato un campione X = {xi , i = 1, . . . , n} di valori indipendenti tra loro e con distribuzione comune di media µ, con probabilità uno si verifica che n 1X xi = µ. lim n→0 n i=1 Teorema (Teorema del limite centrale) Dato un campione X = {xi , i = 1, . . . , n} di valori indipendenti tra loro e con distribuzione comune di media µ, si ha che Z b √ X̄ − µ 1 2 e−x dx. (3.4) lim Probabilita a < n <b = √ n→∞ σX 2π a La legge dei grandi numeri esprime il fatto che per un campione di valori indipendenti di dimensioni sempre maggiori, la media campionaria tende 3.3. TEOREMI ASINTOTICI 43 a convergere ad un valore costante che dipende solo dalla distribuzione, e non dai singoli valori. Una realizzazione approssimata di tale convergenza può essere facilmente ottenuta in OCTAVE generando campioni casuali dalla stessa distribuzione e mostrando come 1) campioni diversi, ma della stessa dimensione su (sufficientemente grande) hanno un valore molto simile della media campionaria 2) al crescere della dimensione del campione, tale valore tende ad un valore teorico. Il teorema del limite centrale descrive invece in modo approssimato il comportamento delle fluttuazioni della media campionaria di campioni grandi attorno al valore della media della distribuzione del campione stesso. Come si deduce dalla legge dei grandi numeri, tali fluttuazioni diventano sempre più piccole all’aumentare delle dimensioni del campione. Come si nota però dalla formula 3.4, se l’ampiezza di tali fluttuazioni viene riscalata con un fattore di √ ordine di grandezza n, dove n è la dimensione del campione, si ottengono dei valori di ordine di grandezza finito. Più precisamente, si osserva che l’ampiezza tipica delle fluttuazioni della media campionaria attorno alla media √ centrale esprime il fatto che della distribuzione è 1/ n. Il teorema del limite √ moltiplicando le fluttuazioni per il fattore n e dividendo per lo scarto quadratico medio si ottiene una variabile che è distribuita approssimativamente come una normale standard. Questa approssimazione migliora all’aumentare delle dimensioni del campione, il che permette di poter prevedere l’andamento delle fluttuazioni di grandi campioni. Una dimostrazione empirica del comportamento asintotico predetto dal teorema del limite centrale è ottenibile eseguendo lo script riportato nella sezione 7.3 dell’appendice, il cui risultato è visualizzato nella figura 3.1. 44 CAPITOLO 3. STATISTICA E CAMPIONI CASUALI 0.4 0.35 0.3 0.25 0.2 0.15 0.1 0.05 0 -4 -3 -2 -1 0 1 2 3 4 Figura 3.1: Grafico dell’istogramma delle fluttuazioni della media campionaria e della distribuzione standard. Capitolo 4 Soluzione numerica di equazioni nonlineari Il problema del calcolo approssimato di soluzioni di equazioni nonlineari costituisce una delle più semplici ed al tempo stesso più tipiche aree di applicazione dei concetti fondamentali dell’analisi numerica. Una generica equazione in una incognita reale può essere scritta come f (x) = 0 (4.1) per una opportuna funzione f (x), da cui la caratterizzazione di tale classe di metodi come metodi per il calcolo degli zeri di una funzione. Ci si concentrerà qui sul problema del calcolo di valore numerico per tali soluzioni, supponendo di essere in un caso in cui esse esistano ed in cui si sia individuato un intervallo in cui sia presente solo una di esse. È però ben noto che si possono avere equazioni che coinvolgono funzioni a valori reali che non ammettono soluzioni reali (ad esempio x2 + 1 = 0) o che non ammettono soluzioni reali in un determinato intervallo (ad esempio 2 + x − e−x = 0 per x ≥ 0, o per cui le soluzioni sono molto più di una, come nel caso di sin(10x) = 0 per x ∈ [0, 2π]. Per classi molto particolari di equazioni, come le equazioni algebriche di grado inferiore al quinto, esistono formule risolutive che consentono di determinare le soluzioni esatte di tali equazioni. Ci si rende però conto facilmente che tali formule sono di applicabilità molto limitata, dal momento che riguardano equazioni di forma molto particolare. Inoltre, anche le classiche formule di risoluzione per radicali richiedono, oltre alle quattro operazioni 45 46 CAPITOLO 4. EQUAZIONI NONLINEARI aritmetiche, l’utilizzo di operazioni come l’estrazione di radice quadrata che sono di fatto a loro volta implicitamente definite da un’equazione del tipo x2 − a = 0. Quindi, anche nel caso che si utilizzino formule esatte, per una loro concreta valutazione numerica è necessario fare ricorso a procedure di approssimazione come quelle viste nel capitolo 2 per il calcolo della radice quadrata. Di fatto, le procedure iterative introdotte nel capitolo 2 non sono altro che il risultato della applicazione di particolari metodi per la soluzione di equazioni nonlineari. Anche tutti i metodi che saranno introdotti in questo capitolo sono metodi iterativi, che calcolano una successione x(k) , k = 1, . . . , n di approssimazioni successive della soluzione, a partire da una stima iniziale x(0) che deve essere fornita dall’utente. Tali metodi sono in generale solo localmente convergenti, ovvero, detta xex la soluzione esatta, si può garantire che limk→∞ x(k) = xex solo se la stima iniziale x(0) è sufficientemente vicino alla vera soluzione. In pratica, prima ancora che per implementare algoritmi approssimati di soluzione lo strumento informatico può essere utilizzato per uno studio approssimato dell’andamento della funzione mediante la visualizzazione del suo grafico. A partire da un grafico ottenuto mediante la valutazione della funzione su di un insieme finito di punti si possono determinare approssimativamente gli intervalli in cui la funzione assume valore zero, e si può produrre di volta in volta un grafico relativo ad intervalli sempre più vicini al punto in cui viene approssimativamente assunto il valore zero, cosı̀da ottenere di fatto delle prime approssimazioni, sebbene non particolarmente accurate, della soluzione stessa. Esercizio Determinare il numero di soluzioni dell’equazione 6x6 +5x5 +4x4 +3x3 −2x2 + x−1 = 0 sull’intervallo [−2, 1] e calcolarne graficamente una approssimazione con un errore di ordine di grandezza 10−2 . Esercizio Determinare il numero di soluzioni dell’equazione sin( x1 ) sull’intervallo [0.01, 0.03]. 4.1. METODO DI BISEZIONE 4.1 47 Metodo di bisezione Il metodo di bisezione utilizza le proprietà di ordinamento totale dei numeri reali e le proprietà delle funzioni continue per determinare una soluzione di una equazione nonlineare e, al tempo stesso, un intervallo in cui la soluzione cercata è certamente contenuta. Il metodo può essere descritto facilmente a parole. Se una funzione continua assume valori di segno opposto agli estremi un intervallo [a, b], per il cosidetto teorema di esistenza degli zeri (o più semplicemente per una evidenza geometrica intuitiva) vi deve essere un punto in tale intervallo in cui la funzione assuma il valore zero. Il metodo di bisezione consiste appunto nel considerare come prima approssimazione di tale punto il punto medio x(1) = (a + b)/2 dell’intervallo dato. Dopo questo primo passo vi sono solo tre possibilità: 1) si ha effettivamente f (x(1) ) = 0, nel qual caso si è concluso il calcolo; 2) agli estremi dell’intervallo [a, x(1) ] la funzione f assume valori di segno opposto; 3) agli estremi dell’intervallo [x(1) , b] la funzione f assume valori di segno opposto. Si noti che i casi 2) e 3) sono mutuamente esclusivi solo se si è certi che nell’intervallo [a, b] vi sia una sola soluzione, altrimenti, qualora siano presenti più soluzioni (esempio: sin x = 0 sull’intervallo [−π/2, 3π/2]) le alternative 2) e 3) potrebbero essere entrambe soddisfatte. In questo caso il metodo sceglierà, sulla base di un criterio dipendente dalla specifica implementazione, solo uno dei due intervalli e non permetterà in generale di approssimare tutte le soluzioni presenti nell’intervallo di partenza. Come si è detto in precedenza, in questa presentazione ci si suppone per semplicità di avere sempre a che fare con soluzioni isolate in un dato intervallo. Iterando questa procedura, il metodo di bisezione porta alla determinazione di una successione di intervalli [ak , b(k) ], in cui di volta in volta è garantita la presenza della soluzione cercata e di cui uno degli estremi è il punto medio dell’intervallo determinato nell’iterazione precedente. Alla iterazione k−esima, la migliore possibile approssimazione della soluzione cercata consiste nel punto medio x(k) = (ak +b(k) )/2 dell’intervallo stesso. Poiché è certo che la soluzione è contenuta o nel semi-intervallo sinistro o nel semi-intervallo destro, si può ottenere facilmente una stima per eccesso dell’errore assoluto che si commette approssimando la soluzione con x(k) , ovvero b−a . 2k Questa caratteristica è peculiare del metodo di bisezione, perché nessuno (k) Ebisez ≤ 48 CAPITOLO 4. EQUAZIONI NONLINEARI degli altri metodi applicabili ad equazioni nonlineari generiche fornisce una stima certa dell’errore. D’altra parte, il metodo converge in modo relativamente lento, come può essere verificato risolvendo gli esercizi proposti. Si può verificare dalla formula di stima dell’errore che, per raggiungere una tolleranza di errore ǫ, sono necessarie almeno log2 ((b − a)/ǫ). Questo significa ad esempio che per raggiungere una tolleranza di 10−6 su di un intervallo di ampiezza 1 sono necessarie 20 iterazioni, e per raggiungerne una di 10−13 ne sono necessarie 44. Una implementazione del metodo di bisezione è riportata in appendice nella sezione 7.4. Esercizio Calcolare la soluzione dell’equazione sin x = 0 sull’intervallo [−1, 2] utilizzando il metodo di bisezione con 20 iterazioni. Esercizio Calcolare la soluzione dell’equazione 7e−5x + 3e−2x − 5 nell’intervallo [0, 1] utilizzando il metodo di bisezione con 15 iterazioni. Esercizio Calcolare la soluzione dell’equazione tanh(108 x) = 0 sull’intervallo [−1, 2] utilizzando il metodo di bisezione con n = 10, 100, 1000 iterazioni. Esercizio Eseguire nuovamente gli esercizi precedenti con tolleranze 10−3 , 10−6, 10−12 e confrontare il numero di iterazioni effettuato in ogni caso. 4.2 Metodo di Newton e le sue varianti Il metodo di Newton rappresenta un esempio di un metodo molto più rapidamente convergente del metodo di bisezione, che richiede però la conoscenza di più informazioni relative alla funzione stessa, in particolare della sua derivata. Il metodo di Newton applicato alla soluzione di f (x) = 0 si scrive come 4.2. METODO DI NEWTON E LE SUE VARIANTI 49 f (x(k) ) k = 1, . . . , n (4.2) f ′ (x(k) ) Come valore iniziale delle iterazioni si deve utilizzare una stima iniziale della soluzione determinata dall’utente. È importante sottolineare come questo metodo sia il risultato dell’applicazione ripetuta del principio di linearizzazione. All’equazione originale f (x) = 0 si sostituisce infatti, nell’intorno di un punto x(0) fissato, l’equazione x(k+1) = x(k) − f (x(0) ) + f ′ (x(0) )(x − x(0) = 0 ottenuta approssimando i valori di f con quelli della retta tangente al grafico di f in x(0) . Risolvendo esattamente tale equazione lineare si ottiene una prima approssimazione della soluzione di f (x) = 0. Applicando ripetutamente tale procedura si ottiene il metodo di Newton sopra descritto. Il metodo di Newton, come si può verificare ripetendo ad esempio gli esercizi della sezione precedente, porta in genere ad approssimare la soluzione in un numero di iterazioni molto minore del metodo di bisezione. Un modo solitamente usato per imporre di fermare le iterazioni quando si è raggiunta una accuratezza maggiore di una tolleranza d’errore fissata è il seguente. Il metodo viene riscritto come f (x(k) ) f ′ (x(k) ) = x(k) − δx(k) k = 1, . . . , n δx(k) = x(k+1) (4.3) (4.4) evidenziando il fatto che ad ogni passo iterativo si calcola un incremento rispetto alla soluzione precedentemente calcolata. Se si è fissata una tolleranza d’errore ǫ, il ciclo di calcolo può essere interrotto quando si abbia |δx(k) | < ǫ. Si deve tenere presente però che il metodo di Newton non è in generale convergente per tutte le scelte della stima iniziale x(0) . Si tratta infatti di uno dei casi di convergenza locale descritti nell’introduzione. Ciò può essere facilmente verificato modificando i valori della stima iniziale. Se l’equazione non ammette altre soluzioni, la successione ottenuta partendo da una stima iniziale sufficientemente lontana dalla soluzione stessa può divergere, mentre in presenza di altre soluzioni oltre quella cercata è possibile che si abbia convergenza ad una di esse. In OCTAVE un metodo simile al metodo di Newton è implementato come solutore predefinito nella funzione fsolve. La sintassi completa può essere 50 CAPITOLO 4. EQUAZIONI NONLINEARI trovata nella documentazione del codice. La tolleranza d’errore con cui le equazioni assegnate vengono risolte può essere modificata o assegnata con la funzione fsolve options. Come il metodo di Newton, l’algoritmo implementato in fsolve è solo localmente convergente. Tale comando può essere utilizzato per produrre soluzioni di riferimento in casi in cui la soluzione esatta non sia nota, ma si deve tenere presente che, come il metodo di Newton, può portare a successioni divergenti se la stima iniziale non è adeguata. Esercizio Scegliere una soluzione dell’equazione 6x6 + 5x5 + 4x4 + 3x3 − 2x2 + x − 1 = 0 sull’intervallo [−2, 1] e calcolarne una approssimazione con il metodo di Newton, individuando graficamente la stima iniziale. Esercizio Ripetere l’esercizio precedente utilizzando il comando fsolve di OCTAVE. Esercizio Calcolare la soluzione dell’equazione 7e−5x + 3e−2x − 5 nell’intervallo [0, 1] utilizzando il metodo di Netwon. Determinare graficamente una stima iniziale x(0) . Verificare in quante iterazioni si calcola la soluzione ottenuta con il metodo di bisezione applicato con 50 iterazioni e tolleranza ǫ = 10−16 . Esercizio Applicare il metodo di Newton alla soluzione dell’equazione tanh(108 x) = 0 sull’intervallo [−1, 2]. Utilizzare la stima iniziale x(0) e verificare che il metodo non converge. Determinare una stima iniziale sufficientemente vicina a x = 0 per cui si abbia convergenza. Usare il fatto che se y(x) = tanh(αx), si ha y ′(x) = α(1 − y 2). Esercizio Eseguire nuovamente gli esercizi precedenti interrompendo le iterazioni una volta che si siano raggiunte tolleranze d’errore pari a 10−3 , 10−6 , 10−12 . 51 4.3. METODO DEL PUNTO FISSO Il metodo di Newton richiede il calcolo della derivata della funzione ad ogni passo iterativo. Ciò può risultare scomodo per funzioni la cui derivata abbia una espressione molto complessa. Delle varianti del metodo di Newton, che hanno in generale una convergenza non ugualmente rapida ma comunque migliore di quella del metodo di bisezione, sostituiscono al calcolo Il metodo delle corde si definisce fissando un intervallo [a, b] in cui sia contenuta la soluzione e calcolando le iterazioni successive come f (x(k) ) f (b) − f (a) = x(k) − δx(k) k = 1, . . . , n. δx(k) = (b − a) x(k+1) (4.5) (4.6) Si vede che si è approssimata la derivata prima di f con il rapporto incrementale calcolato tra gli estremi dell’intervallo [a, b]. Il metodo delle secanti si definisce invece ponendo f (x(k) ) f (x(k) ) − f (x(k−1) ) k = 2, . . . , n. δx(k) = (x(k) − x(k−1) ) x(k+1) = x(k) − δx(k) (4.7) (4.8) Si vede che si è approssimata la derivata prima di f con il rapporto incrementale calcolato tra le ultime due soluzioni approssimate. Il metodo delle secanti necessita di due stime iniziali differenti per poter essere utilizzato, oltre che della memorizzazione delle due ultime soluzioni approssimate per poter calcolare la successiva. Esercizio Eseguire nuovamente gli esercizi precedenti utilizzando una implementazione del metodo delle secanti e del metodo delle corde. 4.3 Metodo del punto fisso Il metodo di punto fisso permette di risolvere equazioni che si presentino nella forma x = φ(x), 52 CAPITOLO 4. EQUAZIONI NONLINEARI detta di equazione di punto fisso. Tale forma è apparentemente molto particolare, ma si può vedere facilmente come a partire dalla equazione f (x) = 0 si possa in realtà arrivare ad una forma di punto fisso scrivendo ad esempio x = x − f (x) o x = x + f (x)/(1 + x2 ). Più precisamente, con semplici passaggi si vede che se le equazioni riformulate ammettono soluzione x̂, per questa soluzione deve essere anche f (x̂) = 0, per cui la soluzione di una qualsiasi equazione di punto fisso cosı̀ottenuta fornisce anche una soluzione del problema di partenza. Il metodo di punto fisso si scrive come x(k+1) = φ(x(k) ) k = 1, . . . , n. (4.9) Si può dimostrare che tale metodo è globalmente convergente su intervalli per cui si abbia |φ′(x)| ≤ a < 1. Ovvero, in tali situazioni il metodo converge indipendentemente dalla scelta della stima iniziale. Esercizio Verificare che le procedure di approssimazione della radice quadrata introdotte nel capitolo 2 sono applicazioni del metodo del punto fisso e determinare le funzioni di iterazione utilizzate. Esercizio Risolvere con il metodo di punto fisso l’equazione e−x − x = 0. Scegliere graficamente la stima iniziale. Capitolo 5 Calcolo approssimato di integrali definiti Per ogni funzione continua f (x) su un intervallo [a, b], l’integrale definito Z b I(f ) = f (x) d x. (5.1) a esiste ed ha l’interpretazione geometrica di valore dell’area (con segno) sottesa al grafico di f. Le usuali procedure di calcolo degli integrali in analisi matematica si basano sulla determinazione di una primitiva della funzione f (x), ovvero di una funzione F tale che F ′ (x) = f (x), e sul teorema fondamentale del calcolo, per cui I(f ) = F (b) − F (a). La funzione F viene chiamata anche integrale indefinito di f. Si deve però tenere presente che, a differenza della operazione di derivazione, per cui l’applicazione delle regole di derivazione ad una funzione ottenuta per composizione e combinazione algebrica di funzioni derivabili porta sempre ad una espressione esplicita (per quanto complicata) della derivata, l’integrazione indefinita è un problema per cui spesso non esiste una soluzione esprimibile mediante una formula chiusa, per quanto complessa. Ad esempio, se si considera il problema del calcolo dell’integrale definito della funzione gaussiana Z b 1 x2 √ exp (− ) dx, 2 2π a che è fondamentale per un gran numero di applicazioni in statistica e probabilità, si può dimostrare che non esiste una formula esplicita per il calco53 54 CAPITOLO 5. INTEGRALI lo del corrispondente integrale indefinito. In questi casi, che, vale la pena sottolinearlo, costituiscono la grande maggioranza, per ottenere una approssimazione di I(f ) si deve ricorrere ad una approssimazione numerica dell’integrale definito richiesto. Tali formule consistono in generale nel calcolo di una appropriata combinazione lineare di valori della funzione in un numero finito di punti dell’intervallo [a, b]. Anche tali formule ammettono una interpretazione geometrica, in quanto possono essere viste come approssimazioni dell’area sottesa al grafico di f con la somma di aree di figure geometriche più semplici, la cui area possa essere calcolata esattamente. Tutte le formule considerate sono in realtà formule polinomiali, ovvero ottenute approssimando localmente la funzione data con un opportuno polinomio. Questo tipo di derivazione delle formule consente anche di ottenere delle stime dell’errore compiuto nell’approssimazione numerica, che però si possono considerare Per tutti i metodi di integrazione considerati si introduce un insieme finito di punti xi detti nodi di integrazione. Si considerano qui per semplicità solo nodi equispaziati, ad una distanza h = (b−a)/n l’uno dall’altro. Il parametro h è detto passo di integrazione e ovviamente l’accuratezza dell’approssimazione dipende in modo essenziale dal suo valore, o equivalentemente, dal numero di nodi n utilizzato. Una analisi completa delle stime d’errore associate alle formule di integrazione richiede strumenti di analisi matematica che vanno oltre i contenuti dei programmi scolastici. Un approccio possibile al concetto di accuratezza e convergenza di tali formule è quello di quantificare empiricamente l’errore nel caso di funzioni semplici che possono essere integrate esattamente senza difficoltà. In tal modo si può anche verificare che, per polinomi di grado basso e dipendente dalla formula utilizzata, le formule introdotte danno, a meno di errori di arrotondamento, risultati esatti. 5.1 Alcuni metodi di integrazione numerica Il più semplice per approssimare gli integrali si basa sulla definizione delle somme di Riemann mediante cui si definisce teoricamente il concetto di integrale (si vedano ad esempio [3], [5]). Se si definiscono i nodi come xi = a + ih, i = 1, . . . , n, un esempio di somma di Riemann è dato dalla formula IR,n (f ) = X i=1,n f (xi )h. (5.2) 5.1. ALCUNI METODI DI INTEGRAZIONE NUMERICA 55 Approssimare I(f ) con tale formula equivale ad approssimare l’area sottesa al grafico di f con la somma delle aree di rettangoli di base [xi , xi+1 ] ed altezza pari al valore della funzione in xi . Una formula del tutto analoga si può ottenere sostituendo xi con un punto qualsiasi dell’intervallo [xi , xi+1 ]. Se in particolare si utilizza il punto medio (xi + xi+1 )/2, si ottiene il cosidetto metodo del punto medio, che può essere riscritto definendo xi = a + (i + 1/2)h, i = 0, n − 1 e X Ipm,n (f ) = f (xi )h. (5.3) i=0,n−1 Si può verificare che, in generale, la scelta del punto medio aumenta, a parità di numero di nodi, l’accuratezza dell’approssimazione. Esercizio R1 Calcolare l’integrale 0 x5 d x = 1/6 con il metodo delle somme di Riemann e con il metodo del punto medio con n = 10, 20, 40, 80 e confrontare i risultati ottenuti. Esercizio R1 Calcolare l’integrale 0 x d x = 1/2 con il metodo delle somme di Riemann e con il metodo del punto medio con n = 5, 10, 20 e confrontare i risultati ottenuti. Un ulteriore possibilità consiste nell’approssimare l’area sottesa al grafico di f con la somma delle aree di trapezi di base [xi , xi+1 ] ed altezze pari ai segmenti verticali (xi , f (xi )), (xi+1 , f (xi+1 )). Tale metodo dei trapezi può essere definito ponendo xi = a + ih, i = 0, n e X [f (xi ) + f (xi+1 )] 2 i=0,n−1 f (x ) i h f (x ) X n 0 h + f (xi ) + = 2 2 i=1,n−1 Itrap,n (f ) = h (5.4) La seconda variante della formula 5.4 è quella da utilizzare nell’implementazione, dal momento che evita di ricalcolare due volte ciascun f (xi ). Dai 56 CAPITOLO 5. INTEGRALI confronti con gli integrali esatti in casi semplici, si può osservare che le caratteristiche di accuratezza del metodo dei trapezi sono assolutamente analoghe a quelle del metodo del punto medio. Esercizio Ripetere gli esercizi precedenti utilizzando il metodo dei trapezi. Si introducono infine due metodi con caratteristiche di maggiore accuratezza. Il cosidetto metodo di Cavalieri - Simpson si definisce ponendo xi = a + ih/2, i = 0, 2n e i h X h Icav,n (f ) = f (xi ) + 4f (xi+1 ) + f (xi+2 ) (5.5) 6 i=0,2n−2 X X i hh f (x0 ) + 2 f (x2i ) + 4 f (x2i+1 ) + f (x2n ) . = 6 i=1,n−1 i=0,n−1 Approssimare I(f ) con tale formula equivale ad approssimare l’area sottesa al grafico di f con la somma delle aree di rettangoli curvilinei compresi tra [xi , xi+2 ], i segmenti verticali (xi , f (xi )), (xi+2 , f (xi+2 )) ed il grafico del polinomio di grado 2 passante per (xi , f (xi )), (xi+1 , f (xi+1 )) (xi+2 , f (xi+2 )). Il cosidetto metodo di Gauss-Legendre a due punti è invece l’esempio più semplice di una famiglia di formule di integrazione molto accurate, utilizzate in applicazioni in cui sia necessaria una grande precisione. Si definisce ponendo xi = a + (i + 21 + 2√1 3 )h, i = 0, n − 1 yi = a + (i + 21 − 2√1 3 )h, i = 0, n − 1 e h X [f (xi ) + f (yi)]. (5.6) IGL2,n (f ) = 2 i=0,n−1 Le caratteristiche di accuratezza di tale metodo sono analoghe a quelle del metodo di Cavalieri-Simpson, ma a parità di nodi il costo computazionale del metodo di Gauss-Legendre è inferiore, come si può osservare confrontando il numero di operazioni aritmetiche nelle due formule. Ciò è possibile grazie alla scelta molto particolare dei nodi di integrazione, che sono ottenuti come zeri di una speciale famiglia di polinomi (appunto i polinomi di Legendre). 5.2. SEMPLICE TECNICA DI STIMA DELL’ERRORE 57 Esercizio R1 Calcolare l’integrale 0 x3 d x = 1/4 con i metodi di Cavalieri-Simpson e di Gauss-Legendre medio con n = 5, 10, 20 e confrontare i risultati ottenuti. Esercizio Rπ Calcolare 0 cos x dx = 0 con tutti i metodi sopra introdotti utilizzando n = 10, 20, 40, 80 e confrontare i risultati. 5.2 Semplice tecnica di stima dell’errore Tutti i metodi introdotti hanno la caratteristica di essere convergenti per funzioni continue, ovvero se f è continua si ha limn→∞ Ixx,n (f ) = I(f ). Tale caratteristica può essere utilizzata, in assenza di una stima rigorosa dell’errore per ottenere una approssimazione di I(f ) che sia corretta a meno di una tolleranza d’errore imposta. Se infatti si confrontano i valori ottenuti con due diversi numeri di nodi e si osserva che ad esempio |Ixx,n(f ) − Ixx,n+k (f )| < ǫ, in virtù della convergenza della formula di integrazione si può ritenere che l’errore commesso approssimando l’integrale con Ixx,n+k (f ) sia inferiore alla tolleranza ǫ. Una applicazione di questa procedura al metodo dei trapezi è implementata nello script presentato nella sezione 7.5. Esercizio R2 2 Calcolare 0 exp (− x2 ) dx con tutti i metodi sopra introdotti imponendo una tolleranza d’errore di ǫ = 10−3, 10−6 , 10−9 . Confrontare il numero di nodi necessario in ogni caso per raggiungere tale accuratezza. Si può però osservare che la velocità con cui l’errore si riduce all’aumentare del numero di nodi, oltre a dipendere dal metodo utilizzato, dipende dalla regolarità della funzione integranda. Per funzioni regolari (ovvero derivabili e con derivate limitate) l’errore si riduce più rapidamente per i metodi più sofisticati (ad esempio Cavalieri Simpson e Gauss Legendre), mentre per funzioni non regolari (ad esempio con molti punti di non derivabilità o con valori molto elevati delle derivate) tale velocità di riduzione dell’errore è comparabile per tutti i metodi, come pure i valori dell’errore ottenuto. 58 CAPITOLO 5. INTEGRALI In OCTAVE è implementata con il comando quad una procedura di integrazione numerica che, mediante utilizzo di una opportuna stima teorica dell’errore e di una disposizione non uniforme dei nodi di integrazione, garantisce di effettuare il calcolo di integrali definiti a meno di una tolleranza fissata sull’errore. La tolleranza d’errore può essere fissata usando il comando quad options, mentre il comando quad si utilizza come nell’esempio seguente >>f=’sin(x)’ >>a=0 >>b=pi >>integrale=quad(f,a,b) integrale=2 Esercizio R2 2 Calcolare 0 exp (− x2 ) dx utilizzando quad imponendo una tolleranza d’errore ǫ = 10−13 e confrontare il valore ottenuto con i risultati ottenuti nell’esercizio precedente. Studiare la velocità di convergenza delle varie formule introdotte in precedenza al valore ottenuto con quad. Esercizio R2 Calcolare 0 tanh 10000x dx utilizzando il comando quad e imponendo una tolleranza d’errore ǫ = 10−13 . Studiare la velocità di convergenza delle varie formule introdotte al valore ottenuto con quad. Capitolo 6 Soluzione numerica di equazioni differenziali ordinarie Il problema della soluzione di una equazione differenziale ordinaria (ODE nel seguito, dal corrispondente acronimo anglosassone che sta per ordinary differential equations). del primo ordine consiste nel cercare di determinare una funzione a partire dalla conoscenza di una relazione tra il valore della funzione stessa e quello della sua derivata. Dal un punto di vista analitico, tale problema si formula come problema ai valori iniziali o problema di Cauchy come ( y ′(t) = f (y(t), t) y(0) = y0 . t ∈ (0, T ] (6.1) È noto che tale problema ammette una soluzione unica almeno localmente (ovvero per un T sufficientemente piccolo) sotto opportune ipotesi sulla relazione funzionale f che lega l’incognita y e la sua derivata (si vedano ad esempio [1],[3]). Per alcuni casi particolari (equazioni lineari del primo ordine a coefficienti variabili, equazioni a variabili separabili), la soluzione di tale problema può essere rappresentata esplicitamente. Si deve però notare che il fatto che sia possibile calcolare la soluzione esatta di alcune (semplici) equazioni differenziali non deve indurre a pensare che per tale tipo di problema possa sempre essere calcolata la soluzione mediante una formula esplicita. In generale, è vero esattamente il contrario. Per la maggior parte delle equazioni differenziali ordinarie, anche qualora l’esistenza e l’unicità della soluzione siano garantite dall’applicabilità dei relativi teoremi, non esi59 60 CAPITOLO 6. EQUAZIONI DIFFERENZIALI stono soluzioni facilmente calcolabili ed esprimibili mediante formule chiuse. Un esempio tipico di questa situazione è il seguente problema di Cauchy ′ 2 y (t) = e−t t ∈ (0, 3] y(0) = 1, L’equazione differenziale associata a questo problema è concettualmente banale, dato che equivale ad una semplice integrazione definita e la soluzione non è altro che Z t 2 e−s d s y(t) = 1 + 0 t ∈ (0, 3]. D’altra parte, dato che l’integrale definito della funzione gaussiana non può essere espresso mediante una semplice formula chiusa, tale formula non è altro che una rappresentazione della soluzione che deve poi essere approssimata numericamente qualora si vogliano effettivamente calcolare i valori della soluzione al variare di t. 6.1 Discretizzazione delle ODE: il metodo di Eulero I metodi di approssimazione numerica più comuni del problema 6.1 si basano sulla discretizzazione del problema stesso. Si introduce cioè una serie discreta tk di valori della variabile indipendente, per ciascuno dei quali si cerca di calcolare una approssimazione uk di y(tk ). Tale approssimazione viene cercata usualmente mediante la soluzione di un problema discreto, ottenuto approssimando la derivata prima presente in 6.1 con un rapporto incrementale tra le approssimazioni ottenute in istanti tk successivi. L’esempio più semplice di tale procedura è il metodo di Eulero (più precisamente, metodo di Eulero in avanti o metodo di Eulero esplicito), che può essere definito nel modo seguente. All’interno dell’ intervallo [0, T ] si considerano N + 1 valori tk , k = 0, . . . , N, definiti come t0 = 0 e tk+1 = tk + h, k = 0, . . . , N − 1 dove h = T /N è detto passo di discretizzazione o spesso passo temporale, data la frequente interpretazione della variabile indipendente come tempo. La scelta di un passo di discretizzazione costante è fatta qui solo per motivi di semplicità di esposizione, e in realtà le implementazioni più avanzate dei metodi per equazioni differenziali ordinarie utilizzano passi di discretizzazione variabili. La procedura di calcolo che definisce il metodo di Eulero esplicito è data da 6.2. MISURE DELL’ ERRORE NELLA SOLUZIONE NUMERICA DI ODE61 ( uk+1 = uk + hf (uk , tk ) k = 0, . . . , N u0 = y0 . (6.2) Si può notare come la procedura 6.2 sia stata ottenuta dal problema di Cauchy originale 6.1 considerando solo i valori della soluzione agli istanti tk e sostituendo il valore della derivata prima al generico istante tk con il rapporto incrementale approssimato (uk+1 −uk )/h. Tale tecnica numerica può essere facilmente implementata in OCTAVE, si veda ad esempio lo script eulero.m. 6.2 Misure dell’ errore nella soluzione numerica di ODE Una volta che i valori uk della soluzione approssimata siano stati calcolati, ci si può porre il problema di quanto essi si discostino dalla soluzione esatta y(tk ). Stime rigorose dell’andamento dell’errore possono essere ricavate utilizzando strumenti di analisi matematica avanzati (si vedano ad esempio [2], [6], [8]). Rimanendo nel contesto dei programmi previsti per la scuola superiore, ci si può limitare a quantificare l’errore in casi in cui y(t) possa essere calcolata esattamente. I concetti di errore introdotti nella sezione 2.1 devono però essere ampliati, tenendo conto del fatto che l’incognita di una equazione differenziale non è un numero, ma una funzione. Gli errori possono essere calcolati relativamente all’istante finale T = tN o relativamente a tutto l’intervallo [0, T ]. L’errore assoluto all’istante finale può essere definito come err abs (T ) = |y(tN ) − uN |. Tenendo conto però che i valori numerici della soluzione esatta potrebbero essere molto grandi o molto piccoli, ci si rende conto che è più opportuno rapportare la dimensione dell’errore a quella della soluzione stessa, introducendo quindi il cosidetto errore relativo err rel (T ) = |y(tN ) − uN | . |y(tN )| Se si vuole considerare invece l’errore compiuto su tutto l’intervallo [0, T ] si deve tenere conto anche degli istanti precedenti all’ultimo. Una possibile 62 CAPITOLO 6. EQUAZIONI DIFFERENZIALI definizione è quella del cosidetto errore assoluto in norma l∞ (o norma del massimo) data da abs err∞ (0, T ) = max |y(tk ) − uk |. k=0,...,N Il corrispondente errore relativo è invece rel err∞ (0, T ) = maxk=0,...,N |y(tk ) − uk | . maxk=0,...,N |y(tk )| Tale misura di errore considera il massimo scarto rilevato tra la soluzione esatta e quella numerica in tutti gli istanti in cui si è proceduto a calcolare l’ approssimazione uk . Un’altra possibile definizione è invece quella del cosidetto errore assoluto in norma l2 , data da v u N uX abs err2 (0, T ) = t |y(tk ) − uk |2 h. k=0 Il corrispondente errore relativo è invece qP rel err∞ (0, T ) = N k=0 |y(tk ) qP N − u k |2 h . 2 k=0 |y(tk )| h Tale misura di errore considera lo scarto quadratico medio rilevato tra la soluzione esatta e quella numerica su tutti gli istanti in cui si è proceduto a calcolare l’approssimazione uk . Si noti che nella definizione dell’errore PN 2 |y(t )| h costituisce di fatto una approssimazione relativo il termine k k=0 RT 2 dell’integrale 0 |y(s)| ds. Esercizio Calcolare gli errori assoluti e relativi compiuti nell’approssimazione della soluzione del problema di Cauchy y ′ = −y y(0) = 1 sull’intervallo [0, 2] utilizzando il metodo di Eulero con un passo h = 0.1, h = 0.01, h = 0.001. Confrontare i risultati ottenuti. Utilizzare lo script eulero.m. 6.3. DISCRETIZZAZIONE DELLE ODE: ALTRI METODI AD UN PASSO63 Esercizio Calcolare gli errori assoluti e relativi compiuti nell’approssimazione della soluzione del problema di Cauchy y ′ = −y + 2t y(0) = 1, che ha soluzione esatta y(t) = −2 + 2t + 3 exp (−t), sull’intervallo [0, 6] utilizzando il metodo di Eulero con un passo h = 0.1, h = 0.01, h = 0.001. Confrontare i risultati ottenuti. Risolvere l’esercizio modificando lo script eulero.m. 6.3 Discretizzazione delle ODE: altri metodi ad un passo La procedura di calcolo che definisce il generico metodo ad un passo esplicito è data da ( uk+1 = uk + hΦ(uk , tk ) k = 0, . . . , N (6.3) u0 = y0 . Si può notare come la procedura 6.3 sia stata ottenuta dal problema di Cauchy originale 6.1 considerando solo i valori della soluzione agli istanti tk , sostituendo il valore della derivata prima al generico istante tk con il rapporto incrementale approssimato (uk+1 − uk )/h e approssimando il termine f (y(tk ), tk ) con l’espressione Φ(uk , tk ). La forma specifica di tale termine distingue tra loro i diversi metodi e ne determina una maggiore o maggiore accuratezza. Si possono definire ad esempio, tra i metodi più semplici e noti, • metodo di Runge Kutta di ordine 2: f1 = f (uk , tk ) hf1 k h ,t + ) f2 = f (uk + 2 2 uk+1 = uk + hf2 64 CAPITOLO 6. EQUAZIONI DIFFERENZIALI • metodo di Heun: f1 = f (uk , tk ) f2 = f (uk + hf1 , tk+1 ) h uk+1 = uk + (f1 + f2 ) 2 • metodo di Runge Kutta di ordine 4: f1 = f (uk , tk ) h h f2 = f (uk + f1 , tk + ) 2 2 h h f3 = f (uk + f2 , tk + ) 2 2 f4 = f (uk + hf3 , tk+1 ) h uk+1 = uk + (f1 + 2f2 + 2f3 + f4 ) 6 Tali metodi sono detti espliciti poiché permettono di calcolare esplicitamente il valore approssimato al passo temporale tk+1 una volta noto il valore approssimato al passo temporale tk . Sono detti ad un passo poiché il termine Φ(uk , tk ) non dipende dai valori approssimati ai passi temporali precedenti tk . I metodi impliciti sono invece quelli in cui il valore approssimato al passo temporale tk+1 è definito solo implicitamente da una equazione uk+1 = uk + hΦ(uk+1, tk+1 , uk , tk ) che deve poi essere risolta numericamente ad ogni passo temporale, mentre i metodi multistep sono quelli in cui per il calcolo della soluzione al passo temporale tk+1 si utilizzano anche i valori approssimati ai passi temporali precedenti tk . Esercizio Calcolare gli errori assoluti e relativi in norma l2 e l∞ compiuti nell’approssimazione della soluzione dei seguenti problemi di Cauchy utilizzando i metodi di Heun e Runge Kutta di ordine 2 e 4 con un passo temporale h = 0.01 : 6.3. DISCRETIZZAZIONE DELLE ODE: ALTRI METODI AD UN PASSO65 a) y ′ = −3t2 y y(0) = 3 t ∈ [0, 2], che ha soluzione esatta y(t) = 3 exp (−t3 ); b) 3 y(1) = 2 t ∈ [1, ], 2 y ′ = y 2 /t che ha soluzione esatta y(t) = −2/(2 log t − 1); c) y ′ = −2ty y(0) = 1/2 t ∈ [0, 2] che ha soluzione esatta y(t) = exp (−t2 )/2; d) π y(0) = 0 t ∈ [0, ] 3 y′ = 1 + y2 che ha soluzione esatta y(t) = tan (t); e) y ′ = 3 − 2y/t y(2) = 3 t ∈ [2, 4] che ha soluzione esatta y(t) = t + 4/t2 ; f) y′ = y y(0) = 2 t ∈ [0, 2] che ha soluzione esatta y(t) = 2 exp (t). 66 CAPITOLO 6. EQUAZIONI DIFFERENZIALI In OCTAVE è implementato anche un solutore numerico avanzato di equazioni differenziali ordinarie, che utilizza tecniche di adattamento del passo temporale e stima dell’errore per ottenere soluzioni che siano accurate a meno di una tolleranza d’errore fissata. Tale solutore è implementato dal comando lsode, la cui sintassi è spiegata in dettaglio nel manuale di OCTAVE. Nella sezione 7.7 si trova un esempio di utilizzo di tale solutore predefinito. Si noti che questo comando non permette la scelta del passo temporale: gli istanti temporali che vengono specificati dall’utente vengono utilizzati solo per produrre un vettore di valori della soluzione numerica corrispondenti a istanti temporali assegnati. Tali valori vengono calcolati dal solutore con un passo temporale scelto autonomamente. La tolleranza d’errore e altri parametri determinabili dall’utente possono essere fissati con il comando lsode options. Esercizio Confrontare le soluzioni esatte delle equazioni introdotte nell’esercizio precedente con quelle ottenute mediante l’uso di lsode utilizzando una tolleranza d’errore relativo di 10−7 . Esercizio Confrontare le soluzioni ottenute con i metodi di Heun e Runge Kutta di ordine 2,4 per i problemi prima definiti con quelle ottenute mediante l’uso di lsode utilizzando una tolleranza d’errore relativo di 10−7 . 6.4 Stabilità numerica Uno dei problemi più caratteristici della soluzione numerica di ODE consiste nel fatto che, in generale, per i metodi più comuni la scelta del passo temporale non dipende solo da considerazioni di accuratezza, ma anche dalla cosidetta stabilità numerica. Con questo termine si intende il fatto che, per alcuni problemi di Cauchy, esiste un valore critico del passo temporale sopra il quale non solo la soluzione numerica è più o meno inaccurata, ma tende ad assumere valori che possono essere completamente irrealistici e raggiungere (e oltrepassare) rapidamente i limiti dell’insieme dei numeri floating 67 6.4. STABILITÀ NUMERICA point. Associate a questi fenomeni di instabilità numerica sono spesso anche oscillazioni molto forti della soluzione approssimata tra istanti temporali successivi. Il valore critico sotto il quale tali fenomeni non si verificano può essere stimato con precisione solo su alcuni semplici problemi modello lineari, tipicamente y ′ = −ay, a > 0. Per problemi nonlineari non è in generale possibile stabilire a priori il massimo passo temporale che può essere utilizzato, per cui è spesso necessario effettuare stime empiriche o scelte molto prudenti del passo temporale stesso. Esercizio Calcolare gli errori assoluti e relativi compiuti nell’approssimazione della soluzione del problema di Cauchy y ′ = −100y y(0) = 1 sull’intervallo [0, 1] utilizzando il metodo di Eulero con un passo h = 0.1, h = 0.01, h = 0.005, h = 0.001. Confrontare i risultati ottenuti. Esercizio Ripetere l’esercizio precedente con i metodi di Heun e Runge Kutta di ordine 2,4, eventualmente modificando i valori di h utilizzati. 68 CAPITOLO 6. EQUAZIONI DIFFERENZIALI 1 Sol. numerica Sol. esatta 0.5 0 -0.5 -1 0 0.1 0.2 0.3 0.4 0.5 Figura 6.1: Esempio di instabilità numerica del metodo di Eulero: soluzione di y ′ = −100y con y(0) = 1 e h = 0.02. Capitolo 7 Appendice A: esempi di programmi OCTAVE Si presentano in questa appendice alcuni esempi di script OCTAVE che implementano algoritmi presentati nel testo delle dispense in modo ragionevolmente documentato e trasparente. Non si garantisce in alcun modo che tali implementazioni diano risultati corretti se male utilizzate o se utilizzate con versioni di OCTAVE diverse dalla 3.0.1. 7.1 Calcolo approssimato di π % % Script OCTAVE per il calcolo approssimato di Pi % con procedura quadraticamente convergente proposta da Borwein. % % Sviluppato da L. Bonaventura - MOX Polimi % per corso SILSIS 2009 % % % Azzeramento eventuali variabili definite in precedenza % clear % % Formato output % 69 70 CAPITOLO 7. APPENDICE A format long % % % Inizializzazione procedura iterativa % x=sqrt(2); picom=2+x; y=sqrt(x); % % Numero massimo iterazioni permesse (modificabile dall’utente) % nmax=5; % % Ciclo di calcolo principale % for i=1:nmax disp(’iterazione’),i x=0.5*(sqrt(x)+1./sqrt(x)); disp(’valore approssimato di Pi’) picom=picom*(x+1)/(y+1) y=(y*sqrt(x)+1./sqrt(x))/(y+1); disp(’Errore relativo’) errore relativo=abs(pi-picom)/abs(pi) end 7.2 % % % % % % % Generatore lineare congruente di numeri pseudocasuali Function OCTAVE per la generazione di numeri pseudocasuali con procedura proposta da Park e Miller (vedi ’Numerical Recipes in C’). Calcola un numero pseudocasuale y in (0,1) e un numero intero ii da utilizzare per il calcolo del successivo % numero pseudocasuale. 7.2. GENERATORE LINEARE CONGRUENTE DI NUMERI PSEUDOCASUALI71 % Sviluppato da L. Bonaventura - MOX Polimi % per corso SILSIS 2009 % % % % function [y,ii]=ran0(id) % % Variabili in input: % id, intero: primo valore utilizzato deve avere almeno 6 % e al massimo 11 cifre % % Variabili in output: % y, reale, numero pseudocasuale % distribuito uniformemente tra 0 e 1 % ii, intero, da usare per generare % il successivo numero pseudocasuale % % % Costanti predefinite: l’efficacia del % generatore dipende da questi valori % ia = 16807; im = 2147483647; iq = 127773; ir = 2836; am = 1.0/im; % % Generatore lineare congruente % k=int32(id/iq); id=ia*(id-k*iq)-ir*k; if(id<=0) id=id+im; endif y=am*double(id); ii=id; end 72 7.3 CAPITOLO 7. APPENDICE A Teorema del limite centrale % % Script OCTAVE che implementa una dimostrazione % empirica del teorema del limite centrale % % Sviluppato da L. Bonaventura - MOX Polimi % per corso SILSIS 2009 % % % % Azzeramento eventuali variabili definite in precedenza % clear % % Formato output % format long % % Dimensione del campione studiato % N=1000; % % Numero di realizzazioni del campione di dimensione N % nreal=5000; % % Numero di classi per la visualizzazione con istogramma % nbins=30; y=[]; % % Creazione di nreal realizzazioni di un campione di dimensione N % tratto dalla distribuzione uniforme su [0,1] % e calcolo delle fluttuazioni del campione rispetto alla media; 7.4. METODO DI BISEZIONE 73 % tutte le nreal fluttuazioni, riscalate secondo la formula del teorema % del limite centrale, vengono immagazzinate nel vettore y % for i=1:nreal x=rand(N,1); y=[y sqrt(N)*(mean(x)-0.5)/std(x)]; end % % calcolo di media e varianza campionaria delle fluttuazioni % mi=mean(y) vv=var(y); sqm=sqrt(vv); % % Visualizzazione con istogramma con nbin classi % della distribuzione empirica delle fluttuazioni riscalate % e confronto con la distribuzione normale standard; % il fattore scale viene calcolato per ottenere un istogramma % normalizzato in modo analogo alla normale standard % [nn,xx]= hist(y,nbins); scale=0.; for i=1:nbins scale=scale+nn(i)*8/nbins; end bar(xx,nn/scale) zz=[mi-4:0.01:mi+4]; gg=exp(-0.5*(zz-mi).*(zz-mi)/vv)/sqrt(2*pi*vv); hold on plot(zz,gg,’r’) 7.4 Metodo di bisezione % % Script OCTAVE che implementa il metodo di bisezione per il calcolo % approssimato degli zeri di una funzione 74 CAPITOLO 7. APPENDICE A % % Sviluppato da L. Bonaventura - MOX Polimi % per corso SILSIS 2009, sulla base di uno script di R. Sacco % % % % Azzeramento eventuali variabili definite in precedenza % clear % % Formato output % format long % % % Inizializzazione procedura iterativa: % % a,b Estremi intervallo di ricerca radice % nmax Numero massimo di iterazioni % toll Tolleranza sul criterio di arresto % fun Macro contenente la funzione % a=-1; b=2; fun=’sin(x)’; nmax=50; toll=1e-9; err=1; it=0; while (it < nmax & err > toll) c=(a+b)/2; x=c; fc=eval(fun); x=a; if (fc == 0) err=0; else if (fc*eval(fun) > 0), 7.5. METODO DEI TRAPEZI CON CONTROLLO SULLA TOLLERANZA D’ERRORE75 a=c; else b=c; end; err=abs(b-a)/2; end it=it+1; disp(’Iterazione’),it disp(’Soluzione approssimata’), x disp(’Stima di errore’), err end 7.5 Metodo dei trapezi con controllo sulla tolleranza d’errore % % Script OCTAVE che implementa il metodo dei trapezi per il calcolo % approssimato di integrali definiti con stima di errore % mediante confronto valori approssimati con diverso numero di intervalli % % Sviluppato da L. Bonaventura - MOX Polimi % per corso SILSIS 2009 % % % % Azzeramento eventuali variabili definite in precedenza % clear all % % Formato output % format long % % funzione integranda % 76 CAPITOLO 7. APPENDICE A f=’sin(x)’; % % estremi integrazione % a=0; b=pi; % % valore iniziale fittizio integrale % ytrap old=100000; % % tolleranza % toll=1.e-9; % % numero massimo intervalli % nmax=1000000; % % calcolo integrale % for m=1:10:nmax h=(b-a)/m; x=[a:h:b]; y=eval(f); ytrap=h*(0.5*y(1)+sum(y(2:m))+0.5*y(m+1)); error est=abs(ytrap-ytrap old); if (error est<toll) break endif ytrap old=ytrap; end disp(’N. Intervalli’),m disp(’Valore integrale’), ytrap disp(’Stima errore’), error est 7.6. METODO DI EULERO IN AVANTI PER ODE 7.6 77 Metodo di Eulero in avanti per ODE % % Script OCTAVE che implementa il metodo di Eulero esplicito (in avanti) % per la soluzione numerica di y’=-a*y % % Sviluppato da L. Bonaventura - MOX Polimi % per corso SILSIS 2009 % % % % Azzeramento eventuali variabili definite in precedenza % clear close % % Formato output % format long % % % assegna dati iniziali % t0=0; y0=1; % % definisce parametri equazione % a=1; % % definisce istante finale simulazione % (iniziale posto uguale a t0 per default) % tfin=2; % % definisce numero passi temporali % 78 CAPITOLO 7. APPENDICE A nstep=10; % % calcola passo temporale % h=(tfin-t0)/nstep; % % inizializza vettori % t=zeros(nstep+1,1); t(1)=t0; u=zeros(nstep+1,1); u(1)=y0; % % definizione secondo membro problema di Cauchy % f=’-a*yy’; % % ciclo principale che implementa Eulero in avanti % for k=1:nstep tt=t(k); yy=u(k); t(k+1) = t(k)+ h; u(k+1) = u(k) + h*eval(f,yy,tt); end % % visualizza soluzione esatta e numerica % figure(1) clf plot(t,u) hold on y=exp(-a*t); % %Se si e’ modificato il file, sostituire la riga precedente %con la corretta soluzione esatta! % 7.7. SOLUTORE LSODE PER ODE plot(t,y,’r’); legend(’Sol. numerica’, ’Sol. esatta’) figure(2) % % visualizza errore puntuale % plot(t,abs(y-u)) legend(’Errore del metodo di Eulero’) % % calcola errori in varie norme % errore relativo L2=norm(y-u,2)/norm(y,2) errore relativo Linf=norm(y-u,Inf)/norm(y,Inf) 7.7 Solutore lsode per ODE % % Script OCTAVE che implementa la chiamata al solutore % numerico lsode per la soluzione di una generica equazione % differenziale del primo ordine % % Sviluppato da L. Bonaventura - MOX Polimi % per corso SILSIS 2009 % % % % Azzeramento eventuali variabili definite in precedenza % clear close % % Formato output % format long % % 79 80 CAPITOLO 7. APPENDICE A % assegna dati iniziali % t0=0; y0=1; % % definisce istante finale simulazione % (iniziale posto uguale a t0 per default) % tfin=2; % % definisce numero passi temporali % usati per visualizzare la soluzione % (il numero di passi usato per il calcolo % viene determinato autonomamente dal solver) % nstep=100; % % calcola passo temporale % h=(tfin-t0)/nstep; % % inizializza vettore dei tempi a cui calcolare la soluzione % t=[t0:h:tfin]; % % definizione secondo membro problema di Cauchy % N.B.:per la sintassi interna del solver lsode, % la variabile che rappresenta la funzione % incognita deve essere % chiamata x e la variabile indipendente t % f=’cos(t)*x+sin(12*t)’; % % chiamata al solver numerico % [u,istate,msg]=lsode(f,y0,t); % % visualizza soluzione numerica % 7.7. SOLUTORE LSODE PER ODE plot(t,u) legend(’Soluzione numerica’) 81 82 CAPITOLO 7. APPENDICE A Bibliografia [1] E. Giusti. Analisi Matematica 2. Boringhieri, 1983. [2] G. Naldi, L. Pareschi, and G. Russo. Introduzione al Calcolo Scientifico. McGraw Hill Italia, 2001. [3] C.D. Pagani and S. Salsa. Analisi Matematica. Masson, 1990. [4] W. H. Press, S. A. Teukolsky, W. T. Vetterling, and B. P. Flannery. Numerical Recipes in C. The Art of Scientific Computing. Cambridge University Press, 1992. [5] G. Prodi. Analisi Matematica. Boringhieri, 1970. [6] A. Quarteroni, R. Sacco, and F. Saleri. Edizione. Springer Verlag Italia, 2008. Matematica Numerica, III [7] S.M. Ross. Probabilità e statistica per le scienze e l’ingegneria. Apogeo Editore, 2003. [8] J. Stoer and R. Bulirsch. An Introduction to Numerical Analysis, 2nd edition. Springer Verlag, 1980. 83