11.07.2015 Views

Esercitazioni di Calcolo Numerico in MATLAB® e Octave - Esercizi e ...

Esercitazioni di Calcolo Numerico in MATLAB® e Octave - Esercizi e ...

Esercitazioni di Calcolo Numerico in MATLAB® e Octave - Esercizi e ...

SHOW MORE
SHOW LESS

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

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

Annamaria Mazzia<strong>Esercitazioni</strong> <strong>di</strong> <strong>Calcolo</strong><strong>Numerico</strong> <strong>in</strong> MATLAB® e<strong>Octave</strong>Dipartimento <strong>di</strong> Ingegneria Civile E<strong>di</strong>le e AmbientaleUniversità degli Stu<strong>di</strong> <strong>di</strong> PadovaCreative Commons Attribuzione- Non commerciale -Non opere derivate 3.0 Italia Licensea.a. 2012/2013


In<strong>di</strong>ce3.4 Norme <strong>di</strong> vettori . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 754 Meto<strong>di</strong> iterativi per sistemi l<strong>in</strong>eari 794.1 Metodo <strong>di</strong> Jacobi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 794.2 Mo<strong>di</strong>ficare jacobi.m per implementare gli altri meto<strong>di</strong> . . . . . . . . . . . . . . . . . . . . . . . 834.2.1 Metodo <strong>di</strong> Gauss-Seidel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 834.2.2 Metodo <strong>di</strong> rilassamento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 845 Problemi non l<strong>in</strong>eari 875.1 Metodo <strong>di</strong> Newton per sistemi non l<strong>in</strong>eari . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 875.2 M<strong>in</strong>imi quadrati non l<strong>in</strong>eari . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 916 Formule <strong>di</strong> <strong>in</strong>tegrazione numerica 956.1 Formule <strong>di</strong> quadratura numerica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 956.2 La formula dei trapezi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 956.3 La formula <strong>di</strong> Cavalieri-Simpson . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1007 Equazioni Differenziali Or<strong>di</strong>narie 1037.1 Meto<strong>di</strong> per ODE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1037.1.1 Confronto tra i meto<strong>di</strong> sull’equazione test . . . . . . . . . . . . . . . . . . . . . . . . . . . 1037.2 I meto<strong>di</strong> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1057.3 Sistemi <strong>di</strong> equazioni <strong>di</strong>fferenziali . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1097.3.1 Function <strong>di</strong> MATLAB e <strong>Octave</strong> per ODE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1097.3.2 L’oscillatore semplice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1107.3.3 Equazioni del moto <strong>di</strong> Keplero . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111iii


CAPITOLO 1IntroduzioneL’universo non potrà essere lettof<strong>in</strong>ché non avremo imparato ill<strong>in</strong>guaggio ed avremo familiarizzatocon i caratteri con cui è scritto. Èscritto <strong>in</strong> l<strong>in</strong>guaggio matematico, ele lettere sono triangoli, cerchi edaltre figure geometriche, senza lequali è umanamente impossibilecomprendere una s<strong>in</strong>gola parola.Galileo Galilei1.1 Introduzione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11.2 Avvio <strong>di</strong> MATLAB® e <strong>Octave</strong> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21.2.1 Le variabili . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41.2.2 Prima <strong>in</strong>troduzione (breve) su matrici e vettori <strong>in</strong> MATLAB® . . . . . . . . . . . . . . . . . 51.2.3 Funzioni vettorizzate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71.2.4 Sulle variabili . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81.3 Coman<strong>di</strong> utili . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101.4 Introduzione alla programmazione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111.5 Problemi e Algoritmi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121.6 MATLAB® come l<strong>in</strong>guaggio <strong>di</strong> programmazione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131.7 Primo script e prima function <strong>in</strong> MATLAB® . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131.8 I pre<strong>di</strong>cati elementari . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151.9 Strutture e cicli . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181.9.1 Ciclo if . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181.9.2 Ciclo while . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 241.9.3 Ciclo for . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 331.9.4 Introduzione a file <strong>di</strong> scrittura dati . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 351.9.5 Mo<strong>di</strong>ficare le function <strong>di</strong> punto fisso per creare nuove function . . . . . . . . . . . . . . . 391.1 IntroduzioneMATLAB® è un acronimo per MATrix LABoratory ed è uno strumento utile per il calcolo numerico e per lavisualizzazione. MATLAB® , <strong>in</strong>fatti, può essere considerato un l<strong>in</strong>guaggio <strong>di</strong> programmazione ad alto livelloe, allo stesso tempo, un ambiente <strong>in</strong>terattivo per lo sviluppo <strong>di</strong> algoritmi, per la visualizzazione e l’analisi <strong>di</strong>dati, e per il calcolo numerico.1


1. INTRODUZIONEQu<strong>in</strong><strong>di</strong>, per imparare a usare bene MATLAB® , dobbiamo imparare le tecniche <strong>di</strong> programmazione (cosaè un programma, quali sono le strutture <strong>di</strong> un programma, come si scrive, come si esegue). Ma dobbiamo anchetenere <strong>in</strong> conto che MATLAB® ha le sue proprie funzioni (functions), che permettono <strong>di</strong> eseguire calcolimolto sofisticati, ed è capace <strong>di</strong> fare grafici e visualizzare i risultati <strong>in</strong> maniera <strong>di</strong>retta.Molto spesso la conoscenza <strong>di</strong> MATLAB® è un requisito richiesto per molte posizioni lavorative <strong>in</strong> ambito<strong>in</strong>gegneristico proprio per la sua implementazione <strong>in</strong> numerosi problemi (dall’<strong>in</strong>gegneria aerospaziale aquella chimica, alla meccanica ...).MATLAB® è un programma complesso (orig<strong>in</strong>ariamente fu scritto <strong>in</strong> FORTRAN e successivamente riscritto<strong>in</strong> l<strong>in</strong>guaggio C) che va bene per risolvere programmi d’elaborazione numerica, per lavorare con matricie per la grafica. Questo software è un prodotto della The MathWorks : vedremo <strong>in</strong> particolare la versioneMATLAB® 8.0.0.783 (R2012b) lavorando <strong>in</strong> ambiente L<strong>in</strong>ux.Un prodotto simile a MATLAB® ma open source è GNU <strong>Octave</strong> (si vada sul sito http://www.gnu.org/software/octave/). In queste <strong>di</strong>spense, faremo riferimento alla versione 3.6.2 <strong>di</strong> <strong>Octave</strong>.Nel seguito vedremo come si lavora <strong>in</strong> MATLAB® (e <strong>Octave</strong>) tenendo presente che quasi tutti i coman<strong>di</strong>che daremo <strong>in</strong> MATLAB® valgono alla stessa maniera anche per <strong>Octave</strong> con alcune <strong>di</strong>fferenze, comel’<strong>in</strong>terfaccia grafico o altri coman<strong>di</strong>, che sottol<strong>in</strong>eeremo.1.2 Avvio <strong>di</strong> MATLAB® e <strong>Octave</strong>Tralasciamo la parte relativa alla procedura <strong>di</strong> <strong>in</strong>stallazione <strong>di</strong> MATLAB® (e <strong>di</strong> <strong>Octave</strong>), che <strong>di</strong>pende dalcomputer e dal sistema operativo <strong>in</strong> uso, e <strong>di</strong>amo per scontato che il programma sia presente sul propriocomputer.In ambiente L<strong>in</strong>ux, per avviare MATLAB® basta <strong>di</strong>gitare il comando matlab da una f<strong>in</strong>estra <strong>di</strong> term<strong>in</strong>ale(analogamente, basta <strong>di</strong>gitare octave per entrare <strong>in</strong> ambiente <strong>Octave</strong>). Una volta avviato MATLAB® , siaprirà un ambiente che contiene molte f<strong>in</strong>estre (la Command W<strong>in</strong>dow, la Workspace, la Command History,la Current Folder). Il prompt dei coman<strong>di</strong> è dato dal simbolo >> (> <strong>in</strong> <strong>Octave</strong>) e comparirà il promptdei coman<strong>di</strong> <strong>in</strong> una f<strong>in</strong>estra come quella mostrata <strong>in</strong> Figura 1.1 (si veda Figura 1.2 per l’analogo <strong>di</strong> <strong>Octave</strong>).Per uscire dall’ambiente si <strong>di</strong>gita exit o quit dalla f<strong>in</strong>estra dei coman<strong>di</strong> oppure dal menu File o ancoradall’icona <strong>di</strong> chiusura (x <strong>in</strong> alto a destra della f<strong>in</strong>estra).Per imparare a usare MATLAB® , conviene prendere familiarità con la f<strong>in</strong>estra dei coman<strong>di</strong> eseguendocalcoli come se fosse una calcolatrice. Ve<strong>di</strong>amo che il risultato viene assegnato ad una variabile detta ans eche nella Workspace si trovano <strong>in</strong>formazioni su <strong>di</strong> essa (si veda Figura 1.3).Le pr<strong>in</strong>cipali operazioni aritmetiche sono date da∧ elevamento a potenza∗ moltiplicazione/ <strong>di</strong>visione+ ad<strong>di</strong>zione− sottrazioneNel fare le operazioni aritmetiche, viene data la precedenza agli elevamenti a potenza, poi alle moltiplicazionie <strong>di</strong>visioni, <strong>in</strong>f<strong>in</strong>e alla sottrazione e ad<strong>di</strong>zione. Quando due operatori hanno la stessa prorità vengonoeseguite le operazioni partendo da s<strong>in</strong>istra e andando verso destra. Tuttavia, quando le espressioni sonoabbastanza complicate e c’è il rischio <strong>di</strong> non capire bene quali operazioni vanno fatte prima e quali dopo,conviene mettere sempre le parentesi.Le funzioni <strong>di</strong> base (quelle che troviamo anche su una calcolatrice) sono date da2


1.2. Avvio <strong>di</strong> MATLAB® e <strong>Octave</strong>Figura 1.1: L’ambiente MATLAB consiste <strong>di</strong> una serie <strong>di</strong> f<strong>in</strong>estre, alcune delle la Current Folder (la <strong>di</strong>rectorycorrente <strong>in</strong> cui si sta lavorando), la Workspace (lo spazio <strong>di</strong> lavoro) e la Command History (laf<strong>in</strong>estra con la storia dei coman<strong>di</strong> dati).Figura 1.2: Avvio <strong>di</strong> <strong>Octave</strong>: la f<strong>in</strong>estra che si apre corrisponde alla Command W<strong>in</strong>dow <strong>di</strong> MATLAB® .3


1. INTRODUZIONEFigura 1.3: Primi calcoli <strong>in</strong> MATLAB® : osservare cosa succede nella Command W<strong>in</strong>dow, nella Workspacee nella Command History.Funzione MATLAB® (<strong>Octave</strong>)s<strong>in</strong>(x)cos(x)tan(x)as<strong>in</strong>(x)acos(x)atan(x)exp(x)log(x)log10(x)sqrt(x)abs(x)Significatos<strong>in</strong>(x)cos(x)tan(x)asi n(x)acos(x)at an(x)e xln(x)log(x) x|x|La cosa nuova, da sottol<strong>in</strong>eare, è che ora queste operazioni si possono fare su matrici e vettori e che <strong>in</strong>MATLAB® (<strong>Octave</strong>) si lavora soprattutto su matrici e vettori.Per lavorare meglio, nel seguito <strong>in</strong>troduciamo il concetto <strong>di</strong> variabile e, successivamente, le matrici e ivettori.1.2.1 Le variabiliAbbiamo visto che, se scriviamo nella f<strong>in</strong>estra <strong>di</strong> lavoro, s<strong>in</strong>(10) il risultato è ans =-0.5440. Il risultatodella funzione viene assegnato ad una variabile che, <strong>di</strong> default, viene chiamata ans. Se cambiamo ilcalcolo, il risultato sarà del tipo ans = cui è associato il valore numerico del risultato. Tuttavia, noi possiamodecidere <strong>di</strong> assegnare il risultato <strong>di</strong> una certa operazione o <strong>di</strong> una funzione ad una variabile a cui noi stessiassegniamo un nome ben preciso. Per esempio, vogliamo che il risultato <strong>di</strong> s<strong>in</strong>(10) sia assegnato ad unavariabile che chiamiamo b. Per fare ciò, basta scrivere>> b=s<strong>in</strong>(10)4


1.2. Avvio <strong>di</strong> MATLAB® e <strong>Octave</strong>Figura 1.4: Variabili nella Workspaceb =-0.5440In questo modo il valore della funzione non è più assegnato alla variabile ans ma alla variabile b. Anche10 può <strong>di</strong>ventare il valore <strong>di</strong> una variabile, <strong>in</strong> cui poi valutare la funzione seno.>> a=10a =10>> b=s<strong>in</strong>(a)b =-0.5440Osserviamo che ora nella Workspace, troviamo il nome delle variabili <strong>in</strong>trodotte e il loro valore (si vedafigura ??).1.2.2 Prima <strong>in</strong>troduzione (breve) su matrici e vettori <strong>in</strong> MATLAB®Ciò che <strong>di</strong>remo ora su vettori e su matrici sarà qualcosa <strong>di</strong> breve, (quando parleremo <strong>di</strong> vettori e matric<strong>in</strong>el corso <strong>di</strong> <strong>Calcolo</strong> <strong>Numerico</strong>, li rivedremo sotto un’altra luce) utile per alcune semplici e prime applicazioni<strong>di</strong> MATLAB® (o <strong>Octave</strong>).I vettori si possono scrivere come vettori riga o vettori colonna.Per esempio:>>x=[1 2]>> x=[1 2]x =1 25


1. INTRODUZIONE>> y=[10 20]’y =1020Un vettore riga x viene scritto usando le parentesi quadre e scrivendo le componenti del vettore una dopol’altra. Un vettore colonna può essere creato facendo la trasposta <strong>di</strong> un vettore riga (me<strong>di</strong>ante il simbolo ’ ),oppure mettendo un punto e virgola dopo ciascuna componente:>> y=[10;20]y =1020In MATLAB® i vettori altro non sono che un caso particolare <strong>di</strong> matrice a n righe e 1 colonna (vettorecolonna) o a 1 riga e n colonne (vettore riga). Qu<strong>in</strong><strong>di</strong> per scrivere una matrice si scrivono i valori della matriceriga per riga andando a capo con il punto e virgola:>> A=[1 2 3 4;5 6 7 8;9 10 11 12;13 14 15 16]A =1 2 3 45 6 7 89 10 11 1213 14 15 16Per <strong>in</strong><strong>di</strong>care un valore della matrice A basta specificare l’<strong>in</strong><strong>di</strong>ce <strong>di</strong> riga e <strong>di</strong> colonna: per esempio>> A(2,2)ans =6Per <strong>in</strong><strong>di</strong>care gli elementi <strong>di</strong> tutta la colonna i si usa A(:,i), mentre A(i,:) <strong>in</strong><strong>di</strong>ca gli elementi della rigai.>> A(:,2)ans =261014>> A(2,:)ans =5 6 7 86


1.2. Avvio <strong>di</strong> MATLAB® e <strong>Octave</strong>L’operatore due punti può dunque essere usato per estrarre un’<strong>in</strong>tera riga o colonna da una matrice oun’<strong>in</strong>tera sottomatrice. Se vogliamo estrarre le ultime due righe e colonne della matrice A, si <strong>di</strong>gita il comando>> M=A(3:4,3:4)M =11 1215 16In questo modo abbiamo creato la matrice M che ha come elementi quelli della sottomatrice <strong>di</strong> A con le ultimedue righe e colonne.Per scrivere una matrice vuota A, <strong>in</strong>vece, si usa l’istruzione A=[ ].1.2.3 Funzioni vettorizzateLe funzioni che abbiamo visto prima si possono applicare <strong>di</strong>rettamente su matrici e vettori, sono cioèvettorizzate. Cosa significa questo? Significa che se abbiamo un vettore, ad esempio x = [1,2,3,4] e valutiamos<strong>in</strong>(x), il risultato sarà un vettore che ha come componenti il valore della funzione nelle s<strong>in</strong>gole componentidel vettore, <strong>in</strong> questo caso [s<strong>in</strong>(1),s<strong>in</strong>(2),s<strong>in</strong>(3),s<strong>in</strong>(4)]. Stessa cosa vale per le matrici.Ve<strong>di</strong>amo un esempio>> x=[2 4 6 8 10]x =2 4 6 8 10>> log(x)ans =0.6931 1.3863 1.7918 2.0794 2.3026>> A=[0.1 0.2 ; 0.3 0.4]A =0.1000 0.20000.3000 0.4000>> s<strong>in</strong>(A)ans =0.0998 0.19870.2955 0.3894Per quanto riguarda le operazioni aritmetiche, l’ad<strong>di</strong>zione e la sottrazione sono vettorizzate per def<strong>in</strong>izione.Invece, le operazioni <strong>di</strong> moltiplicazione, <strong>di</strong>visione ed elevamento a potenza vengono vettorizzate facendoprecendere il simbolo <strong>di</strong> moltiplicazione, <strong>di</strong>visione e elevamento a potenza dal simbolo del punto ( .*, ./,.ˆ ) permettendo, <strong>in</strong> tal modo, che le operazioni vengano fatte componente per componente delle matrici (odei vettori) su cui sono applicate.>> x=[2 4 6 8 10]x =2 4 6 8 107


1. INTRODUZIONE>> y=[1 3 5 7 9]y =1 3 5 7 9>> x.*yans =2 12 30 56 90Se facessimo semplicemente x*y avremmo un messaggio <strong>di</strong> errore perchè richiederemmo un’operazione<strong>di</strong> prodotto tra due matrici che hanno n righe e 1 colonna ciascuna, e questa operazione non si può fare(vedremo <strong>in</strong> seguito che si può fare il prodotto tra due matrici A e B se il numero <strong>di</strong> colonne <strong>di</strong> A corrispondeal numero <strong>di</strong> righe <strong>di</strong> B). Ve<strong>di</strong>amo un altro esempio>> A=[ 1 2; 3 4]A =1 23 4>> B=[2 4; 6 8]B =>> A*Bans =>> A.*Bans =2 46 814 2030 442 818 32Questa volta, abbiamo considerato due semplici matrici A B. Se facciamo A*B, abbiamo come risultatola matrice prodotto (la stu<strong>di</strong>eremo più avanti nel corso <strong>di</strong> <strong>Calcolo</strong> <strong>Numerico</strong>), se <strong>in</strong>vece facciamo A.*B,abbiamo come risultato la matrice <strong>in</strong> cui ogni componente è dato dal prodotto dei corrispondenti elementisulle due matrici <strong>di</strong> partenza.1.2.4 Sulle variabiliNegli esempi precedenti, abbiamo dati a matrici e vettori un nome, x,y,A,B... Abbiamo qu<strong>in</strong><strong>di</strong>assegnato delle variabili.Una variabile ha, qu<strong>in</strong><strong>di</strong>, un significato simile a quello che conosciamo già nelle espressioni algebriche:nel nostro caso, però, ad una variabile è sempre associato un valore numerico, se si tratta <strong>di</strong> una variabilescalare, oppure più valori, se si tratta <strong>di</strong> vettori o <strong>di</strong> matrici. In figura 1.5 ve<strong>di</strong>amo come nella Workspace,8


1.2. Avvio <strong>di</strong> MATLAB® e <strong>Octave</strong>Figura 1.5: Workspace con <strong>di</strong>versi tipi <strong>di</strong> variabili.ciascuna variabile con cui si sta lavorando nella f<strong>in</strong>estra dei coman<strong>di</strong>, sia elencata con il suo nome e con ilsuo valore (che è il valore che le è stato assegnato se si tratta <strong>di</strong> una variabile scalare, mentre è <strong>di</strong>chiarato iltipo <strong>di</strong> variabile se è <strong>di</strong> tipo matriciale). Dalla figura, possiamo osservare comeG ci sono due variabili, una chiamata A e una a: questo perchè MATLAB® (<strong>Octave</strong>) è sensibile alle letterem<strong>in</strong>uscole e maiuscole: una variabile chiamata A è <strong>di</strong>versa da a!G il valore per A è : vuol <strong>di</strong>re che si tratta <strong>di</strong> una matrice 10 × 10 i cui valori sonomemorizzati <strong>in</strong> doppia precisione (double)la matrice B, <strong>in</strong>vece, è 10 × 10 <strong>in</strong> s<strong>in</strong>gola precisione (s<strong>in</strong>gle)la matrice C è 4 × 4 ed è u<strong>in</strong>t8 (che significa?, ora ci arriviamo)abbiamo poi due scalari, a e b.G ci sono due vettori, uno riga e uno colonna, <strong>in</strong> doppia precisioneCiascuna variabile, una volta che viene generata, è <strong>di</strong> un certo tipo e viene classificata <strong>di</strong> conseguenza. Didefault, ogni variabile (scalare o matriciale) viene considerata <strong>in</strong> doppia precisione (qu<strong>in</strong><strong>di</strong> <strong>di</strong> tipo double).Me<strong>di</strong>ante apposite functions <strong>di</strong> MATLAB® (<strong>Octave</strong>) è possibile convertire il valore <strong>di</strong> una variabile <strong>in</strong> un altrotipo: se scriviamo A=s<strong>in</strong>gle(A), la matrice A viene convertita <strong>in</strong> una matrice che ha lo stesso nome, i cuivalori però sono ora memorizzati <strong>in</strong> s<strong>in</strong>gola precisione. La function u<strong>in</strong>t8 converte una variabile (che puòessere scalare o matriciale) <strong>in</strong> una variabile il cui valore è ora un <strong>in</strong>tero a 8 bit senza segno (con valori chevanno da 0 a 255). Se la variabile è già <strong>di</strong> tipo <strong>in</strong>tero con valori che si trovano <strong>in</strong> questo <strong>in</strong>tervallo, non ci sonoproblemi, ma se la variabile assume valori al <strong>di</strong> fuori <strong>di</strong> questo <strong>in</strong>tervallo, allora i valori sono arrotondati alpiù vic<strong>in</strong>o valore dell’<strong>in</strong>tervallo ammissibile. Questo tipo <strong>di</strong> dato ha senso quando si lavora con numeri <strong>in</strong>terie per fare certi tipi <strong>di</strong> operazioni. Ve<strong>di</strong>amo esempi semplici>> x=[0 1 2 3]x =0 1 2 3>> u<strong>in</strong>t8(x)ans =9


1. INTRODUZIONE0 1 2 3>> x=[0 -1 -2 3]x =0 -1 -2 3>> x=u<strong>in</strong>t8(x)x =0 0 0 3All’<strong>in</strong>izio il vettore x ha tutti valori positivi e u<strong>in</strong>t8 non cambia i valori del vettore (viene generato unvettore ans identico a x). Nel secondo caso il vettore x ha elementi negativi che vengono trasformati <strong>in</strong> 0.Questa volta il risultato della funcion u<strong>in</strong>t8 è assegnato alla stessa variabile x che viene qu<strong>in</strong><strong>di</strong> sovrascrittae il vettore non è più quello <strong>di</strong> prima.Se usiamo le function double e s<strong>in</strong>gle non osserviamo nessun cambiamento a prima vista, ma <strong>in</strong>realtà è lo spazio <strong>di</strong> memoria per la variabile che cambia.1.3 Coman<strong>di</strong> utiliPer lavorare meglio sia nella f<strong>in</strong>estra dei coman<strong>di</strong> sia, successivamente, per scrivere ed eseguire dei veri epropri programmi, risultano utili le seguenti funzioni:G who – fornisce l’elenco <strong>di</strong> tutte le variabili presenti nella f<strong>in</strong>estra dei coman<strong>di</strong> (lo si può vedere anchenella Workspace;G whos – fornisce l’elenco <strong>di</strong> tutte le variabili <strong>in</strong>sieme allo spazio <strong>in</strong> memoria da esse occupato (con questocomando si può osservare come una stessa variabile, memorizzata come double o come s<strong>in</strong>gle,occupa un <strong>di</strong>verso spazio <strong>di</strong> memoria);G help – può essere usato da solo o <strong>in</strong>sieme al nome <strong>di</strong> una function propria <strong>di</strong> MATLAB® (<strong>Octave</strong>)o creata dall’utente, e mostra tutte le <strong>in</strong>formazioni utili per capire come usare MATLAB® o quellafunction;G clear – se è usata da sola cancella tutte le variabili presenti nella f<strong>in</strong>estra dei coman<strong>di</strong>, se <strong>in</strong>vece èseguita da un elenco <strong>di</strong> variabili (messe una <strong>di</strong> seguito all’altra senza virgole) cancella tutte le variabilidell’elenco;G il punto e virgola “;” messo dopo un’istruzione non fa vedere il risultato dell’istruzione nella f<strong>in</strong>estradei coman<strong>di</strong>;G il simbolo % è il simbolo per scrivere commenti:ciò che viene scritto dopo % rappresenta uncommento;G clc ha la funzione <strong>di</strong> pulire la Command W<strong>in</strong>dow e <strong>di</strong> portare il cursore <strong>di</strong> nuovo <strong>in</strong> alto a s<strong>in</strong>istra nellaf<strong>in</strong>estra (la dove era nel momento <strong>in</strong> cui abbiamo avviato MATLAB® (<strong>Octave</strong>). Le variabili non vengonocancellate.G <strong>di</strong>ary – permette <strong>di</strong> salvare, su un file che viene chiamato <strong>di</strong>ary, il contenuto <strong>di</strong> ciò che viene scrittonella f<strong>in</strong>estra dei coman<strong>di</strong>. Il file <strong>di</strong>ary si trova nella <strong>di</strong>rectory corrente <strong>in</strong> cui si sta lavorando;<strong>di</strong>ary off – chiude il file aperto me<strong>di</strong>ante l’istruzione <strong>di</strong>ary;G <strong>di</strong>ary file<strong>di</strong>ary – comando analogo a <strong>di</strong>ary, ma il file non si chiamerà <strong>di</strong>ary bensìfile<strong>di</strong>ary, dove file<strong>di</strong>ary rappresenta il nome del file def<strong>in</strong>ito dall’utente;G save filesave – salva tutte le variabili presenti nel Workspace, nel file filesave.mat confilesave nome scelto dall’utente, <strong>in</strong> modo da conservare tutte le variabili con cui si stava lavorando.Questo comando è utile se si deve chiudere la sessione <strong>di</strong> lavoro ma si vuole poi ripartire a lavorareproprio da quelle variabili;10


1.4. Introduzione alla programmazioneG load ’filesave’ – riprist<strong>in</strong>a lo stato del Workspace, caricando tutte le variabili che erano statesalvate <strong>in</strong> filesave.mat <strong>in</strong> modo da poterci lavorare <strong>di</strong> nuovo. Si era chiusa la sessione <strong>di</strong> lavoro eora si può ripartire a lavorare con le stesse variabili <strong>di</strong> prima.C‘e una notevole <strong>di</strong>fferenza <strong>di</strong> significato tra i files generati dall’istruzione <strong>di</strong>ary e quelli generati me<strong>di</strong>antesave. Ciò che salviamo con il comando <strong>di</strong>ary è paragonabile a ciò che può essere scritto alla lavagnae <strong>di</strong> cui pren<strong>di</strong>amo appunti: scriviamo un file <strong>di</strong> testo che possiamo elaborare o da cui possiamo trarredei risultati per i nostri problemi. Al contrario, quello che viene salvato me<strong>di</strong>ante il comando save è costituitoda una o più variabili, che possono essere riutilizzate nuovamente <strong>in</strong> MATLAB® (<strong>Octave</strong>) nella f<strong>in</strong>estradei coman<strong>di</strong>, <strong>in</strong> sessioni successive a quella <strong>in</strong> cui sono state create, senza dover rieseguire tutti i coman<strong>di</strong>che hanno portato alla creazione delle variabili stesse. Infatti, quando si chiude MATLAB® (<strong>Octave</strong>), tutte levariabili e i dati vengono persi!Il comando save è utile anche per salvare s<strong>in</strong>gole matrici o una lista <strong>di</strong> matrici nella <strong>di</strong>rectory corrente.Ci soffermiamo sulla possibilità <strong>di</strong> salvare i dati <strong>in</strong> formato ASCII, <strong>in</strong> modo da poter utilizzare i dati che salviamonon solo <strong>in</strong> MATLAB® (<strong>Octave</strong>) ma anche <strong>in</strong> programmi scritti con altri l<strong>in</strong>guaggi <strong>di</strong> programmazione.Supponiamo <strong>di</strong> avere una matrice A e <strong>di</strong> volerla salvare nel file matriceA.dat. Scriveremo il comandosave matriceA.dat A -asciiQuando vogliamo caricare <strong>in</strong> MATLAB® la matrice dal file useremo il comandoload(’matriceA.dat’)e <strong>in</strong> questo modo avremo la matrice nella variabile matriceA (il nome del file senza l’estensione dopo ilpunto).1.4 Introduzione alla programmazioneMATLAB® (e <strong>di</strong> conseguenza <strong>Octave</strong>, d’ora <strong>in</strong> poi quando parleremo <strong>di</strong> MATLAB® ometteremo <strong>di</strong> scrivereanche <strong>Octave</strong>, <strong>in</strong>tendendo che il <strong>di</strong>scorso vale anche per <strong>Octave</strong> e sottol<strong>in</strong>eeremo solo le <strong>di</strong>fferenze importanti)si può <strong>in</strong>tendere come un l<strong>in</strong>guaggio <strong>di</strong> programmazione, anche se non rientra <strong>in</strong> nessuna delle duecategorie <strong>di</strong> base dei l<strong>in</strong>guaggi <strong>di</strong> programmazione.Ci sono <strong>in</strong>fatti due categorie <strong>di</strong> l<strong>in</strong>guaggi per scrivere programmi:G l<strong>in</strong>guaggi <strong>di</strong> alto livello (come FORTRAN, C, C++)G l<strong>in</strong>guaggi <strong>di</strong> basso livello (come assembler).Il l<strong>in</strong>guaggio macch<strong>in</strong>a, <strong>in</strong>vece, è il l<strong>in</strong>guaggio specifico dell’elaboratore e consiste <strong>di</strong> cifre b<strong>in</strong>arie 0 e 1 cheidentificano istruzioni elementari. Ogni elaboratore ha il suo l<strong>in</strong>guaggio macch<strong>in</strong>a.I l<strong>in</strong>guaggi <strong>di</strong> basso e alto livello si possono tradurre <strong>in</strong> un qualsiasi l<strong>in</strong>guaggio macch<strong>in</strong>a e possono essereutilizzati su qualsiasi elaboratore (sono portabili). Con i l<strong>in</strong>guaggi <strong>di</strong> basso livello, i co<strong>di</strong>ci b<strong>in</strong>ari (fatti da0 e 1) vengono sostituiti da opportune ”parole chiave” che permettono una corrispondenza uno-uno tra ill<strong>in</strong>guaggio <strong>di</strong> basso livello e il l<strong>in</strong>guaggio macch<strong>in</strong>a.Con i l<strong>in</strong>guaggi <strong>di</strong> alto livello, una s<strong>in</strong>gola istruzione può tradurre più istruzioni <strong>di</strong> l<strong>in</strong>guaggio macch<strong>in</strong>a.Inoltre un l<strong>in</strong>guaggio <strong>di</strong> alto livello è facile da capire (nella sua s<strong>in</strong>tassi, nelle sue regole, nel suo modo <strong>di</strong>essere utilizzato) da chi programma.Perciò, quando si programma con un l<strong>in</strong>guaggio <strong>di</strong> alto livello, il programmatore deve conoscere e saperebene la grammatica, la s<strong>in</strong>tassi, il vocabolario del l<strong>in</strong>guaggio stesso. Uno volta scritto il programma<strong>in</strong> modo corretto, occorre fare capire al computer che c’è un programma da eseguire: bisogna qu<strong>in</strong><strong>di</strong> tradurre<strong>in</strong> l<strong>in</strong>guaggio macch<strong>in</strong>a il programma scritto con il l<strong>in</strong>guaggio <strong>di</strong> alto livello: questo passaggio lo si fame<strong>di</strong>ante la compilazione: un comando particolare chiama un programma <strong>di</strong> compilazione che viene applicatoal programma scritto nel l<strong>in</strong>guaggio <strong>di</strong> alto livello (che chiamamo programma sorgente) <strong>in</strong> un programmaequivalente scritto <strong>in</strong> l<strong>in</strong>guaggio macch<strong>in</strong>a e che potrà essere eseguito dal calcolatore, detto programmaeseguibile.In MATLAB® , noi scriveremo qualcosa <strong>di</strong> equivalente al programma sorgente ma non lo compileremoperchè ogni volta che lo vorremo eseguire, esso verrà “automaticamente” compilato ed eseguito.Abbiamo due tipi <strong>di</strong> files eseguibili:G lo script, che presenta una lista <strong>di</strong> coman<strong>di</strong> da eseguire <strong>in</strong> ambiente MATLAB® . Al suo <strong>in</strong>terno cipuò essere la chiamata a functions proprie <strong>di</strong> MATLAB® o a functions def<strong>in</strong>ite dall’utente;11


1. INTRODUZIONEG le functions (<strong>di</strong> MATLAB® o def<strong>in</strong>ite dall’utente), che possono avere uno o più variabili <strong>di</strong> <strong>in</strong>gresso(dati <strong>di</strong> <strong>in</strong>put) e una o più variabili <strong>in</strong> uscita (dati <strong>di</strong> output).Sia lo script sia le functions si scrivono su files chiamati M-files perché sono files che vanno salvaticon l’estensione .m (ad esempio prova.m, fun.m, . . . ). I files vanno scritti con l’e<strong>di</strong>tor <strong>di</strong> testo <strong>di</strong> MA-TLAB® (nella barra dei coman<strong>di</strong> <strong>di</strong> MATLAB® <strong>in</strong> alto a s<strong>in</strong>istra compare la scritta New Script o New) o conun altro e<strong>di</strong>tor <strong>di</strong> testo <strong>in</strong> formato ASCII (<strong>in</strong> <strong>Octave</strong> non c’è un e<strong>di</strong>tor e qu<strong>in</strong><strong>di</strong> i files vanno scritti con un altroe<strong>di</strong>tor <strong>di</strong> testo come ge<strong>di</strong>t, ad esempio).Per eseguire uno script salvato <strong>in</strong> nomefile.m basta scrivere il nome del programma (senza l’estensione.m) nella f<strong>in</strong>estra dei coman<strong>di</strong> o me<strong>di</strong>ante il comando run(’nomefile.m’) o run(’nomefile’)oppure posizionandosi con il mouse sul nome del programma nella lista che compare nella f<strong>in</strong>estra <strong>di</strong> CurrentFolder e con il tasto destro del moouse andare sulla scritta run che compare sulla f<strong>in</strong>estra che si apre (più<strong>di</strong>fficile a scriversi che a farsi!).Ovviamente, sia lo script sia le function def<strong>in</strong>ite dall’utente devono trovarsi nella <strong>di</strong>rectory <strong>in</strong> cui si èaperto MATLAB® , altrimenti bisogna spostarsi nella <strong>di</strong>rectory con i files che servono (da MATLAB® lo si fa<strong>di</strong>rettamente o tramite la Current Folder o utilizzando la riga che mostra la <strong>di</strong>rectory <strong>in</strong> cui ci si trova o con icoman<strong>di</strong> dell’ambiente L<strong>in</strong>ux, vale a <strong>di</strong>re cd e il percorso da fare, <strong>in</strong>vece, <strong>in</strong> <strong>Octave</strong>, ci si sposta <strong>di</strong> <strong>di</strong>rectorysolo con i coman<strong>di</strong> dell’ambiente L<strong>in</strong>ux).Per quanto riguarda le function, possono essere eseguite o tramite uno script oppure <strong>di</strong>rettamentenella f<strong>in</strong>estra dei coman<strong>di</strong>, specificando le variabili <strong>di</strong> <strong>in</strong>gresso e <strong>di</strong> uscita.1.5 Problemi e AlgoritmiGli script e functions che scriveremo ed eseguiremo <strong>in</strong> ambiente MATLAB® serviranno a risolveredei problemi.Cosa <strong>in</strong>ten<strong>di</strong>amo per problema? Se ve<strong>di</strong>amo all’etimologia del nome, esso deriva dal verbo grevo “proballe<strong>in</strong>”,dove pro significa davanti e balle<strong>in</strong> significa mettere: mettere davanti... problema ha il significato<strong>di</strong> ostacolo, promontorio, impe<strong>di</strong>mento. E <strong>di</strong>fatti, se si ha un problema, la prima cosa che si pensa è comerisolvere il problema (come superare l’ostacolo!).Per risolvere un problema, bisogna conoscerlo e saperlo descrivere bene. A questo scopo, noi ci serviamodel l<strong>in</strong>guaggio. Ma il l<strong>in</strong>guaggio naturale va usato con cautela: lo stesso evento è descritto, <strong>in</strong>fatti, <strong>in</strong> modo<strong>di</strong>verso da un bamb<strong>in</strong>o rispetto ad un adulto; e lo stesso evento viene descritto con un l<strong>in</strong>guaggio <strong>di</strong>verso daun matematico, da un fisico, da un <strong>in</strong>gegnere e da un letterato.Accanto al l<strong>in</strong>guaggio naturale c’è il l<strong>in</strong>guaggio artificiale, che si presenta sotto forma <strong>di</strong> term<strong>in</strong>i tecnici enotazioni (pensiamo a term<strong>in</strong>i tecnici della fisica e della chimica o ai simboli matematici).A volte, però, le stesse parole possono essere usate per <strong>di</strong>re cose completamente <strong>di</strong>verse! Basti pensarea term<strong>in</strong>i come temperatura, pressione, massa...: hanno significati ben <strong>di</strong>versi se usati <strong>in</strong> un’offic<strong>in</strong>a perriparare il motore <strong>di</strong> un’automobile o se usati <strong>in</strong> un ambulatorio me<strong>di</strong>co nei confronti <strong>di</strong> un paziente...Una volta che, cono attenzione e precisione, si è capito il problema, si può passare alla fase <strong>di</strong> soluzione.Concentrando ora la nostra attenzione su problemi da risolvere con l’aiuto del calcolatore, dobbiamo farecapire al calcolatore quale è il problema da risolvere e come lo deve risolvere. Ma siamo noi che dobbiamodare precise istruzioni da eseguire, qu<strong>in</strong><strong>di</strong> dobbiamo sapere quale tecnica <strong>di</strong> soluzione dobbiamo applicare.Queste precise istruzioni da dare al calcolatore rappresentano quello che chiamiamo algoritmo.Un algoritmo è una sequenza <strong>di</strong> passi che permettono <strong>di</strong> risolvere tutto o parte <strong>di</strong> un problema. 1Un algoritmo si può paragonare ad una ricetta <strong>di</strong> cuc<strong>in</strong>a. La ricetta è fatta <strong>di</strong> due partiG la lista degli <strong>in</strong>gre<strong>di</strong>enti da utilizzareG la sequenza dei passi da fare per realizzare la ricetta.1 La parola algoritmo è entrata <strong>in</strong> uso negli anni ’50 <strong>in</strong> sostituzione <strong>di</strong> algorismo, term<strong>in</strong>e con cui si <strong>in</strong><strong>di</strong>cava il processo <strong>di</strong> calcoloutilizzando i numeri arabi. Il term<strong>in</strong>e algoritmo deriva dal nome <strong>di</strong> “al-Khwarizmi”, importante matematico arabo del nono secolo grazieal quale l’Europa imparò ad usare i numeri arabi, oltre alla notazione <strong>in</strong> base 10. Le procedure che permettevano <strong>di</strong> effettuare calcoli <strong>in</strong>notazione decimale presero il nome <strong>di</strong> algorismi o algoritmi. Anche la parola algebra viene da questo matematico e, <strong>in</strong> particolare, dallasua opera “Al-mukhtasar fi hisab al-jabr wa al-muqabala”.Nel me<strong>di</strong>oevo (e forse anche per qualche studente <strong>di</strong> oggi!!!), si pensava che questa parola derivasse dal greco algiros (panico, dolore)e arithmos (numero).12


1.6. MATLAB® come l<strong>in</strong>guaggio <strong>di</strong> programmazioneNel realizzare una ricetta si possono avere problemi nel cercare alcuni <strong>in</strong>gre<strong>di</strong>enti. Una parte dell’esecuzionerichiederà poco tempo, altre parti richiederanno più tempo. Alcuni passi non richiedono che si segua uncerto or<strong>di</strong>ne, altri passi richiedono che si mantenga l’or<strong>di</strong>ne scritto sulla ricetta. . . Le stesse analogie troviamo<strong>in</strong> un algoritmo.1.6 MATLAB® come l<strong>in</strong>guaggio <strong>di</strong> programmazionePer imparare a usare MATLAB® come uno strumento <strong>di</strong> programmazione, dobbiamo imparare ad usareil l<strong>in</strong>guaggio che ci permetterà <strong>di</strong> scrivere script e function. E, come tutti i l<strong>in</strong>guaggi, dovremo impararealcune regole ben precise.Un l<strong>in</strong>guaggio <strong>di</strong> programmazione è costituito da <strong>di</strong>chiarazioni (statements):G descrizione dei dati: che genere <strong>di</strong> dati abbiamo? Se vogliamo scrivere un programma <strong>in</strong> cui perogni studente calcoliamo la me<strong>di</strong>a dei suoi voti, c’è <strong>di</strong>fferenza tra i nomi degli studenti (una str<strong>in</strong>ga<strong>di</strong> caratteri) e la loro me<strong>di</strong>a (un numero). Si parla <strong>di</strong> tipo <strong>di</strong> dati. In MATLAB® non si <strong>di</strong>chiarano levariabili, come avviene <strong>in</strong>vece per altri l<strong>in</strong>guaggi <strong>di</strong> alto livello. Ciò facilita la programmazione ma ponepiù rischi (se ci si <strong>di</strong>mentica il tipo <strong>di</strong> una variabile!). Conviene, perciò, prestare sempre attenzione altipo <strong>di</strong> variabili utlizzate.G strutture <strong>di</strong> controllo. Un programma può essere visto come una sequenza <strong>di</strong> istruzioni per risolvereun certo problema. Alcune istruzioni vanno ripetute, altre vanno eseguite solo <strong>in</strong> determ<strong>in</strong>atecon<strong>di</strong>zioni. . .G lavorazione dei dati (data process<strong>in</strong>g). In un programma occorre poter lavorare sui dati e poterli“manipolare” opportunamente.G <strong>di</strong>chiarazioni <strong>di</strong> <strong>in</strong>gresso e uscita (<strong>in</strong>put e output). In genere, un programma è scritto <strong>in</strong> modo che idati su cui si lavora possano esistere fuori del programma stesso.1.7 Primo script e prima function <strong>in</strong> MATLAB®Con un e<strong>di</strong>tor <strong>di</strong> testo scriviamo f<strong>in</strong>almente il nostro primo script. Uno script è un programma (unaserie <strong>di</strong> istruzioni) che si <strong>di</strong>fferenzia dai programmi scritti con altri l<strong>in</strong>guaggi <strong>di</strong> programmazione perchè nonsi devono <strong>di</strong>chiarare le variabili. Nel programma che scrivamo, <strong>in</strong>troduciamo due vettori ma non dobbiamousare istruzioni che <strong>di</strong>chiarano il tipo <strong>di</strong> variabili (vettori, s<strong>in</strong>gola o doppia precisione o variabile <strong>di</strong> tipo <strong>in</strong>tero,...).% questa e ’ una riga <strong>di</strong> commentox=[−1 , −0.5 , 0 , 0 . 5 , 1]y=s<strong>in</strong> ( x )<strong>di</strong>sp (’ho eseguito il mio primo script’) %<strong>di</strong>sp e ’ una function per la% visualizzazione% <strong>in</strong> questo caso la str<strong>in</strong>ga% ’ ho eseguito i l mio primo s c r i p t ’Già da questo primo script impariamo cose nuove. Intanto per eseguirlo, dopo averlo salvato, scriviamoil nome con cui abbiamo salvato il file (<strong>in</strong> questo caso scegliamo il nome primoscript.m) sulla CommandW<strong>in</strong>dow. Ve<strong>di</strong>amo cosa succede>> primoscriptx =-1.0000 -0.5000 0 0.5000 1.0000y =-0.8415 -0.4794 0 0.4794 0.841513


1.8. I pre<strong>di</strong>cati elementariistruzione, conviene mettere delle righe <strong>di</strong> commento per <strong>di</strong>re cosa fa questa function. Questo perchè, facendohelp nomefunction sulla Command W<strong>in</strong>dow, avremo <strong>di</strong>sponibili tutte le <strong>in</strong>formazioni che abbiamoscritto <strong>in</strong> quelle righe <strong>di</strong> commento e ci sarà utile per ricordare cosa fa quella determ<strong>in</strong>ata funzione.Una function term<strong>in</strong>a con l’istruzione end.Una volta salvata, la funzione può essere chiamata <strong>di</strong>rettamente nella Command W<strong>in</strong>dow, oppure all’<strong>in</strong>terno<strong>di</strong> uno script. Se scriviamo semplicemente y=mys<strong>in</strong>(x), la function restituisce solo il primo vettoreche viene generato. Se <strong>in</strong>vece scriviamo [y,b]=mys<strong>in</strong>(x), allora ci vengono restituiti i due vettori.Possiamo usare anche nomi <strong>di</strong>versi rispetto a y b.La function può essere richiamata anche all’<strong>in</strong>terno <strong>di</strong> uno script. Mo<strong>di</strong>fichiamo lo script primoscript<strong>in</strong> questo modo:% questa e ’ una riga <strong>di</strong> commentox=<strong>in</strong>put (’ scrivi il vettore x ’ ) ;[ y , b]=mys<strong>in</strong> ( x )<strong>di</strong>sp (’ho eseguito il mio secondo script’)Osserviamo che, <strong>in</strong> questo caso, non abbiamo messo il ; dopo la chiamata alla function, <strong>in</strong> modo davisualizzare subito il risultato.Dagli esempi che abbiamo visto, possiamo chiederci quando serve scrivere uno script piuttosto <strong>di</strong> unafunction. Ve<strong>di</strong>amo, <strong>in</strong>tanto, le pr<strong>in</strong>cipali <strong>di</strong>fferenze.G Le variabili usate all’<strong>in</strong>terno <strong>di</strong> uno script non vengono cancellate a meno che non venga fatto tramitela funzione clear. In una function tutte le variabili usate al suo <strong>in</strong>terno e che non compaiononella lista delle variabili <strong>di</strong> output vengono cancellate una volta che la function viene eseguita.G Una function può essere usata all’<strong>in</strong>terno <strong>di</strong> uno script, per snellirne la sua struttura (se determ<strong>in</strong>ateistruzioni vanno ripetute più e più volte, la function ci permette <strong>di</strong> scriverle una volta sola e <strong>di</strong>richiamarle con parametri <strong>di</strong> <strong>in</strong>put <strong>di</strong>versi). In tal caso, la function agisce da sottoprogramma.1.8 I pre<strong>di</strong>cati elementariLe istruzioni che traducono algoritmi <strong>di</strong> soluzione <strong>di</strong> problemi numerici non sono sempre istruzioni<strong>di</strong> tipo sequenziale, cioè istruzioni da eseguire l’una dopo l’altra (fai questo, poi questo, poi questo ancora...esempioponi a=10, b=s<strong>in</strong>(a), c=a*b...). Molte volte alcune istruzioni vanno eseguite se sonovere determ<strong>in</strong>ate con<strong>di</strong>zioni piuttosto che altre, o f<strong>in</strong>o a quando è vera una determ<strong>in</strong>ata con<strong>di</strong>zione...EsempioEsempio 1.8.1 Per calcolare le ra<strong>di</strong>ci <strong>di</strong> un’equazione <strong>di</strong> secondo grado, ax 2 + bx + c = 0 sappiamo chedobbiamo calcolare il <strong>di</strong>scrim<strong>in</strong>ante ∆ = b 4 − 4ac e se ∆ = 0 le due ra<strong>di</strong>ci co<strong>in</strong>cidono, se ∆ > 0 abbiamodue ra<strong>di</strong>ci <strong>di</strong>st<strong>in</strong>te, se <strong>in</strong>vece ∆ < 0 le due ra<strong>di</strong>ci non sono reali.Abbiamo una con<strong>di</strong>zione su ∆ e, a seconda della con<strong>di</strong>zione, facciamo una cosa piuttosto <strong>di</strong> un altra.I simboli =, >, < sono degli operatori logici. La proposizione ∆ < 0 può essere vera o falsa a seconda delvalore assunto dalla variabile ∆. Gli operatori logici, qu<strong>in</strong><strong>di</strong>, ci permettono <strong>di</strong> costruire dei pre<strong>di</strong>cati. Ve<strong>di</strong>amoquali sono gli operatori logici che useremo15


1. INTRODUZIONEOperatore Significato Esempio Valore> maggiore (a >b) Vero se a > bFalso se a ≤ b>= maggiore o uguale (a>=b) Vero se a ≥ bFalso se a < b< m<strong>in</strong>ore (a a=12;>> b=5;>> (a> (a==b)ans =0>> (a>=b)ans =1Il pre<strong>di</strong>cato è esso stesso una variabile (si osservi che il risultato è associato alla variabile ans): vale 1 se èvero, 0 se falso.Un operatore logico può essere applicato anche a matrici e vettori: se A e B sono due matrici, il pre<strong>di</strong>cato(A>B) restituisce una matrice i cui elementi sono il risultato del confronto tra ciascun elemento della matriceA con il corrispondente elemento della B.>> A=[1 2; 8 9]A =1 28 9>> B=[ 1 4; 5 10]B =1 45 1016


1.8. I pre<strong>di</strong>cati elementari>> A>=Bans =1 01 0In molti algoritmi, tuttavia, non basta vedere se un s<strong>in</strong>golo pre<strong>di</strong>cato sia vero o falso. A volte ci servonopiù pre<strong>di</strong>cati da mettere <strong>in</strong>sieme per formare una proposizione logica.EsempioEsempio 1.8.2 Supponiamo <strong>di</strong> dover implementare un algoritmo <strong>in</strong> cui vanno eseguite alcune istruzionif<strong>in</strong>tantochè è vero che (1) il numero <strong>di</strong> iterazioni, it, è m<strong>in</strong>ore <strong>di</strong> un numero massimo prefissato,itmax, e (2) il valore assoluto della <strong>di</strong>fferenza <strong>di</strong> due valori che sono generati dall’algoritmo (chiamiamoquesta quantità sc) è maggiore <strong>di</strong> una tolleranza prefissata, tol. Abbiamo una proposizione fatta<strong>di</strong> due pre<strong>di</strong>cati (it tol). I due pre<strong>di</strong>cati sono messi <strong>in</strong>sieme tramite la congiunzionee. F<strong>in</strong>tantochè è vera tutta la proposizione (qu<strong>in</strong><strong>di</strong> sono veri tutti e due i pre<strong>di</strong>cati) allora cisaranno da eseguire determ<strong>in</strong>ate istruzioni, altrimenti non si eseguiranno. Quando la proposizione nonè più vera? Diventa falsa quando il primo o il secondo pre<strong>di</strong>cato <strong>di</strong>ventano falsi, cioè quando le iterazioni<strong>di</strong>ventano maggiori del massimo prefissato oppure quando la variabile sc <strong>di</strong>venta m<strong>in</strong>ore dellatolleranza.Ve<strong>di</strong>amo allora gli operatori logici per unire due proposizioni:OperatoreSignificato&congiunzione <strong>di</strong> più pre<strong>di</strong>cati| <strong>di</strong>sgiunzione <strong>di</strong> più pre<strong>di</strong>cati∼ negazione <strong>di</strong> un pre<strong>di</strong>cato o <strong>di</strong> una proposizioneEsempioEsempio 1.8.3 Ripren<strong>di</strong>amo i pre<strong>di</strong>cati <strong>di</strong> prima it < itmax e sc > tol. La proposizione (ittol) è un proposizione che è vera quando entrambi i pre<strong>di</strong>cati sono veri,<strong>di</strong>venta falsa quando uno dei due pre<strong>di</strong>cati è falso.La proposizione (it tol) è vera quando uno dei due pre<strong>di</strong>cati è vero (può essereuno vero e uno falso, la proposizione è comunque vera perchè | significa o, oppure). La proposizioneè falsa quando entrambi i pre<strong>di</strong>cati sono falsi.La proposizione (it = itmax. Qu<strong>in</strong><strong>di</strong> è vera se it >= itmax e sarà falsa se it


1. INTRODUZIONE1.9 Strutture e cicliVe<strong>di</strong>amo, <strong>in</strong> generale, adesso come si possono eseguire alcuni tipi <strong>di</strong> istruzioni.1.9.1 Ciclo ifSupponiamo <strong>di</strong> voler calcolare la ra<strong>di</strong>ce quadrata positiva <strong>di</strong> un numero reale : + x. Sappiamo che sel’argomento x è negativo, la funzione non dà un valore reale (si passa <strong>in</strong>fatti nel campo dei numeri complessi:provare la function <strong>di</strong> MATLAB® sqrt con un numero negativo e vedere il risultato che dà). Proviamo alloraa scrivere una nostra function che calcoli la ra<strong>di</strong>ce quadrata solo per valori positivi dell’argomento.function [ y ]= mysqrt ( x )% function [ y ]= mysqrt ( x )% <strong>in</strong>put x% output y= s q r t ( x ) per x >=0% altrimenti s i ha un messaggio <strong>di</strong> e r r o r e% e y = [ ] v a r i a b i l e vuotai f ( x >=0)y=sqrt ( x ) ;else<strong>di</strong>sp (’l’’argomento e’’ negativo’)y = [ ] ;endAbbiamo usato il cosiddetto ciclo if. Se (if) (x>0) allora fai una determ<strong>in</strong>ata cosa, altrimenti (else)fai un’altra cosa. Osserviamo che per visualizzare una str<strong>in</strong>ga <strong>di</strong> caratteri <strong>in</strong> cui c’è l’apostrofo o l’accento,abbiamo usato due volte gli apici.Il ciclo if si può schematizzare nei seguenti mo<strong>di</strong> a seconda che si abbia una o più con<strong>di</strong>zione.Ciclo if con più con<strong>di</strong>zioniCiclo if con una con<strong>di</strong>zionei f ( espr . logica ){ istruzione 1a }{ istruzione 2a }{ . . . . }else{ istruzione 1b }{ istruzione 2b }{ . . . . }en<strong>di</strong> f ( espr . logica1 ){ istruzione 1a }{ istruzione 2a }{ . . . . }e l s e i f ( espr . logica2 ){ istruzione 1b }{ istruzione 2b }{ . . . . }. . . .else{ istruzione 1z }{ istruzione 2z }{ . . . . }endOsserviamo che <strong>in</strong> MATLAB® elseif va scritto tutto attaccato altrimenti si apre un altro ciclo if concatenatoal precedente.Se non c’è nessuna istruzione <strong>in</strong> alternativa alle con<strong>di</strong>zioni poste, si omette l’else.Scriviamo uno script che risolve un’equazione <strong>di</strong> secondo grado ax 2 + bx + c = 0. Usiamo un ciclo if percontrollare il segno del <strong>di</strong>scrim<strong>in</strong>ante ∆ = b 2 − 4ac e, <strong>di</strong> conseguenza, scrivere le ra<strong>di</strong>ci.a=<strong>in</strong>put (’valore <strong>di</strong> a ’ ) ;b=<strong>in</strong>put (’ valore <strong>di</strong> b ’ ) ;c=<strong>in</strong>put (’ valore <strong>di</strong> c ’ ) ;delta=sqrt (b^2 −4*a* c ) ;18


1.9. Strutture e ciclii f ( delta ==0)x1=−b/(2* a ) ;x2=x1 ;<strong>di</strong>sp (’le ra<strong>di</strong>ci sono co<strong>in</strong>cidenti’)<strong>di</strong>sp ( [ x1 x2 ] )e l s e i f ( delta >0)x1= (−b + delta ) / ( 2 * a ) ;x2= (−b − delta ) / ( 2 * a ) ;<strong>di</strong>sp (’le ra<strong>di</strong>ci sono’)<strong>di</strong>sp ( [ x1 x2 ] )else<strong>di</strong>sp (’non ci sono ra<strong>di</strong>ci reali’)endSalviamo lo script con il nome ra<strong>di</strong>ci.m. Per visualizzare su una sola riga il valore delle due ra<strong>di</strong>ci abbiamocreato il vettore che ha come componenti x1 e x2 e lo abbiamo visualizzato me<strong>di</strong>ante la function <strong>di</strong>sp.Osserviamo che, quando eseguiamo questo script, dobbiamo dare noi <strong>in</strong> <strong>in</strong>put i valori dei coefficienti dell’equaazione.Tutte le variabili che vengono generate nello script rimangono nella Workspace (a meno che nondeci<strong>di</strong>amo noi <strong>di</strong> cancellarle usando il comando clean). Per capire meglio la <strong>di</strong>fferenza tra script e function,scriviamo ora una function che fa la stessa cosa. Chiamiamo la function funra<strong>di</strong>cieq2.m.function [ x1 , x2 ]= funra<strong>di</strong>cieq2 ( a , b , c )% function [ x1 , x2 ]= ra<strong>di</strong>cieq2 ( a , b , c )% <strong>in</strong>put : a , b , c v a r i a b i l i s c a l a r i dell ’ equazione <strong>di</strong> secondo grado% ax^2+bx+c=0% output : x1 e x2 , l e due r a d i c i dell ’ equazionedelta=sqrt (b^2 −4*a* c ) ;i f delta ==0x1=−b/(2* a ) ;x2=x1 ;e l s e i f delta >0x1= (−b + delta ) / ( 2 * a ) ;x2= (−b − delta ) / ( 2 * a ) ;else<strong>di</strong>sp (’non ci sono ra<strong>di</strong>ci reali’)x1 = [ ] ;x2 = [ ] ;endendI coman<strong>di</strong> sono quasi gli stessi dello script. Per avere sempre dei valori <strong>in</strong> uscita, abbiamo posto x1, x2uguali a due variabili vuote (l’uso delle parentesi quadre senza nessun valore all’<strong>in</strong>terno []) <strong>in</strong>sieme ad unmessaggio <strong>di</strong> spiegazione, per <strong>di</strong>scrim<strong>in</strong>anti negativi. Questa volta possiamo eseguire la function all’<strong>in</strong>ternodella Command W<strong>in</strong>dow o me<strong>di</strong>ante uno script.>> [x1, x2]=funra<strong>di</strong>cieq2(1,-2,1)x1 =1x2 =1Tutte le variabili che sono usate all’<strong>in</strong>terno della function non sono salvate nella Workspace, ad eccezionedelle variabili <strong>di</strong> output.Sia nello script che nella function abbiamo visto un esempio <strong>di</strong> uso del ciclo if.19


1. INTRODUZIONEProviamo a complicare le cose, <strong>in</strong>serendo altri cicli if all’<strong>in</strong>terno del ciclo if.Nello stu<strong>di</strong>are la propagazione degli errori, abbiamo visto che, per effetto della cancellazione numerica,le due ra<strong>di</strong>ci <strong>di</strong> un’equazione <strong>di</strong> secondo grado possono non essere arrotondate correttamente se b 2 >> 4ac.In tal caso, applicando la formula x 1 x 2 = c possiamo evitare il fenomeno della cancellazione. Consideriamoadue casi, assumendo x 1 = −b + b 2 − 4ace x 2 = −b − b 2 − 4ac:2a2aG b > 0: per effetto della cancellazione numerica è x 1 affetta da errore. In tal caso dobbiamo correggerex 1 me<strong>di</strong>ante la formula x 1 = c/(x 2 a).G b < 0: ora è x 2 affetto da errore (−b è positivo e va sottratto ad una quantità molto vic<strong>in</strong>a a b stesso).Correggiamo x 2 me<strong>di</strong>ante la formula x 2 = c/(x 1 a).An<strong>di</strong>amo a correggere la function (stessa cosa si può fare con lo script precedente).function [ x1 , x2 ]= funra<strong>di</strong>cieq2nocanc ( a , b , c )% function [ x1 , x2 ]= ra<strong>di</strong>cieq2 ( a , b , c )% <strong>in</strong>put : a , b , c v a r i a b i l i s c a l a r i dell ’ equazione <strong>di</strong> secondo grado% ax^2+bx+c=0% output : x1 e x2 , l e due r a d i c i dell ’ equazione% s i usa la formula per e v i t a r e la cancellazione numericadelta=sqrt (b^2 −4*a* c ) ;i f delta ==0x1=−b/(2* a ) ;x2=x1 ;e l s e i f delta >0i f b> [x1, x2]=funra<strong>di</strong>cieq2(1,1e+6,0.1)x1 =-1.000007614493370e-07x2 =-9.999999999999000e+05>> x1*x2ans =20


1.9. Strutture e cicli0.100000761449327>> [x1, x2]=funra<strong>di</strong>ceeq2nocanc(1,1e+6,0.1)x1 =-1.000000000000100e-07x2 =-9.999999999999000e+05>> x1*x2ans =0.100000000000000L’errore sul prodotto x 1 x 2 è dell’or<strong>di</strong>ne <strong>di</strong> 7.6 · 10 −7 , ma l’errore sulla ra<strong>di</strong>ce x 1 è comunque un erroremolto basso. Ciò è dovuto al fatto che le nostre variabili sono tutte <strong>in</strong> doppia precisione e MATLAB® eseguele operazioni con precisione <strong>di</strong> macch<strong>in</strong>a.Se <strong>in</strong>seriamo i valori <strong>di</strong> a,b e c <strong>in</strong> s<strong>in</strong>gola precisione me<strong>di</strong>ante la function s<strong>in</strong>gle, si vede qualche<strong>di</strong>fferenza <strong>in</strong> più. Proviamo:>> a=s<strong>in</strong>gle(1);>> b=s<strong>in</strong>gle(1.e+6);>> c=s<strong>in</strong>gle(0.1);>> [x1, x2]=funra<strong>di</strong>cieq2(a,b,c)x1 =0x2 =-1000000>> x1*x2ans =0>> [x1, x2]=funra<strong>di</strong>cieq2nocanc(a,b,c)x1 =-1.0000000e-07x2 =-1000000>> x1*x221


1. INTRODUZIONEans =0.1000000In questo caso la prima function ci dà x 1 = 0 al posto <strong>di</strong> x 1 = −1 · 10 −7 . L’errore è più alto rispetto al casoprecedente ma non è così appariscente.Proviamo allora a creare una function che ci permetta <strong>di</strong> lavorare solo con un certo numero <strong>di</strong> cifre decimali,come se avessimo una macch<strong>in</strong>a <strong>in</strong> virgola mobile normalizzata a n cifre decimali, con n stabilitodall’utente (più piccolo è n, maggiore sarà il fenomeno <strong>di</strong> cancellazione numerica). Attenzione, però: leoperazioni che eseguiremo con MATLAB® saranno sempre eseguite <strong>in</strong> doppia precisione mentre il risultatodovrà essere convertito nella precisione che vogliamo noi.Per capire la function che scriveremo, partiamo con un esempio. Supponiamo <strong>di</strong> avere il numero x =−12.987654. Vogliamo rappresentare questo numero <strong>in</strong> una macch<strong>in</strong>a <strong>in</strong> virgola mobile normalizzata conn = 4 cifre decimali. Qu<strong>in</strong><strong>di</strong> passeremo al numero x = 1.2988 · 10 1 .L’algoritmo che implementeremo si basa sui seguenti passiG considero il numero <strong>in</strong> valore assoluto, cioè 12.987654;G valuto log 10 del numero: <strong>in</strong> questo caso ottengo il valore 1.113530710205556, che, se viene arrotondatoall’<strong>in</strong>tero più vic<strong>in</strong>o per <strong>di</strong>fetto, mi dà il valore 1, cioè proprio l’esponente della base (10 1 );G adesso <strong>di</strong>vido il valore assoluto del numero per 10 1 <strong>in</strong> modo da avere la parte frazionaria del numerostesso (eventualmente, come <strong>in</strong> questo caso, <strong>in</strong> forma normalizzata): 12.987654/10 1 = 1.2987654;G moltiplico questo valore per 10 n , dove n è il numero <strong>di</strong> cifre decimali che ho deciso <strong>di</strong> avere nellarappresentazione f<strong>in</strong>ale, <strong>in</strong> questo caso 4: ottengo 1.2987654e + 04 (cioè 12987.654)G arrotondo il valore all’<strong>in</strong>tero più vic<strong>in</strong>o: ho 12988;G <strong>di</strong>vido per 10 n : ricavo 1.2988;G ora prendo questo valore, lo moltiplico per il segno del numero <strong>di</strong> partenza e per 10 1 (l’esponenteche avevo trovato al secondo passo): arrivo al valore −12.988. Il numero non è espresso <strong>in</strong> formanormalizzata, ma <strong>in</strong> sostanza è il numero che andavo cercando (−12.988 = −1.2988 · 10 1 ).Per completare la function ci serve qualcosa che ci permetta <strong>di</strong> arrotondare all’<strong>in</strong>tero più vic<strong>in</strong>o per <strong>di</strong>fettoe <strong>di</strong> arrotondare all’<strong>in</strong>tero più vic<strong>in</strong>o. Fortunatamente, <strong>in</strong> MATLAB® , esistono già due function che fannoqueste cose:G la function floor arrotonda all’<strong>in</strong>tero più vic<strong>in</strong>o per <strong>di</strong>fetto;G la function round arrotonda all’<strong>in</strong>tero più vic<strong>in</strong>o con la regola dell’arrotondamento simmetrico.Queste function (come altre simili – ceil, fix – per la cui spiegazione riman<strong>di</strong>amo all’help on l<strong>in</strong>e)possono essere applicate a variabili matriciali (vettori e scalari vengono visti come casi particolari <strong>di</strong> matrici).>> floor(2.5)ans =2>> round(2.5)ans =3>> floor(1.1)ans =1>> round(1.1)22


1.9. Strutture e ciclians =1Per avere il segno <strong>di</strong> una variabile, usiamo la function sign (che vale +1 o -1 a seconda <strong>di</strong> segno positivoo negativo). Ecco allora la function, che chiamiamo roundnormfunction y=roundnorm( x , n)% function y=roundnorm( x , n)% <strong>in</strong>put x : puo ’ e s s e r e scalare , v e t t o r e o matrice% n : numero <strong>di</strong> c i f r e decimali <strong>in</strong> un sistema normalizzato% pensiamo i l numero s c r i t t o come a . b_1b_2b_3 . . . b_n x 10^p% con a ~= 0% output y : arrotondamento <strong>di</strong> x <strong>in</strong> un sistema normalizzato a n c i f r e decimali% <strong>di</strong> default , <strong>in</strong> MATLAB i l numero non viene v i s u a l i z z a t o <strong>in</strong> virgola% mobile normalizzata .%%% Esempi% x=s<strong>in</strong> (3)=0.141120008059867% n=4 % 4 c i f r e decimali% y=roundnorm( x , n)= 0.141120000000000% ( <strong>in</strong> virgola mobila normalizzata , y= 1.4112 10^(−1)%% x=exp(1)=2.718281828459046% y=roundnorm( x , n)= 2.718300000000000 (=2.7183 10^0)%% x=exp(10)=2.202646579480672 e+04% y=roundnorm( x , n)= 22026 (= 2.2026 10^4)%% s i possono avere c a s i p a r t i c o l a r i% x=55.981999999999999% <strong>in</strong> MATLAB y=roundnorm( x , n)= 55.981999999999999 (= 55.982)% <strong>in</strong> questo caso , i n f a t t i ,% f *10^e = 5.598200000000000*10=55.981999999999999% <strong>in</strong> <strong>Octave</strong> y=roundnorm( x , n)= 55.9820000000000xx = abs ( x ) ; % s i considera i l valore assoluto <strong>di</strong> xe = floor ( log10 ( xx ) ) ; %esponente <strong>di</strong> xf = xx . / 1 0 . ^ e ; %parte frazionaria <strong>di</strong> xf =round( f *10^n)/10^n ;y=sign ( x ) . * f .*10^ e ;endProviamo a vedere cosa succede se applichiamo questa function per risolvere un’equazione <strong>di</strong> secondogrado. Nelle due function precedenti sulla soluzione <strong>di</strong> un’equazione <strong>di</strong> secondo grado, dobbiamo andarea convertire le variabili delta, x1 e x2 applicando la function roundnorm: aggiungeremo delle istruzionidel tipo delta=roundnorm(delta,n); x1=roundnorm(x1,n); x2=roundnorm(x2,n);,23


1. INTRODUZIONEmentre l’<strong>in</strong>tero n viene dato <strong>in</strong> <strong>in</strong>put.<strong>Esercizi</strong>o 1.9.1 Come esercizio si cre<strong>in</strong>o, dunque, due nuove function, una che risolve l’equazione <strong>di</strong> secondogrado senza andare a considerare la correzione del fenomeno <strong>di</strong> cancellazione numerica e l’altra,<strong>in</strong>vece, che corregge la cancellazione numerica, <strong>in</strong> modo che, <strong>in</strong> <strong>in</strong>put, oltre ai parametri a,b,c vengachiamato anche l’<strong>in</strong>tero n. All’<strong>in</strong>terno delle function si aggiungano le istruzioni <strong>di</strong> chiamata alla functionroundnorm.Si trov<strong>in</strong>o, qu<strong>in</strong><strong>di</strong>, le ra<strong>di</strong>ci delle equazioniG 0.1x 2 − 42x + 0.3 = 0G x 2 − 56x + 1 = 0G x 2 − 18x + 0.03 = 0Si confront<strong>in</strong>o i risultati tra le due function, lavorando con n = 4 cifre decimali e utilizzando anche lefunction che lavorano <strong>in</strong> doppia precisione.1.9.2 Ciclo whileUn’altra struttura molto importante è data dal ciclo while. Ci possono essere situazioni <strong>in</strong> cui determ<strong>in</strong>ateistruzioni sono da ripetere f<strong>in</strong>tantochè è vera una determ<strong>in</strong>ata con<strong>di</strong>zione. Pren<strong>di</strong>amo <strong>in</strong> esame lo schema<strong>di</strong> bisezione: ad ogni passo del metodo si prende il punto me<strong>di</strong>o dell’<strong>in</strong>tervallo, si confronta il valore dellafunzione nel punto me<strong>di</strong>o con il valore agli estremi e si prende, come nuovo sotto<strong>in</strong>tervallo, l’<strong>in</strong>tervallo cheha come estremi il punto me<strong>di</strong>o e uno dei estremi dell’<strong>in</strong>tervallo precedente. Queste istruzioni vanno ripetutef<strong>in</strong>o a quando l’ampiezza dell’<strong>in</strong>tervallo su cui si lavora <strong>di</strong>venta molto piccola (m<strong>in</strong>ore <strong>di</strong> una certa tolleranzaprefissata) oppure siamo così fortunati che il punto me<strong>di</strong>o è proprio la ra<strong>di</strong>ce della funzione, oppure nonstiamo arrivando a convergenza ma abbiamo fatto un numero elevato <strong>di</strong> iterazioni.La struttura del cilclo while è fatta nel seguente modoCiclo whilewhile ( espressione logica ){ istruzione 1 }{ istruzione 2 }{ . . . }{ istruzione n }endLe istruzioni 1, 2, . . . , n vengono ripetute ciclicamente e non una sola volta come accade nel ciclo if: <strong>in</strong>fattiogni volta che si esegue l’ultima istruzione all’<strong>in</strong>terno del ciclo while, si torna poi all’espressione logica postasubito dopo la parola while e se è vera si eseguono <strong>di</strong> nuovo le istruzioni 1, 2, . . . , n, se è falsa, <strong>in</strong>vece, si escedal ciclo. È importante, dunque, avere un’espressione logica che eviti <strong>di</strong> creare cicli <strong>in</strong>f<strong>in</strong>iti, che farebberoentrare <strong>in</strong> stallo l’esecuzione <strong>di</strong> uno script o <strong>di</strong> una function!Ve<strong>di</strong>amo un esempio <strong>di</strong> ciclo while, scrivendo una function che implementa lo schema delle bisezioni.Vedendo questa function, impareremo nuove potenzialità <strong>di</strong> MATLAB® .function [ c , i t e r , scarto ]= funbisez ( fun , a , b , t o l l , itmax )% function [ c , i t e r , scarto ]= funbisez ( fun , a , b , t o l l , itmax )% function che calcola una ra<strong>di</strong>ce della funzione fun d e f i n i t a% nell ’ i n t e r v a l l o [ a , b ]% <strong>in</strong>put : function fun : puo ’ e s s e r e una function <strong>in</strong>l<strong>in</strong>e , una% function .m ( <strong>in</strong> questo caso i l nome della function% va s c r i t t o tra apici ) oppure una function_handle% estremi dell ’ i n t e r v a l l o a e b24


1.9. Strutture e cicli% tolleranza t o l l% numero massimo <strong>di</strong> i t e r a z i o n i itmax% output : approssimazione della ra<strong>di</strong>ce data dalla v a r i a b i l e c% numero <strong>di</strong> i t e r a z i o n i e f f e t t u a t e i t e r% scarto f i n a l e%% Esempi con i n l i n e function e handle function%% f = i n l i n e ( ’ 2 . * x−cos ( x ) + 1 ’ ) ;% a=−6; b=4; t o l l =1. e −10; itmax=100;% [ c , i t e r , scarto ]= funbisez ( f , a , b , t o l l , itmax )% r e s t i t u i s c e% c = −1.4552e−11% i t e r =36% scarto =7.2760e−11%% f = i n l i n e ( ’ x.^2− s<strong>in</strong> (3−x ) + 2 ’ ) ;% a=−2; b=1; t o l l =1. e −10; itmax=100;% [ c , i t e r , scarto ]= funbisez ( f , a , b , t o l l , itmax )% r e s t i t u i s c e% estremi d e l l o s t e s s o segno% c = [ ]% i t e r = [ ]% scarto = [ ]%%% a = 0 . ; b=3; t o l l =1. e −10; itmax=100;% [ c , i t e r , scarto ]= funbisez ( @cos , a , b , t o l l , itmax )% r e s t i t u i s c e% c =1.5708% i t e r =34% scarto =8.7311e−11%aux= f e v a l ( fun , a ) * f eval ( fun , b ) ; %aux= v a r i a b i l e d ’ appoggio per% c o n t r o l l a r e i l segno% della funzione a g l i estremi a e b%f e v a l e ’ una function che permette <strong>di</strong> valutare% i l valore della funzione fun nella v a r i a b i l e a% ( f e v a l ( fun , a ) ) oppure fun ( b ) <strong>in</strong> f e v a l ( fun , b ) )i f aux>=0<strong>di</strong>sp (’estremi dello stesso segno’)c =[ ] ;i t e r =[ ] ;scarto =[ ] ;return % l ’ i s t r u z i o n e return <strong>in</strong>terrompe l ’ esecuzione della function% se g l i estremi sono d e l l o s t e s s o segno non s i puo ’% applicare lo schema d e l l e b i s e z i o n ien<strong>di</strong> t e r =0; % i t e r e ’ la v a r i a b i l e <strong>in</strong>tera che conta l e i t e r a z i o n i che vengono% e f f e t t u a t ec =(a+b ) * 0 . 5 ;scarto=abs (b−a ) * 0 . 5 ; % v a r i a b i l e che permette <strong>di</strong> c o n t r o l l a r e <strong>di</strong> quanto c i% s i sta avvic<strong>in</strong>ando alla ra<strong>di</strong>cewhile i t e r t o l li t e r = i t e r +1;aux= f eval ( fun , a ) * f eval ( fun , c ) ;i f aux


1. INTRODUZIONEb=c ;elsea=c ;endc =(a+b ) * 0 . 5 ;scarto=abs (b−a ) * 0 . 5 ;en<strong>di</strong> f ( i t e r >itmax )<strong>di</strong>sp (’raggiunto il numero massimo <strong>di</strong> iterazioni’)endOltre all’uso del ciclo while (e <strong>di</strong> un ciclo if all’<strong>in</strong>terno del ciclo while), la novità nella function funbisez èdato dal fatto che, tra i parametri <strong>di</strong> <strong>in</strong>put, compare la funzione <strong>di</strong> cui si vuole approssimare una ra<strong>di</strong>ce. Inl<strong>in</strong>ea <strong>di</strong> massima il nostro schema può essere applicato su una generica funzione f (x) (funzione reale <strong>di</strong> unasola variabile reale), al f<strong>in</strong>e <strong>di</strong> poter approssimare (se esiste) una sua ra<strong>di</strong>ce. Possiamo scrivere la funzione delnostro problema utilizzando una function (qu<strong>in</strong><strong>di</strong> scrivere un file e salvarlo con l’estensione .m). Esempiofunction y=fun ( x )% function y=fun ( x )% function da usare nel metodo <strong>di</strong> b i s e z i o n i% function <strong>di</strong> esempioy =2.* x−cos ( x)+1endQuesta function la salviamo come fun.m e la chiamiano tra i parametri <strong>di</strong> <strong>in</strong>put della function funbiseztra apici [c, iter ,scarto]=funbisez(’fun’,a,b,toll,itmax) In tal modo, noi <strong>di</strong>amo il nome della function su cuiapplicheremo il metodo <strong>di</strong> bisezione. Potremmo chiamare la nostra function anche <strong>in</strong> modo <strong>di</strong>verso, nonfun.m ma, ad esempio, g.m: l’importante è mettere tra apici il nome della function. D’altra parte, non èimportante il nome dato alla variabile ma il significato <strong>di</strong> ciascuna variabile e l’or<strong>di</strong>ne con cui compare.È corretto chiamare la function <strong>in</strong> questo modo [x, it ,sc]=funbisez(’fprova’,extra,extrb,toller,maxit) Ciòsignifica che fprova.m è la function <strong>di</strong> cui vogliamo calcolare lo zero, extra e extrb sono gli estremidell’<strong>in</strong>tervallo, etc etc. Ogni variabile ha un nome <strong>di</strong>verso rispetto a quello che abbiamo scritto nella functionma il significato corrisponde.Non è corretto <strong>in</strong>vece scrivere [c, iter ,scarto]=funbisez(a,b,’fun’,toll,itmax) perchè ora abbiamo lavariabile a come prima variabile e non la funzione su cui applicare il metodo!Ci sono anche altri mo<strong>di</strong> per <strong>in</strong>serire una funzione tra i parametri <strong>di</strong> <strong>in</strong>gresso <strong>di</strong> una function. Se la funzioneè già predef<strong>in</strong>ita si può scrivere il nome della function tra apici: per esempio, vogliamo calcolare gli zeridella funzione f (x) = cos(x): basta scrivere [c, iter ,scarto]=funbisez(’cos’,a,b,toll,itmax)Se la funzione è più complicata si può usare la cosiddetta <strong>in</strong>l<strong>in</strong>e function. Sulla Command W<strong>in</strong>dow (oall’<strong>in</strong>terno <strong>di</strong> uno script che poi chiamerà la funbisez) scriviamo il seguente comando>> f=<strong>in</strong>l<strong>in</strong>e(’2.*x-cos(x)+1’)f =Inl<strong>in</strong>e function:f(x) = 2.*x-cos(x)+1La function <strong>di</strong> MATLAB® <strong>in</strong>l<strong>in</strong>e ci permette <strong>di</strong> creare una function che <strong>di</strong>pende da una o più variabili.Esempi:f=<strong>in</strong>l<strong>in</strong>e(’cos(x)-2’) (<strong>di</strong>pende da una sola variabile),f=<strong>in</strong>l<strong>in</strong>e(’cos(x)+s<strong>in</strong>(y)’) (<strong>di</strong>pende da due variabili).Rispetto alle function .m, questa function è caratterizzata da una sola istruzione (non possiamo costruirefunction che <strong>di</strong>pendono da cicli o da più righe <strong>di</strong> istruzioni). Una volta che chiu<strong>di</strong>amo la session <strong>di</strong>MATLAB® , per<strong>di</strong>amo questa function (se ci serve <strong>in</strong> un’altra sessione dovremo riscriverla).26


1.9. Strutture e cicliUn altro modo per passare una funzione tra i parametri <strong>di</strong> una function è <strong>di</strong> usare una cosiddetta functionhandle: una function handle si costruisce mettendo il simbolo @ prima del nome della function già def<strong>in</strong>ita(ad esempio @s<strong>in</strong>, @cos) oppure def<strong>in</strong>ita dall’utente come M-file (ad esempio @myfun). Esempi:[c, iter ,scarto]=funbisez(@cos,a,b,toll,itmax)[c, iter ,scarto]=funbisez(@myfun,a,b,toll,itmax) ,dove myfun.m è una function che abbiamo def<strong>in</strong>ito noi. In maniera equivalente, si può assegnare ad unavariabile il nome <strong>di</strong> una function handle nella Command W<strong>in</strong>dow o <strong>in</strong> uno script. Esempio:>> f=@funf =@fun>> [c,iter,scarto]=funbisez(f,a,b,toll,itmax);Ora che abbiamo visto che una funzione può essere chiamata tra i parametri <strong>di</strong> <strong>in</strong>put <strong>di</strong> una function,ve<strong>di</strong>amo come valutarla al suo <strong>in</strong>terno Nell’esempio che stiamo considerando, come valutare all’<strong>in</strong>terno dellafunbisez la funzione fun (che può essere un M-file, una function <strong>in</strong>l<strong>in</strong>e o una function handle)? Si usa laseguente istruzione (che possiamo leggere nella function funbisez) feval(fun,a) dove fun è il nome che <strong>di</strong>amoalla funzione all’<strong>in</strong>terno della function – nell’esempio, funbisez, mentre a è la variabile <strong>in</strong> cui dobbiamovalutare la fun. Qu<strong>in</strong><strong>di</strong> feval è una function <strong>di</strong> MATLAB® che permette <strong>di</strong> valutare il valore <strong>di</strong> una function:corrisponde a fun(a). Se la funzione è una funzione <strong>di</strong> più variabili, vanno messe tutte le variabili da cui<strong>di</strong>pende: feval(fun,x1,x2 ,...)<strong>Esercizi</strong>o 1.9.2 Si applichi il metodo <strong>di</strong> bisezione per trovare gli zeri <strong>di</strong> funzione delle seguenti funzioni,imponendo una tolleranza pari a 10 −10 e fissando itmax=100:G f (x) = ln(x) + x 2 − x (ammette come ra<strong>di</strong>ce ξ = 1)G f (x) = e 1−x2 − x s<strong>in</strong>(x) (ammette più <strong>di</strong> una ra<strong>di</strong>ce)Se risolviamo l’esercizio precedente, ci accorgiamo che non è sempre facile trovare un <strong>in</strong>tervallo <strong>in</strong> cui lafunzione assegnata abbia segno opposto agli estremi. È utile qu<strong>in</strong><strong>di</strong> avere un’idea del grafico della funzionestessa. In questo senso MATLAB® ci permette <strong>di</strong> visualizzare facilmente una funzione tramite la functionezplot. La function ezplot può avere uno o più argomenti <strong>di</strong> <strong>in</strong>put. Si può dare solo la funzione (<strong>in</strong>l<strong>in</strong>e,m-file o function handle) da visualizzare, e il grafico viene fatto <strong>di</strong> default per x che varia <strong>in</strong> [−6,6] (se èdef<strong>in</strong>ita per valori negativi) o <strong>in</strong> [0,6] se non è def<strong>in</strong>ita per valori negativi. Possiamo cambiare gli estremidell’<strong>in</strong>tervallo, aggiungendo come variabile l’<strong>in</strong>tervallo stesso.Esempiezplot(f) %f e’ una function <strong>in</strong>l<strong>in</strong>e o una function handleezplot(’f’) %f e’ una function M−file def<strong>in</strong>ita dall’utente o <strong>di</strong> MATLABezplot(f ,[ a,b]) %si visualizza il grafico della f per x <strong>in</strong> [a,b]Per visualizzare tutte gli usi della function ezplot si controlli me<strong>di</strong>ante l’help sulla Commans W<strong>in</strong>dow.Del tutto simile a ezplot è la function fplot <strong>in</strong> cui, tuttavia, va specificato l’<strong>in</strong>tervallo [a,b]. Vedremo,comunque, che ci sono altri mo<strong>di</strong> per fare grafici.Ora, seguendo le stesse l<strong>in</strong>ee della function funbisez, scriviamo una function che applichi lo schema delpunto fisso. Chiamiamo questa function pfisso0.m (capiremo poi perché abbiamo scritto quello zero nelnome della function).Questa volta, per vedere se ci stiamo avvic<strong>in</strong>ando a convergenza, controlliamo la <strong>di</strong>fferenza <strong>in</strong> valoreassoluto tra due approssimazioni successive. Qu<strong>in</strong><strong>di</strong>, la variabile scarto assume davvero il significato delnome (al contrario <strong>di</strong> quanto abbiamo fatto <strong>in</strong> funbisez). Nella function <strong>di</strong>amo anche una stima del fattore<strong>di</strong> convergenza (o costante as<strong>in</strong>totica <strong>di</strong> convergenza) M tramite le variabili as<strong>in</strong>t1 e as<strong>in</strong>t2. Ve<strong>di</strong>amoquesta function27


1. INTRODUZIONEfunction [ xkp1 , i t e r , scartokp1 , as<strong>in</strong>t1 , as<strong>in</strong>t2 ]= pfisso0 ( fun , dfun , x0 , t o l l , itmax )%function [ xkp1 , i t e r , scartokp1 , as<strong>in</strong>t1 , as<strong>in</strong>t2 ]= p f i s s o 0 ( fun , dfun , x0 , t o l l , itmax )% s i g n i f i c a t o d e l l e v a r i a b i l i% i t e r : i t e r a z i o n e del metodo del punto f i s s o% itmax : numero massimo <strong>di</strong> i t e r a z i o n i% t o l l : tolleranza p r e f i s s a t a per l ’ approssimazione del punto f i s s o% x0 : punto i n i z i a l e della successione% xk : approssimazione al passo k% xkp1 : approssimazione al passo k+1% scartok : scarto all ’ i t e r a t a precedente% scartokp1 : valore assoluto tra l ’ i t e r a t a corrente e quella al% passo precedente% as<strong>in</strong>t1 : scartokp1 / scartok − approsimazione del f a t t o r e <strong>di</strong> convergenza M% as<strong>in</strong>t2 : abs ( dfun ( xkp1 ) ) − approssimazione del f a t t o r e <strong>di</strong> convergenza M% fun : funzione <strong>di</strong> cui s i vuole c a l c o l a r e un ’ approssimazione del punto f i s s o% dfun : derivata della funzione fun%% Esempio% x0 = 0 . 1 ; t o l l =1. e −12; itmax=100;% dfun= i n l i n e ( ’ − s<strong>in</strong> ( x ) ’ ) ;% [ xkp1 , i t e r , scartokp1 , as<strong>in</strong>t1 , as<strong>in</strong>t2 ]= p f i s s o 0 ( @cos , dfun , x0 , t o l l , itmax )% r e s t i t u i s c e% xkp1=0.7391% i t e r =70% scartokp1 =9.4613e−13% as<strong>in</strong>t1= 0.6735% as<strong>in</strong>t2 =0.6736scartokp1 =2.0* t o l l ;scartok=scartokp1 ;i t e r = 0 ;xk=x0 ;while ( scartokp1 >= t o l l )&& ( i t e r itmax )<strong>di</strong>sp (’raggiunto il numero massimo <strong>di</strong> iterazioni’)endendCon questa function implementiamo il metodo del punto fisso e conosciamo l’approssimazione f<strong>in</strong>ale delpunto fisso, il numero <strong>di</strong> iterazioni effettuate, lo scarto f<strong>in</strong>ale, una stima della costante as<strong>in</strong>totica. Con questafunction, tuttavia, non possiamo fare nessun grafico <strong>di</strong> convergenza perchè per<strong>di</strong>amo tutte le <strong>in</strong>formazioni<strong>in</strong>terme<strong>di</strong>e (i valori delle approssimazioni, degli scarti, etc, ad ogni iterazione). In effetti, per alcune variabilipossiamo farci stampare su un file il loro valore <strong>in</strong> modo da sapere cosa è successo ad ogni passo <strong>di</strong> iterazione.Per altre, <strong>in</strong>vece, è utile metterle <strong>in</strong> un grafico.Esam<strong>in</strong>iamo ciascuna variabile:G i valori x0,xk,xkp1 rappresentano i valori dell’approssimazione <strong>in</strong>iziale al passo 0, al passo precedenteiter e al nuovo passo <strong>di</strong> iterazione iter+1. Questi valori ci servono per calcolare lo scarto adogni iterazione e per approssimare il fattore <strong>di</strong> convergenza tramite la variabile as<strong>in</strong>t2. Potremmo solostampare questi valori ad ogni passo oppure salvarceli <strong>in</strong> un vettore (e calcolare la variabile as<strong>in</strong>t228


1.9. Strutture e ciclicome vettore applicando il valore assoluto della derivata della funzione <strong>di</strong> punto fisso al vettore delleapprossimazioni).G gli scarti scartok e scartokp1 servono per calcolare as<strong>in</strong>t1 ma soprattutto se vogliamo fare ungrafico <strong>di</strong> convergenza! Qu<strong>in</strong><strong>di</strong> ci servono i valori degli scarti ad ogni iterazione. Possiamo creareun vettore <strong>in</strong> cui la componente i -sima corrisponde allo scarto al passo i . In tal modo potremo siacalcolare as<strong>in</strong>t1 <strong>in</strong> modo vettoriale, sia fare un grafico semilogaritmico <strong>di</strong> convergenza.G la variabile iter è un contatore scalare. Quando occorre, creeremo il vettore che ha come componentigli <strong>in</strong>teri 1,2,...,i ter dove i ter rappresenterà il numero f<strong>in</strong>ale delle iterazioni effettuate.Mo<strong>di</strong>fichiamo qu<strong>in</strong><strong>di</strong> la function lavorando su vettori (la possibilità <strong>di</strong> scrivere alcuni risultati su file lalasciamo per il seguito). Scriviamo il seguente file pfisso.m.function [ x , i t e r , scarto , as<strong>in</strong>t1 , as<strong>in</strong>t2 ]= pfisso ( fun , dfun , x0 , t o l l , itmax )%function [ x , i t e r , scarto , as<strong>in</strong>t1 , as<strong>in</strong>t2 ]= p f i s s o ( fun , dfun , x0 , t o l l , itmax )% s i g n i f i c a t o d e l l e v a r i a b i l i% i t e r : i t e r a z i o n e del metodo del punto f i s s o% itmax : numero massimo <strong>di</strong> i t e r a z i o n i% t o l l : tolleranza p r e f i s s a t a per l ’ approssimazione del punto f i s s o% x0 : punto i n i z i a l e della successione% x : v e t t o r e d e l l e approssimazioni del punto f i s s o% scarto : v e t t o r e d e g l i s c a r t i% as<strong>in</strong>t1 : v e t t o r e che approssimazione i l f a t t o r e <strong>di</strong> convergenza M usando% i l v e t t o r e d e g l i s c a r t i% as<strong>in</strong>t2 : v e t t o r e che approssima i l f a t t o r e <strong>di</strong> convergenza M usando% i l valore assoluto della derivata prima della funzione <strong>di</strong> punto% f i s s o% fun : funzione <strong>di</strong> cui s i vuole c a l c o l a r e un ’ approssimazione del punto f i s s o% dfun : derivata della funzione fun% Esempio% x0 = 0 . 1 ; t o l l =1. e −12; itmax=100;% dfun= i n l i n e ( ’ − s<strong>in</strong> ( x ) ’ ) ;% [ x , i t e r , scarto , as<strong>in</strong>t1 , as<strong>in</strong>t2 ]= p f i s s o ( @cos , dfun , x0 , t o l l , itmax )% r e s t i t u i s c e% i l v e t t o r e x <strong>di</strong> lunghezza 70% i t e r =70% i l v e t t o r e scarto% i l v e t t o r e as<strong>in</strong>t1% i l v e t t o r e as<strong>in</strong>t2% per f a r e i l g r a f i c o <strong>di</strong> convergenza semilogaritmico basta s c r i v e r e% semilogy ( [ 1 : 1 : i t e r ] , scarto )scarto =2* t o l l ;i t e r = 1 ;x=x0 ;while ( scarto ( i t e r )>= t o l l )&& ( i t e r itmax )<strong>di</strong>sp (’raggiunto il numero massimo <strong>di</strong> iterazioni’)end29


1. INTRODUZIONEendOsserviamo <strong>in</strong> che modo abbiamo creato i due vettori as<strong>in</strong>t1 e as<strong>in</strong>t2.Per il vettore as<strong>in</strong>t1 la generica componente i -sima deve essere uguale ascar to i. Supponiamoscar to i−1che il vettore scarto abbia queste componenti: scarto=[ 2 0.90 0.45 0.31 0.20 0.14] dovescarto(1) corrisponde al valore che si ha all’iterazione 0 (il valore che, nella function, abbiamo postouguale a 2*tol <strong>in</strong> modo da poter entrare nel ciclo while). Per approssimare il fattore <strong>di</strong> convergenza al primopasso <strong>di</strong> iterazione dobbiamo fare il rapporto tra lo scarto all’iterazione 1 e lo scarto all’iterazione 0, cioè0.90. Alla seconda iterazione dobbiamo fare il rapporto tra lo scarto corrente e lo scarto al passo precedente,2cioè 0.45 e così via. Nel vettore scarto abbiamo 6 componenti, la prima corrisponde all’iterazione 0, ciò vuol0.90<strong>di</strong>re che sono state effettuate 5 iterazioni. Dobbiamo fare dunque 5 rapporti per approssimare il fattore <strong>di</strong>convergenza ad ogni iterazione:0.902 , 0.450.90 , 0.310.45 , 0.200.31 , 0.140.20 .A tal f<strong>in</strong>e costruiamo il vettore (a cui ora per como<strong>di</strong>tà <strong>di</strong>amo il nome sc1) che ha come componentiquelle del vettore scarto dalla seconda componente <strong>in</strong> poi, cioè sc1=[0.90 0.45 0.31 0.200.14]. Costruiamo poi il vettore (che chiamiamo sc2) che ha come componenti quelle del vettore scartodalla prima alla penultima componente, vale a <strong>di</strong>re sc2=[2 0.90 0.45 0.31 0.20]. Ora, se <strong>di</strong>vi<strong>di</strong>amoi due vettori sc1 componente per componente, abbiamo proprio i rapporti che abbiamo scrittoprima. Questa operazione si può fare senza dover <strong>in</strong>trodurre nuovi vettori. Possiamo scrivere, <strong>in</strong>fatti,sc2as<strong>in</strong>t1= scarto(2:iter )./scarto(1:iter−1);Per quanto riguarda as<strong>in</strong>t2, abbiamo semplicemente valutato la funzione dfun nel vettore delleapprossimazioni x.Poi, poichè la prima componente che abbiamo dato al vettore scarto non ci <strong>in</strong>teressa, la togliamoandando ad aggiornare il vettore scarto=scarto(2:iter);Questa istruzione ci permette <strong>di</strong> prendere il vettore che ha come componenti quelle del vettore scartodalla seconda componente <strong>in</strong> poi e <strong>di</strong> chiamare questo vettore <strong>di</strong> nuovo con la stessa variabile.Inf<strong>in</strong>e, aggiorniamo il numero delle iterazioni, togliendo un’unità perchè eravamo partiti dal contatoredelle iterazioni pari a uno <strong>in</strong> corrispondenza dell’iterazione 0.A questo punto, <strong>in</strong> uscita abbiamo dei vettori.Per fare il grafico <strong>di</strong> convergenza dello schema, ci serve fare un grafico semilogaritmico dove, sull’assedelle ascisse ci sono le iterazioni effettuate e sull’asse delle or<strong>di</strong>nate i logaritmi (<strong>in</strong> base 10) degli scarti.La function <strong>di</strong> MATLAB® che ci permette <strong>di</strong> fare grafici <strong>in</strong> scala semilogaritmica sull’asse delle or<strong>di</strong>nateprende il nome <strong>di</strong> semilogy. Nel nostro caso, basta creare il vettore delle or<strong>di</strong>nate, che deve avere i valori1, 2, 3,...,i ter e applicare questa function. Per creare un vettore che parte dal valore 1 e arriva al valore itercon passo unitario, basta scrivere it =[1:1: iter ];Perciò possiamo usare il comando semilogy(it, scarto), oppure, <strong>in</strong> modo equivalente,semilogy([1:1:iter], scarto) (si veda figura 1.6).Introduzione alla graficaAbbiamo visto le function ezplot, fplot, semilogy. Ve<strong>di</strong>amo ora le altre function <strong>di</strong> base perpoter fare un grafico. Abbiamo semilogx (analogo <strong>di</strong> semilogy, il grafico è semilogaritmico sull’assedelle ascisse), loglog (il grafico è <strong>in</strong> scala logaritmica su entrambi gli assi) e <strong>in</strong>f<strong>in</strong>e plot.Le function plot, semilogx, semiloy e loglog hanno le stesse caratteristiche. Ve<strong>di</strong>amo qu<strong>in</strong><strong>di</strong>gli elementi pr<strong>in</strong>cipali <strong>di</strong> come si usa la function plot. In maniera analoga si usano le altre function cheabbiamo detto.plot(x,y) dove x e y sono dei vettori della stessa <strong>di</strong>mensione, produce il grafico <strong>in</strong> cui sull’asse delle ascissec’è il vettore x e sull’asse delle or<strong>di</strong>nate il vettore y.Esempio:30


1.9. Strutture e cicliFigura 1.6: Grafico generato dall’istruzione semilogy(it, scarto). per lo schema <strong>di</strong> punto fisso applicato allafunzione <strong>di</strong> punto fisso g (x) = cos(x), con x 0 = 0.1.>> x=[0, 0.1 , 0.2, 0.3, 0.4, 0.5];>> y=s<strong>in</strong>(x);>> plot(x,y)I coman<strong>di</strong> precedenti producono il grafico <strong>di</strong> figura 1.7Si può anche usare semplicemente l’istruzione plot(y) che produce il grafico del vettore <strong>in</strong> funzione degli<strong>in</strong><strong>di</strong>ci delle componenti del vettore (qu<strong>in</strong><strong>di</strong> sull’asse delle ascisse ci saranno gli <strong>in</strong><strong>di</strong>ci 1,2,...,n del vettore ymentre sull’asse delle or<strong>di</strong>nate le componenti del vettore y – <strong>di</strong> lunghezza n).Si possono fare più grafici sovrapposti <strong>in</strong> <strong>di</strong>versi mo<strong>di</strong>. Uno <strong>di</strong> questi è <strong>di</strong> avere più coppie <strong>di</strong> vettorix1,y1, x2, y2 e così via e scrivere l’istruzione plot(x1,y1,x2,y2, ...) Un altro modo è <strong>di</strong> sovrascriverei grafici l’uno sull’altro me<strong>di</strong>ante il comando hold on Abb<strong>in</strong>ato è poi il comando hold off che chiude ilprocesso.Ve<strong>di</strong>amo degli esempi>> x1=[0, 0.1 , 0.2, 0.3, 0.4, 0.5];>> y1=s<strong>in</strong>(x1);>> x2=[-0.5, -0.2 0.2 0.5];>> y2=cos(x2);>> plot(x1,y1,x2,y2)Si faccia poi>> plot(x1,y1) % il grafico precedente non c’e’ piu’ ma si crea questo>> hold on>> plot(x2,y2)>> hold offPer esercizio si prov<strong>in</strong>o i coman<strong>di</strong> precedenti. La figura generata nel primo caso mostra le due curve <strong>di</strong>colore <strong>di</strong>verso, mentre nel secondo caso le curve hanno lo stesso colore.31


1. INTRODUZIONEFigura 1.7:y=s<strong>in</strong>(x).Esempio <strong>di</strong> uso della function plot con x=[0, 0.1 , 0.2, 0.3, 0.4, 0.5] ePer cambiare colore e tipo <strong>di</strong> l<strong>in</strong>ea della curva, oppure fare un grafico per punti, si possono fare le mo<strong>di</strong>fiche<strong>di</strong>rettamente dal menu che si presenta sulla f<strong>in</strong>estra del grafico oppure tramite coman<strong>di</strong> <strong>in</strong> l<strong>in</strong>ea.Ve<strong>di</strong>amo questi ultimi (comuni ad <strong>Octave</strong>).L’istruzione plot(x1,y1,s1,x2,y2,s2, ...) dove s1, s2, ... sono delle str<strong>in</strong>ghe <strong>di</strong> caratteri (da scriveretra apici, qu<strong>in</strong><strong>di</strong>) permette <strong>di</strong> cambiare colore, l<strong>in</strong>ea o punto della curva.Esempi: plot(x,y,’g:’) produce il grafico <strong>in</strong> cui la curva è <strong>di</strong> colore verde (green) e la curva è a punt<strong>in</strong>i.plot(x,y,’r-.’) dà come risultato una curva <strong>di</strong> colore rosso con l<strong>in</strong>ea fatta a tratteggio del tipo ’-.-.-.’.plot(x,y,’yo’) produce una curva dove i punti non sono legati tra loro me<strong>di</strong>ante una l<strong>in</strong>ea ma è per punti,ciascuno dei quali ha la forma <strong>di</strong> un cerchietto (’o’) mentre il colore è giallo (yellow)plot(x,y,’c--*’) comb<strong>in</strong>a la l<strong>in</strong>ea <strong>di</strong> tipo tratteggio ’–’ con i punti a forma <strong>di</strong> asterisco ’*’ mentre il colore è ilceleste (cyan). Per vedere tutti i colori, punti e l<strong>in</strong>ee a <strong>di</strong>sposizione basta fare help plot dalla CommandW<strong>in</strong>dow.Altri coman<strong>di</strong> utili sonoG <strong>in</strong>serire un titolo al grafico, me<strong>di</strong>ante la function title.Esempio: title (’grafico <strong>di</strong> prova’)G <strong>in</strong>serire una descrizione sull’asse delle x (e delle y) me<strong>di</strong>ante la function xlabel (ylabel).Esempio: xlabel(’iterazioni’), ylabel(’scarti’);G Inserire una legenda me<strong>di</strong>ante la function legend.Esempio: abbiamo fatto un grafico con l’istruzione plot(x,y1,x,y2) dove y1 corrisponde aduna certa funzione f mentre y2 corrisponde ad una certa funzione g . Con l’istruzionelegend(’funz f’, ’funz g’) sul grafico compare la legenda che abbiamo scritto unita al tipo <strong>di</strong> l<strong>in</strong>eao punti associati a quel vettore.G <strong>in</strong>serire una griglia <strong>di</strong> fondo al grafico o toglierla, me<strong>di</strong>ante il comando gridEsempio: grid on <strong>in</strong>troduce l<strong>in</strong>ee <strong>di</strong> griglia; grid off le toglie.Per ciaascuno <strong>di</strong> queste function fare delle prove e controllare l’help <strong>in</strong> l<strong>in</strong>ea.Negli esempi fatti, tuttavia, abbiamo creato dei vettori <strong>di</strong> lunghezza molto ridotta. Se avevamo <strong>in</strong> mente<strong>di</strong> fare il grafico della funzione s<strong>in</strong>(x) o cos(x), il risultato che abbiamo avuto è stato molto povero perchè32


1.9. Strutture e cicliavevamo pochi punti a <strong>di</strong>sposizione. Potevamo certamente usare le function ezplot o fplot per questoscopo, ma poiché stiamo imparando ad usare MATLAB® ci conviene prendere spunto da questa occasioneper imparare qualcosa <strong>in</strong> più sui vettori.Nel fare il grafico semilogaritmico, abbiamo visto un modo per creare un vettore, me<strong>di</strong>ante l’istruzione[1:1: iter ].L’istruzione x=[x0: <strong>in</strong>cr: xf] produce un vettore che ha come valore <strong>in</strong>iziale x0 e come valore f<strong>in</strong>ale xfe le altre componenti sono date a partire da x0 con <strong>in</strong>cremento dato dal valore <strong>in</strong>cr: x0, x0+<strong>in</strong>cr,x0+2<strong>in</strong>cr, ...., xf. Con questa istruzione possiamo creare dei vettori che hanno molte componentisenza doverle scrivere a mano. Per vedere la lunghezza del vettore, basta scrivere il comando size(x) (chepuó essere applicato anche a matrici) : restituisce il numero <strong>di</strong> righe e <strong>di</strong> colonne della variabile x. Si puòanche usare l’istruzione length(x) che restituisce, <strong>in</strong>vece, la lunghezza del vettore.>> x=[0:0.1:1]x =Columns 1 through 60 0.1000 0.2000 0.3000 0.4000 0.5000Columns 7 through 110.6000 0.7000 0.8000 0.9000 1.0000>> size(x)ans =1 11>> length(x)ans =11Un altro modo <strong>di</strong> creare vettori è dato dalla function l<strong>in</strong>space, il cui uso è il seguente: x=l<strong>in</strong>space(a,b);crea, <strong>di</strong> default, un vettore (<strong>in</strong> questo caso x) che ha 100 componenti,con valori equi<strong>di</strong>stanti a partire da aper f<strong>in</strong>ire a b: qu<strong>in</strong><strong>di</strong> il vettore ha come prima componente a, poi a + (b-a)/99, ..., f<strong>in</strong>o ad arrivare allacentesima componente che vale b. Si applica la formula x i = x 1 + (i − 1)h, per i = 2,3,...,100 , dove x 1 = a eh = b − a99 (<strong>in</strong> tal modo: x 2 = x 1 + h; x 3 = x 1 + 2h = x 2 + h, f<strong>in</strong>o ad arrivare a x 100 = x 1 + 99h = a + (b − a) = b.Se vogliamo un vettore con un certo numero n <strong>di</strong> punti equi<strong>di</strong>stanti tra a e b, si scrive l’istruzionex=l<strong>in</strong>space(a,b,n);A questo punto, ve<strong>di</strong>amo anche un altro modo per creare dei vettori, utilizzando un ciclo che nonabbiamo visto f<strong>in</strong>o ad ora, e che prende il nome <strong>di</strong> ciclo for.1.9.3 Ciclo forIl ciclo for è strutturato nel modo seguente33


1. INTRODUZIONECiclo forfor <strong>in</strong>d= v a l i n i z : <strong>in</strong>cr : v a l f i n{ i s t r u z i o n i }endUn esempio <strong>di</strong> ciclo for per creare un vettore <strong>di</strong> 11 elementi con componenti equi<strong>di</strong>stanti tra 0 e 1 puòessere il seguentex ( 1 ) = 0 ;for i =2:11x ( i )= x ( i −1)+0.1;endOsserviamo che usare un ciclo for per creare vettori non è conveniente nè ottimale. Questo non vuol <strong>di</strong>reche non lo useremo mai e che possiamo <strong>di</strong>menticarci che esiste! Dobbiamo solo prestare molta attenzionequando lo usiamo e usarlo solo quando effettivamente serve!!!!Ve<strong>di</strong>amo un esempio, <strong>in</strong> cui misuriamo il tempo che impiega MATLAB® per creare un vettore <strong>di</strong> lunghezzan con n grande, usando la forma compatta x=[x0:<strong>in</strong>cr:xn], la function l<strong>in</strong>space e il ciclofor.Per misurare il tempo che impiega ciascuno proce<strong>di</strong>mento, applichiamo due functions <strong>di</strong> MATLAB® tice toc che sono da usare comb<strong>in</strong>ate <strong>in</strong>sieme perché permettono <strong>di</strong> misurare il tempo per effettuare leistruzioni che si trovano nel mezzo.Scriviamo uno script allo scopo <strong>di</strong> creare un vettore x <strong>di</strong> lunghezza n=100001 tra a=0 e a=1 applicando1i <strong>di</strong>versi approcci che abbiamo visto. La <strong>di</strong>stanza tra due componenti del vettore è data da h =100000 = 10−5 .cleart i cx = [ 0 : 1 . e − 5 : 1 ] ;toc<strong>di</strong>sp (’lunghezza vettore’)<strong>di</strong>sp ( length ( x ) )clear xt i cx=l<strong>in</strong>space (0 ,1 ,100001);toc<strong>di</strong>sp (’lunghezza vettore’)<strong>di</strong>sp ( length ( x ) )clear xt i cx ( 1 ) = 0 ;for i =2:100001x ( i )= x ( i −1)+1.e−5;endtoc<strong>di</strong>sp (’lunghezza vettore’)<strong>di</strong>sp ( length ( x ) )Eseguiamo questo script (salviamolo prima dandogli un nome con l’estesione .m,confrontotictoc.m). In MATLAB® otteniamo>> confrontotictocElapsed time is 0.000631 seconds.lunghezza vettore100001<strong>in</strong> questo caso34


1.9. Strutture e cicliElapsed time is 0.003618 seconds.lunghezza vettore100001Elapsed time is 0.058935 seconds.lunghezza vettore100001Ve<strong>di</strong>amo cosa succede <strong>in</strong> ambiente <strong>Octave</strong>:octave:3> confrontotictocElapsed time is 2.90871e-05 seconds.lunghezza vettore100001Elapsed time is 0.001910925 seconds.lunghezza vettore100001Elapsed time is 1.404992 seconds.lunghezza vettore100001Come possiamo osservare dai risultati, il primo approccio per scrivere i vettori è quello che vadecisamente meglio.1.9.4 Introduzione a file <strong>di</strong> scrittura datiRipren<strong>di</strong>amo a stu<strong>di</strong>are lo schema <strong>di</strong> punto fisso e i risultati ottenuti. Immag<strong>in</strong>iamo <strong>di</strong> volerli stamparesu un file per poterli stu<strong>di</strong>are ed esam<strong>in</strong>are con calma. La function pfisso ci ha dato dei vettori, noi abbiamofatto il grafico <strong>di</strong> convergenza. Ora vogliamo salvare, per ogni iterazione, i valori delle approssimazioni,degli scarti e delle stime as<strong>in</strong>t1 e as<strong>in</strong>t2 <strong>in</strong>serendoli <strong>in</strong> una tabella con una riga <strong>di</strong> <strong>in</strong>testazione <strong>in</strong> cuiscriviamo il significato della colonna corrispondente. Ve<strong>di</strong>amo un modo compatto per fare tutto ciò. Creiamouna matrice <strong>in</strong> cui ciascuna riga corrisponde a ciò che vogliamo mettere <strong>in</strong> tabella: la prima riga avrà leiterazioni fatte, la seconda i valori approssimati, la terza gli scarti, la quarta le stime as<strong>in</strong>t1 e la qu<strong>in</strong>ta lestime as<strong>in</strong>t2. La matrice deve avere lo stesso numero <strong>di</strong> colonne, qu<strong>in</strong><strong>di</strong> dobbiamo stare attenti al fatto chealcuni vettori hanno come prima componente un valore che corrisponde all’iterazione 0.Per scrivere su un file <strong>di</strong> testo, dobbiamo aprire da MATLAB® un file e dare ad esso un nome: ciò vienefatto con la function fopen: questa function ha come parametri il nome del file su cui andremo a scriverei dati, scritto tra apici, e aggiungeremo poi dei permessi (ad esempio ’r’ per file <strong>di</strong> sola lettura, ’w’ per file <strong>di</strong>scrittura,... si faccia help fopen). L’output della function è una variabile scalare <strong>di</strong> tipo <strong>in</strong>tero, a cui <strong>di</strong>amonome fid (file identifier). Questa variabile sarà usata come identificatore del file su cui dobbiamo andarea scrivere me<strong>di</strong>ante la function fpr<strong>in</strong>tf. Una volta che si è scritto, si chiude il file me<strong>di</strong>ante la functionfclose, scrivendo semplicemnte fclose(fid).La function fpr<strong>in</strong>tf permette <strong>di</strong> scrivere su un file utilizzando un certo formato. Ciò che <strong>di</strong>ciamo adessoserve <strong>in</strong> maniera analoga per la function spr<strong>in</strong>tf che permette <strong>di</strong> scrivere con un certo tipo <strong>di</strong> formato sullaCommand W<strong>in</strong>dow.I dati <strong>di</strong> <strong>in</strong>put <strong>di</strong> fpr<strong>in</strong>tf sono la variabile fid, alcune istruzioni che riguardano il formato, da scriveretra apici, e una o più matrici. Se, si pone fid=1 l’output sarà lo schermo della Command W<strong>in</strong>dow. Qu<strong>in</strong><strong>di</strong>l’istruzione da dare è fpr<strong>in</strong>tf(fid, ’formato’, A, B, ...) con A,B matrici o array (un array puòessere un vettore o una matrice fatta <strong>di</strong> numeri o <strong>di</strong> str<strong>in</strong>ghe <strong>di</strong> caratteri). Bisogna prestare attenzione al fattoche la scrittura avviene colonna per colonna, (vengono letti gli elementi della prima colonna, poi gli elementidella seconda colonna, ...).Il formato è una str<strong>in</strong>ga <strong>di</strong> caratteri da scrivere tra apici che possono avere <strong>di</strong>versi significati: c’è il formatoassociato al tipo <strong>di</strong> rappresentazione della variabile (se <strong>in</strong> formato esponenziale, fisso, <strong>di</strong> tipo <strong>in</strong>tero, <strong>di</strong> str<strong>in</strong>ga35


1. INTRODUZIONE<strong>di</strong> caratteri...) che si scrive nella forma %e (formato esponenziale) o %12.6e (formato esponenziale cui sonoriservati 12 spazi <strong>di</strong> cui 6 per la mantissa)...; ci sono i caratteri che hanno il significato <strong>di</strong> riga bianca, andarea capo, ... che sono preceduti dal simbolo \ ( \n, nuova l<strong>in</strong>ea, \r andare a capo,...); ci possono essere str<strong>in</strong>ghe<strong>di</strong> caratteri. In tabella ve<strong>di</strong>amo i pr<strong>in</strong>cipali simboli che ci <strong>in</strong>teressano.formatoSignificato%s str<strong>in</strong>ghe <strong>di</strong> caratteri%d formato <strong>in</strong>tero%f formato decimale <strong>in</strong> virgola fissa%e formato esponenziale (del tipo 3.5e + 00)%E formato esponenziale (del tipo 3.5E + 00)%g formato che è una via <strong>di</strong> mezzo tra %f e %e senza gli zeri che non servono\ n nuova l<strong>in</strong>ea (il risultato è come schiacciare il tasto <strong>di</strong> <strong>in</strong>vio)\ r per andare a capo\\ \” ’Il significato associato a \ n è molto importante, perchè permette <strong>di</strong> andare a capo ogni volta che è stataletta una riga, altrimenti viene scritta solo una riga sul file, lunghissima a seconda del contenuto da scrivere!Al formato che specifica il valore <strong>di</strong> una variabile numerica può essere aggiunto il numero dei caratteri dautilizzare per rappresentare la variabile: oltre all’esempio visto prima %12.6e, possiamo vedere %10d : sonoriservati 10 caratteri ad una variabile <strong>di</strong> tipo <strong>in</strong>tero.Ve<strong>di</strong>amo degli esempi per capire meglio. Scriviamo ed eseguiamo i seguenti script.f i d =fopen (’fileprova.txt’ , ’w’)x =10.5;f p r i n t f ( fid , ’Ho scritto questo numero %f’ , x ) ;s p r i n t f (’Ho scritto questo numero %f’ , x )f c l o s e ( f i d ) ;Se eseguiamo questo script, sulla Command W<strong>in</strong>dow, compare quanto richiesto dalla function spr<strong>in</strong>tf,cioè Ho scritto questo numero 10.500000 (associato ad una variabile ans) mentre nella <strong>di</strong>rectory<strong>in</strong> cui stiamo lavorando <strong>in</strong> MATLAB® , troveremo il file fileprova.txt. Se lo apriamo con un e<strong>di</strong>tor<strong>di</strong> testo troveremo Ho scritto questo numero 10.500000.Proviamo a voler stampare più elementi sulla stessa riga. Introduciamo un vettore.f i d =fopen (’fileprova.txt’ , ’w’)a=12;b=2;c=a*b ;f p r i n t f ( fid , ’il prodotto <strong>di</strong> %g per %g da’’ %g \n’ , [ a b c ] ) ;f c l o s e ( f i d )Questa volta sul file fileprova.txt troviamo (al posto della frase precedente, abbiamo sovrascritto!), lariga il prodotto <strong>di</strong> 12 per 2 da’ 24.Consideriamo ora sia un vettore sia una str<strong>in</strong>ga <strong>di</strong> caratteri. Questa volta usiamo la function spr<strong>in</strong>tf.str<strong>in</strong>ga=’numeri reali’ ;vettore =[1.1 1.2 1.3 1 . 4 ] ;s p r i n t f (’%2g %2g %2g e %2g sono %s \n’ , vettore , str<strong>in</strong>ga )Otteniamo: 0.1 0.2 0.3 e 0.4 sono reali.Se vogliamo visualizzare una matrice, dobbiamo tener conto del fatto che la lettura viene fatta sugli elementi<strong>di</strong> ogni colonna e, se an<strong>di</strong>amo a capo, questi elementi vengono <strong>di</strong>sposti su riga. Perciò, se vogliamovisualizzare la matrice <strong>in</strong> modo corretto dobbiamo lavorare sulla sua trasposta e scrivere il formato per ciascunelemento <strong>di</strong> colonna della trasposta (o <strong>di</strong> riga della matrice <strong>di</strong> partenza). Ve<strong>di</strong>amo con degli esempi(il primo uso <strong>di</strong> spr<strong>in</strong>tf non è corretto perchè non abbiamo la matrice A che scriviamo, nel secondo caso ilrisultato è quello giusto).36


1.9. Strutture e cicli>> A=[1 2 3; 4 5 6; 7 8 9]A =1 2 34 5 67 8 9>> spr<strong>in</strong>tf( ’ %g %g %g \n’, A)ans =1 4 72 5 83 6 9>> spr<strong>in</strong>tf( ’ %g %g %g \n’, A’)ans =1 2 34 5 67 8 9Ve<strong>di</strong>amo cosa succede con matrici rettangolari.>> A=[ 1 2 3 4; 5 6 7 8; 9 10 11 12]A =1 2 3 45 6 7 89 10 11 12>> spr<strong>in</strong>tf( ’ %2d %2d %2d %2d \n’, A’)ans =1 2 3 45 6 7 89 10 11 12In questo caso, dobbiamo visualizzare quattro elementi per riga, e <strong>di</strong>fatti abbiamo scritto quattro formati(%2d). Se proviamo a scrivere togliendo delle <strong>in</strong>formazioni sul formato o applicando la function alla matriceA e non alla sua trasposta, abbiamo risultati scorretti.>> spr<strong>in</strong>tf( ’ %2d %2d %2d %2d \n’, A)ans =1 5 9 26 10 3 711 4 8 1237


1. INTRODUZIONE>> spr<strong>in</strong>tf( ’ %2d %2d %2d \n’, A)ans =1 5 92 6 103 7 114 8 12>> spr<strong>in</strong>tf( ’ %2d %2d %2d \n’, A’)ans =1 2 34 5 67 8 910 11 12Provare a fare altri esempi.Torniamo allora alla visualizzazione dei risultati dello schema <strong>di</strong> punto fisso. Ci <strong>in</strong>teressano i dati dallaprima all’ultima iterazione, ma alcuni vettori hanno anche delle <strong>in</strong>formazioni sull’iterazione zero. Inoltre,siccome noi vogliamo scrivere una tabell<strong>in</strong>a, dove ciascuna colonna ha il significato <strong>di</strong> iterazioni, approssimazioni,scarto, etc.... conviene scrivere ciascuno <strong>di</strong> questi vettori come righe della matrice <strong>in</strong> modo che poi,senza fare la trasposta, la function fpr<strong>in</strong>tf ci mette quelle righe <strong>in</strong> colonna facendo la trasposta. In tal mododobbiamo scrivere il formato solo per il generico elemento <strong>di</strong> ciascuno vettore e non per tutti gli elementidei vettori (5 formati e non <strong>in</strong> numero che corrisponde al numero delle iterazioni).Lo script da eseguire dopo la function pfisso è il seguente (che abbiamo chiamato salvadati.m. Loscript tiene conto che i vettori <strong>in</strong> uscita dalla pfisso sono dei vettori riga.f i d =fopen (’rispfisso.txt’ ,’w’ ) ;f p r i n t f ( fid ,’%5s %12s %12s %12s %12s \n’ , ’iter’ , ’x’ , ’scarto’ ,’as<strong>in</strong>t1’ ,’as<strong>in</strong>t2’)f p r i n t f ( fid , ’\n%5d %12.8e ’ , [0 x ( 1 ) ] ) ; %stampiamo i l valore i n i z i a l e x0i t = [ 1 : 1 : i t e r ] ; %creo i l v e t t o r e d e l l e i t e r a z i o n iA=[ i t ; x ( 2 : length ( x ) ) ; scarto ; as<strong>in</strong>t1 ; as<strong>in</strong>t2 ( 2 : length ( as<strong>in</strong>t2 ) ) ] ;% la prima riga e ’ data dal v e t t o r e i t% la seconda riga da x , . . .% non consideriamo la prima componente dei% v e t t o r e x e as<strong>in</strong>t2 che corrispondono a x0f p r i n t f ( fid , ’\n%5d %12.8e %12.8e %12.8e %12.8e ’ , A ) ; %stampa la matrice A% <strong>in</strong> modo traspostof c l o s e ( f i d ) ;Applichiamo questo script una volta eseguita la function pfisso per approssimare il punto fisso dellafunzione g (x) = cos(x) partendo da x 0 = 0.1 con una tolleranza tol = 1.e − 10. Viene generato il filerispfisso.txt. Ve<strong>di</strong>amo come è fatto (togliendo <strong>di</strong>verse righe centrali <strong>in</strong> modo da vedere l’<strong>in</strong>izio e laf<strong>in</strong>e).iter x scarto as<strong>in</strong>t1 as<strong>in</strong>t20 1.00000000e-011 9.95004165e-01 8.95004165e-01 4.47502083e+09 8.38761234e-012 5.44499396e-01 4.50504769e-01 5.03354942e-01 5.17989945e-013 8.55386706e-01 3.10887310e-01 6.90086612e-01 7.54824623e-014 6.55926664e-01 1.99460042e-01 6.41583094e-01 6.09893870e-015 7.92483102e-01 1.36556438e-01 6.84630549e-01 7.12098800e-016 7.02079268e-01 9.04038340e-02 6.62025424e-01 6.45806605e-0138


1.9. Strutture e cicli7 7.63501034e-01 6.14217657e-02 6.79415496e-01 6.91454893e-018 7.22419636e-01 4.10813975e-02 6.68841037e-01 6.61201836e-01.............................................................53 7.39085134e-01 7.81694154e-10 6.73612013e-01 6.73612029e-0154 7.39085133e-01 5.26558575e-10 6.73612016e-01 6.73612029e-0155 7.39085133e-01 3.54696161e-10 6.73611975e-01 6.73612029e-0156 7.39085133e-01 2.38927544e-10 6.73611870e-01 6.73612029e-0157 7.39085133e-01 1.60944480e-10 6.73612079e-01 6.73612029e-0158 7.39085133e-01 1.08414167e-10 6.73612208e-01 6.73612029e-0159 7.39085133e-01 7.30291383e-11 6.73612505e-01 6.73612029e-01Attenzione! Osserviamo ancora due elementi sulle function <strong>di</strong> punto fisso che abbiamo scritto.G Nella function pfisso abbiamo operato con dei vettori. Il primo elemento del vettore x e delvettore scarto li abbiamo assegnati con l’istruzione x=x0; scarto=2*toll; Avremmo potuto anchescrivere x(1)=x0; scarto(1)=2*toll; Nel primo caso ( x=x0;) è come se partissimo da una variabilescalare e poi <strong>di</strong>cessimo ”creiamo un vettore“, anche se <strong>in</strong> realtà sappiamo che creeremo unvettore e che quella è la prima componente. Nel secondo caso <strong>di</strong>ciamo <strong>in</strong> maniera esplicita chestiamo creando un vettore e che quella è la prima componente.G Le function <strong>di</strong> punto fisso che abbiamo scritto sono pensate per il caso generale <strong>di</strong> schema conor<strong>di</strong>ne <strong>di</strong> convergenza p = 1 (convergenza l<strong>in</strong>eare). Se lo schema <strong>di</strong> punto fisso ha or<strong>di</strong>ne <strong>di</strong>convergenza maggiore, le stime delle costanti as<strong>in</strong>totiche non vanno più bene (che risultati cidaranno?). Dagli scarti, tuttavia, e dal grafico <strong>di</strong> convergenza otteniamo <strong>in</strong>formazioni utili per laconvergenza.<strong>Esercizi</strong>o 1.9.3 Applicare lo schema <strong>di</strong> punto fisso alle seguenti funzioni g (x). Per ciascun caso, fare ungrafico <strong>di</strong> convergenza semilogaritmico e stampare i risultati <strong>in</strong> un file. Dai risultati capire se c’è convergenzal<strong>in</strong>eare oppure no. In caso contrario, cosa si può fare per stabilire l’or<strong>di</strong>ne <strong>di</strong> convergenza? (1) sipossono considerare le derivate successive della g e valutarle nell’approssimazione <strong>di</strong> punto fisso ricavataall’ultima approssimazione – quali derivate e quando mi posso fermare <strong>in</strong> questo proce<strong>di</strong>mento?; (2) si facciail rapporto tra gli scarti tra due iterazioni successive |x k+1 − x k |con p > 1 (cosa si deve osservare perp|x k − x k−1 |<strong>di</strong>re che un certo p è l’or<strong>di</strong>ne <strong>di</strong> convergenza?).Ai f<strong>in</strong>i dell’implementazione, ricordarsi <strong>di</strong> scrivere le function, <strong>in</strong> particolare la derivata prima, <strong>in</strong> formavettorizzata per poterle valutare su vettori – qu<strong>in</strong><strong>di</strong> .ˆ .* ./G g (x) = 3x + 22x + 3 , x 0 = 0.5, tol l = 1.e − 12, i tmax = 100.G g (x) = −ln(3 − x 2 ), x 0 = 0.1, tol l = 1.e − 12, i tmax = 100.G g (x) = x2 + 42x , x 0 = 0.5, tol l = 1.e − 12, i tmax = 100.1.9.5 Mo<strong>di</strong>ficare le function <strong>di</strong> punto fisso per creare nuove functionLe function <strong>di</strong> punto fisso che abbiamo scritto possono essere usate come base per creare function <strong>in</strong> cuiapplichiamo altri meto<strong>di</strong> iterativi, come quello <strong>di</strong> Newton-Raphson e della secante variabile.39


1. INTRODUZIONEQuali saranno le <strong>di</strong>fferenze? Per lo schema <strong>di</strong> Newton-Raphson,x k+1 = x k − f (x k)f ′ (x k )abbiamo bisogno non solo della funzione f ma anche della sua derivata prima f ′ . Inoltre, per stimare lacostante as<strong>in</strong>totica <strong>di</strong> convergenza, nel caso generale <strong>di</strong> convergenza quadratica, dobbiamo ricordarci cheabbiamo due mo<strong>di</strong> possibili da usare, il rapporto tra gli scarti d k+1d 2 (dove d k+1 = |x k+1 − x k |), e il rapportok| f ′′ (x k+1 )2f ′ (x k+1 ) |.Qu<strong>in</strong><strong>di</strong>, tra le variabili <strong>di</strong> <strong>in</strong>put della function, dovremo <strong>in</strong>serire non solo la funzione f ma anche le suederivate prima e seconda.Il resto dello schema sarà simile a quello visto per il punto fisso. Al posto della formula iterativa dello schema<strong>di</strong> punto fisso, metteremo la formula iterativa dello schema <strong>di</strong> Newton-Raphson. Al posto delle formuleusate per le variabili as<strong>in</strong>t1 e as<strong>in</strong>t2 useremo le analoghe formule dello schema <strong>di</strong> Newton-Raphson.Perciò, mo<strong>di</strong>ficare le function pfisso0.m e pfisso.m per creare le newton0.m e newton.m noncomporta chissà quali <strong>di</strong>fficoltà.Maggiore attenzione <strong>in</strong>vece bisogna prestare per creare le function sul metodo della secante variabile.Infatti, oltre alla f , f ′ e f ′′ , (f ′ e f ′′ servono per stimare la costante as<strong>in</strong>totica) sappiamo che lo schema parteda due approssimazioni <strong>in</strong>iziali, x 0 e x 1 , qu<strong>in</strong><strong>di</strong> tra le variabili <strong>di</strong> <strong>in</strong>put bisogna aggiungere anche x 1 .Lo schema della secante variabile e le stime della costante as<strong>in</strong>totica sono date me<strong>di</strong>ante le formulex k+1 = x k − f (x k)(x k − x k−1 )f (x k ) − f (x k−1 )d k+1d 1.618kf ′′ (x k+1|2f ′ (x k+1 ) |0.618Nello schema da implementare, la <strong>di</strong>fficoltà non si ha nelle formule per as<strong>in</strong>t1 e as<strong>in</strong>t2 quanto nellavorare usando le approssimazioni x k e x k−1 e aggiornarle nel modo corretto, quando si implementa laformula lavorando con variabili scalari (qu<strong>in</strong><strong>di</strong> nella function rfalsi0.m).Partiamo da due variabili x 0 e x 1 : al primo passo queste due variabili saranno per noi xkm e xk (l’approssimazionex k−1 e x k rispettivamente). La variabile iter non parte dal valore 0 ma da 1 avendo anchel’approssimazione x 1 . Alla variabile scartokp1 possiamo dare il valore giusto dello scarto (abs(x1-x0))mentre il valore da dare alla variabile scartok sarà, la prima volta, un valore fittizio (<strong>di</strong>verso da zero) cheserve per calcolare as<strong>in</strong>t1 al primo passo.Quando dobbiamo applicare la formula del metodo, per semplificare le cose, conviene <strong>in</strong>trodurre unavariabile <strong>di</strong> appoggio, che possiamo chiamare c, cui assegniamo il valore del rapporto <strong>in</strong>crementalec= ( f e v a l ( fun , xk)− f eval ( fun ,xkm) ) / ( xk−xkm ) ;xkp1= xk −f eval ( fun , xk ) / c ;Una volta valutato il nuovo scarto scartokp1, e fatta una stima della costante as<strong>in</strong>totica me<strong>di</strong>anteas<strong>in</strong>t1 e as<strong>in</strong>t2, bisogna aggiornare le variabili da utilizzare al passo successivo.Qui bisogna fare attenzione:Iterazione x k−1 x k x k+11 x0 x12 x0 x1 xkp=x 23 x1 x 2 xkp=x 34 x 2 x 3 xkp=x 4....Quando dobbiamo passare dall’iterazione 2 all’iterazione 3, x1 non dovrà più avere il significato <strong>di</strong> x kma quello <strong>di</strong> x k−1 , mentre il valore che abbiamo appena ottenuto xkp=x 2 dovrà passare al significato <strong>di</strong> x k .40


1.9. Strutture e cicliL’aggiornamento delle variabili deve essere fatto sapendo quello che si fa, altrimenti c’è il rischio <strong>di</strong> perdere ilcontenuto <strong>di</strong> alcune variabili.Le istruzioni da fare per l’aggiornamento quali sono?xk=xkm;xk=xkp1 ;oppurexkm=xk ;xk=xkp1 ;oppurexk=xkp1 ;xkm=xk ;oppure .... ?Immag<strong>in</strong>iamo <strong>di</strong> avere tre variabili, a, b e c dove a = 1, b = 2 e c = 3. Vogliamo poi che sia a = 2e b = 3:come facciamo lavorando sulle variabili? Questo è quello che dobbiamo fare nella function rfalsi0.m.Osserviamo che <strong>in</strong> queste function <strong>in</strong> versione 0, la stima delle costanti as<strong>in</strong>totiche viene sempre sovrascrittae i valori <strong>in</strong>terme<strong>di</strong> vengono persi. Avrebbe più senso scriverli su un file <strong>di</strong> dati, <strong>in</strong> modo da non perderli,oppure valutarli solo alla f<strong>in</strong>e. Tuttavia, poichè useremo quasi sempre le function con l’implementazionefatta con vettori, trascuriamo questo particolare.Nella function rfalsi.m, <strong>in</strong>vece, l’implementazione del metodo è molto più semplice, perchè partiamoponendo x(1)=x0 e x(2)=x1 e appplicheremo la formula considerando i vettori. Qui il contatore delleiterazioni, partirà da iter=2, <strong>in</strong> modo da avere concordanza con i vettori che creiamo. Alla f<strong>in</strong>e, torneremo alvettore degli scarti che parte dall’iterazione corrispondente a x 1 , e toglieremo al contatore un’unità (quelloche è stato fatto anche con lo schema <strong>di</strong> punto fisso) <strong>in</strong> modo da avere vettori con lo stesso significato rispettoa quanto fatto con lo schema <strong>di</strong> punto fisso e <strong>di</strong> Newton-Raphson.Una volta scritte queste function possiamo confrontare i meto<strong>di</strong> <strong>di</strong> Newton-Raphson e della secante variabile,facendo ad esempio un grafico <strong>di</strong> convergenza semilogaritmico (ovviamente sulla stessa equazionef (x) = 0). Conviene, a tal f<strong>in</strong>e, eseguire le due function dando nomi <strong>di</strong>versi per le variabili <strong>di</strong> output e <strong>in</strong>particolare per la variabile delle iterazioni e quella del vettore scarto. Supponiamo <strong>di</strong> chiamare con itnr escartonr le variabili corrispondenti a iter e scarto rispettivamente nello schema <strong>di</strong> Newton-Raphson,mentre chiamiamo con itrf e scartorf quelle relative allo schema della secante variabile.Possiamo fare il grafico semilogaritmico <strong>in</strong> questo modo.semilogy ( [ 1 : 1 : i t n r ] , scartonr , [ 1 : 1 : i t r f ] , s c a r t o r f )legend (’Newton-Raphson’ , ’Regula Falsi’)xlabel (’iterazioni’)ylabel (’scarti’)t i t l e (’Grafico <strong>di</strong> convergenza’)pr<strong>in</strong>t −djpeg g r afico . jpgAll’<strong>in</strong>terno dell’istruzione per fare il grafico semilogaritmico abbiamo creato i vettori [1:1:itnr] e[1:1:itrf]. La function legend permette <strong>di</strong> <strong>di</strong>st<strong>in</strong>guere le due curve (a quale metodo si riferiscono);poi ci sono le etichette sui due assi e un titolo. Inf<strong>in</strong>e abbiamo usato un comando che permette <strong>di</strong>rettamente<strong>di</strong> salvare <strong>in</strong> formato .jpg la figura creata utilizzando la function pr<strong>in</strong>t dopo abbiamo scritto -d seguito dajpg per specificare il tipo <strong>di</strong> file e <strong>in</strong>f<strong>in</strong>e il nome del file che vogliamo creare. Quest’ultimo comando è moltoutile <strong>in</strong> <strong>Octave</strong> oppure se vogliamo salvare delle figure tramite uno script o dalla Command W<strong>in</strong>dow.Supponiamo <strong>di</strong> voler fare <strong>di</strong>verse figure e <strong>di</strong> volerle vedere contemporaneamente senza sovrascriverle. Unmodo per risolvere questo problema è <strong>di</strong> creare più figure attraverso la function figure. Capiamo con unesempio a cosa serve:figure ( 1 )ezplot (@cos , [ 0 , 2 ] )x = 0 : 0 . 1 : 2 ;y=cos ( x ) ;41


1. INTRODUZIONEfigure ( 2 )plot ( x , y )Se vogliamo salvare le due figure dalla Command W<strong>in</strong>dow (o da uno script) si riattiva la figura da salvareme<strong>di</strong>ante la function figure e si salva la figura.figure ( 1 )pr<strong>in</strong>t −djpegfigure ( 2 )pr<strong>in</strong>t −djpegf i g 1 . jpgf i g 2 . jpg42


CAPITOLO 2Su <strong>in</strong>terpolazione e approssimazioneLo scienziato descrive ciò che esiste,l’<strong>in</strong>gegnere crea ciò che non era maistato.Theodore von Kármán (1881-1963)2.1 Interpolazione monomiale e con i pol<strong>in</strong>omi <strong>di</strong> Lagrange . . . . . . . . . . . . . . . . . . . . . . . . 442.2 Interpolazione con la tabella delle <strong>di</strong>fferenze <strong>di</strong>vise <strong>di</strong> Newton . . . . . . . . . . . . . . . . . . . . . 502.3 Interpolazione l<strong>in</strong>eare a tratti e spl<strong>in</strong>e cubica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 542.3.1 Interpolazione l<strong>in</strong>eare a tratti . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 542.4 Curve parametriche . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 592.4.1 Il ciclo switch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 602.5 Approssimazione <strong>di</strong> dati . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 622.5.1 Retta <strong>di</strong> regressione sugli scarti verticali . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 622.5.2 Modello potenza e modello esponenziale . . . . . . . . . . . . . . . . . . . . . . . . . . . . 642.5.3 Caricare i dati <strong>di</strong> <strong>in</strong>put da file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65Per <strong>in</strong>terpolare n + 1 coppie <strong>di</strong> punti (x i , y i ), <strong>in</strong> MATLAB® esiste una function, chiamata polyfit. Lafunction polyfit ha come dati <strong>di</strong> <strong>in</strong>put tre variabili, il vettore x che contiene le ascisse dei dati da <strong>in</strong>terpolare,il vettore y che contiene le or<strong>di</strong>nate dei dati da <strong>in</strong>terpolare e <strong>in</strong>f<strong>in</strong>e l’<strong>in</strong>tero n del grado del pol<strong>in</strong>omio <strong>di</strong><strong>in</strong>terpolazione. In output, si ottiene il vettore p, <strong>di</strong> lunghezza n+1, che contiene i coefficienti del pol<strong>in</strong>omio <strong>di</strong>grado n, dal coefficiente corrispondente al grado n f<strong>in</strong>o ad arrivare al coefficiente corrispondente al grado 0.Qu<strong>in</strong><strong>di</strong> p=(p n , p n−1 , p n−2 ,..., p 0 ), tale che il pol<strong>in</strong>omio <strong>di</strong> <strong>in</strong>terpolazione sia p n (x) = p 0 +p 1 x+p 2 x 2 +... p n x n .L’algoritmo della function polyval è basato su un proce<strong>di</strong>mento ai m<strong>in</strong>imi quadrati (che stu<strong>di</strong>eremo conl’approssimazione). Difatti, la function polyval ci servirà anche per approssimare dei dati. Nel casodell’<strong>in</strong>terpolazione, la funzione genera la matrice <strong>di</strong> Vandermonde.Una volta ottenuto il vettore p dalla polyfit, per poter valutare il pol<strong>in</strong>omio <strong>di</strong> <strong>in</strong>terpolazione si puòusare un’altra function <strong>di</strong> MATLAB® chiamata polyval che ha come parametri <strong>di</strong> <strong>in</strong>put il vettore p deicoefficienti del pol<strong>in</strong>omio da valutare (<strong>in</strong> or<strong>di</strong>ne decrescente) e il punto (o vettore o matrice) xval <strong>in</strong> cuivalutare il pol<strong>in</strong>omio. La funzione, <strong>in</strong>fatti, è vettoriale: può restituire il valore del pol<strong>in</strong>omio valutato <strong>in</strong> unpunto o <strong>in</strong> un vettore o <strong>in</strong> una matrice.Ve<strong>di</strong>amo un esempio. Siano date le coppie <strong>di</strong> punti da <strong>in</strong>terpolare (0,1), (1,0) e (2,2). Costruiamo i vettorix=[0,1,2] e y=[ 1,0,2]. Il grado del pol<strong>in</strong>omio <strong>di</strong> <strong>in</strong>terpolazione è n = 2. Qu<strong>in</strong><strong>di</strong>>> x=[0 1 2];>> y=[1 0 2];>> p=polyfit(x,y,2)p =43


2. SU INTERPOLAZIONE E APPROSSIMAZIONE1.5000 -2.5000 1.0000Il vettore p che abbiamo ottenuto ci permette <strong>di</strong> <strong>di</strong>re che il pol<strong>in</strong>omio <strong>di</strong> <strong>in</strong>terpolazione è dato da p 2 (x) =1.5x 2 −2.5x−1 = 1−2.5x+1.5x 2 (lo abbiamo scritto <strong>in</strong> due mo<strong>di</strong> equivalenti). Valutiamo ora questo pol<strong>in</strong>omioproprio nelle ascisse <strong>di</strong> <strong>in</strong>terpolazione, per verificare che la con<strong>di</strong>zione <strong>di</strong> <strong>in</strong>terpolazione è verificata. Usiamola function polyval.>> y1=polyval(p,x)y1 =1.0000 -0.0000 2.0000Se proviamo a vedere l’errore assoluto commesso,>> y-y1ans =1.0e-15 *0.222044604925031 0.444089209850063 0.222044604925031ci accorgiamo che l’errore è dell’or<strong>di</strong>ne <strong>di</strong> 10 −15 . In questo caso non an<strong>di</strong>amo a vedere l’errore relativoperchè una delle or<strong>di</strong>nate <strong>di</strong> <strong>in</strong>terpolazione vale 0.2.1 Interpolazione monomiale e con i pol<strong>in</strong>omi <strong>di</strong> LagrangeProviamo ora a scrivere noi due function per <strong>in</strong>terpolare n +1 coppie <strong>di</strong> dati. In particolare scriviamo unafunction che applica il proce<strong>di</strong>mento <strong>di</strong> <strong>in</strong>terpolazione con funzioni base monomiali: dovremo dunque risolvereun sistema <strong>di</strong> n +1 equazioni <strong>in</strong> n +1 <strong>in</strong>cognite <strong>in</strong> cui la matrice del sistema è la matrice <strong>di</strong> Vandermonde(e chiederemo a MATLAB® <strong>di</strong> risolverci il sistema). Successivamente scriveremo una function che applica ilproce<strong>di</strong>mento <strong>di</strong> <strong>in</strong>terpolazione <strong>di</strong> Lagrange.La prima function la chiamiamo <strong>in</strong>terpmonom.m (per <strong>in</strong>terpolazione monomiale). Eseguiremo iseguenti passaggi:G i due vettori x e y, che contengono, rispettivamente, le ascisse e le or<strong>di</strong>nate da <strong>in</strong>terpolare, vogliamoche siano dei vettori colonna. In <strong>in</strong>put, però, potrebbero essere dati come vettori riga. Qu<strong>in</strong><strong>di</strong> usiamoil comando x=x(:); e y=y(:); per renderli colonna. Se sono già vettori colonna, queste dueistruzioni non alterano i vettori;G controlliamo, con un ciclo if se i due vettori hanno la stessa lunghezza: se hanno lunghezza <strong>di</strong>versanon ha senso procedere con la function e si esce dando un messaggio <strong>di</strong> errore (si veda l’uso <strong>di</strong> error:stampa il messaggio <strong>di</strong> errore, che scriviamo noi, e <strong>in</strong>terrompe l’esecuzione della function);G il grado del pol<strong>in</strong>omio che dobbiamo costruire deve essere <strong>di</strong> grado n se <strong>in</strong> <strong>in</strong>gresso sono state daten + 1 coppie <strong>di</strong> punti. Poniamo perchiò pari a n il valore della lunghezza del vettore x meno uno;G <strong>in</strong>izializziamo la matrice <strong>di</strong> Vandermonde, V, come una matrice <strong>di</strong> tutti uno, usando la function <strong>di</strong>MATLAB® ones; la matrice <strong>di</strong> Vandermonde deve avere n + 1 righe e n + 1 colonne perchè sono n + 1 icoefficienti da determ<strong>in</strong>are;44G A questo punto, ricor<strong>di</strong>amo come è fatta la matrice V .⎛1 x 0 x0 2 ... x n ⎞01 x 1 x1 2 ... x n 1V =1 x 2 x 2 2... x2n ⎜⎝...⎟. ⎠1 x n xn 2 ... xnn


2.1. Interpolazione monomiale e con i pol<strong>in</strong>omi <strong>di</strong> LagrangeLa prima colonna ha tutti uno, la seconda colonna ha il vettore x, la terza colonna ha il vettore con lepotenze al quadrato <strong>di</strong> x e così via. Possiamo scrivere la matrice <strong>in</strong> modo ricorsivo tenendo presenteche ogni colonna è uguale alla precedente moltiplicata, componente per componente, per il vettore x.Ora, la prima colonna ha già gli elementi tutti uguali a uno, perciò applichiamo un ciclo for per scriverele colonne successive.for i : 2 : n+1V ( : , i )= x . * V ( : , i −1);endOgni colonna è il risultato del prodotto, componente per componente (.*) del vettore x con la colonnaprecedente;G una volta creata la matrice usiamo una function <strong>di</strong> MATLAB® che ci permette <strong>di</strong> risolvere il sistema <strong>di</strong>equazioni l<strong>in</strong>eari <strong>in</strong> cui la matrice del sistema è V mentre il vettore dei term<strong>in</strong>i noti è il vettore colonnay. L’istruzione p=V\y; ci permette <strong>di</strong> avere nel vettore p il vettore soluzione del sistema V p = y.G Il vettore ottenuto contiene i coefficienti del pol<strong>in</strong>omio <strong>di</strong> <strong>in</strong>terpolazione <strong>in</strong> or<strong>di</strong>ne crescente, cioèp(1) corrisponde al coefficiente <strong>di</strong> grado 0 e p(n+1) corrisponde al coefficiente che moltiplica x n .Se, successivamente, vogliamo usare la function polyval per poter valutare il pol<strong>in</strong>omio <strong>di</strong> <strong>in</strong>terpolazione,conviene scrivere il vettore con i coefficienti <strong>in</strong> or<strong>di</strong>ne decrescente. Facciamo questo con l’istruzionep=p(n+1:−1:1); che legge il vettore p dall’ultima alla prima componente, partendo dall’<strong>in</strong><strong>di</strong>cen+1 e andando <strong>in</strong><strong>di</strong>etro con passo -1, e riassegna il vettore dato <strong>in</strong> questo or<strong>di</strong>ne alla stessa variabile.G La function ha come parametri <strong>di</strong> output sia il vettore p, sia la matrice <strong>di</strong> Vandermonde V. Se, tuttavia,scriviamo (<strong>in</strong> uno script o nella Command W<strong>in</strong>dow) p=<strong>in</strong>terpmonom(x,y) <strong>in</strong> uscita abbiamosolo il vettore p. Impariamo, <strong>in</strong>fatti, questa importante caratteristica delle function <strong>in</strong> MATLAB® . Seuna function ha più <strong>di</strong> una variabile <strong>di</strong> output – supponiamo m - e se eseguiamo la function con unalista <strong>di</strong> variabili <strong>di</strong> output <strong>in</strong>feriore a quella che c’è nella def<strong>in</strong>izione della function, per esempio r ,MATLAB® restituisce solo le prime r variabili <strong>di</strong> output.Ve<strong>di</strong>amo, dunque, la function <strong>in</strong>terpmonom.mfunction [p , V]=<strong>in</strong>terpmonom( x , y )% <strong>in</strong>terpolazione monomiale% dati i v a l o r i x e y da <strong>in</strong>terpolare s i c o s t r u i s c e i l v e t t o r e p% dei c o e f f i c i e n t i del pol<strong>in</strong>omio <strong>di</strong> <strong>in</strong>terpolazione% applicando i l metodo dei c o e f f i c i e n t i <strong>in</strong>determ<strong>in</strong>ati% Esempio% x=[0 1 2 ] ;% y =[1 0 2 ] ;% [ p , V]=<strong>in</strong>terpmonom ( x , y )% p =%% 1.5000% −2.5000% 1.0000%% V =%% 1 0 0% 1 1 1% 1 2 4%x=x ( : ) ; %con questo comando ren<strong>di</strong>amo i l v e t t o r e come v e t t o r e colonna%nel caso <strong>in</strong> cui s i a s t a t o gia ’ dato come v e t t o r e colonna%l ’ i s t r u z i o n e non cambia i l v e t t o r ey=y ( : ) ;i f length ( x)~= length ( y )error (’MATLAB:<strong>in</strong>terpmonom’ ,’errori sui dati’ )end45


2. SU INTERPOLAZIONE E APPROSSIMAZIONEn=length ( x ) −1; % i v e t t o r i x y hanno n+1 componenti e i l pol<strong>in</strong>omio% <strong>di</strong> <strong>in</strong>terpolazione sara ’ <strong>di</strong> grado nV=ones (n+1 ,n+ 1 ) ; %crea la matrice V <strong>di</strong> t u t t i uno%i n i z i a l i z z a z i o n e della matrice V% <strong>in</strong> questo modo la prima colonna ha gia ’% g l i elementi t u t t i uguali a unofor i =2:n+1V ( : , i )= x . * V ( : , i −1); %ogni colonna ha g l i elementi del tipo% x_j ^( i −1). Si possono vedere anche% come i l prodtto <strong>di</strong> x_j per i l corrispondente% elemento della colonna precedenteendp=V\y ;% i l v e t t o r e p contiene i c o e f f i c i e n t i del pol<strong>in</strong>omio i n t e r p o l a t o r e% <strong>in</strong> or<strong>di</strong>ne c r e s c e n t e − p0 p1 p2 . . .% se vogliamo usare la function del MATLAB polyval per valutare% t a l e pol<strong>in</strong>omio <strong>in</strong> piu ’ punti , dobbiamo porre l e componenti% del v e t t o r e p <strong>in</strong> or<strong>di</strong>ne decrescentep=p(n+1: −1:1);endOra possiamo provare a eseguire questa function e vedere cosa succede con l’esempio che abbiamo vistoprima>> x=[0 1 2];>> y=[1 0 2];>> [p, V]=<strong>in</strong>terpmonom(x,y)p =1.5000-2.50001.0000V =1 0 01 1 11 2 4>> y1=polyval(p,x)y1 =>> y1-yans =1 0 20 0 0Anche questa volta, valutiamo il pol<strong>in</strong>omio <strong>di</strong> <strong>in</strong>terpolazione nei no<strong>di</strong> <strong>di</strong> <strong>in</strong>terpolazione e l’errore valeesattamente zero.46


2.1. Interpolazione monomiale e con i pol<strong>in</strong>omi <strong>di</strong> LagrangePassiamo ora all’<strong>in</strong>terpolazione <strong>di</strong> Lagrange. Il pol<strong>in</strong>omio <strong>di</strong> Lagrange si scrive comep n (x) = L 0 (x)y 0 + L 1 (x)y 1 + ...L n (x)y ne ciascun pol<strong>in</strong>omio <strong>di</strong> Lagrange è dato daL i (x) =n∏j =0j ≠ix − x jx i − x jRispetto al caso precedente, non abbiamo <strong>di</strong>rettamente i coefficienti del pol<strong>in</strong>omio <strong>di</strong> <strong>in</strong>terpolazione,perchè la scrittura del pol<strong>in</strong>omio è fatta <strong>in</strong> modo <strong>di</strong>verso (anche se equivalente nel senso che il pol<strong>in</strong>omiof<strong>in</strong>ale è lo stesso). Perciò dobbiamo pensare ad una function che ci permette <strong>di</strong> valutare <strong>di</strong>rettamente ilpol<strong>in</strong>omio nei punti <strong>di</strong> <strong>in</strong>teresse. A tal f<strong>in</strong>e, dobbiamo essere capaci <strong>di</strong> valutare i pol<strong>in</strong>omi <strong>di</strong> Lagrange (<strong>in</strong>modo da avere i valori L 0 (x),L 1 (x),...) ,fare i prodotti L i (x)y i e sommare i vari contributi <strong>in</strong> modo da avere ilvalore del pol<strong>in</strong>omio <strong>di</strong> <strong>in</strong>terpolazione nel punto x. A tal f<strong>in</strong>e ci serviremo <strong>di</strong> due function, una che permette<strong>di</strong> valutare l’i -simo pol<strong>in</strong>omio <strong>di</strong> Lagrange L i (x) e l’altra che ci permette <strong>di</strong> valutare il valore del pol<strong>in</strong>omio <strong>di</strong><strong>in</strong>terpolazione.Chiamiamo con lagrange.m la function che restituisce la funzione L i (x), a seconda dell’<strong>in</strong><strong>di</strong>ce i assegnato.I dati <strong>di</strong> <strong>in</strong>put saranno le ascisse <strong>di</strong> <strong>in</strong>terpolazione, il punto (o il vettore) <strong>in</strong> cui andare a valutare ilpol<strong>in</strong>omio <strong>di</strong> Lagrange, e – da non trascurare – l’<strong>in</strong><strong>di</strong>ce del pol<strong>in</strong>omio <strong>di</strong> Lagrange. A tal proposito, consideriamoche, se nella teoria, parliamo <strong>di</strong> n+1 punti con <strong>in</strong><strong>di</strong>ce da 0 f<strong>in</strong>o a n (x 0 , x 1 , x 2 ,..., x n ), <strong>in</strong> MATLAB® l’<strong>in</strong><strong>di</strong>ce0 corrisponde alla prima componente del vettore, per cui avremo gli <strong>in</strong><strong>di</strong>ci che vanno da 1 a n + 1.La produttoria della formula del generico i -simo pol<strong>in</strong>omio <strong>di</strong> Lagrange viene fatta con un ciclo for. Osserviamoche, per fare il prodotto, la variabile viene <strong>in</strong>izializzata a 1 <strong>in</strong> modo da poter applicare la formula <strong>in</strong>modo ricorsivo.Ve<strong>di</strong>amo un esempio: dobbiamo fare y = ∏ nj =1 (x − x j ). Inizializziamo y = 1; poi facciamo y = y(x − x 1 ) =(x − x 1 ), qu<strong>in</strong><strong>di</strong> y = y(x − x 2 ) = (x − x 1 )(x − x 2 ) e così via (me<strong>di</strong>ante un ciclo for) f<strong>in</strong>o all’<strong>in</strong><strong>di</strong>ce n. Alla f<strong>in</strong>e ysarà proprio il prodotto <strong>di</strong> tutti i term<strong>in</strong>i <strong>in</strong><strong>di</strong>cati nella formula. Nel nostro caso, dobbiamo considerare chepossiamo valutare il pol<strong>in</strong>omio <strong>di</strong> Lagrange non sono <strong>in</strong> un valore scalare ma anche <strong>in</strong> un vettore. Qu<strong>in</strong><strong>di</strong>come risultato possiamo avere un vettore. Ve<strong>di</strong>amo dunque la function e leggiamo i commenti per capire ciòche viene fatto.function yval=lagrange ( xval , x , i )% function yval=lagrange ( xval , x , i )% function che calcola i l pol<strong>in</strong>omio i−simo <strong>di</strong> Lagrange L_i ( xval )% valutandolo <strong>in</strong> xval ( xval puo ’ e s s e r e uno s c a l are o un v e t t o r e )% x e ’ i l v e t t o r e con i no<strong>di</strong> <strong>di</strong> <strong>in</strong>terpolazione% i e ’ l ’ <strong>in</strong><strong>di</strong>ce del pol<strong>in</strong>omio <strong>di</strong> Lagrange% yval=L_i ( xval )% Esempio%>> x=[0 1 2 ] ;%>> xval = 0 . 5 ;%>> yval=lagrange ( xval , x , 1 )% yval =% 0.375000000000000%>> yval=lagrange ( xval , x , 2 )% yval =% 0.750000000000000%>> yval=lagrange ( xval , x , 3 )% yval =% −0.125000000000000%%>> xval=x ;%>> yval=lagrange ( xval , x , 1 )%47


2. SU INTERPOLAZIONE E APPROSSIMAZIONE%yval =%% 1% 0% 0%xval=xval ( : ) ;m=length ( x ) ;yval=ones ( length ( xval ) , 1 ) ; %<strong>in</strong>izializziamo a uno l e componenti% <strong>di</strong> yval <strong>in</strong> modo da poter f are poi% i l prodotto <strong>in</strong> modo r i c o r s i v o% yval= ( xval−x0 ) ( xval−x1 ) . . . . . ( xval−xn ) / ( ( xi−x0 ) ( xi−x1 ) . . . . ( xi−xn ) )% dove , tra x0 , x1 , . . . , xn non va considerato xi% un modo c l a s s i c o e ’ usare i l c i c l o f o rfor j =1: i −1yval=yval . * ( xval−x ( j ) ) / ( x ( i ) −x ( j ) ) ;endforendendj = i +1:myval=yval . * ( xval−x ( j ) ) / ( x ( i ) −x ( j ) ) ;Osserviamo che questa function non <strong>di</strong>pende dalle or<strong>di</strong>nate dei no<strong>di</strong> <strong>di</strong> <strong>in</strong>terpolazione ma solo dalle ascisse.La function può essere utile, tra le altre cose, per fare il grafico <strong>di</strong> questi pol<strong>in</strong>omi.Passiamo ora a scrivere la function per ottenere il valore del pol<strong>in</strong>omio <strong>di</strong> <strong>in</strong>terpolazione <strong>di</strong> Lagrange<strong>in</strong> un punto o <strong>in</strong> un vettore. Poichè il punto (variabile scalare) è un caso particolare <strong>di</strong> vettore <strong>di</strong> lunghezzauno, organizziamo la function <strong>in</strong> modo da valutare il pol<strong>in</strong>omio su vettori. La function, che chiamiamo<strong>in</strong>terlagrange.m è organizzata nel modo seguente:G <strong>in</strong>nanzitutto controlla se le lunghezze dei vettori x e y sono uguali;G il vettore delle or<strong>di</strong>nate lo si pone come vettore colonna;G si pone uguale a n la lunghezza del vettore x (o y). Sappiamo che il pol<strong>in</strong>omio ha grado <strong>di</strong> <strong>in</strong>terpolazionen − 1 (ricor<strong>di</strong>amo la notazione n + 1 punti <strong>di</strong> <strong>in</strong>terpolazione implica grado n; <strong>in</strong> questo caso n puntiimplica grado n − 1);G si calcola la lunghezza del vettore xval per vedere <strong>in</strong> quanti punti dobbiamo valutare il pol<strong>in</strong>omio <strong>di</strong><strong>in</strong>terpolazione;G si <strong>in</strong>izializza a zero una matrice, A, che ci servirà d’aiuto per costruire il pol<strong>in</strong>omio: questa matrice avràun numero <strong>di</strong> righe pari alla lunghezza del vettore xval e un numero <strong>di</strong> colonne pari a n;G a ciascuna colonna <strong>di</strong> A assegniamo il valore dell’i -simo pol<strong>in</strong>omio <strong>di</strong> Lagrange valutato nel vettore48xval (perciò n colonne). La matrice A sarà dunque del tipo⎛⎞L 0 (xval(1)) L 1 (xval(1)) ··· L n (xval(1))L 0 (xval(2)) L 1 (xval(2)) ··· L n (xval(2))A =L 0 (xval(3)) L 1 (xval(3)) ··· L n (xval(3))⎜⎝...⎟. ⎠L 0 (xval(m)) L 1 (xval(m)) ··· L n (xval(m))Se la matrice è scritta <strong>in</strong> questo modo, se facciamo il prodotto <strong>di</strong> ogni riga per i corrispondenti elementidel vettore y avremo⎛⎞L 0 (xval(1))y 0 + L 1 (xval(1))y 1 + ··· + L n (xval(1))y n⎛⎞L 0 (xval(2))y 0 + L 1 (xval(2))y 1 + ··· + L n (xval(2))y p n (xval(1)n⎜⎝⎟.⎠ = ⎜ p n (xval(2))⎟⎝ ... ⎠L 0 (xval(m))y 0 + L 1 (xval(m))y 1 + ··· + L n (xval(m))y p n n (xval(m))G perciò facciamo il prodotto della matrice A per il vettore y.


2.1. Interpolazione monomiale e con i pol<strong>in</strong>omi <strong>di</strong> LagrangeVe<strong>di</strong>amo la function.function yval=<strong>in</strong>terplagrange ( xval , x , y )% function yval=<strong>in</strong>terplagrange ( xval , x , y )% dati i v e t t o r i x e y da <strong>in</strong>terpolare% la function fa l ’ <strong>in</strong>terpolazione <strong>di</strong> Lagrange valutandola% <strong>in</strong> xval ( che puo ’ e s s e r e un v e t t o r e )% costruiamo la matrice A che ha come colonne g l i i−simi pol<strong>in</strong>omi <strong>di</strong> Lagrange% v a l u t a t i nel v e t t o r e xval% ciascuna riga j <strong>di</strong> A contiene dunque L_1 ( xval ( j ) ) L_2 ( xval ( j ) . . . .% i l prodotto <strong>di</strong> ciascuna riga per i l v e t t o r e colonna y r e s t i t u i s c e qu<strong>in</strong><strong>di</strong>% i l valore del pol<strong>in</strong>omio <strong>di</strong> Lagrange <strong>in</strong> yval ( j )% Per questo faremo i l prodotto matrice−v e t t o r e% Esempio% >> x = [ 0 , 1 , 2 ] ;% >> y =[1 0 2 ] ;% >> xval = 0 . 5 ;% >> yval=<strong>in</strong>terplagrange ( xval , x , y )%% yval =%% 0.1250% >> yval=<strong>in</strong>terplagrange ( x ( 1 ) , x , y )%% yval =%% 1%% >> yval=<strong>in</strong>terplagrange ( x ( 2 ) , x , y )%% yval =%% 0%% >> yval=<strong>in</strong>terplagrange ( x ( 3 ) , x , y )%% yval =%% 2%%i f length ( x)~= length ( y )error (’MATLAB:lagrange’ ,’x e y non hanno la stessa lunghezza’)endy=y ( : ) ;n=length ( x ) ;% n−1 e ’ i l grado del pol<strong>in</strong>omiom=length ( xval ) ;A=zeros (m, n ) ;A( : , 1 ) = lagrange ( xval , x , 1 ) ;for i =2:nA ( : , i )= lagrange ( xval , x , i ) ;endyval=A* y ;end49


2. SU INTERPOLAZIONE E APPROSSIMAZIONE<strong>Esercizi</strong>o 2.1.1 Date le coppie <strong>di</strong> punti (0,−1), (0.5,0.1), (1,−0.3), (1.2,1.2) e (2,3), fare il grafico del pol<strong>in</strong>omio<strong>di</strong> <strong>in</strong>terpolazione nell’<strong>in</strong>tervallo [0,2]. Si faccia uno script <strong>in</strong> modo da poter scegliere, <strong>in</strong> <strong>in</strong>put, se usarela function polyfit, o la <strong>in</strong>terpmonom o la <strong>in</strong>terplagrange associando la scelta ad una variabile(per esempio scelta : se scelta==1 applica l’approccio della polyfit, se scelta==2 si usa la<strong>in</strong>terpmonom, se scelta==3 si applica l’<strong>in</strong>terpolazione <strong>di</strong> Lagrange). Si valuti il pol<strong>in</strong>omio nel vettorexval=0:0.02:2 e se ne faccia il grafico.2.2 Interpolazione con la tabella delle <strong>di</strong>fferenze <strong>di</strong>vise <strong>di</strong> NewtonProviamo ora a calcolare il pol<strong>in</strong>omio <strong>di</strong> <strong>in</strong>terpolazione utilizzando le <strong>di</strong>fferenze <strong>di</strong>vise <strong>di</strong> Newton.Ricor<strong>di</strong>amo che, date n + 1 coppie <strong>di</strong> punti da <strong>in</strong>terpolare, (x i , f (x i )), i = 0,1,...,n, la tabella delle<strong>di</strong>fferenze <strong>di</strong>vise si costruisce considerando la formulaf [x i ] = f (x i )f [x i ,..., x j ] = f [x i+1,... x j ] − f [x i ,..., x j −1 ]x j − x iPossiamo costruire una tabella nel modo seguente:x i f [·] f [·,·] f [·,·,·] f [·,·,·,·] f [·,·,·,·,·] ···x 0 f (x 0 )f (x 1 ) − f (x 0 )x 1 f (x 1 )x 1 − x 0f (x 2 ) − f (x 1 ) f [x 2 , x 1 ] − f [x 0 , x 1 ]x 2 f (x 2 )x 2 − x 1 x 2 − x 0f (x 3 ) − f (x 2 ) f [x 2 , x 3 ] − f [x 1 , x 2 ] f [x 1 , x 2 , x 3 ] − f [x 0 , x 1 , x 2 ]x 3 f (x 3 )x 3 − x 2 x 3 − x 1 x 3 − x 0f (x 4 ) − f (x 3 ) f [x 3 , x 4 ] − f [x 2 , x 3 ] f [x 2 , x 3 , x 4 ] − f [x 1 , x 2 , x 3 ] f [x 1 , x 2 , x 3 , x 4 ] − f [x 0 , x 1 , x 2 , x 3 ]x 4 f (x 4 )x 4 − x 3 x 4 − x 2 x 4 − x 1 x 4 − x 0...... ·Di questa tabella, ci serviranno, poi, i valori della <strong>di</strong>agonale pr<strong>in</strong>cipale presi a partire da f (x 0 ).Possiamo allora costruire, <strong>in</strong> MATLAB, una matrice <strong>in</strong> cui salviamo i valori a partire dalla colonna delleor<strong>di</strong>nate.Nel caso <strong>di</strong> n + 1 = 5 coppie <strong>di</strong> punti, la matrice che andremo a costruire sarà:f (x 0 ) 0 0 0 0f (x 1 ) − f (x 0 )f (x 1 )0 0 0x 1 − x 0f (x 2 ) − f (x 1 ) f [x 2 , x 1 ] − f [x 0 , x 1 ]f (x 2 )0 0x 2 − x 1 x 2 − x 0f (x 3 ) − f (x 2 ) f [x 2 , x 3 ] − f [x 1 , x 2 ] f [x 1 , x 2 , x 3 ] − f [x 0 , x 1 , x 2 ]f (x 3 )0x 3 − x 2 x 3 − x 1 x 3 − x 0f (x 4 ) − f (x 3 ) f [x 3 , x 4 ] − f [x 2 , x 3 ] f [x 2 , x 3 , x 4 ] − f [x 1 , x 2 , x 3 ] f [x 1 , x 2 , x 3 , x 4 ] − f [x 0 , x 1 , x 2 , x 3 ]f (x 4 )x 4 − x 3 x 4 − x 2 x 4 − x 1 x 4 − x 050


2.2. Interpolazione con la tabella delle <strong>di</strong>fferenze <strong>di</strong>vise <strong>di</strong> NewtonDi questa matrice, che chiamiamo A; ci serviranno, poi, i valoriA(1,1) = f (x 0 ),A(2,2) = f (x 1) − f (x 0 )x 1 − x 0,A(3,3) = f [x 2, x 1 ] − f [x 0 , x 1 ]x 2 − x 0,A(4,4) = f [x 1, x 2 , x 3 ] − f [x 0 , x 1 , x 2 ]x 3 − x 0,A(5,5) = f [x 1, x 2 , x 3 , x 4 ] − f [x 0 , x 1 , x 2 , x 3 ]x 4 − x 0, cioè gli elementi della <strong>di</strong>agonale pr<strong>in</strong>cipale della matrice A (l’<strong>in</strong><strong>di</strong>ce <strong>di</strong> riga è uguale all’<strong>in</strong><strong>di</strong>ce <strong>di</strong> colonna).In particolare, A(2,2) = f [x 0 , x 1 ], A(3,3) = f [x 0 , x 1 , x 2 ], A(4,4) = f [x 0 , x 1 , x 2 , x 3 ] e A(5,5) =f [x 0 , x 1 , x 2 , x 3 , x 4 ]. Questi sono i coefficienti del pol<strong>in</strong>omio <strong>di</strong> <strong>in</strong>terpolazione che va scritto comep 4 (x) = f (x 0 ) + f [x 0 , x 1 ](x − x 0 ) + f [x 0 , x 1 , x 2 ](x − x 0 )(x − x 1 ) + f [x 0 , x 1 , x 2 , x 3 ](x − x 0 )(x − x 1 )(x − x 2 )+f [x 0 , x 1 , x 2 , x 3 , x 4 ](x − x 0 )(x − x 1 )(x − x 2 )(x − x 3 )Partiamo con il costruire una function che, date le ascisse e le or<strong>di</strong>nate dei punti da <strong>in</strong>terpolare, cirestituisce questa tabella delle <strong>di</strong>fferenze <strong>di</strong>vise. Chiamiamo questa function <strong>di</strong>v<strong>di</strong>f.mfunction table= d i v d i f ( x , y )%function table=<strong>di</strong>v<strong>di</strong>f ( x , y )% x − a s c i s s e dei dati da <strong>in</strong>terpolare% y − or<strong>di</strong>nate dei dati da <strong>in</strong>terpolare% table − t a b e l l a d e l l e d i f f e r e n z e d i v i s e% la t a b e l l a ha l e colonne <strong>di</strong>sposte nel modo seguente% f f [ . , . ] f [ . , . , . ] f [ . , . , . , . ] f [ . , . , . , . , . ]% al f i n e <strong>di</strong> c o s t r u i r e i l pol<strong>in</strong>omio <strong>di</strong> <strong>in</strong>terpolazione , la% t a b e l l a parte dalla colonna d e l l e or<strong>di</strong>nate da <strong>in</strong>terpolare%% Esempio% x=[0 0.5 1 1.2 2 ] ;% y=[−1 0.1 −0.3 1.2 2 ] ;% table=<strong>di</strong>v<strong>di</strong>f ( x , y )%table =%% −1.0000 0 0 0 0% 0.1000 2.2000 0 0 0% −0.3000 −0.8000 −3.0000 0 0% 1.2000 7.5000 11.8571 12.3810 0% 2.0000 1.0000 −6.5000 −12.2381 −12.3095%x=x ( : ) ;y=y ( : ) ;n=length ( x ) ; % n numero t o t a l e <strong>di</strong> coppie <strong>di</strong> punti da <strong>in</strong>terpolare% qu<strong>in</strong><strong>di</strong> i l grado del pol<strong>in</strong>omio sara ’ n−1i f n~=length ( y )error (’MATLAB:<strong>di</strong>fferenze_<strong>di</strong>vise’ , ’errore sui dati’)elsetable=zeros (n , n ) ; % la t a b e l l a deve arrivare a c a l c o l a r e la d i f f e r e n z a% <strong>di</strong>visa <strong>di</strong> or<strong>di</strong>ne ntable ( : , 1 ) = y ; % la prima colonna ha l e or<strong>di</strong>nate d e l l e coppie <strong>di</strong> punti da <strong>in</strong>terpolarefor j =2:nfor k =2: j51


2. SU INTERPOLAZIONE E APPROSSIMAZIONEtable ( j , k)= ( table ( j , k−1) − table ( j −1,k−1) ) / ( x ( j ) − x ( j−k+1) ) ;endend% con la formula r i c o r s i v a usata nei due c i c l i f o r an<strong>di</strong>amo a c o s t r u i r e i% v a l o r i della t a b e l l a riga dopo riga% j =2 k=2 abbiamo solo table ( 2 , 2 ) che corrisponde alla prima d i f f e r e n z a% <strong>di</strong>visa tra x0 e x1% j =3 , k =2 ,3; ricaviamo table ( 3 , 2 ) e table ( 3 , 3 ) , dove table ( 3 , 2 )% corrisponde alla d i f f e r e n z a <strong>di</strong>visa del primo or<strong>di</strong>ne tra x1 e x2% table ( 3 , 3 ) corrisponde alla d i f f e r e n z a <strong>di</strong>visa del secondo or<strong>di</strong>ne% tra x0 , x1 e x2 . E cosi ’ via .endOsserviamo che abbiamo chiamato table la matrice che contiene i valori della tabella delle <strong>di</strong>fferenze<strong>di</strong>vise. I valori sono costruiti riga per riga.Di questa tabella, abbiamo detto, ci servono solo i valori della <strong>di</strong>agonale pr<strong>in</strong>cipale, <strong>in</strong> modo da potervalutare il pol<strong>in</strong>omio <strong>di</strong> <strong>in</strong>terpolazione.Per valutare il pol<strong>in</strong>omio <strong>di</strong> <strong>in</strong>terpolazione nel modo più efficiente, applichiamo l’algoritmo <strong>di</strong> Horner,che è un algoritmo molto semplice. Cerchiamo <strong>di</strong> capire con un esempio come funziona.Supponiamo <strong>di</strong> dover calcolare il pol<strong>in</strong>omio p(x) = 2 + 3(x − 1) + 4(x − 1)(x − 2) + 10(x − 1)(x − 2)(x − 3).Se facciamo i calcoli così come leggiamo la formula dobbiamo fare somme e prodotti e, <strong>in</strong> particolare, dobbiamofare 3(x − 1) (una moltiplicazione) 4(x − 1)(x − 2) (due moltiplicazioni) e 10(x − 1)(x − 2)(x − 3) (tremoltiplicazioni). Riscriviamo la formula nel modo seguentep(x) = 2 + (x − 1)(3 + 4(x − 2) + 10(x − 2)(x − 3))p(x) = 2 + (x − 1)(3 + (x − 2)(4 + 10(x − 3)))Abbiamo messo <strong>in</strong> evidenza i term<strong>in</strong>i (x − 1) e poi (x − 2). Ora dobbiamo fare 10(x − 3) (una moltiplicazione),poi sommiamo 4 e moltiplichiamo il tutto per (x − 2) (un’altra moltiplicazione), sommiamo 3 emoltiplichiamo per (x − 1) (un’altra moltiplicazione). Rispetto alle 6 moltiplicazioni <strong>di</strong> prima ora ne facciamosolo 3. L’algoritmo <strong>di</strong> Horner si può scrivere nel modo seguente, per calcolare il pol<strong>in</strong>omio p(x) =a 0 + a 1 (x − x 0 ) + a 2 (x − x 0 )(x − x 1 ) + a 3 (x − x 0 )(x − x 1 )(x − x 2 ) + ... a n (x − x 0 )(x − x 1 )(x − x 2 )···(x − x n−1 ):p = a np = p(x − x n−1 ) + a n−1= a n (x − x n−1 ) + a n−1p = p(x − x n−2 ) + a n−2.= a n (x − x n−1 )(x − x n−2 ) + a n−1 (x − x n−2 ) + a n−2p = p(x − x 0 ) + a 0= a n (x − x n−1 )(x − x n−2 )...(x − x 1 )(x − x 0 ) + ... + a 1 (x − x 1 )(x − x 0 ) + a 0= a 0 + a 1 (x − x 0 )(x − x 1 ) + ... + a n (x − x 0 )(x − x 1 )...(x − x n−2 )(x − x n−1 )Se a è il vettore che contiene i coefficienti del pol<strong>in</strong>omio (<strong>in</strong> questo caso sarà un vettore <strong>di</strong> lunghezza n+1), sex è il vettore delle ascisse e xval il punto <strong>in</strong> cui valutare il pol<strong>in</strong>omio p, le istruzioni precedenti si scriveranno<strong>in</strong> MATLAB comep=a (n+ 1 ) ;for i =n: −1:1p=p* ( xval−x ( j ) ) + a ( j ) ;endScriviamo dunque la function <strong>in</strong>terp<strong>di</strong>v<strong>di</strong>f.m (teniamo conto del fatto che, nella function n è la lunghezzadel vettore x, qu<strong>in</strong><strong>di</strong> il grado del pol<strong>in</strong>omio è n − 1). Poichè possiamo valutare il pol<strong>in</strong>omio sia <strong>in</strong>52


2.2. Interpolazione con la tabella delle <strong>di</strong>fferenze <strong>di</strong>vise <strong>di</strong> Newtonuno scalare sia <strong>in</strong> un vettore, dobbiamo tenere conto anche <strong>di</strong> questo fatto quando an<strong>di</strong>amo ad applicarel’algoritmo <strong>di</strong> Horner: si veda l’istruzione yval=table(n,n)*ones(length(xval),1); e l’uso del .∗ all’<strong>in</strong>terno del ciclofor.function yval= i n t e r p d i v d i f ( xval , x , table )% function yval= i n t e r p d i v d i f ( xval , x , table )% x − a s c i s s e dei dati da <strong>in</strong>terpolare% table − t a b e l l a d e l l e d i f f e r e n z e <strong>di</strong>vise , ottenuta dalla function d i v d i f% xval − array <strong>di</strong> v a l o r i <strong>in</strong> cui c a l c o l a r e i l pol<strong>in</strong>omio i n t e r p o l a t o r e% puo ’ e s s e r e un s<strong>in</strong>golo punto o un <strong>in</strong>sieme <strong>di</strong> punti% yval − valore ( o v a l o r i ) del pol<strong>in</strong>omio i n t e r p o l a t o r e valutato <strong>in</strong> xval% nel calcolo del pol<strong>in</strong>omio <strong>in</strong>terpolatore ,% s i parte dalla f i n e e s i applica l ’ algoritmo <strong>di</strong> Horner ( s i veda <strong>di</strong>spensa% per la spiegazione sull ’ algoritmo <strong>di</strong> Horner )% Esempio% x=[0 0.5 1 1.2 2 ] ;% y=[−1 0.1 −0.3 1.2 2 ] ;% table=<strong>di</strong>v<strong>di</strong>f ( x , y ) ;% xval = [ 0 : 0 . 1 : 2 ] ;% yval= i n t e r p d i v d i f ( xval , x , table ) ;% plot ( x , y , ’ o ’ , xval , yval )xval=xval ( : ) ;x=x ( : ) ;n=length ( x ) ; % n lunghezza del v e t t o r e x , qu<strong>in</strong><strong>di</strong> n−1 e ’ i l grado del% pol<strong>in</strong>omio <strong>di</strong> <strong>in</strong>terpolazioneyval=table (n , n) * ones ( length ( xval ) , 1 ) ;for j =n−1:−1:1yval=yval . * ( xval−x ( j ) ) + table ( j , j ) ;endendUn altro modo per costruire il pol<strong>in</strong>omio <strong>di</strong> <strong>in</strong>terpolazione <strong>di</strong> Newton può essere quello <strong>di</strong> richiamare lafunction che genera la tabella delle <strong>di</strong>fferenze <strong>di</strong>vise all’<strong>in</strong>terno della stessa function che valuta il pol<strong>in</strong>omio <strong>di</strong><strong>in</strong>terpolazione. In MATLAB, <strong>in</strong>fatti, una function può richiamare al suo <strong>in</strong>terno un’altra function e questa puòessere scritta <strong>in</strong> forma concatenata alla prima, cioè all’<strong>in</strong>terno della function che la richiama! Si parla <strong>di</strong> nestedfunctions. Ciò si può fare se la function <strong>in</strong>terna non è chiamata all’<strong>in</strong>terno <strong>di</strong> un ciclo come if, for,while, .... Osserviamo che la function <strong>in</strong>terna deve necessariamente essere chiusa con l’istruzione end.In questo modo, al posto <strong>di</strong> usare due functions, ne usiamo solo una. Se ci <strong>in</strong>teressa conoscere la tabelladelle <strong>di</strong>fferenze <strong>di</strong>vise, possiamo metterla tra i parametri <strong>di</strong> output. Scriviamo allora la function chechiamiamo <strong>in</strong>t<strong>di</strong>v<strong>di</strong>f1.mfunction [ yval , table ]= i n t d i v d i f 1 ( x , y , xval )% function yval= i n t d i v d i f 1 ( xval , x , y )% x − a s c i s s e dei dati da <strong>in</strong>terpolare% y − or<strong>di</strong>nate dei dati da <strong>in</strong>terpolare% xval − array <strong>di</strong> v a l o r i <strong>in</strong> cui c a l c o l a r e i l pol<strong>in</strong>omio i n t e r p o l a t o r e% puo ’ e s s e r e un s<strong>in</strong>golo punto o un v e t t o r e% yval − valore ( o v a l o r i ) del pol<strong>in</strong>omio i n t e r p o l a t o r e valutato <strong>in</strong> xval% nel calcolo del pol<strong>in</strong>omio <strong>in</strong>terpolatore ,% s i parte dalla f i n e e s i applica l ’ algoritmo <strong>di</strong> Horner% all ’ <strong>in</strong>terno <strong>di</strong> questa function s i richiama un ’ a l t r a function che% calcola la t a b e l l a d e l l e d i f f e r e n z e d i v i s etable=tab ( x , y ) ;%%%%%%%%%%%%% function chiamata e s c r i t t a all ’ <strong>in</strong>terno della function %%%function table=tab ( x , y )%function table=<strong>di</strong>v<strong>di</strong>f ( x , y )% x − a s c i s s e dei dati da <strong>in</strong>terpolare53


2. SU INTERPOLAZIONE E APPROSSIMAZIONE% y − or<strong>di</strong>nate dei dati da <strong>in</strong>terpolare% table − t a b e l l a d e l l e d i f f e r e n z e d i v i s ex=x ( : ) ;y=y ( : ) ;n=length ( x ) ;m=length ( y ) ;i f n~=merror (’MATLAB:<strong>di</strong>fferenze_<strong>di</strong>vise’ , ’errore sui dati’)elsetable=zeros (n , n ) ;table ( : , 1 ) = y ;for j =2:nfor k =2: jtable ( j , k)= ( table ( j , k−1) − table ( j −1,k−1) ) / ( x ( j ) − x ( j−k+1) ) ;endendendend%%%%%%%%%%%%%%%%%%%%%% f i n e function tab%%xval=xval ( : ) ;x=x ( : ) ;n=length ( x ) ;yval=table (n , n) * ones ( length ( xval ) , 1 ) ;for j =n−1:−1:1yval=yval . * ( xval−x ( j ) ) + table ( j , j ) ;endend<strong>Esercizi</strong>o 2.2.1 Si riprendano i dati (0,−1), (0.5,0.1), (1,−0.3), (1.2,1.2) e (2,3), e si applichi il proce<strong>di</strong>mento<strong>di</strong> <strong>in</strong>terpolazione delle <strong>di</strong>fferenze <strong>di</strong>vise <strong>di</strong> Newton per calcolare il pol<strong>in</strong>omio <strong>di</strong> <strong>in</strong>terpolazione. Lo si valut<strong>in</strong>ei punti del vettore xval=0:0.01:2. Si faccia il grafico del pol<strong>in</strong>omio.2.3 Interpolazione l<strong>in</strong>eare a tratti e spl<strong>in</strong>e cubica2.3.1 Interpolazione l<strong>in</strong>eare a trattiAbbiamo visto, nella teoria, che, date m coppie <strong>di</strong> punti (x i , y i ) possiamo costruire il pol<strong>in</strong>omio <strong>di</strong> <strong>in</strong>terpolazionel<strong>in</strong>eare su ciascun <strong>in</strong>tervallo [x i , x i+1 ]. In questo caso è importante che le ascisse da <strong>in</strong>terpolare,oltre ad essere <strong>di</strong>st<strong>in</strong>te tra loro, siano or<strong>di</strong>nate <strong>in</strong> senso crescente, <strong>in</strong> modo da poter considerare gli <strong>in</strong>tervalli<strong>in</strong><strong>di</strong>cati [x i , x i+1 ]. Il pol<strong>in</strong>omio <strong>di</strong> <strong>in</strong>terpolazione si può scrivere come v(x) tale chev(x) = y i + f [x i , x i+1 ](x − x i ), x i ≤ x ≤ x i+1 , i = 1,2,...,m − 1.Dato un punto x bisogna capire a quale <strong>in</strong>tervallo appartiene per poter applicare la formula <strong>di</strong> <strong>in</strong>terpolazionel<strong>in</strong>eare corretta.Come scrivere una function <strong>in</strong> MATLAB che faccia tutto questo?Dato il vettore che contiene le ascisse dei punti da <strong>in</strong>terpolare, x=(x(1), x(2), ..., x(m)) e assegnato unpunto xval, il valore del pol<strong>in</strong>omio <strong>di</strong> <strong>in</strong>terpolazione l<strong>in</strong>eare a tratti si calcola <strong>in</strong> due passaggi:54


2.3. Interpolazione l<strong>in</strong>eare a tratti e spl<strong>in</strong>e cubica1. si <strong>in</strong><strong>di</strong>vidua l’<strong>in</strong>tervallo [x(i ), x(i + 1)] a cui appartiene xval;2. si calcola, qu<strong>in</strong><strong>di</strong> il valore del pol<strong>in</strong>omio applicando la formula per quell’<strong>in</strong>tervallo.Per scrivere una function che faccia tutto questo, useremo due strumenti <strong>di</strong> MATLAB:G Visto che, una volta <strong>in</strong><strong>di</strong>viduato l’<strong>in</strong>tervallo <strong>in</strong> cui valutare la funzione l<strong>in</strong>eare a tratti, ci serve la <strong>di</strong>fferenza<strong>di</strong>visa del primo or<strong>di</strong>ne (che altro non è che la pendenza del segmento <strong>di</strong> retta), consideriamoun vettore con le <strong>di</strong>fferenze <strong>di</strong>vise del primo or<strong>di</strong>ne. Usiamo la function <strong>di</strong> MATLAB <strong>di</strong>ff che calcolale <strong>di</strong>fferenze delle componenti del vettore dato <strong>in</strong> <strong>in</strong>put. Qu<strong>in</strong><strong>di</strong>, se x è un vettore <strong>di</strong> lunghezza m,<strong>di</strong>ff(x) è un vettore che ha come componenti x(2)-x(1), x(3)-x(1), ..., x(m) -x(m-1).Il vettore <strong>di</strong>ff(x) ha lunghezza m-1. Possiamo costruirci due vettori, <strong>di</strong>ff(x) e <strong>di</strong>ff(y). Dividendoquesti due vettori, componente per componente (usando qu<strong>in</strong><strong>di</strong> il comando ./) avremo ilvettore delle <strong>di</strong>fferenze <strong>di</strong>vise del primo or<strong>di</strong>ne. Chiamiamo p questo vettore (che sarà dunque dato dap=<strong>di</strong>ff(y)./<strong>di</strong>ff(x);G La cosa più <strong>di</strong>fficile è <strong>in</strong><strong>di</strong>viduare l’<strong>in</strong>tervallo <strong>in</strong> cui si trova ciascuna componente del vettore u <strong>in</strong> cuiandare a valutare il pol<strong>in</strong>omio <strong>di</strong> <strong>in</strong>terpolazione l<strong>in</strong>eare a tratti. Nel caso <strong>di</strong> una sola componente,potremmo pensare a qualcosa del generefor i =1: m−1i f x ( i )


2. SU INTERPOLAZIONE E APPROSSIMAZIONEx =[0 1 2 3 4 ] ;u=[1.5 2 . 4 ] ;k=ones ( 2 , 1 ) ;for i : 1 : lenght ( x)−1k ( x ( i )


2.3. Interpolazione l<strong>in</strong>eare a tratti e spl<strong>in</strong>e cubicax =[0 0.5 1 1.2 2 ] ;y=[−1 0.2 −0.2 0.3 1 . 5 ] ;pp=spl<strong>in</strong>e ( x , y ) ;u = 0 : 0 . 0 1 : 2 ;v=ppval (pp , u ) ;Oppure, più semplicemente, proviamo a scriverex =[0 0.5 1 1.2 2 ] ;y=[−1 0.2 −0.2 0.3 1 . 5 ] ;u = 0 : 0 . 0 1 : 2 ;v=spl<strong>in</strong>e ( x , y , u ) ;Dopo facciamo il grafico plot(x,y,’o’, u,v).Proviamo adesso a scrivere noi una function che costruisca la spl<strong>in</strong>e cubica. Noi abbiamo stu<strong>di</strong>ato <strong>in</strong> tuttii passaggi come si arriva alla costruzione della spl<strong>in</strong>e cubica naturale ed è proprio una function che generaquesto tipo <strong>di</strong> spl<strong>in</strong>e che andremo a costruire.Ricor<strong>di</strong>amo che l’algoritmo per arrivare alla spl<strong>in</strong>e cubica naturale prevede la soluzione <strong>di</strong> un sistemal<strong>in</strong>eare. La spl<strong>in</strong>e cubica ha la formav(x) = s i (x) = a i + b i (x − x i ) + c i (x − x i ) 2 + d i (x − x i ) 3 , x i ≤ x ≤ x i+1 , i = 1,2,...m − 1I coefficienti c i sono ricavati risolvendo il sistema Ac = β, con A e β dati da,⎛⎞2(h 1 + h 2 ) h 2 0 ··· 0h 2 2(h 2 + h 3 ) h 3 0.0 h 3 2(h 3 + h 4 ) h 4 ...A =. 0.. . .. . .. 0⎜⎝⎟. h m−3 2(h m−3 + h m−2 ) h m−2⎠0 ··· 0 h m−2 2(h m−2 + h m−1 )⎛⎞3(f [x 2 , x 3 ] − f [x 1 , x 2 ])3(f [x 3 , x 4 ] − f [x 2 , x 3 ])ψ =⎜⎝⎟.⎠3(f [x m−1 , x m ] − f [x m−2 , x m−1 ])dove h 1 , h 2 , ...,h m−1 sono le ampiezze dei s<strong>in</strong>goli sotto<strong>in</strong>tervalli.I passi da seguire (per i dettagli, si controlli la <strong>di</strong>spensa del corso) sono:1. risolvere il sistema Ac = ψ che, risolto, fornisce i coefficienti c 2 ,c 3 ,...,c m−1 delle spl<strong>in</strong>e;2. aggiungere al vettore c, i valori c 1 = c m = 03. applicare, per i = 1,...,m − 1 le relazionia i = y ib i = f [x i , x i+1 ] − (2c i + c i+1 )h i3d i = c i+1 − c i3h iOsserviamo che la matrice A ha elementi tutti uguali a zero tranne che gli elementi della <strong>di</strong>agonale pr<strong>in</strong>cipale(i valori A i i ) e gli elementi che si trovano sulla <strong>di</strong>agonale imme<strong>di</strong>atamente sopra e sotto la <strong>di</strong>agonalepr<strong>in</strong>cipale. Per costruire questa matrice <strong>in</strong> MATLAB usiamo la function <strong>di</strong>ag che costruisce matrici <strong>di</strong>agonalio estrae <strong>di</strong>agonali da una matrice. Ve<strong>di</strong>amo come si usa: supponiamo <strong>di</strong> avere un vettore d=[1 2 3],se scrivamo <strong>di</strong>ag(d) il risultato è la matrice57


2. SU INTERPOLAZIONE E APPROSSIMAZIONE1 0 00 2 00 0 3La matrice ha tutti zeri, tranne sulla <strong>di</strong>agonale pr<strong>in</strong>cipale <strong>in</strong> cui ci sono gli elementi del vettore d. La matriceha dunque la <strong>di</strong>mensione del vettore: <strong>in</strong> questo caso, 3 righe e 3 colonne Se <strong>in</strong>vece scriviamo il comando<strong>di</strong>ag(d,1) abbiamo0 1 0 00 0 2 00 0 0 30 0 0 0La matrice ha gli elementi del vettore d sulla <strong>di</strong>agonale che si trova sopra la <strong>di</strong>agonale pr<strong>in</strong>cipale. Ora la matriceè 4×4 perchè il vettore d deve riempire tutta la <strong>di</strong>agonale considerata. Qu<strong>in</strong><strong>di</strong>, se scriviamo <strong>di</strong>ag(d,-1)la matrice sarà con gli elementi del vettore d sulla sotto<strong>di</strong>agonale pr<strong>in</strong>cipale0 0 0 01 0 0 00 2 0 00 0 3 0In genere l’istruzione <strong>di</strong>ag(d,n) crea una matrice che ha tutti zeri tranne quelli che si trovano sulla<strong>di</strong>agonale spostata <strong>di</strong> n rispetto alla <strong>di</strong>agonale pr<strong>in</strong>cipale, <strong>in</strong> cui ci sono gli elementi del vettore d. La matriceè <strong>di</strong> <strong>di</strong>mensione uguale alla lunghezza del vettore d + il valore assoluto <strong>di</strong> n. La <strong>di</strong>agonale pr<strong>in</strong>cipale è comese avesse il valore n = 0, qu<strong>in</strong><strong>di</strong> ci spostiamo <strong>di</strong> n sopra o sotto la <strong>di</strong>agonale pr<strong>in</strong>cipale a seconda che nsia positivo o negativo. La function <strong>di</strong>ag si può applicare anche a matrici (si consulti l’help <strong>in</strong> l<strong>in</strong>ea perapprofon<strong>di</strong>re).A noi <strong>in</strong>teressa questa function perché, grazie ad essa, possiamo scrivere la matrice del sistema chedobbiamo risolvere:h= d i f f ( x ) ;n=length ( x ) −1;a= 2*(h ( 1 : n−1)+h ( 2 : n ) ) ;bi= h ( 2 : n−1);A=<strong>di</strong>ag ( a ) + <strong>di</strong>ag ( bi , 1 ) + <strong>di</strong>ag ( bi , −1);Infatti <strong>di</strong>ag(a) ci dà la matrice con tutti zero tranne che sulla <strong>di</strong>agonale pr<strong>in</strong>cipale e questi elementi corrispondonoproprio a quelli che vogliamo noi sulla matrice A. Se osserviamo poi come è fatta la matrice A glielementi sulla sovra e sotto <strong>di</strong>agonale sono gli stessi. Perciò usiamo il vettore b e creiamo altre due matrici.Con un operazione <strong>di</strong> somma, mettiamo <strong>in</strong>sieme i vari contributi e otteniamo la matrice A. Il vettore term<strong>in</strong>enoto fa uso delle <strong>di</strong>fferenze <strong>di</strong>vise del primo or<strong>di</strong>ne. Scriviamo ora la function e osserviamo bene l’uso degli<strong>in</strong><strong>di</strong>ci nei vettori per i vari coefficienti b, c,d.function v=spl<strong>in</strong>ecubiche ( x , y , u)% function v=spl<strong>in</strong>ecubiche ( x , y , u)% costruzione della spl<strong>in</strong>e cubica naturale a t r a t t i% x − v e t t o r e d e l l e a s c i s s e da <strong>in</strong>terpolare% y − v e t t o r e d e l l e or<strong>di</strong>nate da <strong>in</strong>terpolare% u − v e t t o r e <strong>in</strong> cui andare a c a l c o l a r e la spl<strong>in</strong>e cubica naturale% v − v e t t o r e della spl<strong>in</strong>e cubica naturale valutata nel v e t t o r e u% Esempio% x=[0 0.5 1 1.2 2 ] ;% y=[−1 0.2 −0.2 0.3 1 . 5 ] ;% u = [ 0 : 0 . 0 1 : 2 ] ;% v=spl<strong>in</strong>ecubiche ( x , y , u ) ;58


2.4. Curve parametriche% plot ( x , y , ’ o ’ , u , v )x=x ( : ) ;y=y ( : ) ;u=u ( : ) ;h= d i f f ( x ) ; % v e t t o r e che da ’ l e ampiezze dei s i n g o l i s o t t o i n t e r v a l l ip= d i f f ( y ) . / h ; % v e t t o r e d e l l e d i f f e r e n z e d i v i s e del primo or<strong>di</strong>nen=length ( x ) −1;a= 2*(h ( 1 : n−1)+h ( 2 : n ) ) ;bi= h ( 2 : n−1);A=<strong>di</strong>ag ( a ) + <strong>di</strong>ag ( bi , 1 ) + <strong>di</strong>ag ( bi , −1);psi= 3*(p ( 2 : n) −p ( 1 : n−1));c=A\ psi ;c = [ 0 ; c ; 0 ] ; % c o e f f i c i e n t i cd=( c ( 2 : n+1)−c ( 1 : n ) ) . / ( 3 * h ) ; % c o e f f i c i e n t i db=p−h . / 3 . * ( 2 . * c ( 1 : n)+ c ( 2 : n+ 1 ) ) ; % c o e f f i c i e n t i bk=ones ( length (u ) , 1 ) ;for i =1:nk ( x ( i )


2. SU INTERPOLAZIONE E APPROSSIMAZIONEche si aprirà dopo aver schiacchiato il tasto <strong>di</strong> <strong>in</strong>vio. Se <strong>in</strong>vece scriviamo [x,y]=g<strong>in</strong>put pren<strong>di</strong>amo un numero<strong>di</strong> punti a piacere f<strong>in</strong>o a che non schiacchiamo il tasto <strong>di</strong> <strong>in</strong>vio. Subito dopo, sia nel primo che nel secondocaso, troveremo le coor<strong>di</strong>nate dei punti nei vettori x e y. Inf<strong>in</strong>e, si può usare g<strong>in</strong>put me<strong>di</strong>ante l’istruzione[x,y,but]=g<strong>in</strong>put(n) che dà <strong>in</strong> output anche una terza variabile, but, che contiene un vettore <strong>di</strong> <strong>in</strong>teri chespecificano quale tasto del mouse è stato usato (1, 2 o 3 a partire da s<strong>in</strong>istra).Useremo questa soluzione per scegliere i punti. Porremo but=1, che è associato al tasto s<strong>in</strong>istro delmouse e prenderemo i punti con il tasto s<strong>in</strong>istro del mouse. Per scegliere l’ultimo punto, lo scegliamo conil tasto destro (eventualmente anche con il tasto centrale), <strong>in</strong> modo tale da cambiare il valore della variabilebut.Una volta ottenuti i punti scegliamo il tipo <strong>di</strong> <strong>in</strong>terpolazione. Approfittiamo dell’occasione per imparareun altro ciclo che si può usare <strong>in</strong> MATLAB, il ciclo switch.2.4.1 Il ciclo switchIl ciclo switch si usa <strong>in</strong> questo modo:Ciclo switchswitch ( espressione ) % ( l ’ espressione puo ’ e s s e r e uno s c alare o una str<strong>in</strong>ga )case { valore1 } % eseguita se l ’ espressione e ’ valutata al valore1 ){ i s t r u z i o n i }{ . . . }case { valore2 } % ( eseguita se l ’ espressione e ’ valutata al valore2 ){ i s t r u z i o n i }{ . . . }otherwise{ i s t r u z i o n i }{ . . . }endIl ciclo con switch confronta i valori dati nell’espressione che si trova subito dopo switch, con ciascunvalore assegnato a case ed esegue le istruzioni relative al case <strong>in</strong> cui valore ed espressione co<strong>in</strong>cidono.Ve<strong>di</strong>amo un semplice esempio dove l’espressione da confrontare è una str<strong>in</strong>ga:s c e l t a =’test1’ ;switch s c e l t acase {’test1’}x0= 0 . 1 ;x1= 0 . 2 ;case {’test2’}x0= 0 . 0 ;x1= 1 . 0 ;otherwise<strong>di</strong>sp (’nessun caso test scelto’)endA seconda del caso cambiano i valori x0,x1.Oltre al ciclo switch, per scegliere il tipo <strong>di</strong> <strong>in</strong>terpolazione usiamo un’altra function, <strong>di</strong> MATLAB, chiamatamenu. La function menu genera un menu che permette <strong>di</strong> fare delle scelte, ognuna associata adun numero. Questo menu, <strong>in</strong> MATLAB compare come una f<strong>in</strong>estra separata dalle altre f<strong>in</strong>estre <strong>di</strong> MA-TLAB. In <strong>Octave</strong>, <strong>in</strong>vece, il menu rimane nella f<strong>in</strong>estra <strong>di</strong> lavoro. In genere la function si usa <strong>in</strong> questo modoscelta= menu(’titolo del menu’, scelta1,scelta2,scelta3,...) dove scelta1,scelta2,... sono dellestr<strong>in</strong>ghe che <strong>di</strong>cono la possibile scelta da fare. Il valore della variabile scelta corrisponde al numero checorrisponde alla str<strong>in</strong>ga della scelta fatta.Ve<strong>di</strong>amo un esempio60


2.4. Curve parametricheFigura 2.1: Esempio <strong>di</strong> menu <strong>in</strong> MATLABs c e l t a =menu(’scegli un metodo’ , ’bisezioni’ , ’punto fisso’ , ’Newton-Raphson’ ,’Regula Falsi’)In MATLAB vedremo qualcosa come mostrato <strong>in</strong> figura 2.1. Con il mouse sceglieremo quale metodoapplicare e la variabile scelta sarà 1, 2, 3 o 4 a seconda del metodo.In <strong>Octave</strong> <strong>in</strong>vece, ve<strong>di</strong>amo questo:scegli un metodo[ 1] bisezioni[ 2] punto fisso[ 3] Newton-Raphson[ 4] Regula Falsipick a number, any number:Ve<strong>di</strong>amo dunque lo script per le curve parametrice, che chiamiamo curveparam.m% questo e ’ uno s c r i p t per f are g r a f i c i <strong>di</strong> curve parametriche , potendo% s c e g l i e r e <strong>di</strong> f a r l e utilizzando un pol<strong>in</strong>omio <strong>di</strong> <strong>in</strong>terpolazione l i n e a r e% a t r a t t i oppure una spl<strong>in</strong>e cubica <strong>di</strong> tipo naturale o not−a−knot% i punti della curva vengono s c e l t i dall ’ utente me<strong>di</strong>ante la function% g<strong>in</strong>put :close a l l % chiude t u t t e l e eventuali f i g u r e e s i s t e n t i<strong>di</strong>sp (’**************** CURVE PARAMETRICHE*************’)<strong>di</strong>sp (’Usa il tasto s<strong>in</strong>istro del mouse per scegliere i punti.’)<strong>di</strong>sp (’Per l’’ultimo punto usare il tasto destro del mouse’)<strong>di</strong>sp (’Scegli dal menu il tipo <strong>di</strong> <strong>in</strong>terpolazione’)s c e l t a =menu(’tipo <strong>di</strong> <strong>in</strong>terpolazione a tratti’ , ’l<strong>in</strong>eare’ , ’spl<strong>in</strong>e naturale’ , . . .’spl<strong>in</strong>e not-a-knot’ ) ;figure ( 1 ) % apre una figuraaxis ( [ 0 1 0 1 ] ) % posiziona l ’ asse d e l l e a s c i s s e e d e l l e or<strong>di</strong>nate tra 0 e 1% Scegliamo i punti s u l l a f i n e s t r a della figura che s i e ’ aperta% con punti nell ’ i n t e r v a l l o [ 0 , 1 ] x [ 0 , 1 ]hold on % i g r a f i c i verranno t u t t i s o v r a s c r i t t ix = zeros ( 2 0 , 1 ) ; % <strong>in</strong>izializziamo a zero i v e t t o r i x e yy = zeros ( 2 0 , 1 ) ; % se saranno p r e s i piu ’ <strong>di</strong> 20 punti , i v e t t o r i% aumenteranno la loro lunghezzan = 0 ;but = 1 ; % but e ’ una v a r i a b i l e che serve per la function g<strong>in</strong>put61


2. SU INTERPOLAZIONE E APPROSSIMAZIONEwhile but == 1n=n+1;[ x (n) , y (n) , but ] = g<strong>in</strong>put ( 1 ) ; % g<strong>in</strong>put serve per acquisire i punti% s u l l a f i n e s t r a della figura% a nostro piacereplot ( x (n) , y (n) ,’g*’ ,’markersize’ , 6 )% t e x t ( xi +0.01 , y i +0.01 , i n t 2 s t r (n ) ) % questo comando serve se vogliamo% v i s u a l i z z a r e l ’ or<strong>di</strong>ne con cui sono% s c e l t i i no<strong>di</strong>endx=x ( 1 : n ) ;y=y ( 1 : n ) ;t =0:1/(n−1):1; % facciamo variare i l parametro t tra 0 e 1 , con passo h= 1 / (n−1)xx=l<strong>in</strong>space ( 0 , 1 ) ; % pren<strong>di</strong>amo 100 punti e q u i d i s t a n t i nell ’ i n t e r v a l l o <strong>in</strong> cui varia tswitch s c e l t acase 1u= a t r a t t i ( t , x , xx ) ;v= a t r a t t i ( t , y , xx ) ;str<strong>in</strong>ga=’<strong>in</strong>terpolazione l<strong>in</strong>eare a tratti’ ;case 2u=spl<strong>in</strong>ecubiche ( t , x , xx ) ;v=spl<strong>in</strong>ecubiche ( t , y , xx ) ;str<strong>in</strong>ga=’spl<strong>in</strong>e cubica naturale’ ;case 3u=spl<strong>in</strong>e ( t , x , xx ) ;v=spl<strong>in</strong>e ( t , y , xx ) ;str<strong>in</strong>ga=’spl<strong>in</strong>e cubica not-a-knot’ ;endplot (u , v ,’l<strong>in</strong>ewidth’ , 2 )t i t l e ( str<strong>in</strong>ga )hold o f f % i g r a f i c i s u c c e s s i v i non verranno s o v r a s c r i t t iE ora <strong>di</strong>vertiamoci a prendere punti e a costruire curve parametriche che passano per essi.2.5 Approssimazione <strong>di</strong> dati2.5.1 Retta <strong>di</strong> regressione sugli scarti verticaliAbbiamo visto, nella teorica, che i coefficienti della retta <strong>di</strong> regressione sugli scarti verticali si trovanorisolvendo il sistema <strong>di</strong> equazioni{(n + 1)a0 + a 1∑ ni=0 x i = ∑ ni=0 y ia 0∑ ni=0 x i + a 1∑ ni=0 (x i ) 2 = ∑ ni=0 x i y iL’ipotesi da cui partiamo è che abbiamo n + 1 coppie <strong>di</strong> punti (x i , y i ) i = 0,1,...,n. La retta che troviamo puòessere scritta come y = a 0 + a 1 x.Lo stesso sistema <strong>di</strong> equazioni si può scrivere <strong>in</strong> forma matriciale comeAa = bdoveA =( ∑ n + 1 ni=0 x )i∑ ni=0 x ∑ ni i=0 (x i ) 2( ∑ nb = i=0 y )i∑ ni=0 x i y iVogliamo risolvere <strong>in</strong> MATLAB questo problema. Come fare? La risposta imme<strong>di</strong>ata ce la fornisce MA-TLAB con la function che abbiamo già <strong>in</strong>contrato nell’<strong>in</strong>terpolazione e, precisamente, la function polyfit.62


2.5. Approssimazione <strong>di</strong> datiRicor<strong>di</strong>amo che i dati <strong>di</strong> <strong>in</strong>put che abbiamo usato per la polyfit sono i vettori x e y e il grado del pol<strong>in</strong>omio<strong>di</strong> <strong>in</strong>terpolazione (qu<strong>in</strong><strong>di</strong> length(x)-1). In generale, la polyfit ha, come dati <strong>di</strong> <strong>in</strong>put, oltre ai vettori xe y, un numero <strong>in</strong>tero m<strong>in</strong>ore o uguale a length(x)-1: per valori m<strong>in</strong>ori <strong>di</strong> length(x)-1, la functionpolyfit restituisce i coefficienti del pol<strong>in</strong>omio <strong>di</strong> migliore approssimazione del grado che abbiamo datonoi <strong>in</strong> <strong>in</strong>put. Perciò, se vogliamo una retta <strong>di</strong> approssimazione, basta scrivere p=polyfit(x,y,1) e nel vettore ptroveremo i coefficienti a 1 e a 0 della retta <strong>di</strong> approssimazione. Usando la polyval potremo fare il graficodella retta.L’algoritmo che costruisce la retta <strong>di</strong> approssimazione è molto semplice. Perché non fare una nostrafunction MATLAB? Approfittiamo dell’occasione per imparare qualche altra function. In particolare, <strong>in</strong>troduciamola function sum che, applicata a un vettore, fornisce come risultato la somma delle componenti delvettore. Ve<strong>di</strong>amo degli esempi:>> x=[-1 -0.4 0.2 0.8 1];>> sum(x)ans =0.6000>> x=[0 1 2 3 4 5 6 ];>> a=sum(x)a =21>> b=sum(x.^2)b =91Le prime due istruzioni che abbiamo dato, ci hanno restituito, <strong>in</strong> ans e <strong>in</strong> a, la somma delle componentidel vettore x. Nel primo caso, sum(x) è stata la stessa cosa dell’operazione: −1 − 0.4 + 0.2 + 0.8 + 1 = 0.6.Nel secondo caso, a = 0 + 1 + 2 + 3 + 4 + 5 + 6 = 21. Inf<strong>in</strong>e abbiamo fatto b=sum(x. 2 ), vale a <strong>di</strong>re, abbiamoprima elevato al quadrato ogni componente del vettore x ottenendo come risultato un vettore, e <strong>di</strong> questovettore abbiamo fatto la somma delle componenti. b = 0 2 + 1 2 + 2 2 + 3 2 + 4 2 + 5 2 + 6 2 = 91. A cosa ci servela function sum? A costruire <strong>in</strong> maniera imme<strong>di</strong>ata e <strong>di</strong>retta la matrice del sistema e il vettore term<strong>in</strong>e noto.Infatti, considerando m la lunghezza dei vettori dei dati da approssimare, possiamo scrivereA=[m sum( x ) ; sum( x ) sum( x . ^ 2 ) ] ;b=[sum( y ) ; sum( x . * y ) ] ;Nel vettore b, la seconda componente si ha costruendo prima il vettore x.*y che fa il prodotto componenteper componente tra i due vettori, e poi facendo la somma delle componenti.La function che possiamo scrivere è dunque la seguente:function [p , A , b]= funapprox ( x , y )% function p=funapprox ( x , y )% x −− a s c i s s e dei dati da approssimare% y −− or<strong>di</strong>nate dei dati da approssimare% p=[a1 a0 ] −− v e t t o r e dei c o e f f i c i e n t i della r e t t a% <strong>di</strong> r e g r e s s i o n e l i n e a r e s u g l i s c a r t i v e r t i c a l i% y=a0+a1x% i c o e f f i c i e n t i sono <strong>in</strong> or<strong>di</strong>ne decrescente% per p o t e r l i usare <strong>in</strong> comb<strong>in</strong>azione con la% function polyval% A −− matrice del sistema da r i s o l v e r e63


2. SU INTERPOLAZIONE E APPROSSIMAZIONE% b −− v e t t o r e term<strong>in</strong>e noto del sistema% Esempio% x=[−1 −0.6 0 0.6 1 ] ;% y =[1.194 0.430 0.052 0.422 1 . 0 3 4 ] ;% [ p , A , b]= funapprox ( x , y )% r e s t i t u i s c e% p =% −0.0606% 0.6264%% A =% 5.0000 0% 0 2.7200%% b =% 3.1320% −0.1648%% s i g n i f i c a che la r e t t a e ’ y=−0.1648 +3.1320xm=length ( x ) ;i f m~=length ( y )error (’MATLAB:funapprox’ , ’errore sui dati’)end% costruiamo la matrice del sistema% A=[ m somma_ascisse ;% somma_ascisse somma_( a s c i s s e ^2)]% i l v e t t o r e term<strong>in</strong>e noto e ’% b= [ somma_or<strong>di</strong>nate ; somma_ascisseperor<strong>di</strong>nate ]% per f are la somma d e l l e componenti <strong>di</strong> un v e t t o r e usiamo la function% sum che permette <strong>di</strong> f a r e la somma d e l l e componenti <strong>di</strong> un v e t t o r e% facendo sum( x . ^ 2 ) prima eseguiamo i quadrati d e l l e componenti% del v e t t o r e x e poi facciamo la somma dei v a l o r i r i c a v a t iA=[m sum( x ) ; sum( x ) sum( x . ^ 2 ) ] ;b=[sum( y ) ; sum( x . * y ) ] ;p=A\b ;% In p la prima componente corrisponde ad a0 e la seconda ad a1% <strong>in</strong>vertiamo l ’ or<strong>di</strong>ne del v e t t o r ep=p( 2 : − 1 : 1 ) ;Data questa function, possiamo (<strong>in</strong>vertendo il ruolo delle ascisse e delle or<strong>di</strong>nate nei dati <strong>di</strong> <strong>in</strong>put),calcolare i coefficienti della retta <strong>di</strong> regressione sugli scarti orizzontali.2.5.2 Modello potenza e modello esponenzialePossiamo scrivere una function che richiami questa che abbiamo appena creato, al f<strong>in</strong>e <strong>di</strong> calcolare icoefficienti delle funzioni <strong>di</strong> approssimazione, modello esponenziale e modello potenza.Per il modello potenza <strong>di</strong>amo, ora, delle l<strong>in</strong>ee da seguire per costruire una function che restituisca i coefficientia e b della funzione del modello potenza, e successivamente, per fare un grafico della funzione stessa.Nel modello potenza cerchiamo i coefficienti a b della funzione <strong>di</strong> approssimazione y = ax b . I passi da faresono i seguenti:G x e y siano i vettori con le ascisse e le or<strong>di</strong>nate dei dati da <strong>in</strong>terpolare;G costruiamo due nuovi vettori, X e Y (possiamo usare le lettere maiuscole) tali che X=log(x); Y=log(y); (abbiamousato il logaritmo naturale (<strong>in</strong> MATLAB log è il logaritmo naturale mentre log10 è il logaritmo<strong>in</strong> base 10);G chiamiamo la function funapprox che ci restituisce p,A,b ; p(1) e p(2) sono i coefficienti dellaretta, <strong>di</strong> grado decrescente;64


2.5. Approssimazione <strong>di</strong> datiG sappiamo che, per il modello potenza, si ha la relazione p(2)=log(a) e p(1)=b, da cuia=exp(p(2)); b=p(1)G una volta ricavati questi coefficienti, se vogliamo fare il grafico, dobbiamo ricondurci alla funzionepotenza, qu<strong>in</strong><strong>di</strong>xval=x ( 1 ) : h : x (end ) ; % con h passo <strong>di</strong> d i s c r e t i z z a z i o n e opportuno% per esempio s i puo ’ d e f i n i r e , prima% <strong>di</strong> questa i s t r u z i o n e% h=(x ( end)−x ( 1 ) ) / 1 0 0 ;% x ( end ) porta <strong>di</strong>rettamente all ’ ultima% componente del v e t t o r eyval=a* xval .^b ;plot ( x , y ,’o,xval,yval)Istruzioni analoghe a queste si possono dare per il modello esponenziale.<strong>Esercizi</strong>o 2.5.1 Si costruiscano due function, da chiamare, rispettivamente, modpotenza.m emodesponenziale.m <strong>in</strong> cui i dati <strong>di</strong> <strong>in</strong>put siano i vettori x e y dei dati da approssimare e <strong>in</strong> output<strong>di</strong>ano i coefficienti a e b rispettivamente del modello potenza e del modello esponenziale.2.5.3 Caricare i dati <strong>di</strong> <strong>in</strong>put da fileA volte, i dati da utilizzare per risolvere determ<strong>in</strong>ati problemi, possono essere vettori o matrici <strong>di</strong><strong>di</strong>mensione elevata. Scrivere i dati dalla Command W<strong>in</strong>dow <strong>di</strong>venta oneroso.Immag<strong>in</strong>iamo <strong>di</strong> dover approssimare i seguenti dati:x iy i0.0 0.00.2 3.220.39 6.610.59 9.690.78 13.220.99 16.401.08 18.011.18 19.701.28 21.331.37 22.75In questo esempio abbiamo 10 coppie <strong>di</strong> punti. Se dobbiamo scrivere tutti questi dati dalla Command W<strong>in</strong>dowe scriviamo male anche uno solo dei dati, se ce ne accorgiamo dobbiamo riscrivere o correggere il vettoree rieseguire lo script o la function. Se non ce ne accorgiamo, avremo i risultati decisamente scorretti. Se poidobbiamo, dopo qualche giorno, ripetere lo stesso esempio, dobbiamo riscrivere <strong>di</strong> nuovo il vettore sperando<strong>di</strong> non sbagliare i dati. Questo solo con 10 coppie <strong>di</strong> punti. Pensiamo se abbiamo 20, 100, 1000, .... dati.Molte volte i dati, proprio perché tanti, sono <strong>in</strong> un file <strong>di</strong> dati... Come procedere <strong>in</strong> questi casi? La cosa piùsemplice è <strong>di</strong> salvare i dati <strong>di</strong> <strong>in</strong>put <strong>in</strong> un file esterno (non <strong>in</strong> uno script o <strong>in</strong> una function) e <strong>di</strong> caricare questidati quando occorre. Tutto questo si fa nel modo seguente.Con un e<strong>di</strong>tor <strong>di</strong> testo scriviamo un file <strong>in</strong> cui mettiamo i dati (<strong>in</strong> questo caso i valori delle ascisse e delleor<strong>di</strong>nate da approssimare) esattamente come nella tabell<strong>in</strong>a che abbiamo scritto prima:0.0 0.00.2 3.220.39 6.610.59 9.6965


2. SU INTERPOLAZIONE E APPROSSIMAZIONE0.78 13.220.99 16.401.08 18.011.18 19.701.28 21.331.37 22.75Salviamo questo file (<strong>in</strong> formato testo, o ASCII) con un nome, ad esempio xy.txt o xy.dat. Ora <strong>in</strong>MATLAB, dalla Command W<strong>in</strong>dow, carichiamo questi dati <strong>in</strong> una matrice, dopo<strong>di</strong>chè, salviamo la primacolonna nel vettore x e la seconda colonna nel vettore y che ci servono per fare l’approssimazione dei datistessi.A=load (’xy.txt’ ) ;x=A ( : , 1 ) ;y=A ( : , 2 ) ;In questo modo, scriviamo i dati solo una volta nel file xy.txt e li carichiamo ogni volta che serve. Inquesto caso la matrice A ha due colonne, una che rappresenta il vettore x e una il vettore y.Potremmo anche scrivere la matrice con due righe: <strong>in</strong> tal caso dovremmo prendere la prima riga e salvarlacome vettore x e la seconda riga e salvarla come vettore y.Nel caso <strong>di</strong> molti dati, comunque, conviene salvare i dati come colonne (anche per facilità <strong>di</strong> lettura <strong>di</strong>essi).<strong>Esercizi</strong>o 2.5.2 Scrivere il file <strong>di</strong> dati xy.txt con i dati dell’esempio precedente. Utilizzare poi la functionfunapprox.m per approssimare i dati, sia costruendo la retta <strong>di</strong> regressione l<strong>in</strong>eare sugli scarti verticalisia costruendo la retta <strong>di</strong> regressione l<strong>in</strong>eare sugli scarti orizzontali. Fare il grafico delle due rette.Un altro modo per caricare dati da file esterni è abb<strong>in</strong>are la function <strong>in</strong>put con la function load. Dapprima<strong>di</strong>amo ad una variabile il nome del file <strong>di</strong> dati da caricare (dando qu<strong>in</strong><strong>di</strong> una str<strong>in</strong>ga <strong>di</strong> caratteri), poicarichiamo il file che ha quel nome. Ve<strong>di</strong>amo con l’esempio precedente come fare.>> str<strong>in</strong>ga=<strong>in</strong>put(’scrivi il file ’, ’s’)scrivi il file dati.txtstr<strong>in</strong>ga =dati.txt>> A=load(str<strong>in</strong>ga)A =>>0 00.2000 3.22000.3900 6.61000.5900 9.69000.7800 13.22000.9900 16.40001.0800 18.01001.1800 19.70001.2800 21.33001.3700 22.7500All’<strong>in</strong>terno <strong>di</strong> <strong>in</strong>put abbiamo scritto la frase scrivi il file e poi, dopo la virgola, abbiamo scritto’s’. Questa istruzione – ’s’ – <strong>di</strong>ce che quanto scriveremo <strong>in</strong> risposta alla function <strong>in</strong>put sarà una str<strong>in</strong>ga66


2.5. Approssimazione <strong>di</strong> dati<strong>di</strong> caratteri che verrà assegnata alla variabile str<strong>in</strong>ga. Successivamente, noi carichiamo il file, messo nellastr<strong>in</strong>ga dando alla matrice il nome A. L’importante è scrivere il nome del file senza apici e senza lasciare spazibianchi prima <strong>di</strong> <strong>in</strong>iziare a scrivere il nome (altrimenti avremmo un messaggio <strong>di</strong> errore).67


CAPITOLO 3Meto<strong>di</strong> <strong>di</strong>retti per sistemi l<strong>in</strong>eariParte della <strong>di</strong>sumanità del computersta nel fatto che, una voltaprogrammato e messo <strong>in</strong> funzione,si comporta <strong>in</strong> manieraperfettamente onesta.Isaac Asimov3.1 Prodotti matrice-vettore, matrice-matrice, scalari . . . . . . . . . . . . . . . . . . . . . . . . . . . . 713.2 Meto<strong>di</strong> <strong>di</strong> sostituzione all’<strong>in</strong><strong>di</strong>etro e <strong>in</strong> avanti . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 723.3 Meto<strong>di</strong> <strong>di</strong>retti . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 743.4 Norme <strong>di</strong> vettori . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75Nello stu<strong>di</strong>are i meto<strong>di</strong> <strong>di</strong>retti per la soluzione <strong>di</strong> sistemi l<strong>in</strong>eari, entriamo pienamente ad usare matrici evettori.MATLAB lavora con matrici e vettori e ha già molte function predef<strong>in</strong>ite che ci permettono <strong>di</strong> risolveresemplicemente problemi dell’algebra l<strong>in</strong>eare.F<strong>in</strong>o ad ora, abbiamo visto che, se abbiamo un sistema l<strong>in</strong>eare Ax = b e lo vogliamo risolvere, bastascrivere <strong>in</strong> MATLAB x=A\b per risolvere il sistema (l’importante è che il vettore b sia una vettore colonna).Abbiamo anche già visto le function:G zeros che agisce nel modo seguente:zeros(n) crea una matrice quadrata <strong>di</strong> <strong>di</strong>mensione nzeros(m,n) crea una matrice rettangolare <strong>di</strong> <strong>di</strong>mensione m×n (abbiamo usato questo comando percreare vettori riga o colonna)G size <strong>di</strong>ce la <strong>di</strong>mensione della matrice o <strong>di</strong> un vettoresize(A) restituisce un vettore <strong>in</strong> cui la prima componente <strong>di</strong>ce il numero <strong>di</strong> righe e la secondacomponente il numero <strong>di</strong> colonne della matrice AG length restituisce la lunghezza <strong>di</strong> un vettoreG <strong>di</strong>ag crea matrici <strong>di</strong>agonaliAbbiamo usato questa function per creare la matrice del sistema da risolvere per ottenere le spl<strong>in</strong>enaturali.Ve<strong>di</strong>amo degli esempi <strong>di</strong> uso <strong>di</strong> questa function per poter prendere maggiore pratica.>> v=[1 2 3];>> A=<strong>di</strong>ag(v)A =1 0 00 2 069


3. METODI DIRETTI PER SISTEMI LINEARI0 0 3>> A=<strong>di</strong>ag(v,1)A =0 1 0 00 0 2 00 0 0 30 0 0 0>> A=<strong>di</strong>ag(v,-1)A =0 0 0 01 0 0 00 2 0 00 0 3 0>> A=[1 2 3; 4 5 6; 7 8 9];>> b=<strong>di</strong>ag(A)b =159>> a=<strong>di</strong>ag(<strong>di</strong>ag(A))a =1 0 00 5 00 0 9Altre function e coman<strong>di</strong> utili già esistenti <strong>in</strong> MATLAB sono (non esauriamo tutto l’elenco delle functiona <strong>di</strong>sposizione ma <strong>di</strong>amo solo le pr<strong>in</strong>cipali!!!):G ones : analogamente a zeros crea matrici con elementi tutti uguali a 1.G eye : crea la matrice identità.A=eye(n) crea la matrice identità <strong>di</strong> <strong>di</strong>mensione nA=eye(m, n) crea la matrice identità <strong>di</strong> <strong>di</strong>mensione m × nSe abbiamo già una matrice (per esempio A): B=eye(size(A)) crea una matrice identità della stessa<strong>di</strong>mensione <strong>di</strong> A.G det : applicato ad una matrice quadrata, restituisce il determ<strong>in</strong>ante della matrice (esempio: d=det(A) )G <strong>in</strong>v : applicato ad una matrice quadrata, restituisce la matrice <strong>in</strong>versa. (Se la matrice è quasi s<strong>in</strong>golareo s<strong>in</strong>golare, si ha un messaggio <strong>di</strong> errore).G tril e triu : applicate ad una matrice estraggono la parte triangolare <strong>in</strong>feriore (o bassa) e superiore (oalta) rispettivamente. Se, tra i parametri <strong>di</strong> <strong>in</strong>put, oltre alla matrice, aggiungiamo uno scalare, k, alloraviene estratta la parte triangolare (<strong>in</strong>feriore o superiore) a partire dalla <strong>di</strong>agonale che si trova <strong>in</strong> alto o <strong>in</strong>basso (a seconda che k abbia segno positivo o negativo) <strong>di</strong> k volte sulla <strong>di</strong>agonale pr<strong>in</strong>cipale. Ve<strong>di</strong>amoqualche esempio.>> A=[1 2 3; 4 5 6; 7 8 9];>> L=tril(A)L =701 0 0


3.1. Prodotti matrice-vettore, matrice-matrice, scalari4 5 07 8 9>> U=triu(A)U =1 2 30 5 60 0 9>> L1=tril(A,1)L1 =1 2 04 5 67 8 9>> L_1=tril(A,-1)L_1 =0 0 04 0 07 8 0>> U=triu(A,1)U =0 2 30 0 60 0 0>> U=triu(A,-1)U =1 2 34 5 60 8 9Si provi a fare qualche altro esempio, con matrici 4 × 4 o 5 × 5.3.1 Prodotti matrice-vettore, matrice-matrice, scalariOra, se vogliamo fare il prodotto matrice-vettore, con altri l<strong>in</strong>guaggi <strong>di</strong> programmazione dobbiamo farequalcosa del genere (scriviamo ora una function matrprod.m)function y=matrprod (A , x )% supponiamo che A s i a quadrata <strong>di</strong> <strong>di</strong>mensione n e che x s i a un v e t t o r e% <strong>di</strong> lunghezza n . Se non siamo s i c u r i , dobbiamo f a r e un c o n t r o l l o% s u l l e <strong>di</strong>mensioni% calcoliamo y=Axn=length ( x ) ;y=zeros (n , 1 ) ; % <strong>in</strong>izializziamo i l v e t t o r e y% y_i= sum_( j =1)^n A_ ( i j ) x_j % per f a r e questa somma usiamo un c i c l o f o rfor i =1:nfor j =1:ny ( i )=y ( i )+A( i , j ) * x ( j ) ;71


3. METODI DIRETTI PER SISTEMI LINEARIendend% ora abbiamo t u t t e l e componenti del v e t t o r e yendIn MATLAB, al posto <strong>di</strong> dover fare qualcosa del genere (osservare il doppio ciclo for), basta scrivere y=A*x eviene generato il vettore x: bisogna solo avere l’accortezza <strong>di</strong> scrivere x come vettore colonna.Se dobbiamo fare un prodotto tra matrici, anche qui MATLAB ci evita <strong>di</strong> scrivere righe e righe <strong>di</strong> co<strong>di</strong>ce(che ora ve<strong>di</strong>amo per capire cosa dovremmo fare e non facciamo) e ci permette <strong>di</strong> usare l’operazione <strong>di</strong> moltiplicazioneanche per fare il prodotto tra matrici. (Attenzione, qu<strong>in</strong><strong>di</strong> al prodotto .* da usare per fare prodotticomponente per componente e al prodotto * che ci permette <strong>di</strong> fare queste altre operazioni). Se abbiamo duematrici A e B e dobbiamo scrivere la matrice prodotto C = AB, dalla teoria sappiamo che:c i j =n∑a i k b k j = a i 1 b 1j + a i 2 b 2j + ... + a i n b n jk=1per i = 1,2,...,n e j = 1,2,...,n.Tutto questo si può tradurre me<strong>di</strong>ante le righe <strong>di</strong> co<strong>di</strong>ce (supponiamo per semplicità che le due matrici Ae B siano quadrate e <strong>di</strong> <strong>di</strong>mensione n).C=zeros (n , n ) ;for i =1:nfor j =1:nfor k =1:nC( i , j )= C( i , j ) + A( i , k ) *B( k , j ) ;endendendIn MATLAB, scriviamo semplicemente C=A*B e abbiamo la matrice prodotto (evitando <strong>di</strong> fare un triplociclo for).Se dobbiamo fare il prodotto scalare tra due vettori α = x T y = ∑ ni=1 x i y i , possiamo vederlo come il prodottotra due matrici (il vettore riga x per il vettore colonna y). Se vogliamo vedere <strong>in</strong> co<strong>di</strong>ce cosa fareabbiamoa l f a =0;for i =1:na l f a = a l f a +x ( i ) * y ( i )endIn MATLAB, però, proprio perché il prodotto scalare si può vedere come caso particolare <strong>di</strong> prodotto tramatrici, usiamo la forma alfa=x*y se x è un vettore riga e y è un vettore colonna. Se i vettori sono entrambicolonna, si scrive alfa= x’*y (facciamo cioè il trasposto del primo vettore <strong>in</strong> modo da poterlo avere come riga).Bisogna qu<strong>in</strong><strong>di</strong> stare attenti a come sono stati def<strong>in</strong>iti i vettori <strong>di</strong> cui fare il prodotto scalare.3.2 Meto<strong>di</strong> <strong>di</strong> sostituzione all’<strong>in</strong><strong>di</strong>etro e <strong>in</strong> avantiNello stu<strong>di</strong>are il metodo <strong>di</strong> elim<strong>in</strong>azione <strong>di</strong> Gauss, abbiamo visto che, dal sistema <strong>di</strong> partenza Ax = b si arrivaal sistema LU x = b (supponiamo che sia verificato il teorema LDU e che abbiamo usato la fattorizzazione<strong>di</strong> Crout o <strong>di</strong> Doolittle). Per risolvere gli esercizi, risolveremo due sistemi:1. Poniamo U x = y da cui il sistema <strong>di</strong>venta Ly = b. Risolviamo qu<strong>in</strong><strong>di</strong> il sistema Ly = b me<strong>di</strong>antesostituzione <strong>in</strong> avanti.2. Una volta ricavato y risolviamo il sistema U x = y me<strong>di</strong>ante sostituzione all’<strong>in</strong><strong>di</strong>etro.Scriviamo allora due function che applich<strong>in</strong>o il metodo <strong>di</strong> sostituzione <strong>in</strong> avanti e <strong>di</strong> sostituzione all’<strong>in</strong><strong>di</strong>etro(possono tornarci utili per verificare gli esercizi che dobbiamo fare per prepararci all’esame scritto...)72


3.2. Meto<strong>di</strong> <strong>di</strong> sostituzione all’<strong>in</strong><strong>di</strong>etro e <strong>in</strong> avantiL’algoritmo per risolvere il sistema Ax = b dove A è adesso una matrice triangolare triangolare <strong>in</strong>feriore è:per i = 1 f<strong>in</strong>o a i = n, procedendo <strong>in</strong> avanti con passo 1x i =b i − ∑ i−1j =1 a i j x ja i iScriviamo una function che traduce questo algoritmo, ricordando che <strong>in</strong> MATLAB dobbiamo cercare <strong>di</strong> vettorizzareil più possibile le operazioni tra matrici e tra matrici e vettori. In questo caso, cerchiamo <strong>di</strong> fare ilmeno possibile i cicli for. E, <strong>in</strong>fatti, evitiamo <strong>di</strong> farlo per la somma ∑ i−1j =1 a i j x j . Ve<strong>di</strong>amo come (nella functionfacciamo anche un controllo sulle <strong>di</strong>mensioni della matrice e del vettore term<strong>in</strong>e noto).function x = sostavanti (A , b)% function x = sostavanti (A , b )% A e ’ una matrice triangolare i n f e r i o r e <strong>di</strong> <strong>di</strong>mensione n% b e ’ un v e t t o r e <strong>di</strong> lunghezza n% applichiamo i l metodo <strong>di</strong> s o s t i t u z i o n e <strong>in</strong> avanti per poter% r i s o l v e r e i l sistema Ax=b% Esempio% A= A=[1 0 0 ; 2 1 0 ; 1 2 3 ] ;% b = [ 1 ; 2 ; 3 ] ;% x=sostavanti (A , b )%%x =%% 1.0000% 0% 0.6667% Se scriviamo x=A\b abbiamo la s t e s s a r i s p o s t am= s i z e (A ) ;i f m( 1 ) ~= m( 2 )error (’MATLAB:sostavanti’ ,’matrice rettangolare’)endn=length (b ) ;i f m( 1 ) ~= nerror (’MATLAB:sostavanti’ , ’matrice e vettori <strong>di</strong> lunghezze <strong>di</strong>verse’)endx=zeros (n , 1 ) ;x (1)=b( 1 ) /A ( 1 , 1 ) ;for i =2:nx ( i )= (b( i ) − A( i , 1 : i −1)*x ( 1 : i −1) ) /A( i , i ) ;endendCome si vede dal listato, per calcolare ciascuna componente del vettore x, la somma ∑ i−1j =1 a i j x j viene fattacome prodotto tra la sottomatrice <strong>di</strong> A che considera la riga i -sima e tutti gli elementi <strong>di</strong> colonna che vannodalla prima colonna f<strong>in</strong>o a quella i − 1 (qu<strong>in</strong><strong>di</strong> questa sottomatrice è un vettore riga) per il vettore x con lecomponenti dalla prima alla i − 1 (e x è stato <strong>in</strong>izializzato come un vettore colonna). Qu<strong>in</strong><strong>di</strong> il risultato cheotteniamo è uno scalare (<strong>in</strong> pratica stiamo facendo il prodotto scalare tra due vettori). C’è da <strong>di</strong>re, <strong>in</strong>oltre, chela prima componente del vettore x è stata già def<strong>in</strong>ita prima <strong>di</strong> entrare nel ciclo for qu<strong>in</strong><strong>di</strong>, quando i=2 nelciclo for, dobbiamo considerare solo la prima componente <strong>di</strong> x che già abbiamo.È naturale ora pensare ad una function che traduca <strong>in</strong> modo simile l’algoritmo <strong>di</strong> sostituzione all’<strong>in</strong><strong>di</strong>etro:per i = n f<strong>in</strong>o a i = 1, procedendo all’<strong>in</strong><strong>di</strong>etro con passo −1x i =b i − ∑ nj =i+1 a i j x ja i iIn MATLAB scriviamo73


3. METODI DIRETTI PER SISTEMI LINEARIfunction x = s o s t i n<strong>di</strong>etro (A , b)% function x = s o s t i n d i e t r o (A , b )% A e ’ una matrice triangolare superiore <strong>di</strong> <strong>di</strong>mensione n% b e ’ un v e t t o r e <strong>di</strong> lunghezza n% applichiamo i l metodo <strong>di</strong> s o s t i t u z i o n e all ’ i n d i e t r o per poter% r i s o l v e r e i l sistema Ax=b% Esempio% A=[1 2 3 ; 0 2 1 ; 0 0 1 ] ;% b = [ 1 ; 2 ; 3]% >> x= s o s t i n d i e t r o (A , b )%% x =%% −7.0000% −0.5000% 3.0000% Se scriviamo x=A\b abbiamo la s t e s s a r i s p o s t am= s i z e (A ) ;i f m( 1 ) ~= m( 2 )error (’MATLAB:sost<strong>in</strong><strong>di</strong>etro’ ,’matrice rettangolare’)endn=length (b ) ;i f m( 1 ) ~= nerror (’MATLAB:sost<strong>in</strong><strong>di</strong>etro’ , ’matrice e vettori <strong>di</strong> lunghezze <strong>di</strong>verse’)endx=zeros (n , 1 ) ;x (n)=b(n) /A(n , n ) ;for i =n−1:−1:1x ( i )= (b( i ) − A( i , i +1:n) * x ( i +1:n) ) /A( i , i ) ;endendOsserviamo che queste function sono pensate esclusivamente per matrici che siano o triangolari <strong>in</strong>feriorio triagolari superiore.3.3 Meto<strong>di</strong> <strong>di</strong>rettiPer risolvere sistemi l<strong>in</strong>eari me<strong>di</strong>ante meto<strong>di</strong> <strong>di</strong>retti, abbiamo visto la fattorizzazione LU e, per matricisimmetriche def<strong>in</strong>ite positive, la fattorizzazione <strong>di</strong> Cholesky.In MATLAB ci sono già delle function che permettono <strong>di</strong> fare queste fattorizzazioni.C’è <strong>in</strong>fatti la function lu che fa la fattorizzazione LU, nel senso <strong>di</strong> Doolittle e me<strong>di</strong>ante una matrice <strong>di</strong>permutazione: si fa la fattorizzazione me<strong>di</strong>ante una matrice <strong>di</strong> permutazione P per cui otteniamo PA = LU .Gli usi più semplici sono[L,U]= lu(A) dà <strong>in</strong> output la matrice U triangolare superiore e L che è il prodotto <strong>di</strong> P −1 per la matrice Ldella fattorizzazione (qu<strong>in</strong><strong>di</strong> possiamo anche non avere come matrice una triangolare <strong>in</strong>feriore!).Se vogliamo capire chi sia questa matrice <strong>di</strong> permutazione, basta scrivere [L,U,P]=lu(A)Per quanto riguarda la fattorizzazione <strong>di</strong> Cholesky, dalla teoria, abbiamo visto che, se esiste la fattorizzazione,possiamo scrivere A = LL T . Se <strong>in</strong>vece <strong>di</strong> considerare L triangolare <strong>in</strong>feriore, pensiamo <strong>in</strong> term<strong>in</strong>i <strong>di</strong>U = L T , abbiamo A = U T U .In MATLAB c’è la function chol che, <strong>di</strong> default, restituisce la matrice triangolare superiore U .Se vogliamo avere la L, dobbiamo aggiungere una str<strong>in</strong>ga tra i parametri <strong>di</strong> <strong>in</strong>put.In particolareU=chol(A) restituisce la matrice triangolare superiore tale che U T U = AL=chol(A,’lower’) restituisce la matrice triangolare <strong>in</strong>feriore tale che LL T = A.Se la matrice <strong>di</strong> <strong>in</strong>put non è def<strong>in</strong>ita positiva si ha un messaggio <strong>di</strong> errore.74


3.4. Norme <strong>di</strong> vettori<strong>Esercizi</strong>o 3.3.1 Si provi a risolvere qualche esercizio <strong>di</strong> quelli proposti nei temi d’esame degli anni passati,implementando le function proposte (lu e chol) unitamente alle due function per la sostituzione <strong>in</strong> avantie all’<strong>in</strong><strong>di</strong>etro per risolvere i sistemi l<strong>in</strong>eari degli esercizi proposti.3.4 Norme <strong>di</strong> vettoriDato un vettore x abbiamo visto che è possibile ”misurare“ <strong>in</strong> un certo modo il vettore (estendendo ilconcetto del valore assoluto <strong>di</strong> un numero) attraverso una misura chiamata norma.In particolare abbiamo visto tre norme:G Norma assoluta (o norma l 1 ), <strong>in</strong><strong>di</strong>cata con ‖ · ‖ 1 : ‖x‖ 1 = ∑ ni=1 |x i |G Norma massima (o norma <strong>in</strong>f<strong>in</strong>ito, l ∞ ), <strong>in</strong><strong>di</strong>cata con ‖ · ‖ ∞ : ‖x‖ ∞ = max 1≤i≤n |x i |G Norma euclidea (o norma l 2 ), <strong>in</strong><strong>di</strong>cata con ‖ · ‖ 2 : ‖x‖ 2 = √ ∑nx T x =i=1 |x i | 2Come implementare queste norme <strong>in</strong> MATLAB?Per la norma 1, ricor<strong>di</strong>amoci della function cum già utilizzata e consideriamo come norma 1 <strong>di</strong> un vettorela variabile norma data danorma=cum( abs ( x ) ) ;Per la norma <strong>in</strong>f<strong>in</strong>ito dobbiamo calcolare il massimo <strong>in</strong> valore assoluto delle componenti del vettore x.In MATLAB la function max calcola il massimo della variabile (scalare o vettoriale) data <strong>in</strong> <strong>in</strong>put 1 , perciò lanorma <strong>in</strong>f<strong>in</strong>ito è data danorma=max( abs ( x ) ) ;Per la norma 2, la formula si può scrivere comenorma=sqrt (cum( x . ^ 2 ) ) ;oppure comenorma=sqrt ( x ’ * x ) ; % con x dato come v e t t o r e colonnaC’è tuttavia una function <strong>di</strong> MATLAB che fa già tutto questo e si chiama normG alfa=norm(x,1) restituisce la norma 1G alfa=norm(x) restituisce la norma 2 (potremmo anche scrivere alfa=norm(x,2) )G alfa=norm(x,<strong>in</strong>f) restituisce la norma <strong>in</strong>f<strong>in</strong>ito (al posto <strong>di</strong> <strong>in</strong>f possiamo anche scrivere Inf).Questa function ci tornerà utile anche per le norme su matrici.Per maggiori dettagli su questa e su tutte le altre function che abbiamo <strong>in</strong>contrato si rimanda all’helponl<strong>in</strong>e <strong>di</strong> MATLAB (o <strong>Octave</strong>).In molte occasioni ci serviranno vettori <strong>di</strong> norma unitaria (cioè la cui norma vale 1).Eseguiamo allora uno script per visualizzare graficamente, nello spazio R 2 , i vettori <strong>di</strong> norma unitarianelle varie norme 1, <strong>in</strong>f<strong>in</strong>ito e 2.Se un vettore x dello spazio R 2 , <strong>di</strong> componenti (x, y), ha norma unitaria <strong>in</strong> norma 1 vuol <strong>di</strong>re che |x|+|y| =1. Qu<strong>in</strong><strong>di</strong>, se facciamo variare la componente x nell’<strong>in</strong>tervallo [−1,1], sarà |y| = 1 − |x|. In questo mododelimitiamo la regione dei vettori unitari <strong>di</strong> norma 1.Per la norma <strong>in</strong>f<strong>in</strong>ito, deve essere max(|x|,|y|) = 1: qu<strong>in</strong><strong>di</strong> se x ∈ [−1,1], vuol <strong>di</strong>re che se non vale |x| = 1sarà |y| = 1.Inf<strong>in</strong>e, per la norma 2, dovendo essere √ x 2 + y 2 = 1, si ha x 2 + y 2 = 1 da cui y = ± 1 − x 2 .1 Se l’argomento <strong>di</strong> <strong>in</strong>put è una matrice, <strong>in</strong> output max restituisce il valore massimo <strong>di</strong> ogni colonna.75


3. METODI DIRETTI PER SISTEMI LINEARIQu<strong>in</strong><strong>di</strong> consideriamo il vettore delle ascisse, <strong>in</strong> cui facciamo variare x nell’<strong>in</strong>tervallo [−1,1] (non possiamoprendere ascisse al <strong>di</strong> fuori <strong>di</strong> questo <strong>in</strong>tervallo perché poi, qualunque valore prendessimo per y, la norma <strong>di</strong>(x, y) sarebbe maggiore <strong>di</strong> 1 mentre noi vogliamo identificare i vettori <strong>di</strong> norma unitaria).A seconda del tipo <strong>di</strong> norma scelto, andremo a costruire il vettore delle corrispondenti or<strong>di</strong>nate, <strong>in</strong> mododa avere vettori <strong>di</strong> componenti (x i , y i ) <strong>in</strong> norma unitaria.Per fare il grafico dei risultati che otterremo procederemo seguendo due strade: <strong>in</strong>tanto faremo un’unicafigura sud<strong>di</strong>visa <strong>in</strong> tre grafici che mostreranno la regione <strong>in</strong><strong>di</strong>viduata dai vettori <strong>di</strong> norma unitaria per ciascunadelle tre norme considerate. A ciascuno <strong>di</strong> questi grafici faremo vedere un ”campione“ dei vettori <strong>di</strong>norma unitaria.Per fare un’unica figura sud<strong>di</strong>visa <strong>in</strong> più grafici, usiamo il comando subplot che funziona così: immag<strong>in</strong>iamo<strong>di</strong> scomporre la figura <strong>in</strong> un certo numero <strong>di</strong> caselle <strong>di</strong>sposte su m righe e n colonne, <strong>in</strong> modo dadover poi fare m × n grafici. I grafici vengono contati a partire dalla casella (1,1), riga dopo riga. Eseguiremole seguenti istruzioni:subplot (m, n , 1 ) %dobbiamo creare i l primo g r a f i c o nella prima% c a s e l l a <strong>in</strong> alto a s i n i s t r aplot ( x1 , y1 ) % i l g r a f i c o viene f a t t o s u l l a c a s e l l a ( 1 , 1 )subplot (m, n , 2 ) % attiviamo la seconda c a s e l l a ( 1 , 2 )plot ( x2 , y2 ) % facciamo i l secondo g r a f i c osubplot (m, n , 3 ) % attiviamo la seconda c a s e l l a ( 1 , 3 )plot ( x3 , y3 ) % facciamo i l secondo g r a f i c o...Per tornare a fare grafici nel modo solito (un unico grafico su un’unica figura) possiamo chiudere la figuracorrente, con il comando close(1) (se la figura è la figura 1) oppure close all (e chiu<strong>di</strong>amo tutte le figure).Oppure possiamo scrivere subplot(1,1,1) e poi fare il nuovo plot.Per poter poi visualizzare <strong>in</strong> due <strong>di</strong>mensioni dei vettori (come siamo abituati dalla fisica), useremo la functioncompass: compass(x,y) fa il grafico dei vettori <strong>di</strong> componenti [x(i), y(i)] come frecce che partonodall’orig<strong>in</strong>e del sistema <strong>di</strong> assi cartesiani.Ecco allora lo script (come nome possiamo dargli normeunitarie.m 2% s c r i p t per vedere n e l l e norme 1 , i n f i n i t o e 2 e nello spazio R^2% i v e t t o r i <strong>di</strong> norma unitaria .x=l<strong>in</strong>space ( −1 ,1);% norma1= | x | + | y |% norma1=1 −−> | y |= 1−|x |y1=1−abs ( x ) ;y2=−y1 ;subplot ( 3 , 1 , 1 ) % abbiamo sud<strong>di</strong>viso la figura <strong>in</strong> 3 righe e 1 colonna% qu<strong>in</strong><strong>di</strong> i g r a f i c i saranno <strong>in</strong>colonnati uno dopo l ’ a l t r oplot ( x , y1 ,’r’ ,’l<strong>in</strong>ewidth’ , 3)hold onplot ( x , y2 ,’r’ ,’l<strong>in</strong>ewidth’ , 3 )axis ([−1 1 −1 1 ] )axis (’square’)compass( x ( 1 : 1 5 : 1 0 0 ) , y1 ( 1 : 1 5 : 1 0 0 ) ) % non consideriamo t u t t i e 100 i v e t t o r i% ma solo alcuni , <strong>di</strong> 15 <strong>in</strong> 15.compass( x ( 1 : 1 5 : 1 0 0 ) , y2 ( 1 : 1 5 : 1 0 0 ) )legend (’norma 1’ ,’location’ ,’eastoutside’) % ’ location ’ , ’ eastoutside ’% pone la legenda al <strong>di</strong> f u o r i% del grafico , a e s thold o f f3).2 Abbiamo usato, all’<strong>in</strong>terno <strong>di</strong> plot le istruzioni ’l<strong>in</strong>ewidth’,3 per aumentare lo spessore delle l<strong>in</strong>ee (<strong>in</strong> questo caso <strong>di</strong> misura76


3.4. Norme <strong>di</strong> vettori% norma<strong>in</strong>f = max( | x | , | y | )% norma<strong>in</strong>f =1 −−−> max( | x | , | y | ) = 1% se | x | ~= 1 −−> | y | ==1y1=zeros ( 1 0 0 , 1 ) ;y2=y1 ;for i =1:100i f ( abs ( x ( i ) ) ~= 1)y1 ( i ) = 1 ;y2 ( i )=−1;endendsubplot ( 3 , 1 , 2 )plot ( x , y1 ,’b’ , ’l<strong>in</strong>ewidth’ , 3)hold onplot ( x , y2 ,’b’ ,’l<strong>in</strong>ewidth’ , 3)axis ([−1 1 −1 1 ] )axis (’square’)compass( x ( 1 : 1 5 : 1 0 0 ) , y1 ( 1 : 1 5 : 1 0 0 ) )compass( x ( 1 : 1 5 : 1 0 0 ) , y2 ( 1 : 1 5 : 1 0 0 ) )legend (’norma <strong>in</strong>f’ ,’location’ ,’eastoutside’)hold o f f% norma2 = s q r t ( x^2+y ^2)% norma2 =1 −−−> s q r t ( x^2+y^2)= 1% −−−> x^2 +y^2 =1 −−> y^2= 1−x^2y1=sqrt(1−x . ^ 2 ) ;y2=−y1 ;subplot ( 3 , 1 , 3 )plot ( x , y1 ,’g’ ,’l<strong>in</strong>ewidth’ , 3)hold onplot ( x , y2 ,’g’ ,’l<strong>in</strong>ewidth’ , 3)compass( x ( 1 : 1 5 : 1 0 0 ) , y1 ( 1 : 1 5 : 1 0 0 ) )compass( x ( 1 : 1 5 : 1 0 0 ) , y2 ( 1 : 1 5 : 1 0 0 ) )axis ([−1 1 −1 1 ] )axis (’square’)legend (’norma 2’ ,’location’ ,’eastoutside’)hold o f f77


CAPITOLO 4Meto<strong>di</strong> iterativi per sistemi l<strong>in</strong>eariUna macch<strong>in</strong>a è <strong>in</strong> grado <strong>di</strong> lavorarecome c<strong>in</strong>quanta uom<strong>in</strong>i comuni,ma nessuna macch<strong>in</strong>a può svolgereil lavoro <strong>di</strong> un uomo straor<strong>di</strong>nario.Elbert Hubbard4.1 Metodo <strong>di</strong> Jacobi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 794.2 Mo<strong>di</strong>ficare jacobi.m per implementare gli altri meto<strong>di</strong> . . . . . . . . . . . . . . . . . . . . . . . . 834.2.1 Metodo <strong>di</strong> Gauss-Seidel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 834.2.2 Metodo <strong>di</strong> rilassamento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84Cont<strong>in</strong>uiamo la nostra rassegna <strong>di</strong> function <strong>di</strong> MATLAB utili per lavorare con matrici e vettori.G la function norm serve anche per calcolare la norma <strong>di</strong> matrici. In particolare– norm(A) o norm(A,2) restituisce la norma 2 della matrice A;– norm(A,1) restituisce la norma 1 della matrice A;– norm(A,<strong>in</strong>f) restituisce la norma <strong>in</strong>f<strong>in</strong>ito della matrice A;– norm(A,’fro’) restituisce la norma <strong>di</strong> Frobenius o euclidea della matrice A;G la function eig applicata ad una matrice A restituisce un vettore con gli autovalori della matrice. Applicatanel modo [V,D]=eig(A) restituisce <strong>in</strong> V la matrice con gli autovettori della matrice, corrispondentiagli autovalori che si trovano sulla <strong>di</strong>agonale della matrice <strong>di</strong>agonale D.Possiamo vedere ora nei dettagli i meto<strong>di</strong> iterativi per sistemi l<strong>in</strong>eari. Abbiamo visto che la matrice delsistema l<strong>in</strong>eare Ax = b si può scomporre come A = L + D + U dove L è la matrice triangolare <strong>in</strong>feriore, Dla <strong>di</strong>agonale e U la triangolare superiore i cui elementi sono i corrispondenti <strong>di</strong> A. In MATLAB potremmodef<strong>in</strong>ire queste matrici con le seguenti righe <strong>di</strong> coman<strong>di</strong>L= t r i l (A, −1);D=<strong>di</strong>ag ( <strong>di</strong>ag (A ) ) ;U= t r i u (A, + 1 ) ;Questa scomposizione può essere utile per avere, a priori, <strong>in</strong>formazioni sui meto<strong>di</strong> che andremo a usare, manon per la loro implementazione. Ve<strong>di</strong>amo nei dettagli come implementare il metodo <strong>di</strong> Jacobi4.1 Metodo <strong>di</strong> JacobiNel metodo <strong>di</strong> Jacobi, la matrice <strong>di</strong> iterazione vale E J = I − D −1 A = I − D −1 (L + D +U ) = −D −1 (L +U ).Lo schema è dato dax (k+1) = E J x (k) + D −1 bx (k+1) = −D −1 (L +U )x (k) + D −1 b79


4. METODI ITERATIVI PER SISTEMI LINEARIComponente per componente abbiamox (k+1)i=(D −1 ) i i1a i i⇑⎡⎢⎣ b i −(Lx (k) ) ii−1∑j =1a i j x (k)j⇑−n∑(U x (k) ) ij =i+1⇑⎤a i j x (k)⎥j ⎦per i = 1,...,nQuello che faremo per implementare il metodo <strong>di</strong> Jacobi sarà proprio usare quest’ultima formula. Ciascunacomponente del nuovo vettore x (k+1) sarà scritto come x(i)= (b(i) − sum1 −sum2)/A(i,i) dove sum1corrisponde a ∑ i−1j =1 a i j x (k) e sum2 a ∑ njj =i+1 a i j x (k) .jLo schema iterativo si basa sempre su un ciclo while e si procederà con le iterazioni f<strong>in</strong>tantochè le iterazionifatte sono m<strong>in</strong>ori <strong>di</strong> un numero massimo prefissato e (attenzione!) la norma del vettore scarto saràmaggiore <strong>di</strong> una tolleranza prefissata. Stiamo lavorando su vettori e qu<strong>in</strong><strong>di</strong> lo scarto, visto come la <strong>di</strong>fferenzatra le approssimazioni a due passi successivi è un vettore! Per controllare che lo scarto sia m<strong>in</strong>ore <strong>di</strong> una certatolleranza, utilizziamo una misura globale, vale a <strong>di</strong>re una norma vettoriale (<strong>in</strong> genere useremo la normaeuclidea su vettori). In modo del tutto analogo a quanto fatto per gli schemi iterativi per gli zeri <strong>di</strong> funzione,facciamo un’approssimazione della costante as<strong>in</strong>totica del metodo (che, ricor<strong>di</strong>amo, è il raggio spettrale dellamatrice <strong>di</strong> iterazione), me<strong>di</strong>ante il rapporto tra le norme degli scarti a due iterazioni successive. Useremoquesto valore, per avere una stima della velocità as<strong>in</strong>totica <strong>di</strong> convergenza R = −log 10 (ρ(E)).Ve<strong>di</strong>amo, allora, la function, <strong>in</strong> modo da capire bene cosa facciamo, cosa <strong>di</strong>amo <strong>in</strong> <strong>in</strong>put e cosa ci facciamodare <strong>in</strong> output.function [xnew , i t e r , scarto ]= jacobi (A , b , itmax , tol , x0 , str<strong>in</strong>ga )% function [xnew , i t e r , scarto ]= jacobi (A , b , itmax , tol , x0 , str<strong>in</strong>ga )% implementazione del metodo <strong>di</strong> Jacobi per r i s o l v e r e i l sistema l i n e a r e% Ax=b% dati <strong>di</strong> <strong>in</strong>put% A : matrice quadrata del sistema l i n e a r e% b : v e t t o r e term<strong>in</strong>e noto% itmax : numero massimo <strong>di</strong> i t e r a z i o n i da e f f e t t u a r e% t o l : tolleranza s u l l a soluzione% x0 : v e t t o r e <strong>di</strong> approssimazione i n i z i a l e% str<strong>in</strong>ga : nome del f i l e <strong>di</strong> r i s u l t a t i , da s c r i v e r e come str<strong>in</strong>ga <strong>di</strong> c a r a t t e r i% esempio : str<strong>in</strong>ga = ’ r i s j a c o b i . r i s ’% la v a r i a b i l e str<strong>in</strong>ga puo ’ anche e s s e r e omessa e , <strong>in</strong> t a l caso ,% non viene generato nessun f i l e <strong>di</strong> r i s u l t a t i% Esempio% A=[10 3 4 ; 2 8 5 ; 7 6 1 5 ] ;% b =[17; 15; 2 8 ] ;% itmax=200; t o l =1. e −10;% x0=zeros ( 3 , 1 ) ;% [xnew , i t e r , scarto ]= jacobi (A , b , itmax , tol , x0 )% s i ricava% xnew=% 1.0000% 1.0000% 1.0000% i t e r = 121% e i l v e t t o r e scarto <strong>di</strong> 121 componenti%% aggiungiamo la v a r i a b i l e% str<strong>in</strong>ga = ’ r i s j a c o b i . r i s ’ ;% [xnew , i t e r , scarto ]= jacobi (A , b , itmax , tol , x0 , str<strong>in</strong>ga )% o l t r e ai dati <strong>di</strong> prima , viene generato i l f i l e r i s j a c o b i . r i s% da cui s i puo ’ vedere come la stima del raggio s p e t t r a l e% s i a 8.17131760e−01 e per la velocita ’ <strong>di</strong> convergenza s i ha% 8.77079092e−0280


4.1. Metodo <strong>di</strong> Jacobim= s i z e (A ) ;i f m(1)~=m( 2 )error (’MATLAB:jacobi’ ,’matrice A rettangolare’)endn=length (b ) ;i f m(1)~=nerror (’MATLAB:jacobi’ ,’matrice e term<strong>in</strong>e noto: <strong>di</strong>verse <strong>di</strong>mensioni’)en<strong>di</strong> t e r =1;scarto=ones ( itmax , 1 ) ;x0=x0 ( : ) ;xold=x0 ;xnew=zeros (n , 1 ) ; % i n i z i a l i z z a z i o n e del v e t t o r e xnew per% rendere piu ’ e f f i c i e n t e l ’ implementazionewhile i t e r = t o li t e r = i t e r +1;for i =1:nsom1=A( i , 1 : i −1)* xold ( 1 : i −1);som2=A( i , i +1:n) * xold ( i +1:n ) ;xnew( i ) = (b( i )−som1−som2) /A( i , i ) ;endsc=xnew − xold ;scarto ( i t e r )=norm( sc , 2 ) ;xold=xnew ;en<strong>di</strong> f narg<strong>in</strong>==6as<strong>in</strong>t=scarto ( 2 : i t e r ) . / scarto ( 1 : i t e r −1);vel_conv=−log10 ( as<strong>in</strong>t ) ;scarto=scarto ( 2 : i t e r ) ;i t e r = i t e r −1;% scarto , as<strong>in</strong>t e vel_conv sono v e t t o r i colonna , percio ’ l i mettiamo% come v e t t o r i riga nella matrice A che c i serve per la stampaA= [ [ 1 : i t e r ] ; scarto ’ ; as<strong>in</strong>t ’ ; vel_conv ’ ] ;f i d =fopen ( str<strong>in</strong>ga ,’w’ ) ;f p r i n t f ( fid , ’%5s %12s %12s %12s’ , ’iter’ , ’norma scarto’ , ’M’ , ’R’ ) ;f p r i n t f ( fid , ’\n%5d %12.8e %12.8e %12.8e’ , A ) ;f p r i n t f ( fid , ’\n \r’ ) ;f c l o s e ( f i d ) ;elsescarto=scarto ( 2 : i t e r ) ;i t e r = i t e r −1;endendI dati <strong>di</strong> <strong>in</strong>put (rispetto alle function che abbiamo visto f<strong>in</strong>o ad ora) possono variare: sono contemplati duecasiG Nel primo caso i dati <strong>di</strong> <strong>in</strong>put sono la matrice del sistema A, il vettore term<strong>in</strong>e noto b, il numeromassimo <strong>di</strong> iterazioni itmax, la tolleranza tol, l’approssimazione <strong>in</strong>iziale x0.G Nel secondo caso, aggiungiamo, ai dati precendenti una str<strong>in</strong>ga che corrisponde al nome <strong>di</strong> un file <strong>di</strong>risultati.La function viene def<strong>in</strong>ita con il numero massimo <strong>di</strong> dati <strong>di</strong> <strong>in</strong>put possibile. Ci accorgiamo che è possibileusare l’uno o l’altro caso andando sulla parte f<strong>in</strong>ale della function dove c’è un ciclo if che controlla una variabilechiamata narg<strong>in</strong>. Questa variabile, però, non è def<strong>in</strong>ita all’<strong>in</strong>terno della function come accade periter, xold o altre variabili. Infatti narg<strong>in</strong> è una function <strong>di</strong> MATLAB che, usata all’<strong>in</strong>terno <strong>di</strong> una function,<strong>di</strong>ce il numero delle variabili <strong>di</strong> <strong>in</strong>put della function stessa. In questo caso <strong>di</strong>ciamo: se i parametri <strong>di</strong> <strong>in</strong>putsono 6 (la matrice, il term<strong>in</strong>e noto, itmax, tol, x0, str<strong>in</strong>ga) allora an<strong>di</strong>amo a calcolare le stime della costan-81


4. METODI ITERATIVI PER SISTEMI LINEARIte as<strong>in</strong>totica e della velocità as<strong>in</strong>totica <strong>di</strong> convergenza e questi dati, <strong>in</strong>sieme alle iterazioni e alla norma degliscarti, li salviamo su un file (il file chiamato str<strong>in</strong>ga). In caso contrario (avremo qu<strong>in</strong><strong>di</strong> solo le prime 5 variabili<strong>di</strong> <strong>in</strong>put) non andremo a salvare questi dati su un file <strong>di</strong> output.Avere o meno la sesta variabile, comporta la scrittura o meno <strong>di</strong> un file <strong>di</strong> risultati. Invece, <strong>in</strong> outputabbiamo il vettore f<strong>in</strong>ale che approssima la soluzione del sistema l<strong>in</strong>eare, il numero effettivo delle iterazionieffettuate e il vettore con le norme del vettore scarto. La stima della costante as<strong>in</strong>totica e della velocità <strong>di</strong>convergenza viene stampata, se si vuole, solo sul file <strong>di</strong> risultati (e le stime sono per ogni iterazione effettuata).La function è strutturata nel modo seguente:G controlla che la matrice del sistema sia quadrata;G controlla che la <strong>di</strong>mensione della matrice sia uguale alla lunghezza del vettore term<strong>in</strong>e notoG <strong>in</strong>izializza a uno, un vettore chiamato scarto <strong>in</strong> cui andremo a salvare la norma euclidea del vettoresc. Il vettore sc rappresenta il vettore scarto tra il vettore che approssima la soluzione all’iterazionecorrente meno il vettore approssimazione all’iterazione precedente. Facciamo questa <strong>in</strong>izializzazioneper una maggiore efficienza dell’esecuzione della function. In questo modo, la prima componente delvettore (come le altre) vale uno, valore maggiore della tolleranza data <strong>in</strong> <strong>in</strong>put;G <strong>in</strong>izializziamo a 1 la variabile che conta le iterazioni (con la convenzione che iter=1 corrisponde all’iterazione0: questo ci serve per poter <strong>di</strong>re che scarto(iter) corrisponde, formalmente, all’iterazioneiter-1;G ren<strong>di</strong>amo il vettore x0, l’approssimazione <strong>in</strong>iziale, come vettore colonna (nel caso non fosse già vettorecolonna);G <strong>in</strong>troduciamo la variabile xold e la poniamo uguale a x0.xold ha il significato <strong>di</strong> vettoreapprossimazione al passo precedente;G <strong>in</strong>izializziamo a zero il vettore approssimazione al passo corrente, che chiamiamo xnew (operazione,questa, fatta per ragioni <strong>di</strong> efficienza);G parte il ciclo while con il controllo sul numero delle iterazioni e sul vettore scarto: all’<strong>in</strong>terno delciclo while...– ... si aggiorna la variabile iter– si aggiorna la variabile xnew andando a salvare <strong>in</strong> sum1 e sum2 le somme che abbiamo scrittoprima: queste somme possono essere fatte <strong>in</strong> forma compatta, come ve<strong>di</strong>amo dall’istruzionescritta– si scrive la formula per la componente i-sima <strong>di</strong> xnew.– si scrive il vettore scarto sc– si calcola la norma del vettore scarto, salvando il valore nella componente <strong>di</strong> posto iter delvettore scartoG si controlla se abbiamo 6 variabili <strong>di</strong> <strong>in</strong>put per fare una stima della costante as<strong>in</strong>totica ρ(E j ) e <strong>di</strong> R,usando il vettore degli scarti (si hanno le due variabili as<strong>in</strong>t e vel_conv). Se c’è da fare la stampa, sistampano sul file anche le iterazioni e le norme degli scarti. Si sistema il vettore scarto considerando ivalori effettivi degli scarti (scarto=scarto(2:iter)) e si aggiorna iter sottraendo ad esso un’unità (<strong>in</strong> questomodo non abbiamo più quella traslazione fatta all’<strong>in</strong>izio);G se <strong>in</strong>vece le variabili <strong>di</strong> <strong>in</strong>put non sono 6, allora sistemiamo solo il vettore scarto e la variabile iterIn uscita abbiamo qu<strong>in</strong><strong>di</strong> l’ultimo vettore xnew che è stato approssimato (qu<strong>in</strong><strong>di</strong> il vettore che approssima ilvettore soluzione del sistema da risolvere), il numero delle effettive iterazioni, e il vettore delle norme euclideedegli scarti. In questo modo possiamo anche fare un grafico semilogaritmico <strong>di</strong> convergenza.82


4.2. Mo<strong>di</strong>ficare jacobi.m per implementare gli altri meto<strong>di</strong><strong>Esercizi</strong>o 4.1.1 Si provi ad implementare la function jacobi.m per risolvere il sistema Ax = b dove⎛⎞ ⎛ ⎞4 −1 0 −1 0 0 0 0 02−1 4 −1 0 −1 0 0 0 010 −1 4 0 0 −1 0 0 02−1 0 0 4 −1 0 −1 0 01A =0 −1 0 −1 4 −1 0 −1 0b =00 0 −1 0 −1 4 0 0 −11⎜0 0 0 −1 0 0 4 −1 0⎟ ⎜2⎟⎝ 0 0 0 0 −1 0 −1 4 −1⎠⎝1⎠0 0 0 0 0 −1 0 −1 42La matrice viene dalla <strong>di</strong>scretizzazione <strong>di</strong> un’equazione alle derivate parziali che si <strong>in</strong>contra spesso <strong>in</strong> <strong>di</strong>verseapplicazioni (l’equazione <strong>di</strong> Poisson − ∂2 u∂x 2 − ∂2 u= g (x, y)) mentre il term<strong>in</strong>e noto è stato scelto sommandogli elementi sulle righe <strong>di</strong> A <strong>in</strong> modo che la soluzione del sistema l<strong>in</strong>eare sia esattamente il vettore∂y2<strong>di</strong> tutti uno.Si ponga il vettore <strong>in</strong>iziale x0 come il vettore <strong>di</strong> tutti zero, itmax=100, tol=1.e-10.Si provi ad eseguire la function la prima volta senza <strong>in</strong>serire tra gli <strong>in</strong>put la variabile str<strong>in</strong>ga e la secondavolta <strong>in</strong>serendo come str<strong>in</strong>ga, il nome <strong>di</strong> un file <strong>di</strong> risultati (per esempio str<strong>in</strong>ga=’jacobi.ris’ e si chiamala function come [xnew,iter,scarto]=jacobi(A,b,itmax,tol,x0,str<strong>in</strong>ga) oppure <strong>di</strong>rettamente si chiami la functioncome [xnew,iter,scarto]=jacobi(A,b,itmax,tol,x0,’jacobi.ris’)) Si faccia poi il grafico <strong>di</strong> convergenza semilogaritmico.Si verifichi che il vettore xnew approssima correttamente la soluzione esatta (per esempio sicalcoli la norma euclidea dell’errore).<strong>Esercizi</strong>o 4.1.2 Considerando il sistema l<strong>in</strong>eare dell’esercizio precedente e usando le function <strong>di</strong> MATLAB,si provi a scrivere la matrice <strong>di</strong> iterazione del metodo <strong>di</strong> Jacobi, si calcoli il suo raggio spettrale e si confrontiil valore ottenuto con quello stimato dalla function jacobi.m4.2 Mo<strong>di</strong>ficare jacobi.m per implementare gli altri meto<strong>di</strong>A questo punto siamo pronti a implementare anche il metodo <strong>di</strong> Gauss-Seidel e <strong>di</strong> rilassamento.4.2.1 Metodo <strong>di</strong> Gauss-SeidelCopiamo la function jacobi.m dando il nome seidel.m (facciamo cp jacobi.m seidel.m dauna f<strong>in</strong>estra <strong>di</strong> term<strong>in</strong>ale).La function che abbiamo scritta va mo<strong>di</strong>ficata <strong>in</strong> modo da avere l’algoritmo <strong>di</strong> Gauss-Seidel. Cosa cambia?Scriviamo la formula per la componente i -sima del vettore che approssima la soluzione al nuovo passoiterativo (per i dettagli si rimanda alla <strong>di</strong>spensa):[x (k+1) = 1ia i ii−1 ∑b i −j =1a i j x (k+1)j−n∑j =i+1a i j x (k)j]per i = 1,...,nCosa cambia rispetto alla formula scritta per Jacobi?implementa Gauss-Seidel?Cosa va mo<strong>di</strong>ficato, qu<strong>in</strong><strong>di</strong> nell’algoritmo che83


4. METODI ITERATIVI PER SISTEMI LINEARIViene lasciato per esercizio, mo<strong>di</strong>ficare la function <strong>di</strong> Jacobi per implementare <strong>in</strong> modo corretto il metodo<strong>di</strong> Gauss-Seidel. Non va cambiato niente a parte UNA riga della function! (oltre a cambiare il nome dellafunction, e la scrittura jacobi con seidel dove occorre).<strong>Esercizi</strong>o 4.2.1 Si esegua la function seidel.m per risolvere l’esercizio precedente.4.2.2 Metodo <strong>di</strong> rilassamentoQuesta volta copiamo la function seidel.m dando il nome del file copiato come sor.m orilassamento.m.Tra i dati <strong>di</strong> <strong>in</strong>put, va aggiunto il parametro ω. Qu<strong>in</strong><strong>di</strong> questa volta i dati <strong>di</strong> <strong>in</strong>put saranno o 6 o 7:ciò significa che nel ciclo if dove si fa il controllo sul numero delle variabili <strong>di</strong> <strong>in</strong>put (narg<strong>in</strong>) va fatta unacorrezione!Scriviamo la formula per la componente i -sima del vettore che approssima la soluzione al passo k + 1:x (k+1) = (1 − ω)x (k)i+ ω i−1 ∑[bi i −a i ij =1a i j x (k+1)j−n∑j =i+1a i j x (k)jCosa va mo<strong>di</strong>ficato adesso, nella formula da implementare?]per i = 1,...,n<strong>Esercizi</strong>o 4.2.2 Si risolva l’esercizio precedente per <strong>di</strong>versi valori <strong>di</strong> ω. Si confront<strong>in</strong>o, per vari valori <strong>di</strong> ω ilnumero delle iterazioni effettuate per arrivare a convergenza.<strong>Esercizi</strong>o 4.2.3 Si provi a scrivere uno script che implementa il metodo sor per <strong>di</strong>versi valori <strong>di</strong> ω. Comeesempio da implementare si consideri sempre il sistema l<strong>in</strong>eare considerato f<strong>in</strong>o ad ora, mentre si facciavariare ω tra 1 e 1.5 con <strong>in</strong>cremento 0.1. La function <strong>di</strong> rilassamento va dunque chiamata all’<strong>in</strong>terno <strong>di</strong> unciclo for o <strong>di</strong> un ciclo while. Quale dei due cicli è preferibile?Suggerimenti sulla soluzione: Si provi a implementare un ciclo for, nei mo<strong>di</strong> seguenti (equivalenti)for omega= 1 : 0 . 1 : 1 . 5omegaendPoi si controlli che l’ultimo valore <strong>di</strong> omega sia effettivamente corretto. omega


4.2. Mo<strong>di</strong>ficare jacobi.m per implementare gli altri meto<strong>di</strong>Va tutto bene. Proviamo ora a scrivere un ciclo whileomega=1;while omega


4. METODI ITERATIVI PER SISTEMI LINEARIGli altri dati (le norme degli scarti, le stime della costante as<strong>in</strong>totica, e della velocità <strong>di</strong> convergenza)vengono stampati sul file <strong>di</strong> risultati generato all’<strong>in</strong>terno della function sor: basta aprire un file <strong>di</strong> risultati<strong>in</strong> cui i dati vengano appesi e non sovrascritti. L’importante è stampare anche il valore <strong>di</strong> omega per lasimulazione effettuata. Qu<strong>in</strong><strong>di</strong> nella function sor.m le righe relative alla stampa dei dati possono essere leseguentif i d =fopen ( str<strong>in</strong>ga ,’a’ ) ;f p r i n t f ( fid ,’%12s %12.8g’ , ’omega = ’ , omega ) ;f p r i n t f ( fid , ’\n \r’ ) ;f p r i n t f ( fid , ’%5s %12s %12s %12s’ , ’iter’ , ’norma scarto’ , ’M’ , ’R’ ) ;f p r i n t f ( fid , ’\n%5d %12.8e %12.8e %12.8e’ , A ) ;f p r i n t f ( fid , ’\n \r’ ) ;f c l o s e ( f i d ) ;Come si può osservare, per la stampa dei dati fatta <strong>in</strong>ternamente alla function, rispetto alla function <strong>di</strong> Jacobiabbiamo cambiato ben poco.86


CAPITOLO 5Problemi non l<strong>in</strong>eariUn computer è quasi umano, a parteil fatto che non attribuisce i proprierrori a un altro computer.Anonimo5.1 Metodo <strong>di</strong> Newton per sistemi non l<strong>in</strong>eari . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 875.2 M<strong>in</strong>imi quadrati non l<strong>in</strong>eari . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 915.1 Metodo <strong>di</strong> Newton per sistemi non l<strong>in</strong>eariAffrontiamo <strong>in</strong> questa sezione l’algoritmo per risolvere sistemi <strong>di</strong> due equazioni non l<strong>in</strong>eari <strong>in</strong> due<strong>in</strong>cognite, utilizzando il metodo <strong>di</strong> Newton (per la parte che riguarda la teoria si vedano le <strong>di</strong>spense).Abbiamo un sistema <strong>di</strong> due equazioni <strong>in</strong> due <strong>in</strong>cognite. In genere scriviamo il sistema comef (x, y) = 0g (x, y) = 0dove f e g sono due funzioni che <strong>di</strong>pendono dalle variabili x e y (x e y variabili scalari).Per <strong>in</strong>trodurre il metodo e implementarlo, facciamo un cambio <strong>di</strong> notazione e pensiamo a vettori.Pensiamo ad un punto (o vettore) nello spazio R 2 le cui componenti sono x e y: chiamiamo queste componenticome x 1 e x 2 e il punto (o vettore) come x. Qu<strong>in</strong><strong>di</strong> x ha coor<strong>di</strong>nate x 1 e x 2 e può essere visto come unvettore <strong>di</strong> componenti x 1 e x 2 .Mettiamo <strong>in</strong>sieme le due funzioni e abbiamo una funzione vettoriale le cui componenti sono le due funzionistesse. Chiamiamo, cambiando notazione, f 1 e f 2 le due funzioni che <strong>di</strong>pendono qu<strong>in</strong><strong>di</strong> da x 1 e x 2 .Possiamo scrivere f 1 (x 1 , x 2 ) o f 1 (x) (e analogamente possiamo fare per f 2 ). Qu<strong>in</strong><strong>di</strong> <strong>in</strong>troduciamo la funzionevettoriale f le cui componenti sono f 1 e f 2 . Qu<strong>in</strong><strong>di</strong> f = (f 1 , f 2 ) e f(x 1 , x 2 ) = f(x) = (f 1 (x), f 2 (x)).Ripren<strong>di</strong>amo l’esempio visto nella teoria:{9x21+ 4x 2 2 − 36 = 0x 2 1 − x 2 − 1 = 0In questo caso abbiamo f 1 (x 1 , x 2 ) = 9x 2 1 + 4x2 2 − 36 e f 2(x 1 , x 2 ) = x 2 1 − x 2 − 1. La funzione f ha dunque questedue componenti e x è il vettore <strong>di</strong> componenti x 1 , x 2 .Possiamo visualizzare graficamente il sistema da risolvere, utilizzando <strong>in</strong> MATLAB la function ezplot.Creiamo prima le function <strong>in</strong>l<strong>in</strong>e che ci danno f 1 e f 2 come funzioni <strong>di</strong> due variabili (si può fare), poi usiamola function ezplot che, <strong>in</strong> questo caso, ci visualizzerà, nel piano [−2π,2π] × [−2π,2π] tutti i punti <strong>in</strong> cui lafunzione che ha come argomento vale zero.87


5. PROBLEMI NON LINEARIf = i n l i n e (’9.*x1.^2+4*x2.^2-36’)g= i n l i n e (’x1.^2-x2-1’)ezplot ( f )hold onezplot ( g )hold o f fPer implementare l’algoritmo, tuttavia, non abbiamo bisogno solo delle due funzioni del sistema darisolvere, ma abbiamo bisogno anche della matrice Jacobiana che, valutata <strong>in</strong> un punto x (0) si scrive come⎛J(x (0) ) = ⎜⎝∂f 1 (x (0)1 , x(0) 2 )∂f 1 (x (0)∂x 1 ∂x 2∂f 2 (x (0)∂x 1∂f 2 (x (0)1 , x(0) 2 )1 , x(0) 2 )1 , x(0) 2 )∂x 2⎞⎟⎠Il metodo <strong>di</strong> Newton da implementare è s<strong>in</strong>tetizzato nel modo seguente:G Partire da un’approssimazione <strong>in</strong>iziale x (0)G Per k = 0,1,2,... f<strong>in</strong>o a convergenza– Risolvere il sistema J(x (k) )p (k) = −f(x (k) )– Porre la nuova approssimazione x (k+1) = x (k) + p (k)Rivedendo l’algoritmo ci accorgiamo che, ad ogni passo, ci serve sia f(x (k) ) sia J(x (k) ). Allora, ci convienescrivere una function come M-file, che <strong>in</strong> <strong>in</strong>put abbia il vettore <strong>di</strong> due componenti x e che <strong>in</strong> output ci <strong>di</strong>a siala funzione vettoriale f(x) sia la matrice Jacobiana.Ve<strong>di</strong>amo come scrivere la funzione vettoriale e la matrice Jacobiana dell’esempio che stiamo considerando.Chiamiamo la function fun2comp.m per sottol<strong>in</strong>eare che stiamo lavorando su una funzione vettorialeche ha due funzioni componenti e due <strong>in</strong>cognite.function [ f , J f ]=fun2comp( x )% <strong>in</strong> <strong>in</strong>put x v e t t o r e <strong>di</strong> due componenti , la prima corrisponde a x1 ,% la seconda a x2% <strong>in</strong> output v e t t o r e della funzione v e t t o r i a l e valutata <strong>in</strong> x% qu<strong>in</strong><strong>di</strong> f e ’ un v e t t o r e <strong>di</strong> due componenti ,% la prima componente corrisponde a f1 ( x1 , x2 )% la seconda componente corrisponde a f2 ( x1 , x2 )% J f e ’ la matrice jacobiana valutata <strong>in</strong> x% l e componenti corrispondono a l l e derivate p a r z i a l i% <strong>di</strong> f1 e f2% J f =[ f1_x f1_y ; f2_x f2_y ]% Esempio% x=[1 2 ] ; % va bene anche x = [ 1 ; 2 ] ;% [ f , J f ]=fun2comp ( x )% f =%% −11% −2%%% J f =%% 18 16% 2 −1%f = [ 9 . * x ( 1 ) . ^ 2 + 4 . * x (2).^2 −36.; x (1).^2 − x ( 2 ) − 1 . ] ;J f =[ 18.* x ( 1 ) , 8 . * x ( 2 ) ; 2 . * x ( 1 ) , −1. ] ;end88


5.1. Metodo <strong>di</strong> Newton per sistemi non l<strong>in</strong>eariOsserviamo come f sia un vettore <strong>di</strong> componenti f 1 (x) e f 2 (x), mentre Jf rappresenta la matrice Jacobiana.Per implementare il metodo <strong>di</strong> Newton, si tratta ora <strong>di</strong> estendere le nostre conoscenze sul metodo <strong>di</strong>Newton-Raphson e la sua implementazione nel caso scalare.Dal listato che ora vedremo, noteremo qualche <strong>di</strong>fferenza non solo sul fatto <strong>di</strong> usare ora dei vettori maanche sulle variabili usate.G Lavoriamo solo una variabile (vettore) che chiamiamo x e non su due variabili xold e xnew: questoperchè aggiorniamo ogni volta il vettore x me<strong>di</strong>ante la formula x = x+p dove pG La soluzione del sistema l<strong>in</strong>eare, dove la matrice del sistema è la matrice Jacobiana, viene risolto usandola function <strong>di</strong> MATLAB implementata tramite il simbolo \. è il vettore soluzione del sistema l<strong>in</strong>earecon la matrice Jacobiana che corrisponde al vettore scarto (oltrechè alla nuova <strong>di</strong>rezione del vettoreapprossimazione).G Il ciclo while controlla non solo le iterazioni e la norma del vettore scarto, ma anche la norma dellafunzione vettoriale calcolata nella nuova approssimazione (un controllo <strong>in</strong> più per vedere se ci stiamoavvic<strong>in</strong>ando a convergenza). Usiamo la norma perchè la funzione è vettoriale e ha due componenti.G La stampa dei valori <strong>in</strong>terme<strong>di</strong> viene fatta su un file <strong>di</strong> risultati che viene scritto all’<strong>in</strong>terno del ciclowhile (questo per evitare <strong>di</strong> salvare ogni volta il vettore x – andrebbe salvato su una matrice – e lanorma della funzione vettoriale – che non ci serve successivamente. Salviamo su vettore solo la normadel vettore p (cioè la norma del vettore scarto), <strong>in</strong> modo da poter successivamente fare il grafico <strong>di</strong>convergenza semilogaritmico.Viste le pr<strong>in</strong>cipali <strong>di</strong>fferenze/aggiunte/cambiamenti rispetto a quello che era lo schema <strong>di</strong> Newton-Raphsonper funzioni scalari, ve<strong>di</strong>amo la function (che chiamiano nonl<strong>in</strong>sis2.m per <strong>di</strong>re che stiamo risolvendosistemi <strong>di</strong> due equazioni non l<strong>in</strong>eari).function [ x , i t e r , scarto ]= nonl<strong>in</strong>sis2 ( f , x0 , tol , itmax , str<strong>in</strong>ga )%function [ x , i t e r , scarto ]= nonl<strong>in</strong>sis2 ( f , x0 , tol , itmax )%% dati <strong>di</strong> <strong>in</strong>put : funzione v e t t o r i a l e che f o r n i s c e <strong>in</strong> output s i a la% funzione v e t t o r i a l e del sistema da r i s o l v e r e , s i a% la matrice Jacobiana legata al sistema s t e s s o% Questa function va s c r i t t a come m−f i l e e dato <strong>in</strong> <strong>in</strong>put% scrivendo i l nome della function tra apici% x0 v e t t o r e approssimazione i n i z i a l e , <strong>di</strong> due componenti% t o l tolleranza% itmax numero massimo <strong>di</strong> i t e r a z i o n i% str<strong>in</strong>ga str<strong>in</strong>ga con i l nome del f i l e <strong>di</strong> r i s u l t a t i% dati <strong>di</strong> output : x v e t t o r e che approssima la soluzione del sistema% i t e r numero <strong>di</strong> i t e r a z i o n i e f f e t t u a t e% scarto v e t t o r e d e l l e norme euclidee del v e t t o r e scarto% u t i l e per f are i l g r a f i c o <strong>di</strong> convergenza% Esempio% utilizzando la function fun2comp .m ( vedasi <strong>di</strong>spensa ) d e f i n i t a come% function [ f , J f ]=fun2comp ( x )% f = [ 9 . * x ( 1 ) . ^ 2 + 4 . * x (2).^2 −36.; x(1).^2 −x ( 2 ) − 1 . ] ;% J f =[ 18.* x ( 1 ) , 8 . * x ( 2 ) ; 2 . * x ( 1 ) , −1. ] ;% end% dalla Command W<strong>in</strong>dow o da uno s c r i p t , s i eseguono l e seguenti i s t r u z i o n i% x0=[1 1 ] ;% t o l =1. e −12; itmax=100;% str<strong>in</strong>ga = ’ s i s n o n l i n e a r i . r i s ’ ;% [ x , i t e r , scarto ]= nonl<strong>in</strong>sis2 ( ’ fun2comp ’ , x0 , tol , itmax , str<strong>in</strong>ga )% s i ricava% x =%% 1.645049516952767% 1.706187913226531%89


5. PROBLEMI NON LINEARI%% i t e r =%% 6%%% scarto =%% 1.228623445541495% 0.272914827357931% 0.019246539508239% 0.000111222483488% 0.000000003759668% 0.000000000000000%% viene generato i l f i l e <strong>di</strong> r i s u l t a t i ed e ’ p o s s i b i l e f are i l g r a f i c o% <strong>di</strong> convergenzax0=x0 ( : ) ; % scriviamo i l v e t t o r e come v e t t o r e colonna per poter% f a r e la visualizzazione dei r i s u l t a t i nel f i l e <strong>di</strong> r i s u l t a t if i d =fopen ( str<strong>in</strong>ga ,’w’ ) ;f p r i n t f ( fid , ’%3s %12s %12s %18s %18s \n’ , ’iter’ ,’norma scarto’ , ’||f(x_k)||’ , ’x1’ , ’x2’ ) ;scarto=zeros ( itmax , 1 ) ;scarto ( 1 ) = 2 . * t o l ;i t e r =1;x=x0 ;[ fx , Jx ]= f eval ( f , x ) ;f p r i n t f ( fid , ’%3d %12.6e %12.5e %18.16f %18.16f \n’ , [ i t e r scarto ( i t e r ) norm( f x ) x0 ’ ] ’ ) ;% s i o s s e r v i <strong>in</strong> f p r i n t f che abbiamo s c r i t t o i l v e t t o r e x0 traspostowhile i t e r t o l && norm( f x ) >eps% s i o s s e r v i l ’ u l t e r i o r e c o n t r o l l o s u l l a norma della funzione v e t t o r i a l ei t e r = i t e r +1;p= −Jx \ f x ;x=x +p ;scarto ( i t e r )=norm(p ) ;[ fx , Jx ]= f eval ( f , x ) ;f p r i n t f ( fid , ’%3d %12.6e %12.5e %18.16f %18.16f \n’ , [ i t e r −1 scarto ( i t e r ) norm( f x ) x ’ ] ’ ) ;endscarto=scarto ( 2 : i t e r ) ;i t e r = i t e r −1;endA questo punto possiamo risolvere il sistema proposto, eseguendo (tramite script o sulla Command W<strong>in</strong>dow)le istruzioni che troviamo nell’help della function nonl<strong>in</strong>sis2. E possiamo risolvere tanti altri problemi,scrivendo semplicemente la function che fornisce <strong>in</strong> output la funzione vettoriale delle equazioni del sistemae la matrice jacobiana. Se chiamiamo questa function (per esempio) fun2.m poi andremo a chiamarla nellanonl<strong>in</strong>sis2 <strong>in</strong>serendola come ’fun2’ (tra apici).90


5.2. M<strong>in</strong>imi quadrati non l<strong>in</strong>eari<strong>Esercizi</strong>o 5.1.1 Si consideri il sistemax 2 1 − 2x 1 − x 2 − 1 = 0x 2 1 + x2 2 − 1 = 0Si faccia il grafico delle due equazioni del sistema per capire, graficamente, la/le soluzioni del sistema stesso.Si scriva una function dal nome funes.m da utilizzare come function <strong>di</strong> <strong>in</strong>put per la nonl<strong>in</strong>sis2 perrisolvere numericamente il sistema <strong>di</strong> equazioni. Si consideri tol=1.e-12, itmax=50 e x0=[1, 1] esuccessivamente x0=[-1,1]. Per ogni simulazione si veda la soluzione che si ricava e si faccia un grafico<strong>di</strong> convergenza semilogaritmico.5.2 M<strong>in</strong>imi quadrati non l<strong>in</strong>eariIn questa sezione affrontiamo il problema <strong>di</strong> risolvere il problema ai m<strong>in</strong>imi quadrati non l<strong>in</strong>eare chesi <strong>in</strong>contra nell’ambito dell’<strong>in</strong><strong>di</strong>viduazione delle coor<strong>di</strong>nate <strong>di</strong> una posizione tramite il sistema GPS. Sonodate n misure d i tra un punto <strong>in</strong>cognito P 0 <strong>di</strong> coor<strong>di</strong>nate (x 0 , y 0 ) (il ricevitore) ed n punti noti P i (x i , y i ) (isatelliti GPS). La <strong>di</strong>stanza osservata è affetta da errore e, per trovare le coor<strong>di</strong>nate <strong>di</strong> P 0 si m<strong>in</strong>imizza unacerta funzione (simile a quella <strong>in</strong>contrata per calcolare la retta <strong>di</strong> approssimazione ai m<strong>in</strong>imi quadrati).Poichè la funzione da m<strong>in</strong>imizzare è non l<strong>in</strong>eare, si opera una l<strong>in</strong>earizzazione tramite la formula <strong>di</strong> Taylorutilizzando un valore provvisorio <strong>di</strong> coor<strong>di</strong>nate note, denotate come (x, y).I passaggi pr<strong>in</strong>cipali da considerare sono (per le formule complete si rimanda alla <strong>di</strong>spensa <strong>di</strong> teoria):G La funzione da m<strong>in</strong>imizzare èn∑ √S(x 0 , y 0 ) = (d i − (x i − x 0 ) 2 + (y i − y 0 ) 2 ) 2i=1non l<strong>in</strong>eare <strong>in</strong> x 0 , y 0 .G Si <strong>in</strong>troduce la funzione δ i (x, y) = √ (x i − x) 2 + (y i − y) 2 , per i = 1,2,...,n <strong>in</strong> modo che d i = δ i (x 0 , y 0 )+ɛ i(ɛ i è l’errore della misura rilevata).G Si applica la formula <strong>di</strong> Taylor a ciascuna funzione δ i con centro nel punto provvisorio x, y).G In questo modo abbiamoδ i (x 0 , y 0 ) = δ i (x, y) + ∂δ i (x, y)∂x(x 0 − x) + ∂δ i (x, y)(y 0 − y)∂yG Introduciamo il vettore b <strong>di</strong> componenti b i = d i − δ i (x, y) (<strong>di</strong>pende dalle derivate parziali <strong>di</strong> δ i ). Si ha∂δ(x, y) ∂δ(x, y)b i = (x 0 − x) + (y 0 − y) + ɛ i .∂x∂yG Introduciamo il vettore ɛ = (ɛ 1 ,ɛ 2 ,...,ɛ n ) T e la matrice A <strong>di</strong> n righe e 2 colonne data da⎛⎞ ⎛∂δ 1 (x, y) ∂δ 1 (x, y)∂x ∂y− (x 1 − x)− (y ⎞1 − y)δ 1 (x, y) δ 1 (x, y)∂δ 2 (x, y) ∂δ 2 (x, y)− (x 2 − x)− (y 2 − y)A =∂x ∂y=δ 2 (x, y) δ 2 (x, y)....⎜⎟ ⎜⎝ ∂δ n (x, y) ∂δ n (x, y) ⎠ ⎝− (x n − x)− (y ⎟n − y) ⎠∂x ∂y δ n (x, y) δ n (x, y)91


5. PROBLEMI NON LINEARIG In base alle formule scritte prima, esiste una relazione tra A, i vettori b e ɛ: <strong>in</strong>fatti, ponendo ξ = (x 0 −x, y 0 − y) T si haoAξ + ɛ = bɛ = b − AξTornando alla funzione da m<strong>in</strong>imizzare, si può vedere che vale S(x 0 , y 0 ) = ∑ ni=1 ɛ2 i = ɛT ɛPoichè ɛ <strong>di</strong>pende da ξ, si può anche scrivere, <strong>in</strong> forma matriciale, (saltiamo tutti i passaggi <strong>in</strong>terme<strong>di</strong>)S(ξ) = b T b − b T Aξ = −ξ T A T b + ξ T A T AξPer trovare per quale valore <strong>di</strong> ξ la S è m<strong>in</strong>ima, si deve imporre uguale a zero la derivata <strong>di</strong> S rispetto al vettoreξ, vale a <strong>di</strong>re rispetto a ciascuna componente <strong>di</strong> ξ. Si ricava:A T Aξ = A T bRisolvendo questo sistema si trova ξ che m<strong>in</strong>imizza S. E una volta ricavato ξ, possiamo ricavare i valori x 0 ey 0 , ricordando che ξ = (x 0 − x, y 0 − y) T .Fatta questa breve premessa, ve<strong>di</strong>amo cosa dobbiamo fare <strong>in</strong> MATLAB per risolvere il problema. I datia <strong>di</strong>sposizione saranno: le <strong>di</strong>stanze osservate d i , le ascisse e le or<strong>di</strong>nate dei satelliti (per semplicità stiamolavorando <strong>in</strong> uno spazio bi<strong>di</strong>mensionale), le coor<strong>di</strong>nate del valore <strong>di</strong> riferimento provvisorio (x, y).Ve<strong>di</strong>amo la functionfunction [ x0 , A]= lsn ( doss , xsat , ysat , pprov ) ;% function [ coord , A]= lsn ( doss , xsat , ysat , pprov )% dati <strong>di</strong> <strong>in</strong>put% doss : v e t t o r e d e l l e <strong>di</strong>stanze o s s e r vate% xsat : v e t t o r e d e l l e a s c i s s e dei s a t e l l i t i% ysat : v e t t o r e d e l l e corrispondenti or<strong>di</strong>nate dei s a t e l l i t i% pprov : punto provvisorio <strong>di</strong> riferimento <strong>di</strong> due componenti% ( a s c i s s a e or<strong>di</strong>nata del valore <strong>di</strong> riferimento )% dati <strong>di</strong> output% x0 : v e t t o r e che contiene l ’ a s c i s s a e l ’ or<strong>di</strong>nata del% punto <strong>in</strong>cognito% A : matrice A della formula ( con l e derivate p a r z i a l i )% A^T A xi = A^T b con b=doss−<strong>di</strong>stanza_rispetto_pprov% xi = A^A A / A^T b% x0= xi+pprov% Esempio% xsat =[7 2 1 10 −5 −20]% ysat =[ 9 7 4 15 8 −15]% pprov =[4.04 4 . 9 6 ]% doss =[5 2.83 3.16 11.66 9.48 31.24]% [ x0 , A]= lsn ( doss , xsat , ysat , pprov )% r e s t i t u i s c e% x0=% 3.997633885126340% 5.001312558881406% A=% −0.591017363980430 −0.806658834621938% 0.707106781186548 −0.707106781186548% 0.953582665134142 0.301131367937097% −0.510459597546841 −0.859901738149376% 0.947841163176306 −0.318743046023890% 0.769374270742105 0.63879827138154892


5.2. M<strong>in</strong>imi quadrati non l<strong>in</strong>earixsat=xsat ( : ) ;ysat=ysat ( : ) ;doss=doss ( : ) ;pprov=pprov ( : ) ;x=xsat−pprov ( 1 ) ;y=ysat−pprov ( 2 ) ;dcalc= sqrt ( x .^2 + y . ^ 2 ) ;A=[ −x . / dcalc −y . / dcalc ] ;tn=A ’ * ( doss−dcalc ) ; %term<strong>in</strong>e notoB=A’ * A ; % matrice del sistemasol=B\ tn ; %soluzione del sistemax0=sol +pprov ;endCome esercizio si provi a verificare l’esempio fornito nella function stessa.93


CAPITOLO 6Formule <strong>di</strong> <strong>in</strong>tegrazione numericaL’esperienza è la madre dellascienza.Henry George Bohn (1796-1884)6.1 Formule <strong>di</strong> quadratura numerica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 956.2 La formula dei trapezi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 956.3 La formula <strong>di</strong> Cavalieri-Simpson . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1006.1 Formule <strong>di</strong> quadratura numericaSia dato il problema <strong>di</strong> risolvere l’<strong>in</strong>tegrale <strong>di</strong> una funzione f (x) nell’<strong>in</strong>tervallo [a,b]:∫ bI = f (x)d xaIn MATLAB ci sono già delle function predef<strong>in</strong>ite che servono per il calcolo <strong>di</strong> un <strong>in</strong>tegrale. Ricor<strong>di</strong>amo lefunction quad e <strong>in</strong>tegral per il calcolo <strong>di</strong> <strong>in</strong>tegrali <strong>di</strong> funzioni scalari e riman<strong>di</strong>amo all’help on l<strong>in</strong>e <strong>di</strong> MATLABper capire come funzionano.Noi però vogliamo imparare a scrivere le nostre function per calcolare numericamente l’<strong>in</strong>tegrale <strong>di</strong> unafunzione usando i meto<strong>di</strong> che abbiamo conosciuto dalla teoria e, <strong>in</strong> particolare, applicando il metodo deitrapezi e <strong>di</strong> Cavalieri-Simpson.Le formule dei trapezi e <strong>di</strong> Cavalieri-Simpson sono state applicate su tutto l’<strong>in</strong>tervallo <strong>di</strong> <strong>in</strong>tegrazione:<strong>in</strong> questo caso abbiamo parlato <strong>di</strong> formula semplice. Tuttavia, per avere accuratezza nei risultati, si preferisceapplicare la formula semplice (dei trapezi o <strong>di</strong> Cavalieri-Simpson) su un certo numero <strong>di</strong> sud<strong>di</strong>visionidell’<strong>in</strong>tervallo <strong>di</strong> <strong>in</strong>tegrazione, sommando tutti i contributi per avere l’approssimazione f<strong>in</strong>ale.Focalizziamo l’attenzione sul metodo dei trapezi.6.2 La formula dei trapeziChiamiamo f la funzione (<strong>in</strong>l<strong>in</strong>e, handle o m-file) <strong>di</strong> cui dobbiamo calcolare l’<strong>in</strong>tegrale. Gli estremi <strong>di</strong><strong>in</strong>tegrazione siano assegnati alle variabili a e b. La formula dei trapezi semplice si può vedere come il risultatodella functionfunction [ Itrap ] = trapsempl ( f , a , b)% function [ Itrap ] = trapsempl ( f , a , b )% function per applicare la formula semplice dei trapezi% Itrap= ( b−a ) / 2 ( f ( a)+ f ( b ) )% dati <strong>di</strong> <strong>in</strong>put : f funzione da <strong>in</strong>tegrare95


6. FORMULE DI INTEGRAZIONE NUMERICAFigura 6.1: Intervallo <strong>di</strong> <strong>in</strong>tegrazione [a,b]: un’unica sud<strong>di</strong>visione, 6 sud<strong>di</strong>visioni <strong>in</strong> parti non uguali, 9sud<strong>di</strong>visioni <strong>in</strong> parti uguali.% a e b estremi dell ’ i n t e r v a l l o <strong>di</strong> <strong>in</strong>tegrazione% dati <strong>di</strong> output : Itrap valore dell ’ i n t e g r a l e con la formula dei trapeziItrap= f eval ( f , a)+ f eval ( f , b ) ;Itrap=Itrap * ( b−a ) * 0 . 5 ;endAbbiamo applicato la formulaI T = b − a (f (a) + f (b))2Poichè la formula semplice si può vedere come caso particolare della formula composta con n = 1sud<strong>di</strong>visione, la nostra attenzione ora si concentra sulla formula composta con m sud<strong>di</strong>visioni.Dalla teoria, applicare la formula dei trapezi composta su m sud<strong>di</strong>visioni dell’<strong>in</strong>tervallo [a,b] vuol <strong>di</strong>reapplicare la formula semplice su ciascuna sud<strong>di</strong>visione e sommare i contributi <strong>di</strong> tutte le sud<strong>di</strong>visioni: <strong>in</strong>fattiil valore dell’<strong>in</strong>tegrale si può vedere come la somma degli <strong>in</strong>tegrali su ciascuna sud<strong>di</strong>visione.In figura 6.1 ve<strong>di</strong>amo l’<strong>in</strong>tervallo [a,b] visto come un’unica sud<strong>di</strong>visione (sul quale possiamo applicare,qu<strong>in</strong><strong>di</strong>, la formula <strong>di</strong> <strong>in</strong>tegrazione semplice), oppure sud<strong>di</strong>viso <strong>in</strong> più sud<strong>di</strong>visioni. Nell’esempio ci sono 6sud<strong>di</strong>visioni <strong>in</strong> parti non uguali e 9 sud<strong>di</strong>visioni <strong>in</strong> parti uguali.Per semplicità costruiremo le nostre function che implementano la formula composta su un numero n <strong>di</strong>sud<strong>di</strong>visioni <strong>in</strong> parti uguali.Sud<strong>di</strong>vi<strong>di</strong>amo l’<strong>in</strong>tervallo [a,b] <strong>in</strong> n sotto<strong>in</strong>tervalli def<strong>in</strong>iti dai punti d’appoggio x 0 , x 1 ,..., x n ( i punti sonoequi<strong>di</strong>stanti con passo h = b − an, <strong>in</strong> modo che x 0 = a e x n = b, x i = x 0 +i h, i = 0,...,n). Qu<strong>in</strong><strong>di</strong> n sud<strong>di</strong>visioni,n + 1 punti da considerare: questi punti, presi a due a due, sono gli estremi dei sotto<strong>in</strong>tervalli.Implementiamo la formula composta dei trapezi considerando che∫ baf (x)d x =n∑i=1∫ xix i−1f (x)d xCiascun <strong>in</strong>tegrale ∫ x ix i−1f (x) viene approssimato applicando la formula semplice. Allora la function daconsiderare sarà la seguente96


6.2. La formula dei trapezifunction [ Itrap ] = trapcomposta ( f , a , b , n)% function [ Itrap ] = trapcomposta ( f , a , b , n)% function per applicare la formula composta dei trapezi% Itrap= somma della formula dei trapezi semplice su ciascun% s o t t o i n t e r v a l l o% dati <strong>di</strong> <strong>in</strong>put : f funzione da <strong>in</strong>tegrare% a e b estremi dell ’ i n t e r v a l l o <strong>di</strong> <strong>in</strong>tegrazione% n numero <strong>di</strong> sud<strong>di</strong>visioni% dati <strong>di</strong> output : Itrap valore dell ’ i n t e g r a l e con la formula dei trapezi% La function trapcomposta richiama al suo <strong>in</strong>terno la function trapsempl% che applica la formula semplice dei trapezi .% Esempio <strong>di</strong> applicazione% a=0; b = 0 . 2 ;% n=4;% f = i n l i n e ( ’ cos ( x ) ’ )% Itrap=trapcomposta ( f , a , b , n) r e s t i t u i s c e% Itrap= 0.198627939626483h=(b−a ) /n ;x0=a ;Itrap =0;for i =1:nx1=x0+h ;Itrap= Itrap+ trapsempl ( f , x0 , x1 ) ;x0=x1 ;endfunction [ Itrap ] = trapsempl ( f , a , b)% function [ Itrap ] = trapsempl ( f , a , b )% function per applicare la formula semplice dei trapezi% Itrap= ( b−a ) / 2 ( f ( a)+ f ( b ) )% dati <strong>di</strong> <strong>in</strong>put : f funzione da <strong>in</strong>tegrare% a e b estremi dell ’ i n t e r v a l l o <strong>di</strong> <strong>in</strong>tegrazione% dati <strong>di</strong> output : Itrap valore dell ’ i n t e g r a l e con la formula dei trapeziItrap= f e v a l ( f , a)+ f eval ( f , b ) ;Itrap=Itrap * ( b−a ) * 0 . 5 ;endendOsserviamo che al suo <strong>in</strong>terno la function trapcomposta richiama la function trapsempl che implementala formula semplice. Quello che viene fatto nella function si può riassumere nei seguenti punti.Dovendo sud<strong>di</strong>videre l’<strong>in</strong>tervallo <strong>in</strong> n sud<strong>di</strong>visioniG l’ampiezza <strong>di</strong> ogni sud<strong>di</strong>visione è data da h=(b-a)/n;G il primo estremo da considerare vale x0=a (<strong>in</strong> questa function le variabili x0 e x1 hanno il significato<strong>di</strong> estremo <strong>in</strong>feriore ed estremo superiore del s<strong>in</strong>golo sotto<strong>in</strong>tervallo;G si <strong>in</strong>izializza il valore approssimato dell’<strong>in</strong>tegrale come Itrap=0G ora si fa un ciclo for su ciascun sotto<strong>in</strong>tervallo (for i=1:n)– si considera il secondo estremo del sotto<strong>in</strong>tervallo dato da x1=x0+h– si applica la formula semplice dei trapezi e il valore ottenuto lo si aggiunge alla variabile Itrap(<strong>in</strong> modo da sommare tutti i contributi dati da ciascun sotto<strong>in</strong>tervallo)– quando si passerà al successivo sotto<strong>in</strong>tervallo quello che adesso è l’estremo superiore <strong>di</strong>venteràl’estremo <strong>in</strong>feriore: perciò si fa l’aggiornamento x0=x1In questo modo applichiamo <strong>in</strong> MATLAB quello che è il proce<strong>di</strong>mento visto nella teoria per le formulecomposte.97


6. FORMULE DI INTEGRAZIONE NUMERICASi potrebbe <strong>di</strong>re: ma se si fanno tutti i calcoli, la formula composta dei trapezi si può scrivere <strong>in</strong> formacompatta comef (a) + f (b)I T = h[ + f (x 1 ) + f (x 2 ) + ... f (x n−1 )]2Allora perchè non usare poche istruzioni MATLAB per fare tutto questo? Nella function che abbiamo scritto,la funzione <strong>in</strong>tegranda viene valutata due volte nei punti <strong>in</strong>terni dell’<strong>in</strong>tervallo [a,b], non è ottimale... È vero!E <strong>di</strong>fatti la function <strong>di</strong> prima può essere sostituita dalla functionfunction [ Itrap ] = trapcompcompatta ( f , a , b , n)% function [ Itrap ] = trapcompcompatta ( f , a , b , n)h=(b−a ) /n ;x =[a : h : b ] ;y= f e v a l ( f , x ) ;Itrap=sum( y ( 2 : n ) ) ;Itrap=Itrap +(y (1)+ y (n + 1 ) ) * 0 . 5 ;Itrap=Itrap *h ;endPoche righe per avere la formula dei trapezi. Tuttavia, preferiamo cont<strong>in</strong>uare a lavorare con la function<strong>in</strong>iziale, benché non ottimale, perchè <strong>in</strong> questo modo ricor<strong>di</strong>amo meglio due cose (si spera):1. la formula semplice2. il concetto che la formula composta deriva dall’applicare la formula semplice su più sud<strong>di</strong>visioni;Se, al posto della function che chiama la formula semplice dei trapezi, chiamiamo un’altra function che applicala formula semplice <strong>di</strong> Cavalieri-Simpson, abbiamo già la formula composta <strong>di</strong> Cavalieri-Simpson senzadover ricordare la formula compatta... Dobbiamo ricordare solo le formule semplici!Fatta questa premessa, ve<strong>di</strong>amo <strong>di</strong> implementare la formula composta dei trapezi per approssimarel’<strong>in</strong>tegrale <strong>di</strong> <strong>di</strong>verse funzioni.Si consider<strong>in</strong>o ∫ i seguenti casi test (calcolando per ciascun <strong>in</strong>tegrale una primitiva) 111.∫0 cos(x)d x12.−2 xe x2 d xScriviamo uno script che ci permetta <strong>di</strong> eseguire uno <strong>di</strong> questi <strong>in</strong>tegrali (o altri che ci verranno da scrivere)<strong>in</strong> modo del tutto generale. Se l’<strong>in</strong>tegrale non si può calcolare analiticamente, non scriveremo il valore esattodell’<strong>in</strong>tegrale. In <strong>in</strong>put daremo qu<strong>in</strong><strong>di</strong> gli estremi <strong>di</strong> <strong>in</strong>tegrazione, la funzione <strong>in</strong>tegranda e una sua primitiva(se esiste o se l’abbiamo calcolata) e il numero <strong>di</strong> sud<strong>di</strong>visioni per applicare la formula dei trapezi composta.Lo script può essere sviluppato nel modo seguentea=<strong>in</strong>put (’estremo <strong>di</strong> <strong>in</strong>tegrazione a ’ ) ;b=<strong>in</strong>put (’estremo <strong>di</strong> <strong>in</strong>tegrazione b ’ ) ;f =<strong>in</strong>put (’scrivi la function - <strong>in</strong>l<strong>in</strong>e o handle ’ ) ;exact=<strong>in</strong>put (’conosci una primitiva della f ? si’’ 1 no 0 ’ ) ;i f exact==1F=<strong>in</strong>put (’scrivi la primitiva come function <strong>in</strong>l<strong>in</strong>e ’ ) ;Iex= f eval (F , b)− f eval (F , a ) ;endn=<strong>in</strong>put (’# sud<strong>di</strong>visioni per la formula dei trapezi composta ’ ) ;Itrap=trapcomposta ( f , a , b , n ) ;i f exact == 1errore=Iex−Itrap ;endOsserviamo che, se conosciamo il valore esatto dell’<strong>in</strong>tegrale, calcoliamo anche l’errore esatto.<strong>Esercizi</strong>o 6.2.1 Si applichi lo script ai due casi test proposti, con n = 4 e poi n = 8: cosa succede all’errore?1 Se F è una primitiva <strong>di</strong> f , allora ∫ ba f (x)d x = F (b) − F (a). Sfrutteremo questa proprietà per calcolare l’<strong>in</strong>tegrale esatto.98


6.2. La formula dei trapeziIn questo script siamo noi a dare <strong>in</strong> <strong>in</strong>put il numero <strong>di</strong> sud<strong>di</strong>visioni da applicare nella formula composta.Potremmo però pensare <strong>di</strong> fare anche un’altra cosa. Potremmo pensare <strong>di</strong> applicare la formula dei trapezipartendo dall’<strong>in</strong>tervallo [a,b], poi <strong>di</strong> sud<strong>di</strong>videre l’<strong>in</strong>tervallo <strong>in</strong> due parti uguali, e così via: raddoppiareogni volta il numero <strong>di</strong> sud<strong>di</strong>visioni. Prima 1, poi 2, qu<strong>in</strong><strong>di</strong> 4, 8, 16, ... Si spera che aumentando il numero <strong>di</strong>sotto<strong>in</strong>tervalli, l’<strong>in</strong>tegrale da approssimare abbia un’accuratezza via via maggiore (e qu<strong>in</strong><strong>di</strong> l’errore esatto siavia via più piccolo). Inoltre, dalla teoria, se la funzione <strong>in</strong>tegranda è cont<strong>in</strong>ua <strong>in</strong>sieme alla derivata seconda,l’errore della formula dei trapezi tende a zero come h 2 o 1 . Qu<strong>in</strong><strong>di</strong> il rapporto tra gli errori tra due sud<strong>di</strong>visionisuccessive, <strong>in</strong> queste ipotesi, tende ad un valore ben preciso (quale?). Cerchiamo <strong>di</strong> implementare tutton2 questo <strong>in</strong> uno script da applicare per calcolare l’<strong>in</strong>tegrale <strong>di</strong> una funzione (<strong>di</strong> cui si conosca una primitiva <strong>in</strong>modo da calcolare anche l’errore esatto), partendo da una sud<strong>di</strong>visione dell’<strong>in</strong>tervallo <strong>di</strong> <strong>in</strong>tegrazione e raddoppiandoogni volta il numero <strong>di</strong> sud<strong>di</strong>visioni f<strong>in</strong>o ad arrivare ad un certo numero <strong>di</strong> sud<strong>di</strong>visioni del tipo2 ns se operiamo ns sud<strong>di</strong>visioni dell’<strong>in</strong>tervallo <strong>in</strong>iziale. Tenendo conto anche del valore dell’<strong>in</strong>tegrale ottenutosenza effettuare sud<strong>di</strong>visioni (l’<strong>in</strong>tervallo <strong>in</strong>iziale, che possiamo anche <strong>in</strong><strong>di</strong>care come n = 1 sud<strong>di</strong>visione),avremo ns + 1 valori approssimati <strong>di</strong> cui poter calcolare l’errore esatto. E degli errori possiamo calcolare irapporti. Scriviamo uno script dal nome trapezi.ma=<strong>in</strong>put (’estremo <strong>di</strong> <strong>in</strong>tegrazione a ’ ) ;b=<strong>in</strong>put (’estremo <strong>di</strong> <strong>in</strong>tegrazione b ’ ) ;f =<strong>in</strong>put (’scrivi la function - <strong>in</strong>l<strong>in</strong>e o handle ’ ) ;F=<strong>in</strong>put (’scrivi la primitiva come function <strong>in</strong>l<strong>in</strong>e ’ ) ;Iex= f e v a l (F , b)− f eval (F , a ) ;ns=<strong>in</strong>put (’F<strong>in</strong>o a quante sud<strong>di</strong>visioni, 2^ns vuoi arrivare? ’ ) ;n=1;% applicheremo la formula dei trapezi su% 2^0 ( nessuna sud<strong>di</strong>visione e f f e t t u a t a , o% una sud<strong>di</strong>visione== i n t e r v a l l o <strong>di</strong> partenza :% formula semplice ) ,% 2^1 ( due sud<strong>di</strong>visioni : <strong>di</strong>vi<strong>di</strong>amo a meta ’ l ’ i n t e r v a l l o la% prima volta ) ,% 2^2 (4 sud<strong>di</strong>visioni : <strong>di</strong>vi<strong>di</strong>amo a meta ’ l e sud<strong>di</strong>visioni precedenti )% arriviamo a 2^ns sud<strong>di</strong>visioni% La procedura viene e f f e t t u a t a ns+1 v o l t e% Qu<strong>in</strong><strong>di</strong> ricaviamo lo s t e s s o valore dell ’ <strong>in</strong>tegrale , ns+1 v o l t eItrap=zeros ( ns + 1 , 1 ) ;i =0;while m


6. FORMULE DI INTEGRAZIONE NUMERICASe applichiamo questo scritp per risolvere ∫ 10cos(x)d x con ns = 10 ricaviamo⎛⎞⎛⎞0.7701511529340707.131983187382662e − 020.8238668574122211.760412739567518e − 020.8370837513522274.387233455669381e − 030.8403750340273871.095950780509725e − 030.8411970506369422.739341709541154e − 04Itrap=0.841402504609252errore=6.848019864458266e − 050.8414538649672231.711984067342964e − 050.8414667048607894.279947107166393e − 060.8414699148219361.069985960278075e − 06⎜⎟⎜⎟⎝0.841470717311458⎠⎝2.674964384441481e − 07⎠0.8414709179337916.687410580852315e − 08⎛⎞4.0513130966859404.0125804960131164.0031300070144464.0007815625648934.000195332023702rate=4.0000488293600414.000012206871431⎜4.000003052427055⎟⎝4.000000771978438⎠4.000000227443122Questo esempio è <strong>in</strong> buon accordo con la teoria (l’errore decresce con un rapporto 4).<strong>Esercizi</strong>o 6.2.2 Si trasformi lo script trapezi <strong>in</strong> una function che riceve <strong>in</strong> <strong>in</strong>put la funzione <strong>in</strong>tegrandaf , la funzione primitiva F , gli estremi <strong>di</strong> <strong>in</strong>tegrazione a e b e il numero ns (<strong>in</strong> modo da fare 1, 2,...,2 nssud<strong>di</strong>visioni). In output questa function <strong>di</strong>a i vettori Itrap, errore, rate e il valore esatto Iex. Sichiami questa function funtrapezi.m.<strong>Esercizi</strong>o 6.2.3 Si applichi la function funtrapezi per risolvere l’<strong>in</strong>tegrale ∫ 1−2 xe x2 d x con ns = 86.3 La formula <strong>di</strong> Cavalieri-SimpsonA questo punto, passare dalla formula dei trapezi a quella <strong>di</strong> Cavalieri-Simpson <strong>in</strong> MATLAB è qualcosa <strong>di</strong>molto semplice (basterà mo<strong>di</strong>ficare solo la function che applica la formula semplice). Abbiamo detto che perora non ci <strong>in</strong>teressa la formula compatta (è qualcosa che può servire una volta che si è capita bene la teoria ese si vuole migliorare l’efficienza dei programmi). Ci <strong>in</strong>teressa la formula semplice e questa verrà richiamataed applicata su ciascuna sud<strong>di</strong>visione dell’<strong>in</strong>tervallo [a,b] al f<strong>in</strong>e <strong>di</strong> ottenere la formula composta. La formulasemplice <strong>di</strong> Cavalieri-Simpson è data daI C S = b − a (f (a) + 4f (c) + f (b))6con c = a + b2 .Per implementare la formula composta <strong>di</strong> Cavalieri-Simpson, dobbiamo applicare la formula semplice suogni sud<strong>di</strong>visione (e <strong>di</strong> ogni sotto<strong>in</strong>tervallo ci servirà il punto centrale).Da ciò consegue che l’ossatura della function trapcomposta.m rimarrà essenzialmente la stessa (daremoil nome cavcomposta.m ma l’idea <strong>di</strong> applicare la formula su ciascun <strong>in</strong>tervall<strong>in</strong>o rimane la stessa).Ciò che cambierà sarà la function trapsempl.m (che chiamereremo cavsempl.m) <strong>in</strong> cui dobbiamo applicarela formula <strong>di</strong> Cavalieri-Simpson. Ma i parametri <strong>di</strong> <strong>in</strong>put rimarranno gli stessi (<strong>in</strong>fatti, dagli estremidell’<strong>in</strong>tervallo <strong>in</strong> cui stiamo applicando la formula possiamo ricavare il punto c che ci serve, all’<strong>in</strong>terno dellafunction).100


6.3. La formula <strong>di</strong> Cavalieri-Simpson<strong>Esercizi</strong>o 6.3.1 Si mo<strong>di</strong>fichi la function trapcomposta.m dando il nome cavcomposta.m <strong>in</strong> mododa applicare la formula <strong>di</strong> Cavalieri-Simpson composta.<strong>Esercizi</strong>o 6.3.2 Si mo<strong>di</strong>fichi lo script che applica la formula composta dei trapezi con n sud<strong>di</strong>visioni fissate,<strong>in</strong> modo da poter applicare anche la formula <strong>di</strong> Cavalieri-Simpson con n sud<strong>di</strong>visioni.<strong>Esercizi</strong>o 6.3.3 Si mo<strong>di</strong>fichi lo script trapezi.m e la function funtrapezi.m <strong>in</strong> modo da applicare laformula composta <strong>di</strong> Cavalieri-Simpson f<strong>in</strong>o ad un certo numero ns <strong>di</strong> sud<strong>di</strong>visioni.<strong>Esercizi</strong>o 6.3.4 Si faccia una function che esegue sia la formula composta dei trapezi, sia la formula composta<strong>di</strong> Cavalieri-Simpson, <strong>in</strong> modo da poter confrontare i risultati ottenuti con i due meto<strong>di</strong> <strong>in</strong> term<strong>in</strong>i <strong>di</strong>errori e <strong>di</strong> rapporti tra errori.101


CAPITOLO 7Equazioni Differenziali Or<strong>di</strong>narieUna volta un tale che doveva fareuna ricerca andava <strong>in</strong> biblioteca,trovava <strong>di</strong>eci titoli sull’argomento eli leggeva; oggi schiaccia un bottonedel suo computer, riceve unabibliografia <strong>di</strong> <strong>di</strong>ecimila titoli, er<strong>in</strong>uncia.Umberto Eco, La Bust<strong>in</strong>a <strong>di</strong>M<strong>in</strong>erva, 20007.1 Meto<strong>di</strong> per ODE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1037.1.1 Confronto tra i meto<strong>di</strong> sull’equazione test . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1037.2 I meto<strong>di</strong> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1057.3 Sistemi <strong>di</strong> equazioni <strong>di</strong>fferenziali . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1097.3.1 Function <strong>di</strong> MATLAB e <strong>Octave</strong> per ODE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1097.3.2 L’oscillatore semplice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1107.3.3 Equazioni del moto <strong>di</strong> Keplero . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1117.1 Meto<strong>di</strong> per ODETra i meto<strong>di</strong> per la risoluzione <strong>di</strong> equazioni alle derivate or<strong>di</strong>narie, abbiamo visto il metodo <strong>di</strong> Euleroesplicito, <strong>di</strong> Eulero implicito e <strong>di</strong> Crank-Nicolson. Li abbiamo stu<strong>di</strong>ati per la soluzione <strong>di</strong> una equazione<strong>di</strong>fferenziale del tipoy ′ = f (t, y(t))T 0 ≤ t ≤ T fcon con<strong>di</strong>zione <strong>in</strong>iziale y(T 0 ) = y 0 . Abbiamo detto, tuttavia, che questi meto<strong>di</strong> si possono anche applicarea sistemi <strong>di</strong> equazioni <strong>di</strong>fferenziali (dove non abbiamo una funzione scalare y da approssimare ma unafunzione vettoriale y).Cerchiamo allora <strong>di</strong> capire come tradurre <strong>in</strong> MATLAB i meto<strong>di</strong> che abbiamo appena citato e comeapplicarli non solo per ODE scalari, ma anche a sistemi <strong>di</strong> ODE.7.1.1 Confronto tra i meto<strong>di</strong> sull’equazione testNella teoria abbiamo <strong>in</strong>trodotto il concetto <strong>di</strong> stabilità e abbiamo visto che il metodo <strong>di</strong> Eulero esplicitoè stabile sotto con<strong>di</strong>zione, mentre i meto<strong>di</strong> <strong>di</strong> Eulero implicito e <strong>di</strong> Crank-Nicolson sono stabili <strong>in</strong>con<strong>di</strong>zionatamente(cioè senza nessuna con<strong>di</strong>zione sul passo <strong>di</strong> <strong>di</strong>scretizzazione). Abbiamo preso <strong>in</strong> esame, a tale103


7. EQUAZIONI DIFFERENZIALI ORDINARIEscopo, l’equazione test y ′ = −λy con con<strong>di</strong>zione <strong>in</strong>iziale y(0) = y 0 . Per il parametro si ha λ > 0. La soluzioneesatta <strong>di</strong> questa equazione <strong>di</strong>fferenziale è y(t) = y 0 e −λt .Fissato un passo <strong>di</strong> <strong>di</strong>scretizzazione h, il metodo <strong>di</strong> Eulero esplicito, applicato all’equazione test, <strong>di</strong>ventay i+1 = y i (1 − hλ)Perchè il metodo sia stabile, deve valere la con<strong>di</strong>zione 0 < h < 2 λIl metodo <strong>di</strong> Eulero implicito, <strong>in</strong>vece, <strong>di</strong>ventay i+1 =y i(1 + hλ)In questo caso, riusciamo ad avere la soluzione y i+1 <strong>in</strong> maniera esplicita.Analogamente, per il metodo <strong>di</strong> Crank-Nicolson si ha( ) 2 − hλy i+1 = y i2 + hλScriviamo allora uno script che applica i tre meto<strong>di</strong> per l’equazione test, da stu<strong>di</strong>are nell’<strong>in</strong>tervallo [0,20],con con<strong>di</strong>zione <strong>in</strong>iziale data da y 0 = 1. Daremo <strong>in</strong> <strong>in</strong>put il valore <strong>di</strong> λ, e un passo <strong>di</strong> <strong>di</strong>scretizzazione h. Verificheremose la con<strong>di</strong>zione <strong>di</strong> stabilità per lo schema <strong>di</strong> Eulero esplicito è verificata, e graficamente vedremole curve ottenute dai vari meto<strong>di</strong> <strong>in</strong>sieme alla soluzione esatta.Chiamiamo lo script meto<strong>di</strong>ode_a_confronto.mclearlambda=<strong>in</strong>put (’valore lambda ’ ) ;h=<strong>in</strong>put (’passo h ’ ) ;Tf<strong>in</strong> = 2 0 . ;y0 =1;f i d =fopen (’ode_a_confronto.ris’ ,’w’ ) ;log=h− 2/lambda


7.2. I meto<strong>di</strong>f p r i n t f ( fid , ’\n%5s %12s %12s %12s %12s’ , ’tempo’ , ’sol. esatta’ , ’Eul. espl.’ , ’Eul. impl.’ , ’Crank-Nic.’ ) ;f p r i n t f ( fid , ’\n%5.2f %12.6e %12.6e %12.6e %12.6e’ , [ t ’ , yex ’ , yespl , yimpl , ycn ] ’ ) ;f c l o s e ( f i d ) ;Sia dal grafico che dai risultati nel file ode_a_confronto.ris possiamo vedere le <strong>di</strong>fferenze tra i varimeto<strong>di</strong>.<strong>Esercizi</strong>o 7.1.1 Si esegua lo script meto<strong>di</strong>ode_a_confronto.m per i seguenti valori1. λ = 1, h = 0.52. λ = 1, h = 23. λ = 1, h = 0.14. λ = 0.5, h = 15. λ = 0.5, h = 0.16. λ = 0.2, h = 1.07. λ = 0.2, h = 0.17.2 I meto<strong>di</strong>Ve<strong>di</strong>amo ora come implementare questi meto<strong>di</strong> per ODE più generali.L’algoritmo <strong>di</strong> Eulero esplicito è quello più semplice da implementare.Supponiamo, per il momento, <strong>di</strong> dover risolvere una ODE del tipo y ′ = f (t, y(t)) con f funzione scalare.Oltre alla funzione dell’equazione test, abbiamo visto f (t, y(t)) = −y + t oppure f (t, y(t))− y 2 ... la funzionef può essere scritta <strong>in</strong> MATLAB come una funzione che <strong>di</strong>pende da t e da y (per semplicità, la def<strong>in</strong>iamocome <strong>di</strong>pendente da due variabili anche se può <strong>di</strong>pendere solo da una delle due). Per far ciò def<strong>in</strong>iamo la funzionecome funzione <strong>di</strong> tipo handle: scriviamo il nome della funzione, poi a destra del segno <strong>di</strong> uguaglianzascriviamo il simbolo @ e tra parentesi le variabili t,y, qu<strong>in</strong><strong>di</strong> la funzione.f =@( t , y ) −y+ t ;f =@( t , y ) −y . ^ 2 ;Introduciamo altre variabili: T<strong>in</strong>iziale e Tf<strong>in</strong>ale che rappresentano l’<strong>in</strong>tervallo <strong>in</strong> cui vogliamostu<strong>di</strong>are l’equazione <strong>di</strong>fferenziale, y0 la con<strong>di</strong>zione <strong>in</strong>iziale, h il passo <strong>di</strong> <strong>di</strong>scretizzazione.Sottol<strong>in</strong>eiamo il fatto che, <strong>in</strong> genere, nei meto<strong>di</strong> per ODE il passo <strong>di</strong> <strong>di</strong>scretizzazione viene fatto variare(si parla <strong>di</strong> adattività) seguendo determ<strong>in</strong>ati criteri che permettono <strong>di</strong> arrivare alla soluzione approssimata<strong>in</strong> un m<strong>in</strong>or numero <strong>di</strong> passi, rispetto allo stesso problema risolto con un passo <strong>di</strong> <strong>di</strong>scretizzazione costante.Noi non operiamo questa scelta, perché richiederebbe spiegazioni <strong>di</strong> tipo teorico che vanno al <strong>di</strong> là del corso<strong>di</strong> base <strong>di</strong> <strong>Calcolo</strong> <strong>Numerico</strong>. Vedremo, comunque, che le function <strong>di</strong> MATLAB che risolvono ODE utilizzanotutte delle tecniche <strong>di</strong> adattività del passo <strong>di</strong> <strong>di</strong>scretizzazione.Fatta questa premessa, ricor<strong>di</strong>amo la formula del metodo <strong>di</strong> Eulero esplicitoy i+1 = y i + h f (t i , y i )Il metodo può essere implementato nel modo seguente:function [ t , y ]= e u l e r o e s p l i c i t o ( f , y0 , T i n i z i a l e , Tf<strong>in</strong>ale , h)%function [ t , y ]= e u l e r o e s p l i c i t o ( f , y0 , T<strong>in</strong>iziale , Tf<strong>in</strong>ale , h)% dati <strong>di</strong> <strong>in</strong>put :% f funzione dell ’ equazione d i f f e r e n z i a l e y ’ = f ( t , y ( t ) )% <strong>di</strong> tipo handle% se e ’ <strong>di</strong> tipo v e t t o r i a l e , deve e s s e r e data come% funzione colonna% y0 con<strong>di</strong>zione i n i z i a l e105


7. EQUAZIONI DIFFERENZIALI ORDINARIE% T i n i z i a l e tempo i n i z i a l e% Tf<strong>in</strong>ale tempo f i n a l e% dati <strong>di</strong> output :% t v e t t o r e dei tempi% y v e t t o r e d e l l e soluzioni approssimate%%%t = T i n i z i a l e : h : Tf<strong>in</strong>ale ; % v e t t o r e dei temp<strong>in</strong>step=length ( t ) ; % nstep −1 e ’ i l numero <strong>di</strong> passi t o t a l i che saranno e f f e t t u a t iy0=y0 ’ ;m=length ( y0 ) ; % lunghezza del v e t t o r e con<strong>di</strong>zione i n i z i a l ey=zeros (m, nstep ) ;y ( : , 1 ) = y0 ’ ;for i =2: nstepy ( : , i )=y ( : , i −1)+h* f eval ( f , t ( i −1) ,y ( : , i −1));endy=y ’ ; %i l v e t t o r e d e l l e soluzioni approssimate lo s i rende come v e t t o r e% <strong>di</strong> nstep+1 righe e m colonne per uniformita ’ r i s p e t t o a l l e% function <strong>di</strong> MATLAB che risolvono ODEendPer poter eseguire questo script, possiamo ad esempio, dare i datif =@( t , y ) −y+ t ;y0 =1;T i n i z i a l e =0;Tf<strong>in</strong>ale =2;h=0.01;[ t , y ]= e u l e r o e s p l i c i t o ( f , y0 , T i n i z i a l e , Tf<strong>in</strong>ale , h ) ;In questo caso, sapendo che la funzione esatta vale fex=@(t) t-1+2*exp(-t), possiamo calcolare ivalori della soluzione esatta negli stessi punti del vettore t e fare il grafico che mette a confronto soluzioneesatta e soluzione approssimata.yex= f e v a l ( fex , t ) ;plot ( t , y , t , yex ) ;legend (’soluzione approssimata’ , ’soluzione esatta’)Per applicare lo schema <strong>di</strong> Eulero implicito, <strong>in</strong>vece, dobbiamo fare più attenzione. Nello script sull’equazionetest y ′ = −λy abbiamo sfruttato la l<strong>in</strong>earità della f per poter esplicitare le approssimazioni y i+1 .Ricor<strong>di</strong>amo la formula del metodo:y i+1 = y i + h f (t i+1 , y i+1 ))Se la funzione f <strong>di</strong>pende <strong>in</strong> modo non l<strong>in</strong>eare da y allora il metodo resta implicito. Potremmo scrivere, allora,due tipi <strong>di</strong> function, una per risolvere equazioni <strong>di</strong>fferenziali <strong>in</strong> cui si riesce a esplicitare y i+1 (come nel casodell’equazione test), quando la funzione f del problema è l<strong>in</strong>eare rispetto a y, e un’altra function per risolvereproblemi <strong>in</strong> cui la f è non l<strong>in</strong>eare.Potremmo farlo, ma visto che ci serve capire come funziona lo schema nel caso più generale, lo pensiamocome schema implicito. Come facciamo allora a trovare y i+1 se <strong>di</strong>pende da y i+1 stesso? Abbiamo visto dallateoria, che possiamo ricondurci ad uno schema <strong>di</strong> punto fisso o <strong>di</strong> ricerca <strong>di</strong> zeri <strong>di</strong> funzione. Lo schema piùsemplice da applicare è quello <strong>di</strong> punto fisso ed è proprio quello che faremo. 1 Dato il valore y i , per ricavarey i+1 , la formula da applicare si può leggere come lo schema <strong>di</strong> punto fissoy i+1 = g (t i+1 , y i+1 )1 Sicuramente va meglio applicare uno schema <strong>di</strong> tipo Newton-Raphson o secante variabile. Non lo facciamo per ragioni <strong>di</strong>semplicità. Vogliamo solo capire come si risolvono questi meto<strong>di</strong> <strong>di</strong> tipo implicito.106


7.2. I meto<strong>di</strong>dove g (t, y) = y i + h f (t, y). Si può partire da un punto <strong>in</strong>iziale x 0 = y i e poi iterare lo schema iterativo f<strong>in</strong>o ache non si trova un’approssimazione del punto fisso della funzione g che altro non è che un’approssimazione<strong>di</strong> y i+1 . Il valore appena trovato per y i+1 <strong>di</strong>venterà il valore <strong>in</strong>iziale x 0 per fare partire <strong>di</strong> nuovo lo schema <strong>di</strong>punto fisso e trovare la successiva approssimazione y i+2 , e così via. La function che scriviamo sarà:function [ t , y ]= euleroimplicito ( f , y0 , T i n i z i a l e , Tf<strong>in</strong>ale , h)%function [ t , y ]= euleroimplicito ( f , y0 , T<strong>in</strong>iziale , Tf<strong>in</strong>ale , h)% dati <strong>di</strong> <strong>in</strong>put :% f funzione dell ’ equazione d i f f e r e n z i a l e y ’ = f ( t , y ( t ) )% <strong>di</strong> tipo handle% se e ’ <strong>di</strong> tipo v e t t o r i a l e , deve e s s e r e data come% funzione colonna% y0 con<strong>di</strong>zione i n i z i a l e% T i n i z i a l e tempo i n i z i a l e% Tf<strong>in</strong>ale tempo f i n a l e% dati <strong>di</strong> output :% t v e t t o r e dei tempi% y v e t t o r e d e l l e soluzioni approssimate%%%t = T i n i z i a l e : h : Tf<strong>in</strong>ale ;nstep=length ( t ) ;y0=y0 ’ ;m=length ( y0 ) ;y=zeros (m, nstep ) ;y ( : , 1 ) = y0 ;for i =2: nstepx0=y ( : , i −1); %punto i n i z i a l e per lo schema <strong>di</strong> punto f i s s oscarto =2; % valore i n i z i a l e d e l l o scartoi t =0; % contatore d e l l e i t e r a z i o n i per lo schema <strong>di</strong> punto f i s s owhile scarto >=1.e−6 && i t =1.e−6 && i t ==10error (’EuleroImplicito’ ,’warn<strong>in</strong>g nel punto fisso’)endy ( : , i )= xk ; % nuova approssimazione dallo schema <strong>di</strong> punto f i s s oendy=y ’ ;endNello schema <strong>di</strong> punto fisso abbiamo considerato una tolleranza sulla soluzione pari a 10 −6 e un numeromassimo <strong>di</strong> iterazioni pari a 10. Abbiamo messo un segnale <strong>di</strong> avvertimento nel caso <strong>in</strong> cui lo schema <strong>di</strong>punto fisso non converge. Sottol<strong>in</strong>eiamo che lo schema <strong>di</strong> punto fisso potrebbe non convergere, ma pervalori <strong>di</strong> h sufficientemente piccoli, lo schema converge e riusciamo ad avere una buona approssimazioneper la soluzione numerica.Se, <strong>in</strong>vece, usiamo questa function per stu<strong>di</strong>are la stabilità del metodo applicandola all’equazione testy ′ = −y vedremo che, per valori <strong>di</strong> h gran<strong>di</strong>, non avremo convergenza <strong>in</strong> quanto lo schema <strong>di</strong> punto fisso nonconvergerà. Nel caso <strong>di</strong> Eulero implicito <strong>in</strong>fatti, per l’equazione test ora <strong>in</strong><strong>di</strong>cata, si ha y i+1 = y i − hy i+1 . Seconsideriamo la funzione <strong>di</strong> punto fisso g (y) = y i − hy ve<strong>di</strong>amo che g ′ (y) = −h. Perciò per valori <strong>di</strong> h > 1 loschema non converge e qu<strong>in</strong><strong>di</strong> non otteniamo neanche i valori dello schema <strong>di</strong> Eulero implicito. In questocaso, sarebbe preferibile applicare lo schema <strong>di</strong> Newton-Raphson perchè avremmo i risultati corretti. Comeabbiamo detto, comunque, la scelta <strong>di</strong> applicare lo schema <strong>di</strong> punto fisso è esclusivamente <strong>di</strong> tipo <strong>di</strong>dattico.107


7. EQUAZIONI DIFFERENZIALI ORDINARIEPer problemi più <strong>di</strong>fficili, comunque, useremo passi <strong>di</strong> <strong>di</strong>scretizzazione sufficientemente piccoli e tali che loschema <strong>di</strong> punto fisso andrà bene. Perciò, lasciamo il punto fisso come metodo che approssima la nuovaapprossimazione.Gli stessi <strong>di</strong>scorsi valgono anche per lo schema <strong>di</strong> Crank-Nicolson, la cui formula è data day i+1 = y i + h 2[f (ti , y i ) + f (t i+1 , y i+1 ) ]Per implementare lo schema, ci serviamo ancora del metodo <strong>di</strong> punto fisso, applicato ora alla funzione <strong>di</strong>punto fissog (t, y) = y i + h 2La function che ricaviamo è[f (ti , y i ) + f (t, y) ]function [ t , y ]= cranknicolson ( f , y0 , T i n i z i a l e , Tf<strong>in</strong>ale , h)%function [ t , y ]= cranknicolson ( f , y0 , T<strong>in</strong>iziale , Tf<strong>in</strong>ale , h)% dati <strong>di</strong> <strong>in</strong>put :% f funzione dell ’ equazione d i f f e r e n z i a l e y ’ = f ( t , y ( t ) )% <strong>di</strong> tipo handle% se e ’ <strong>di</strong> tipo v e t t o r i a l e , deve e s s e r e data come% funzione colonna% y0 con<strong>di</strong>zione i n i z i a l e% T i n i z i a l e tempo i n i z i a l e% Tf<strong>in</strong>ale tempo f i n a l e% dati <strong>di</strong> output :% t v e t t o r e dei tempi% y v e t t o r e d e l l e soluzioni approssimate%%%t = T i n i z i a l e : h : Tf<strong>in</strong>ale ;nstep=length ( t ) ;y0=y0 ’ ;m=length ( y0 ) ;y=zeros (m, nstep ) ;y ( : , 1 ) = y0 ;for i =2: nstepx0=y ( : , i −1);scarto =2;i t =0;fm= f eval ( f , t ( i −1) ,y ( : , i −1)); %valore della f all ’ approssimazione% i −1% serve nello schema <strong>di</strong> Crank−Nicolsonwhile scarto >=1.e−6 && i t =1.e−6 && i t ==10error (’CrankNicolson’ ,’warn<strong>in</strong>g nel punto fisso’)endy ( : , i )= x0 ;endy=y ’ ;end108


7.3. Sistemi <strong>di</strong> equazioni <strong>di</strong>fferenzialiNotiamo come lo schema sia stato implementato <strong>in</strong> modo del tutto analogo allo schema <strong>di</strong> Eulero implicito.Valgono perciò le stesse considerazioni fatte rispetto allo schema <strong>di</strong> punto fisso applicato.Ora, alla stessa maniera con cui abbiamo eseguito il metodo <strong>di</strong> Eulero esplicito, possiamo vedere i risultatiche si ottengono con gli altri due meto<strong>di</strong> (Eulero implicito e Crank-Nicolson).7.3 Sistemi <strong>di</strong> equazioni <strong>di</strong>fferenzialiCiò che abbiamo detto sulle equazioni <strong>di</strong>fferenziali scalari, valgono anche per sistemi <strong>di</strong> equazioni <strong>di</strong>fferenziali.Lo schema si applica componente per componente, per le s<strong>in</strong>gole equazioni che compongono ilsistema. Per i meto<strong>di</strong> impliciti, lo schema <strong>di</strong> punto fisso sarà applicato sulle s<strong>in</strong>gole equazioni (se si vanno arivedere le function sul metodo <strong>di</strong> Eulero implicito e <strong>di</strong> Crank-Nicolson, si può notare che il controllo dellaconvergenza dello schema <strong>di</strong> punto fisso è stato fatto calcolando la norma euclidea – che co<strong>in</strong>cide con il valoreassoluto nel caso <strong>di</strong> quantità scalari – <strong>in</strong> modo che la function possa andare bene anche per sistemi <strong>di</strong>equazioni!)In tutte le function che abbiamo scritto, <strong>in</strong>oltre, abbiamo considerato la lunghezza della variabile checontiene la con<strong>di</strong>zione <strong>in</strong>iziale (per capire se stiamo lavorando su quantità scalari o su vettori).7.3.1 Function <strong>di</strong> MATLAB e <strong>Octave</strong> per ODECi sono tante function sviluppate <strong>in</strong> MATLAB (solo <strong>in</strong> MATLAB però) per risolvere equazioni <strong>di</strong>fferenziali.Tra queste ricor<strong>di</strong>amoG ode45G ode23Come parametri <strong>di</strong> base <strong>in</strong> <strong>in</strong>put occorre dare, nell’or<strong>di</strong>ne, la function handle dell’equazione <strong>di</strong>fferenziale, unvettore che contiene i valori T 0 e T f <strong>in</strong> cui risolvere l’equazione <strong>di</strong>fferenziale e la con<strong>di</strong>zione <strong>in</strong>iziale y 0 . Lafunzione deve essere data come vettore colonna nel caso <strong>in</strong> cui ci sia un sistema <strong>di</strong> ODE. La function (ode45o ode23) restituisce il vettore dei tempi e delle soluzioni approssimate.Per gli esempi precedenti, dobbiamo qu<strong>in</strong><strong>di</strong> scrivere l’istruzione [t ,y]=ode45(f,[T<strong>in</strong>iziale, Tf<strong>in</strong>ale], y0); perpoter risolvere l’equazione <strong>di</strong>fferenziale con la function ode45 (analogamente si farà per ode23).Facendo un help <strong>di</strong> queste function, MATLAB ci rimanda a tantissime altre function, tutte utili perrisolvere ODE.In <strong>Octave</strong>, tra le function da ricordare per risolvere equazioni <strong>di</strong>fferenziali, troviamo la lsode, la cui s<strong>in</strong>tassiè <strong>di</strong>versa da quelle <strong>di</strong> MATLAB e da quelle che abbiamo costruito f<strong>in</strong>o ad ora. La s<strong>in</strong>tassi <strong>di</strong> base cambia unpo’. Abbiamo <strong>in</strong>fatti[y,stato,messaggio]=lsode(f,y0,t)dove f è una function (<strong>in</strong>l<strong>in</strong>e o handle) che deve avere la forma yd=f(y,t) (notiamo l’<strong>in</strong>versione <strong>di</strong> or<strong>di</strong>ne nellevariabili <strong>di</strong> <strong>in</strong>put), con t scalare e y,yd vettori (o scalari a seconda della funzione). La funzione da dare <strong>in</strong> <strong>in</strong>put(per problemi complicati) può essere costituita come str<strong>in</strong>ga <strong>di</strong> due function handle, <strong>in</strong> cui la prima componenteè data dalla funzione f dell’equazione <strong>di</strong>fferenziale e la seconda componente è data dalla funzione checontiene la matrice la matrice Jacobiana, scritta nella forma JAC=j(y,t). Per questi casi, <strong>in</strong> <strong>in</strong>put, daremo unafunction del tipo F={f, j } (si osserv<strong>in</strong>o le parentesi graffe che def<strong>in</strong>iscono una str<strong>in</strong>ga <strong>di</strong> function). Nei nostriproblemi, tuttavia, non useremo la matrice Jacobiana e qu<strong>in</strong><strong>di</strong> bisogna prestare attenzione solo a scrivere lafunction f con le variabili <strong>in</strong>vertite e a seguire la s<strong>in</strong>tassi, (come vedremo nell’esempio).Il parametro y0 rappresenta la con<strong>di</strong>zione <strong>in</strong>iziale, mentre t è il vettore dei tempi, <strong>in</strong> cui la primacomponente è il tempo <strong>in</strong>iziale e le altre componenti sono gli istanti <strong>di</strong> tempo <strong>in</strong> cui si vuole risolvere ilproblema.In uscita, stato vale 2 se la function è stata eseguita con successo, altrimenti si ha un valore <strong>di</strong>verso da 2.La variabile messaggio contiene <strong>in</strong>formazioni aggiuntive.Ve<strong>di</strong>amo un esempio: dall’equazione y ′ = −y 2 , lo script da lanciare saràf =@( y , t ) −y . ^ 2 ;y0 =1;T i n i z i a l e =0;109


7. EQUAZIONI DIFFERENZIALI ORDINARIETf<strong>in</strong>ale =10;t = T i n i z i a l e : h : Tf<strong>in</strong>ale ;[ y , i s t a t e , messaggio ]= lsode ( f , y0 , t ) ;7.3.2 L’oscillatore sempliceUn esempio che ci porta ad un sistema <strong>di</strong> equazioni <strong>di</strong>fferenziali è dato dal modello costituito da massamolla-smorzatore.Se si vuole stu<strong>di</strong>are l’evoluzione <strong>di</strong>namica del sistema (vale a <strong>di</strong>re la posizione e la velocitàdella massa m) al variare <strong>di</strong> alcuni parametri (lo smorzamento e l’elasticità della molla) <strong>in</strong> presenza o meno<strong>di</strong> una forza esterna F (t), si ottiene un’equazione <strong>di</strong>fferenziale data dam d 2 x(t)d t 2+ c d x(t) + kx(t) = F (t)d tdove x(t) rappresenta lo spostamento della massa m dalla posizione <strong>di</strong> equilibrio, d x(t) è la sua velocità,d tmentre d 2 x(t)d t 2 rappresenta la sua accelerazione. I valori m, c e k rappresentano la massa, il coefficiente <strong>di</strong>smorzamento e la costante elastica della molla, rispettivamente.Scriviamo <strong>di</strong>versamente l’equazione comed 2 x(t)d t 2 =F (t) − c d x(t) − kx(t)d tmPer passare da questa equazione <strong>di</strong>fferenziale del secondo or<strong>di</strong>ne (perchè compare una derivata seconda)ad un sistema <strong>di</strong> equazioni <strong>di</strong>fferenziali del primo or<strong>di</strong>ne, si fanno le seguenti trasformazioni. Si <strong>in</strong>troduce ilvettore y = (y 1 , y 2 ) tale che y 1 = x e y 2 = d xd t . Allora (usiamo il simbolo ′ per <strong>in</strong><strong>di</strong>care la derivata rispetto a t).y ′ 1 = x′ = d xd t = y 2y ′ 2 = d d t( d xd t)= d 2 x(t)d t 2 =F (t) − c d x(t) − kx(t)d tm= F (t) − c y 2 − k y 1mAbbiamo qu<strong>in</strong><strong>di</strong> il sistemay ′ = f(t,y)dove f(t,y) è una funzione vettoriale <strong>di</strong> due componenti:⎛⎞y 2f(t,y) = ⎝ F (t) − c y 2 − k y 1⎠mPossiamo <strong>in</strong>trodurre una function handle <strong>di</strong> questo tipo (specificando i vari parametri) da applicare allenostre funzioni che risolvono ODE o alle function <strong>di</strong> MATLAB/<strong>Octave</strong> per risolvere ODE. Ad esempio, perm = 1kg , k = 10N /m, c = 0.5N s/m e F (t) = 0N e dando come con<strong>di</strong>zione <strong>in</strong>iziale (sullo spostamento e sullasua velocità) x(0) = 1m x ′ (0) = 0m/s possiamo scrivere,k=10; c = 0 . 5 ; m=1;f =@( t , y ) [ y ( 2 ) ; (−k*y(1)−c * y ( 2 ) ) /m] ; %scriviamo una funzione v e t t o r i a l e% come v e t t o r e colonna% come serve anche per l e function% proprie <strong>di</strong> MATLAB110


7.3. Sistemi <strong>di</strong> equazioni <strong>di</strong>fferenzialiy0 = [ 1 ; 0 ] ;h=0.01;T i n i z i a l e =0;Tf<strong>in</strong>ale =60;[ tespl , yespl ]= e u l e r o e s p l i c i t o ( f , y0 , T i n i z i a l e , Tf<strong>in</strong>ale , h ) ;[ timpl , yimpl ]= euleroimplicito ( f , y0 , T i n i z i a l e , Tf<strong>in</strong>ale , h ) ;Possiamo confrontare i due meto<strong>di</strong>, oppure applicare la function ode45 o altre ancora... Se vogliamo applicare<strong>in</strong> <strong>Octave</strong> la function lsode scriveremo <strong>in</strong>vecek=10; c = 0 . 5 ; m=1;f =@( y , t ) [ y ( 2 ) ; (−k*y(1)−c * y ( 2 ) ) /m] ;y0 = [ 1 ; 0 ] ;h=0.01;T i n i z i a l e =0;Tf<strong>in</strong>ale =60;t = T i n i z i a l e : t : Tf<strong>in</strong>ale ;[ y , i s t a t e , messaggio ]= lsode ( f , y0 , t ) ;Come grafici, possiamo fare un grafico <strong>in</strong> cui mettiamo sull’asse delle ascisse il vettore dei tempi e sull’assedelle or<strong>di</strong>nate i due valori <strong>di</strong> spostamento e velocità che abbiamo ottenuto. Basta scrivere (ad esempio perEulero esplicito)plot ( tespl , yespl )Possiamo anche fare un grafico <strong>in</strong> cui ve<strong>di</strong>amo come varia la velocità <strong>in</strong> funzione dello spostamento conl’istruzione plot(yespl (:,1), yespl (:,2)) (si parla <strong>di</strong> piano delle fasi <strong>in</strong> questo caso).7.3.3 Equazioni del moto <strong>di</strong> KepleroLa legge <strong>di</strong> gravitazione universale <strong>di</strong> Newton <strong>di</strong>ce che due corpi si attraggono con una forza <strong>di</strong>rettamenteproporzionale alle loro rispettive masse m 1 e m 2 e <strong>in</strong>versamente proporzionale al quadrato della <strong>di</strong>stanza |r |(<strong>in</strong>teso come norma euclidea del vettore <strong>di</strong>stanza) tra essi:F = G m 1m 2|r | 2Nella formula G rappresenta la costante gravitazionale, G = 6.67 × 10 −11 m 3 K g −1 s −2 .In un sistema <strong>di</strong> due corpi (pensiamo a due pianeti), la forza <strong>di</strong> attrazione del secondo corpo agisce sulprimo <strong>di</strong> massa m 1 e la forza del primo corppo agisce sul secondo <strong>di</strong> massa m 2 . Entrambe le forze sono ugualie <strong>di</strong>rette lungo la <strong>di</strong>rezione r tra i due corpi (con versi opposti).Ciò significa che, rispetto ad un sistema <strong>di</strong> riferimento <strong>in</strong> cui r 1 e r 2 rappresentano la <strong>di</strong>stanza dei duecorpi rispetto all’orig<strong>in</strong>e del sistema <strong>di</strong> riferimento, vale r = r 2 − r 1 . Applicando la seconda legge <strong>di</strong> NewtonF = ma (Forza=massa per accelerazione) per ogni corpo, e considerando che per l’accelerazione si ha a i =d 2 r id t 2 , otteniamom 1d 2 r 1d t 2 = G m 1m 2|r | 3 r, m 2d 2 r 2d t 2 = −G m 1m 2|r | 3 rAbbiamo considerato, a destra, il vettore unitario che dà la <strong>di</strong>rezione della forza, dato dae sottraendo abbiamocioèd 2 r 2 − r 1d t 2 = −G m 1 + m 2|r | 3 rd 2 rd t 2 = −G m 1 + m 2|r | 3 rr|r | . Semplificando111


7. EQUAZIONI DIFFERENZIALI ORDINARIENel caso <strong>in</strong> cui i due pianeti siano il sole e la terra, poichè la massa del sole è 333000 volte più grandedella massa della terra, si considera solo il prodotto Gm sol e : questa quantità prende il nome <strong>di</strong> costantegravitazionale geocentrica della Terra e si <strong>in</strong><strong>di</strong>ca con GM. L’equazione del moto della Terra attorno al sole sipuò qu<strong>in</strong><strong>di</strong> vedere comed 2 rd t 2 = −GM |r | 3 rAbbiamo un’equazione alle derivate or<strong>di</strong>narie, vettoriale, del secondo or<strong>di</strong>ne perchè compare la derivataseconda d 2 rd t 2 .Per rendere il problema piú semplice, si può scegliere un sistema <strong>di</strong> riferimento <strong>in</strong> cui la quantità GM nonsia nè troppo grande nè troppo piccola. Per descrivere l’orbita della Terra, si pone la convenzione <strong>di</strong> def<strong>in</strong>irecome unità <strong>di</strong> lunghezza il semiasse maggiore dell’orbita della terra. Questa unità <strong>di</strong> lunghezza si chiamaunità astronomica (AU) e vale1AU = 1.496 × 10 11 mCome unità <strong>di</strong> tempo si considera l’anno (o 3.15 × 10 7 s). In queste unità, il periodo (per compiere un <strong>in</strong>terogiro attorno al sole) per la Terra vale T = 1 anno e il suo semiasse maggiore vale a = 1AU . In questo sistemaabbiamoGM = 4π2 a 3T 2 = 4π 2 AU 3 /anni 2Stu<strong>di</strong>ando questa equazione <strong>di</strong>fferenziale nel caso più semplice (vale a <strong>di</strong>re considerando il vettore <strong>di</strong>stanzacome un vettore nello spazio bi<strong>di</strong>mensionale), abbiamo un’equazione <strong>di</strong>fferenziale <strong>di</strong> secondo gradoda ridurre ad un sistema <strong>di</strong> equazioni <strong>di</strong>fferenziali del primo or<strong>di</strong>ne. Si consideri allora il vettore che ha comecomponenti il vettore r = (r x ,r y ) e il vettore velocità <strong>di</strong> v <strong>di</strong> componenti (v x , v y ). Introduciamo il vettore yfatto <strong>in</strong> questo modo: y = (y 1 , y 2 , y 3 , y 4 ) = (r x ,r y , v x , v y ) Allora⎛ ⎞ ⎛ ⎞⎛y ′ ⎞ v xy 31y ′ = ⎜y 2′ v y⎝y 3′ ⎟⎠ = − GMy 4⎜ |r | 3 r x=− GMy4′ ⎝− GM⎟ ⎜ |r | 3 y 1|r | 3 r ⎠ ⎝y − GM⎟|r | 3 y ⎠2Abbiamo trovato le equazioni del sistema (dette anche equazioni <strong>di</strong> Keplero). Poichè |r | =√y1 2 + y 2 2 , <strong>in</strong> MATLAB scriveremo (usiamo le unità astronomiche):GM=4* pi ^2;f =@( t , y ) [ y ( 3 ) ; y ( 4 ) ; −GM* y ( 1 ) / sqrt ( y(1)^2+y (2)^2)^3; . . .−GM* y ( 2 ) / sqrt ( y(1)^2+y ( 2 ) ^ 2 ) ^ 3 ] ;√r 2 x + r 2 y =Come con<strong>di</strong>zione <strong>in</strong>iziale consideriamo r x = 1, r y = 0, v x = 0 e v y = GM (dalle leggi gravitazioniali vale√GM<strong>in</strong>fatti per la velocità |v| = ). Eseguiremo, qu<strong>in</strong><strong>di</strong> le seguenti righe <strong>di</strong> co<strong>di</strong>ce (usiamo, questa volta, il|r |metodo <strong>di</strong> Crank-Nicolson) che ci permettono <strong>di</strong> risolvere l’equazione e fare <strong>di</strong>versi grafici:GM=4* pi ^2;f =@( t , y ) [ y ( 3 ) ; y ( 4 ) ; −GM* y ( 1 ) / sqrt ( y(1)^2+y (2)^2)^3; −GM* y ( 2 ) / sqrt ( y(1)^2+y ( 2 ) ^ 2 ) ^ 3 ] ;y0=[1 0 0 sqrt (GM) ] ’ ;T i n i z i a l e =0;Tf<strong>in</strong>ale = 1 . 0 ; %annoh=1./365;112


7.3. Sistemi <strong>di</strong> equazioni <strong>di</strong>fferenziali[ t , y ]= cranknicolson ( f , y0 , T i n i z i a l e , Tf<strong>in</strong>ale , h ) ;figure ( 1 )plot ( t , y ( : , 3 ) , t , y ( : , 4 ) ) % velocita ’ e accelerazione al variare del tempofigure ( 2 )plot ( y ( : , 1 ) , y ( : , 2 ) ) % l ’ orbita della Terra ( rx , ry )figure ( 3 )plot ( y ( : , 3 ) , y ( : , 4 ) ) % velocita ’ e accelerazioneUno script completo per eseguire tutti questi esempi con i vari meto<strong>di</strong> proposti è scaricabile sul sito delle<strong>di</strong>spense <strong>di</strong>spense.dmsa.unipd.it/mazzia con nome scriptODE.m.113

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

Saved successfully!

Ooh no, something went wrong!