dispensamatlab

117
Annamaria Mazzia Esercitazioni di Calcolo Numerico in MATLAB® e Octave Dipartimento di Ingegneria Civile Edile e Ambientale Università degli Studi di Padova Creative Commons Attribuzione- Non commerciale -Non opere derivate 3.0 Italia License a.a. 2012/2013

description

vcxvxvxc

Transcript of dispensamatlab

  • Annamaria Mazzia

    Esercitazioni di CalcoloNumerico in MATLAB e

    Octave

    Dipartimento di Ingegneria Civile Edile e AmbientaleUniversit degli Studi di Padova

    Creative Commons Attribuzione- Non commerciale -Non opere derivate 3.0 Italia License

    a.a. 2012/2013

  • Indice

    Indice ii

    1 Introduzione 11.1 Introduzione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11.2 Avvio di MATLAB e Octave . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2

    1.2.1 Le variabili . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41.2.2 Prima introduzione (breve) su matrici e vettori in MATLAB . . . . . . . . . . . . . . . . 51.2.3 Funzioni vettorizzate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71.2.4 Sulle variabili . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

    1.3 Comandi utili . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101.4 Introduzione alla programmazione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111.5 Problemi e Algoritmi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121.6 MATLAB come linguaggio di programmazione . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131.7 Primo script e prima function in MATLAB . . . . . . . . . . . . . . . . . . . . . . . . . . . 131.8 I predicati elementari . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151.9 Strutture e cicli . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18

    1.9.1 Ciclo if . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181.9.2 Ciclo while . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 241.9.3 Ciclo for . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 331.9.4 Introduzione a file di scrittura dati . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 351.9.5 Modificare le function di punto fisso per creare nuove function . . . . . . . . . . . . . . 39

    2 Su interpolazione e approssimazione 432.1 Interpolazione monomiale e con i polinomi di Lagrange . . . . . . . . . . . . . . . . . . . . . . . 442.2 Interpolazione con la tabella delle differenze divise di Newton . . . . . . . . . . . . . . . . . . . . 502.3 Interpolazione lineare a tratti e spline cubica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54

    2.3.1 Interpolazione lineare a tratti . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 542.4 Curve parametriche . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59

    2.4.1 Il ciclo switch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 602.5 Approssimazione di dati . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62

    2.5.1 Retta di regressione sugli scarti verticali . . . . . . . . . . . . . . . . . . . . . . . . . . . . 622.5.2 Modello potenza e modello esponenziale . . . . . . . . . . . . . . . . . . . . . . . . . . . 642.5.3 Caricare i dati di input da file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65

    3 Metodi diretti per sistemi lineari 693.1 Prodotti matrice-vettore, matrice-matrice, scalari . . . . . . . . . . . . . . . . . . . . . . . . . . . 713.2 Metodi di sostituzione allindietro e in avanti . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 723.3 Metodi diretti . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74

    ii

  • Indice

    3.4 Norme di vettori . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75

    4 Metodi iterativi per sistemi lineari 794.1 Metodo di Jacobi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 794.2 Modificare jacobi.m per implementare gli altri metodi . . . . . . . . . . . . . . . . . . . . . . . 83

    4.2.1 Metodo di Gauss-Seidel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 834.2.2 Metodo di rilassamento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84

    5 Problemi non lineari 875.1 Metodo di Newton per sistemi non lineari . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 875.2 Minimi quadrati non lineari . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91

    6 Formule di integrazione numerica 956.1 Formule di quadratura numerica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 956.2 La formula dei trapezi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 956.3 La formula di Cavalieri-Simpson . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100

    7 Equazioni Differenziali Ordinarie 1037.1 Metodi per ODE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103

    7.1.1 Confronto tra i metodi sullequazione test . . . . . . . . . . . . . . . . . . . . . . . . . . . 1037.2 I metodi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1057.3 Sistemi di equazioni differenziali . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109

    7.3.1 Function di MATLAB e Octave per ODE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1097.3.2 Loscillatore semplice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1107.3.3 Equazioni del moto di Keplero . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111

    iii

  • CAPITOLO 1

    Introduzione

    Luniverso non potr essere lettofinch non avremo imparato illinguaggio ed avremo familiarizzatocon i caratteri con cui scritto. scritto in linguaggio matematico, ele lettere sono triangoli, cerchi edaltre figure geometriche, senza lequali umanamente impossibilecomprendere una singola parola.

    Galileo Galilei

    1.1 Introduzione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11.2 Avvio di MATLAB e Octave . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2

    1.2.1 Le variabili . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41.2.2 Prima introduzione (breve) su matrici e vettori in MATLAB . . . . . . . . . . . . . . . . . 51.2.3 Funzioni vettorizzate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71.2.4 Sulle variabili . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

    1.3 Comandi utili . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101.4 Introduzione alla programmazione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111.5 Problemi e Algoritmi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121.6 MATLAB come linguaggio di programmazione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131.7 Primo script e prima function in MATLAB . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131.8 I predicati elementari . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151.9 Strutture e cicli . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18

    1.9.1 Ciclo if . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181.9.2 Ciclo while . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 241.9.3 Ciclo for . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 331.9.4 Introduzione a file di scrittura dati . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 351.9.5 Modificare le function di punto fisso per creare nuove function . . . . . . . . . . . . . . . 39

    1.1 Introduzione

    MATLAB un acronimo per MATrix LABoratory ed uno strumento utile per il calcolo numerico e per lavisualizzazione. MATLAB , infatti, pu essere considerato un linguaggio di programmazione ad alto livelloe, allo stesso tempo, un ambiente interattivo per lo sviluppo di algoritmi, per la visualizzazione e lanalisi didati, e per il calcolo numerico.

    1

  • 1. INTRODUZIONE

    Quindi, per imparare a usare bene MATLAB , dobbiamo imparare le tecniche di programmazione (cosa un programma, quali sono le strutture di un programma, come si scrive, come si esegue). Ma dobbiamo an-che tenere in conto che MATLAB ha le sue proprie funzioni (functions), che permettono di eseguire calcolimolto sofisticati, ed capace di fare grafici e visualizzare i risultati in maniera diretta.

    Molto spesso la conoscenza di MATLAB un requisito richiesto per molte posizioni lavorative in ambi-to ingegneristico proprio per la sua implementazione in numerosi problemi (dallingegneria aerospaziale aquella chimica, alla meccanica ...).

    MATLAB un programma complesso (originariamente fu scritto in FORTRAN e successivamente riscrit-to in linguaggio C) che va bene per risolvere programmi delaborazione numerica, per lavorare con matricie per la grafica. Questo software un prodotto della The MathWorks : vedremo in particolare la versioneMATLAB 8.0.0.783 (R2012b) lavorando in ambiente Linux.

    Un prodotto simile a MATLAB ma open source GNU Octave (si vada sul sito http://www.gnu.org/software/octave/). In queste dispense, faremo riferimento alla versione 3.6.2 di Octave.

    Nel seguito vedremo come si lavora in MATLAB (e Octave) tenendo presente che quasi tutti i coman-di che daremo in MATLAB valgono alla stessa maniera anche per Octave con alcune differenze, comelinterfaccia grafico o altri comandi, che sottolineeremo.

    1.2 Avvio di MATLAB e Octave

    Tralasciamo la parte relativa alla procedura di installazione di MATLAB (e di Octave), che dipende dalcomputer e dal sistema operativo in uso, e diamo per scontato che il programma sia presente sul propriocomputer.

    In ambiente Linux, per avviare MATLAB basta digitare il comando matlab da una finestra di termina-le (analogamente, basta digitare octave per entrare in ambiente Octave). Una volta avviato MATLAB , siaprir un ambiente che contiene molte finestre (la Command Window, la Workspace, la Command Histo-ry, la Current Folder). Il prompt dei comandi dato dal simbolo >> (> in Octave) e comparir il promptdei comandi in una finestra come quella mostrata in Figura 1.1 (si veda Figura 1.2 per lanalogo di Octave).Per uscire dallambiente si digita exit o quit dalla finestra dei comandi oppure dal menu File o ancoradallicona di chiusura (x in alto a destra della finestra).

    Per imparare a usare MATLAB , conviene prendere familiarit con la finestra dei comandi eseguendocalcoli come se fosse una calcolatrice. Vediamo che il risultato viene assegnato ad una variabile detta ans eche nella Workspace si trovano informazioni su di essa (si veda Figura 1.3).

    Le principali operazioni aritmetiche sono date da

    elevamento a potenza moltiplicazione/ divisione+ addizione sottrazione

    Nel fare le operazioni aritmetiche, viene data la precedenza agli elevamenti a potenza, poi alle moltiplica-zioni e divisioni, infine alla sottrazione e addizione. Quando due operatori hanno la stessa prorit vengonoeseguite le operazioni partendo da sinistra e andando verso destra. Tuttavia, quando le espressioni sonoabbastanza complicate e c il rischio di non capire bene quali operazioni vanno fatte prima e quali dopo,conviene mettere sempre le parentesi.

    Le funzioni di base (quelle che troviamo anche su una calcolatrice) sono date da

    2

    http://www.gnu.org/software/octave/http://www.gnu.org/software/octave/

  • 1.2. Avvio di MATLAB e Octave

    Figura 1.1: Lambiente MATLAB consiste di una serie di finestre, alcune delle la Current Folder (la di-rectory corrente in cui si sta lavorando), la Workspace (lo spazio di lavoro) e la Command History (lafinestra con la storia dei comandi dati).

    Figura 1.2: Avvio di Octave: la finestra che si apre corrisponde alla Command Window di MATLAB .

    3

  • 1. INTRODUZIONE

    Figura 1.3: Primi calcoli in MATLAB : osservare cosa succede nella Command Window, nella Workspacee nella Command History.

    Funzione MATLAB (Octave) Significatosin(x) sin(x)cos(x) cos(x)tan(x) tan(x)asin(x) asi n(x)acos(x) acos(x)atan(x) at an(x)exp(x) ex

    log(x) ln(x)log10(x) log(x)sqrt(x)

    px

    abs(x) |x|

    La cosa nuova, da sottolineare, che ora queste operazioni si possono fare su matrici e vettori e che inMATLAB (Octave) si lavora soprattutto su matrici e vettori.

    Per lavorare meglio, nel seguito introduciamo il concetto di variabile e, successivamente, le matrici e ivettori.

    1.2.1 Le variabili

    Abbiamo visto che, se scriviamo nella finestra di lavoro, sin(10) il risultato ans =-0.5440. Il ri-sultato della funzione viene assegnato ad una variabile che, di default, viene chiamata ans. Se cambiamo ilcalcolo, il risultato sar del tipo ans = cui associato il valore numerico del risultato. Tuttavia, noi possiamodecidere di assegnare il risultato di una certa operazione o di una funzione ad una variabile a cui noi stes-si assegniamo un nome ben preciso. Per esempio, vogliamo che il risultato di sin(10) sia assegnato ad unavariabile che chiamiamo b. Per fare ci, basta scrivere

    >> b=sin(10)

    4

  • 1.2. Avvio di MATLAB e Octave

    Figura 1.4: Variabili nella Workspace

    b =

    -0.5440

    In questo modo il valore della funzione non pi assegnato alla variabile ans ma alla variabile b. Anche10 pu diventare il valore di una variabile, in cui poi valutare la funzione seno.

    >> a=10

    a =

    10

    >> b=sin(a)

    b =

    -0.5440

    Osserviamo che ora nella Workspace, troviamo il nome delle variabili introdotte e il loro valore (si vedafigura ??).

    1.2.2 Prima introduzione (breve) su matrici e vettori in MATLAB

    Ci che diremo ora su vettori e su matrici sar qualcosa di breve, (quando parleremo di vettori e matricinel corso di Calcolo Numerico, li rivedremo sotto unaltra luce) utile per alcune semplici e prime applicazionidi MATLAB (o Octave).

    I vettori si possono scrivere come vettori riga o vettori colonna.Per esempio:

    >>x=[1 2]>> x=[1 2]

    x =

    1 2

    5

  • 1. INTRODUZIONE

    >> y=[10 20]

    y =

    1020

    Un vettore rigax viene scritto usando le parentesi quadre e scrivendo le componenti del vettore una dopolaltra. Un vettore colonna pu essere creato facendo la trasposta di un vettore riga (mediante il simbolo ),oppure mettendo un punto e virgola dopo ciascuna componente:

    >> y=[10;20]

    y =

    1020

    In MATLAB i vettori altro non sono che un caso particolare di matrice a n righe e 1 colonna (vettorecolonna) o a 1 riga e n colonne (vettore riga). Quindi 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 12

    13 14 15 16

    Per indicare un valore della matrice A basta specificare lindice di riga e di colonna: per esempio

    >> A(2,2)

    ans =

    6

    Per indicare gli elementi di tutta la colonna i si usa A(:,i), mentre A(i,:) indica gli elementi della rigai.

    >> A(:,2)

    ans =

    26

    1014

    >> A(2,:)

    ans =

    5 6 7 8

    6

  • 1.2. Avvio di MATLAB e Octave

    Loperatore due punti pu dunque essere usato per estrarre unintera riga o colonna da una matrice ounintera sottomatrice. Se vogliamo estrarre le ultime due righe e colonne della matriceA, si digita il comando

    >> M=A(3:4,3:4)

    M =

    11 1215 16

    In questo modo abbiamo creato la matriceM che ha come elementi quelli della sottomatrice diA con le ultimedue righe e colonne.

    Per scrivere una matrice vuota A, invece, si usa listruzione A=[ ].

    1.2.3 Funzioni vettorizzate

    Le funzioni che abbiamo visto prima si possono applicare direttamente su matrici e vettori, sono ciovettorizzate. Cosa significa questo? Significa che se abbiamo un vettore, ad esempio x = [1,2,3,4] e valutiamosin(x), il risultato sar un vettore che ha come componenti il valore della funzione nelle singole componentidel vettore, in questo caso [sin(1),sin(2),sin(3),sin(4)]. Stessa cosa vale per le matrici.

    Vediamo 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

    >> sin(A)

    ans =

    0.0998 0.19870.2955 0.3894

    Per quanto riguarda le operazioni aritmetiche, laddizione e la sottrazione sono vettorizzate per definizio-ne. Invece, le operazioni di moltiplicazione, divisione ed elevamento a potenza vengono vettorizzate facendoprecendere il simbolo di moltiplicazione, divisione e elevamento a potenza dal simbolo del punto (.*, ./,. ) permettendo, in 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 10

    7

  • 1. INTRODUZIONE

    >> y=[1 3 5 7 9]

    y =

    1 3 5 7 9>> x.*y

    ans =

    2 12 30 56 90

    Se facessimo semplicementex*y avremmo un messaggio di errore perch richiederemmo unoperazionedi prodotto tra due matrici che hanno n righe e 1 colonna ciascuna, e questa operazione non si pu fare(vedremo in seguito che si pu fare il prodotto tra due matrici A e B se il numero di colonne di A corrispondeal numero di righe di B). Vediamo un altro esempio

    >> A=[ 1 2; 3 4]

    A =

    1 23 4

    >> B=[2 4; 6 8]

    B =

    2 46 8

    >> A*B

    ans =

    14 2030 44

    >> A.*B

    ans =

    2 818 32

    Questa volta, abbiamo considerato due semplici matrici A B . Se facciamo A*B, abbiamo come risulta-to la matrice prodotto (la studieremo pi avanti nel corso di Calcolo Numerico), se invece facciamo A.*B,abbiamo come risultato la matrice in cui ogni componente dato dal prodotto dei corrispondenti elementisulle due matrici di partenza.

    1.2.4 Sulle variabili

    Negli esempi precedenti, abbiamo dati a matrici e vettori un nome, x,y,A,B... Abbiamo quindiassegnato delle variabili.

    Una variabile ha, quindi, 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 di una variabilescalare, oppure pi valori, se si tratta di vettori o di matrici. In figura 1.5 vediamo come nella Workspace,

    8

  • 1.2. Avvio di MATLAB e Octave

    Figura 1.5: Workspace con diversi tipi di variabili.

    ciascuna variabile con cui si sta lavorando nella finestra dei comandi, sia elencata con il suo nome e con ilsuo valore (che il valore che le stato assegnato se si tratta di una variabile scalare, mentre dichiarato iltipo di variabile se di tipo matriciale). Dalla figura, possiamo osservare comeG ci sono due variabili, una chiamata A e una a: questo perch MATLAB (Octave) sensibile alle lettere

    minuscole e maiuscole: una variabile chiamata A diversa da a!G il valore per A : vuol dire che si tratta di una matrice 10 10 i cui valori sono

    memorizzati in doppia precisione (double)G la matrice B, invece, 1010 in singola precisione (single)G la matrice C 44 ed uint8 (che significa?, ora ci arriviamo)G abbiamo poi due scalari, a e b.G ci sono due vettori, uno riga e uno colonna, in doppia precisione

    Ciascuna variabile, una volta che viene generata, di un certo tipo e viene classificata di conseguenza. Didefault, ogni variabile (scalare o matriciale) viene considerata in doppia precisione (quindi di tipo double).Mediante apposite functions di MATLAB (Octave) possibile convertire il valore di una variabile in un altrotipo: se scriviamo A=single(A), la matrice A viene convertita in una matrice che ha lo stesso nome, i cuivalori per sono ora memorizzati in singola precisione. La function uint8 converte una variabile (che puessere scalare o matriciale) in una variabile il cui valore ora un intero a 8 bit senza segno (con valori chevanno da 0 a 255). Se la variabile gi di tipo intero con valori che si trovano in questo intervallo, non ci sonoproblemi, ma se la variabile assume valori al di fuori di questo intervallo, allora i valori sono arrotondati alpi vicino valore dellintervallo ammissibile. Questo tipo di dato ha senso quando si lavora con numeri interie per fare certi tipi di operazioni. Vediamo esempi semplici

    >> x=[0 1 2 3]

    x =

    0 1 2 3

    >> uint8(x)

    ans =

    9

  • 1. INTRODUZIONE

    0 1 2 3

    >> x=[0 -1 -2 3]

    x =

    0 -1 -2 3

    >> x=uint8(x)

    x =

    0 0 0 3

    Allinizio il vettore x ha tutti valori positivi e uint8 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 in 0.Questa volta il risultato della funcion uint8 assegnato alla stessa variabile x che viene quindi sovrascrittae il vettore non pi quello di prima.

    Se usiamo le function double e single non osserviamo nessun cambiamento a prima vista, ma inrealt lo spazio di memoria per la variabile che cambia.

    1.3 Comandi utili

    Per lavorare meglio sia nella finestra dei comandi sia, successivamente, per scrivere ed eseguire dei veri epropri programmi, risultano utili le seguenti funzioni:G who fornisce lelenco di tutte le variabili presenti nella finestra dei comandi (lo si pu vedere anche

    nella Workspace;G whos fornisce lelenco di tutte le variabili insieme allo spazio in memoria da esse occupato (con que-

    sto comando si pu osservare come una stessa variabile, memorizzata comedouble o come single,occupa un diverso spazio di memoria);

    G help pu essere usato da solo o insieme al nome di una function propria di MATLAB (Octave)o creata dallutente, e mostra tutte le informazioni utili per capire come usare MATLAB o quellafunction;

    G clear se usata da sola cancella tutte le variabili presenti nella finestra dei comandi, se invece seguita da un elenco di variabili (messe una di seguito allaltra senza virgole) cancella tutte le variabilidellelenco;

    G il punto e virgola ; messo dopo unistruzione non fa vedere il risultato dellistruzione nella finestradei comandi;

    G il simbolo % il simbolo per scrivere commenti: ci che viene scritto dopo % rappresenta uncommento;

    G clc ha la funzione di pulire la Command Window e di portare il cursore di nuovo in alto a sinistra nellafinestra (la dove era nel momento in cui abbiamo avviato MATLAB (Octave). Le variabili non vengonocancellate.

    G diary permette di salvare, su un file che viene chiamato diary, il contenuto di ci che viene scrittonella finestra dei comandi. Il file diary si trova nella directory corrente in cui si sta lavorando;

    G diary off chiude il file aperto mediante listruzione diary;G diary filediary comando analogo a diary, ma il file non si chiamer diary bens

    filediary, dove filediary rappresenta il nome del file definito dallutente;G save filesave salva tutte le variabili presenti nel Workspace, nel file filesave.mat con

    filesave nome scelto dallutente, in modo da conservare tutte le variabili con cui si stava lavorando.Questo comando utile se si deve chiudere la sessione di lavoro ma si vuole poi ripartire a lavorareproprio da quelle variabili;

    10

  • 1.4. Introduzione alla programmazione

    G load filesave ripristina lo stato del Workspace, caricando tutte le variabili che erano statesalvate in filesave.mat in modo da poterci lavorare di nuovo. Si era chiusa la sessione di lavoro eora si pu ripartire a lavorare con le stesse variabili di prima.

    Ce una notevole differenza di significato tra i files generati dallistruzione diary e quelli generati me-diante save. Ci che salviamo con il comando diary paragonabile a ci che pu essere scritto alla lava-gna e di cui prendiamo appunti: scriviamo un file di testo che possiamo elaborare o da cui possiamo trarredei risultati per i nostri problemi. Al contrario, quello che viene salvato mediante il comando save costi-tuito da una o pi variabili, che possono essere riutilizzate nuovamente in MATLAB (Octave) nella finestradei comandi, in sessioni successive a quella in cui sono state create, senza dover rieseguire tutti i comandiche hanno portato alla creazione delle variabili stesse. Infatti, quando si chiude MATLAB (Octave), tutte levariabili e i dati vengono persi!

    Il comando save utile anche per salvare singole matrici o una lista di matrici nella directory corrente.Ci soffermiamo sulla possibilit di salvare i dati in formato ASCII, in modo da poter utilizzare i dati che sal-viamo non solo in MATLAB (Octave) ma anche in programmi scritti con altri linguaggi di programmazione.Supponiamo di avere una matrice A e di volerla salvare nel file matriceA.dat. Scriveremo il comando

    save matriceA.dat A -asciiQuando vogliamo caricare in MATLAB la matrice dal file useremo il comandoload(matriceA.dat)e in questo modo avremo la matrice nella variabile matriceA (il nome del file senza lestensione dopo il

    punto).

    1.4 Introduzione alla programmazione

    MATLAB (e di conseguenza Octave, dora in poi quando parleremo di MATLAB ometteremo di scrivereanche Octave, intendendo che il discorso vale anche per Octave e sottolineeremo solo le differenze impor-tanti) si pu intendere come un linguaggio di programmazione, anche se non rientra in nessuna delle duecategorie di base dei linguaggi di programmazione.

    Ci sono infatti due categorie di linguaggi per scrivere programmi:G linguaggi di alto livello (come FORTRAN, C, C++)G linguaggi di basso livello (come assembler).

    Il linguaggio macchina, invece, il linguaggio specifico dellelaboratore e consiste di cifre binarie 0 e 1 cheidentificano istruzioni elementari. Ogni elaboratore ha il suo linguaggio macchina.

    I linguaggi di basso e alto livello si possono tradurre in un qualsiasi linguaggio macchina e possono essereutilizzati su qualsiasi elaboratore (sono portabili). Con i linguaggi di basso livello, i codici binari (fatti da0 e 1) vengono sostituiti da opportune parole chiave che permettono una corrispondenza uno-uno tra illinguaggio di basso livello e il linguaggio macchina.

    Con i linguaggi di alto livello, una singola istruzione pu tradurre pi istruzioni di linguaggio macchina.Inoltre un linguaggio di alto livello facile da capire (nella sua sintassi, nelle sue regole, nel suo modo diessere utilizzato) da chi programma.

    Perci, quando si programma con un linguaggio di alto livello, il programmatore deve conoscere e sa-pere bene la grammatica, la sintassi, il vocabolario del linguaggio stesso. Uno volta scritto il programmain modo corretto, occorre fare capire al computer che c un programma da eseguire: bisogna quindi tra-durre in linguaggio macchina il programma scritto con il linguaggio di alto livello: questo passaggio lo si famediante la compilazione: un comando particolare chiama un programma di compilazione che viene appli-cato al programma scritto nel linguaggio di alto livello (che chiamamo programma sorgente) in un program-ma equivalente scritto in linguaggio macchina e che potr essere eseguito dal calcolatore, detto programmaeseguibile.

    In MATLAB , noi scriveremo qualcosa di equivalente al programma sorgente ma non lo compileremoperch ogni volta che lo vorremo eseguire, esso verr automaticamente compilato ed eseguito.

    Abbiamo due tipi di files eseguibili:G lo script, che presenta una lista di comandi da eseguire in ambiente MATLAB . Al suo interno ci

    pu essere la chiamata a functions proprie di MATLAB o a functions definite dallutente;

    11

  • 1. INTRODUZIONE

    G le functions (di MATLAB o definite dallutente), che possono avere uno o pi variabili di ingresso(dati di input) e una o pi variabili in uscita (dati di output).

    Sia lo script sia le functions si scrivono su files chiamati M-files perch sono files che vanno salvaticon lestensione .m (ad esempio prova.m, fun.m, . . . ). I files vanno scritti con leditor di testo di MA-TLAB (nella barra dei comandi di MATLAB in alto a sinistra compare la scritta New Script o New) o conun altro editor di testo in formato ASCII (in Octave non c un editor e quindi i files vanno scritti con un altroeditor di testo come gedit, ad esempio).

    Per eseguire uno script salvato in nomefile.m basta scrivere il nome del programma (senza lesten-sione .m) nella finestra dei comandi o mediante il comando run(nomefile.m) o run(nomefile)oppure posizionandosi con il mouse sul nome del programma nella lista che compare nella finestra di Cur-rent Folder e con il tasto destro del moouse andare sulla scritta run che compare sulla finestra che si apre (pidifficile a scriversi che a farsi!).

    Ovviamente, sia lo script sia le function definite dallutente devono trovarsi nella directory in cui si aperto MATLAB , altrimenti bisogna spostarsi nella directory con i files che servono (da MATLAB lo si fadirettamente o tramite la Current Folder o utilizzando la riga che mostra la directory in cui ci si trova o con icomandi dellambiente Linux, vale a dire cd e il percorso da fare, invece, in Octave, ci si sposta di directorysolo con i comandi dellambiente Linux).

    Per quanto riguarda le function, possono essere eseguite o tramite uno script oppure direttamentenella finestra dei comandi, specificando le variabili di ingresso e di uscita.

    1.5 Problemi e Algoritmi

    Gli script e functions che scriveremo ed eseguiremo in ambiente MATLAB serviranno a risolveredei problemi.

    Cosa intendiamo per problema? Se vediamo alletimologia del nome, esso deriva dal verbo grevo pro-ballein, dove pro significa davanti e ballein significa mettere: mettere davanti... problema ha il significatodi ostacolo, promontorio, impedimento. E difatti, se si ha un problema, la prima cosa che si pensa comerisolvere il problema (come superare lostacolo!).

    Per risolvere un problema, bisogna conoscerlo e saperlo descrivere bene. A questo scopo, noi ci serviamodel linguaggio. Ma il linguaggio naturale va usato con cautela: lo stesso evento descritto, infatti, in mododiverso da un bambino rispetto ad un adulto; e lo stesso evento viene descritto con un linguaggio diverso daun matematico, da un fisico, da un ingegnere e da un letterato.

    Accanto al linguaggio naturale c il linguaggio artificiale, che si presenta sotto forma di termini tecnici enotazioni (pensiamo a termini tecnici della fisica e della chimica o ai simboli matematici).

    A volte, per, le stesse parole possono essere usate per dire cose completamente diverse! Basti pensa-re a termini come temperatura, pressione, massa...: hanno significati ben diversi se usati in unofficina perriparare il motore di unautomobile o se usati in un ambulatorio medico nei confronti di un paziente...

    Una volta che, cono attenzione e precisione, si capito il problema, si pu passare alla fase di soluzione.Concentrando ora la nostra attenzione su problemi da risolvere con laiuto 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, quindi dobbiamo sapere quale tecnica di soluzione dobbiamo applicare.Queste precise istruzioni da dare al calcolatore rappresentano quello che chiamiamo algoritmo.

    Un algoritmo una sequenza di passi che permettono di risolvere tutto o parte di un problema.1

    Un algoritmo si pu paragonare ad una ricetta di cucina. La ricetta fatta di due partiG la lista degli ingredienti da utilizzareG la sequenza dei passi da fare per realizzare la ricetta.

    1La parola algoritmo entrata in uso negli anni 50 in sostituzione di algorismo, termine con cui si indicava il processo di calcoloutilizzando i numeri arabi. Il termine algoritmo deriva dal nome di al-Khwarizmi, importante matematico arabo del nono secolo grazieal quale lEuropa impar ad usare i numeri arabi, oltre alla notazione in base 10. Le procedure che permettevano di effettuare calcoli innotazione decimale presero il nome di algorismi o algoritmi. Anche la parola algebra viene da questo matematico e, in particolare, dallasua opera Al-mukhtasar fi hisab al-jabr wa al-muqabala.

    Nel medioevo (e forse anche per qualche studente di oggi!!!), si pensava che questa parola derivasse dal greco algiros (panico, dolore)e arithmos (numero).

    12

  • 1.6. MATLAB come linguaggio di programmazione

    Nel realizzare una ricetta si possono avere problemi nel cercare alcuni ingredienti. Una parte dellesecuzionerichieder poco tempo, altre parti richiederanno pi tempo. Alcuni passi non richiedono che si segua uncerto ordine, altri passi richiedono che si mantenga lordine scritto sulla ricetta. . . Le stesse analogie troviamoin un algoritmo.

    1.6 MATLAB come linguaggio di programmazione

    Per imparare a usare MATLAB come uno strumento di programmazione, dobbiamo imparare ad usareil linguaggio che ci permetter di scrivere script e function. E, come tutti i linguaggi, dovremo impararealcune regole ben precise.

    Un linguaggio di programmazione costituito da dichiarazioni (statements):G descrizione dei dati: che genere di dati abbiamo? Se vogliamo scrivere un programma in cui per

    ogni studente calcoliamo la media dei suoi voti, c differenza tra i nomi degli studenti (una stringadi caratteri) e la loro media (un numero). Si parla di tipo di dati. In MATLAB non si dichiarano levariabili, come avviene invece per altri linguaggi di alto livello. Ci facilita la programmazione ma ponepi rischi (se ci si dimentica il tipo di una variabile!). Conviene, perci, prestare sempre attenzione altipo di variabili utlizzate.

    G strutture di controllo. Un programma pu essere visto come una sequenza di istruzioni per risol-vere un certo problema. Alcune istruzioni vanno ripetute, altre vanno eseguite solo in determinatecondizioni. . .

    G lavorazione dei dati (data processing). In un programma occorre poter lavorare sui dati e poterlimanipolare opportunamente.

    G dichiarazioni di ingresso e uscita (input e output). In genere, un programma scritto in modo che idati su cui si lavora possano esistere fuori del programma stesso.

    1.7 Primo script e prima function in MATLAB

    Con un editor di testo scriviamo finalmente il nostro primo script. Uno script un programma (unaserie di istruzioni) che si differenzia dai programmi scritti con altri linguaggi di programmazione perch nonsi devono dichiarare le variabili. Nel programma che scrivamo, introduciamo due vettori ma non dobbiamousare istruzioni che dichiarano il tipo di variabili (vettori, singola o doppia precisione o variabile di tipo intero,...).

    % questa e una riga di commentox=[1 , 0.5 , 0 , 0 . 5 , 1]y=sin ( x )disp (ho eseguito il mio primo script) %disp e una function per la

    % visualizzazione% in questo caso la str inga% 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 (in questo caso scegliamo il nome primoscript.m) sulla CommandWindow. Vediamo cosa succede

    >> primoscript

    x =

    -1.0000 -0.5000 0 0.5000 1.0000

    y =

    -0.8415 -0.4794 0 0.4794 0.8415

    13

  • 1. INTRODUZIONE

    ho eseguito il mio primo script

    Nello script abbiamo assegnato a due variabili x e y il valore di due vettori riga di 5 componenti eabbiamo stampato una scritta sulla Command Window. Le due istruzioni x = ... ey= ... si chiamanoistruzioni di assegnazione. Abbiamo assegnato, in questo caso, i valori delle componenti del vettore x e delvettore y. Nel file, ci che segue il simbolo % una riga di commento. La function disp una functiondi MATLAB che serve a visualizzare il contenuto di una variabile che pu essere uno scalare, una matrice,ma anche una stringa di caratteri, come in questo caso (una stringa di caratteri pu essere considerata asua volta una variabile che, per, non numerica). Modifichiamo il nostro script mettendo un ; dopoogni istruzione. Se eseguiamo di nuovo lo script, i due vettori non vengono visualizzati e compare solo ilmessaggio di esecuzione del primo script. I due vettori, tuttavia, ci sono (basti vedere nella Workspace) e sesi digita x e si schiaccia il tasto di Invio nella Command Window, ci viene visualizzata la variabile x. Stessacosa vale pery. Si provi a vedere invece cosa succede se facciamodisp(x) edisp(y). Quando si eseguonoprogrammi pi lunghi, conviene usare il ; dopo ogni istruzione di assegnazione, in modo da non vedere valoriche scorrono e che comunque non riusciamo a leggere (si pensi a matrici di dimensioni elevate). In tal modosi velocizzano i tempi di esecuzione dello script.

    E se vogliamo cambiare il vettore iniziale x, come facciamo? Usiamo listruzione input. Modifichiamolo script

    % questa e una riga di commentox=input ( scrivi il vettore x ) ;y=sin ( x ) ;disp (ho eseguito il mio primo script ) ; %disp e una function per la

    % visualizzazione% in questo caso la str inga% ho eseguito i l mio primo s c r i p t

    Quando eseguiamo questo script, sulla Command Window compare la frase che abbiamo scritto tra apici enoi dovremo scrivere il vettore che vogliamo (ad esempio, [ 1 2 3]) e schiacciare il tasto di invio.

    >> primoscriptscrivi il vettore x [1 2 3]

    ho eseguito il mio primo script

    Proviamo ora a voler scrivere un programma che, oltre a darci il valore di sin(x) ci dia il segno della funzio-ne (1 se positivo, 0 se uguale a zero, 1 se negativo). Per fare ci noi possiamo usare la funzionesign, propriadi MATLAB . Ma siccome vogliamo imparare a scrivere noi una function, la scriviamo noi: una function chedia come output sia il valore di sin(x) sia il suo segno.

    Scriviamo dunque un file, che salveremo con il nome mysin.m, in questo modo

    function [ y , b]=mysin ( x )% function [ y , b]=mysin ( x )% input : x ( scalare , vettore , matrice )% output : y=sin ( x )% b= sign ( y )y=sin ( x ) ;b=sign ( y ) ;end

    La prima riga fondamentale per dire che stiamo scrivendo una function: la regola da rispettare la seguente

    function [variabili output] = nomefunction(variabili input)

    Se le variabili di output si riducono ad una sola, possiamo evitare di mettere le due parentesi quadre. Levariabili di input e di output possono essere una o pi di una (e a volte anche nessuna). Subito dopo questa

    14

  • 1.8. I predicati elementari

    istruzione, conviene mettere delle righe di commento per dire cosa fa questa function. Questo perch, facen-do help nomefunction sulla Command Window, avremo disponibili tutte le informazioni che abbiamoscritto in quelle righe di commento e ci sar utile per ricordare cosa fa quella determinata funzione.

    Una function termina con listruzione end.Una volta salvata, la funzione pu essere chiamata direttamente nella Command Window, oppure allin-

    terno di uno script. Se scriviamo semplicemente y=mysin(x), la function restituisce solo il primo vet-tore che viene generato. Se invece scriviamo [y,b]=mysin(x), allora ci vengono restituiti i due vettori.Possiamo usare anche nomi diversi rispetto a y b.

    La function pu essere richiamata anche allinterno di uno script. Modifichiamo lo scriptprimoscriptin questo modo:

    % questa e una riga di commentox=input ( scrivi il vettore x ) ;[ y , b]=mysin ( x )disp (ho eseguito il mio secondo script)

    Osserviamo che, in questo caso, non abbiamo messo il ; dopo la chiamata alla function, in modo davisualizzare subito il risultato.

    Dagli esempi che abbiamo visto, possiamo chiederci quando serve scrivere uno script piuttosto di unafunction. Vediamo, intanto, le principali differenze.G Le variabili usate allinterno di uno script non vengono cancellate a meno che non venga fatto tra-

    mite la funzione clear. In una function tutte le variabili usate al suo interno e che non compaiononella lista delle variabili di output vengono cancellate una volta che la function viene eseguita.

    G Una function pu essere usata allinterno di uno script, per snellirne la sua struttura (se determi-nate istruzioni vanno ripetute pi e pi volte, la function ci permette di scriverle una volta sola e dirichiamarle con parametri di input diversi). In tal caso, la function agisce da sottoprogramma.

    1.8 I predicati elementari

    Le istruzioni che traducono algoritmi di soluzione di problemi numerici non sono sempre istruzionidi tipo sequenziale, cio istruzioni da eseguire luna dopo laltra (fai questo, poi questo, poi questo anco-ra...esempioponi a=10, b=sin(a), c=a*b...). Molte volte alcune istruzioni vanno eseguite se sonovere determinate condizioni piuttosto che altre, o fino a quando vera una determinata condizione...

    Esempio

    Esempio 1.8.1 Per calcolare le radici di unequazione di secondo grado, ax2 +bx + c = 0 sappiamo chedobbiamo calcolare il discriminante = b4 4ac e se = 0 le due radici coincidono, se > 0 abbiamodue radici distinte, se invece < 0 le due radici non sono reali.Abbiamo una condizione su e, a seconda della condizione, facciamo una cosa piuttosto di 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, quindi, ci permettono di costruire dei predicati. Vediamoquali sono gli operatori logici che useremo

    15

  • 1. INTRODUZIONE

    Operatore Significato Esempio Valore> maggiore (a >b) Vero se a > b

    Falso se a b>= maggiore o uguale (a>=b) Vero se a b

    Falso se a < b< minore (a a=12;>> b=5;>> (a> (a==b)

    ans =

    0

    >> (a>=b)

    ans =

    1

    Il predicato 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 predicato(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 10

    16

  • 1.8. I predicati elementari

    >> A>=B

    ans =

    1 01 0

    In molti algoritmi, tuttavia, non basta vedere se un singolo predicato sia vero o falso. A volte ci servonopi predicati da mettere insieme per formare una proposizione logica.

    Esempio

    Esempio 1.8.2 Supponiamo di dover implementare un algoritmo in cui vanno eseguite alcune istru-zioni fintantoch vero che (1) il numero di iterazioni, it, minore di un numero massimo prefissato,itmax, e (2) il valore assoluto della differenza di due valori che sono generati dallalgoritmo (chiamia-mo questa quantit sc) maggiore di una tolleranza prefissata, tol. Abbiamo una proposizione fattadi due predicati (it tol). I due predicati sono messi insieme tramite la con-giunzione e. Fintantoch vera tutta la proposizione (quindi sono veri tutti e due i predicati) allora cisaranno da eseguire determinate istruzioni, altrimenti non si eseguiranno. Quando la proposizione non pi vera? Diventa falsa quando il primo o il secondo predicato diventano falsi, cio quando le itera-zioni diventano maggiori del massimo prefissato oppure quando la variabile sc diventa minore dellatolleranza.

    Vediamo allora gli operatori logici per unire due proposizioni:

    Operatore Significato& congiunzione di pi predicati| disgiunzione di pi predicati negazione di un predicato o di una proposizione

    Esempio

    Esempio 1.8.3 Riprendiamo i predicati di prima it < itmax e sc > tol. La proposizione (ittol) un proposizione che vera quando entrambi i predicati sono veri,diventa falsa quando uno dei due predicati falso.La proposizione (it tol) vera quando uno dei due predicati vero (pu es-sere uno vero e uno falso, la proposizione comunque vera perch | significa o, oppure). La proposizione falsa quando entrambi i predicati sono falsi.La proposizione (it = itmax. Quindi vera se it >= itmax e sar falsa se it

  • 1. INTRODUZIONE

    1.9 Strutture e cicli

    Vediamo, in generale, adesso come si possono eseguire alcuni tipi di istruzioni.

    1.9.1 Ciclo if

    Supponiamo di voler calcolare la radice quadrata positiva di un numero reale : +px. Sappiamo che selargomento x negativo, la funzione non d un valore reale (si passa infatti nel campo dei numeri complessi:provare la function di MATLABsqrt con un numero negativo e vedere il risultato che d). Proviamo alloraa scrivere una nostra function che calcoli la radice quadrata solo per valori positivi dellargomento.

    function [ y ]= mysqrt ( x )% function [ y ]= mysqrt ( x )% input x% output y= s q r t ( x ) per x >=0% altrimenti s i ha un messaggio di 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

    disp (largomento e negativo)y = [ ] ;

    end

    Abbiamo usato il cosiddetto ciclo if. Se (if) (x>0) allora fai una determinata cosa, altrimenti (else)fai unaltra cosa. Osserviamo che per visualizzare una stringa di caratteri in cui c lapostrofo o laccento,abbiamo usato due volte gli apici.

    Il ciclo if si pu schematizzare nei seguenti modi a seconda che si abbia una o pi condizione.

    Ciclo if con una condizione

    i f ( espr . logica ){ istruzione 1a }{ istruzione 2a }{ . . . . }

    else{ is truzione 1b }{ istruzione 2b }{ . . . . }

    end

    Ciclo if con pi condizioni

    i f ( espr . logica1 ){ istruzione 1a }{ istruzione 2a }{ . . . . }

    e l s e i f ( espr . logica2 ){ istruzione 1b }{ istruzione 2b }{ . . . . }

    . . . .else

    { is truzione 1z }{ istruzione 2z }{ . . . . }

    end

    Osserviamo che in MATLABelseif va scritto tutto attaccato altrimenti si apre un altro ciclo if concatenatoal precedente.

    Se non c nessuna istruzione in alternativa alle condizioni poste, si omette lelse.Scriviamo uno script che risolve unequazione di secondo grado ax2 +bx + c = 0. Usiamo un ciclo if per

    controllare il segno del discriminante =p

    b2 4ac e, di conseguenza, scrivere le radici.a=input (valore di a ) ;b=input ( valore di b ) ;c=input ( valore di c ) ;delta=sqrt (b^2 4*a* c ) ;

    18

  • 1.9. Strutture e cicli

    i f ( delta ==0)x1=b/(2* a ) ;x2=x1 ;disp (le radici sono coincidenti)disp ( [ x1 x2 ] )

    e l s e i f ( delta >0)x1= (b + delta ) / ( 2 * a ) ;x2= (b delta ) / ( 2 * a ) ;

    disp (le radici sono)disp ( [ x1 x2 ] )

    elsedisp (non ci sono radici reali)

    end

    Salviamo lo script con il nome radici.m. Per visualizzare su una sola riga il valore delle due radici abbia-mo creato il vettore che ha come componenti x1 e x2 e lo abbiamo visualizzato mediante la function disp.Osserviamo che, quando eseguiamo questo script, dobbiamo dare noi in input i valori dei coefficienti delle-quaazione. Tutte le variabili che vengono generate nello script rimangono nella Workspace (a meno che nondecidiamo noi di cancellarle usando il comando clean). Per capire meglio la differenza tra script e function,scriviamo ora una function che fa la stessa cosa. Chiamiamo la function funradicieq2.m.

    function [ x1 , x2 ]= funradicieq2 ( a , b , c )% function [ x1 , x2 ]= radicieq2 ( a , b , c )% input : a , b , c v a r i a b i l i s c a l a r i del l equazione di secondo grado% ax^2+bx+c=0% output : x1 e x2 , l e due r a d i c i del l equazionedelta=sqrt (b^2 4*a* c ) ;i f delta ==0

    x1=b/(2* a ) ;x2=x1 ;

    e l s e i f delta >0x1= (b + delta ) / ( 2 * a ) ;x2= (b delta ) / ( 2 * a ) ;else

    disp (non ci sono radici reali)x1 = [ ] ;x2 = [ ] ;

    endend

    I comandi sono quasi gli stessi dello script. Per avere sempre dei valori in uscita, abbiamo posto x1, x2uguali a due variabili vuote (luso delle parentesi quadre senza nessun valore allinterno []) insieme ad unmessaggio di spiegazione, per discriminanti negativi. Questa volta possiamo eseguire la function allinternodella Command Window o mediante uno script.

    >> [x1, x2]=funradicieq2(1,-2,1)

    x1 =

    1

    x2 =

    1

    Tutte le variabili che sono usate allinterno della function non sono salvate nella Workspace, ad eccezionedelle variabili di output.

    Sia nello script che nella function abbiamo visto un esempio di uso del ciclo if.

    19

  • 1. INTRODUZIONE

    Proviamo a complicare le cose, inserendo altri cicli if allinterno del ciclo if.Nello studiare la propagazione degli errori, abbiamo visto che, per effetto della cancellazione numerica,

    le due radici di unequazione di secondo grado possono non essere arrotondate correttamente se b2 >> 4ac.In tal caso, applicando la formula x1x2 = c

    apossiamo evitare il fenomeno della cancellazione. Consideriamo

    due casi, assumendo x1 = b +p

    b2 4ac2a

    e x2 = b p

    b2 4ac2a

    :

    G b > 0: per effetto della cancellazione numerica x1 affetta da errore. In tal caso dobbiamo correggerex1 mediante la formula x1 = c/(x2a).

    G b < 0: ora x2 affetto da errore (b positivo e va sottratto ad una quantit molto vicina a b stesso).Correggiamo x2 mediante la formula x2 = c/(x1a).

    Andiamo a correggere la function (stessa cosa si pu fare con lo script precedente).

    function [ x1 , x2 ]= funradicieq2nocanc ( a , b , c )% function [ x1 , x2 ]= radicieq2 ( a , b , c )% input : a , b , c v a r i a b i l i s c a l a r i del l equazione di secondo grado% ax^2+bx+c=0% output : x1 e x2 , l e due r a d i c i del l 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 ==0

    x1=b/(2* a ) ;x2=x1 ;

    e l s e i f delta >0i f b> [x1, x2]=funradicieq2(1,1e+6,0.1)

    x1 =

    -1.000007614493370e-07

    x2 =

    -9.999999999999000e+05

    >> x1*x2

    ans =

    20

  • 1.9. Strutture e cicli

    0.100000761449327

    >> [x1, x2]=funradiceeq2nocanc(1,1e+6,0.1)

    x1 =

    -1.000000000000100e-07

    x2 =

    -9.999999999999000e+05

    >> x1*x2

    ans =

    0.100000000000000

    Lerrore sul prodotto x1x2 dellordine di 7.6 107, ma lerrore sulla radice x1 comunque un erroremolto basso. Ci dovuto al fatto che le nostre variabili sono tutte in doppia precisione e MATLAB eseguele operazioni con precisione di macchina.

    Se inseriamo i valori di a,b e c in singola precisione mediante la function single, si vede qualchedifferenza in pi. Proviamo:

    >> a=single(1);>> b=single(1.e+6);>> c=single(0.1);>> [x1, x2]=funradicieq2(a,b,c)

    x1 =

    0

    x2 =

    -1000000

    >> x1*x2

    ans =

    0

    >> [x1, x2]=funradicieq2nocanc(a,b,c)

    x1 =

    -1.0000000e-07

    x2 =

    -1000000

    >> x1*x2

    21

  • 1. INTRODUZIONE

    ans =

    0.1000000

    In questo caso la prima function ci d x1 = 0 al posto di x1 =1 107. Lerrore pi alto rispetto al casoprecedente ma non cos appariscente.

    Proviamo allora a creare una function che ci permetta di lavorare solo con un certo numero di cifre de-cimali, come se avessimo una macchina in virgola mobile normalizzata a n cifre decimali, con n stabilitodallutente (pi piccolo n, maggiore sar il fenomeno di cancellazione numerica). Attenzione, per: leoperazioni che eseguiremo con MATLAB saranno sempre eseguite in doppia precisione mentre il risultatodovr essere convertito nella precisione che vogliamo noi.

    Per capire la function che scriveremo, partiamo con un esempio. Supponiamo di avere il numero x =12.987654. Vogliamo rappresentare questo numero in una macchina in virgola mobile normalizzata conn = 4 cifre decimali. Quindi passeremo al numero x = 1.2988 101.

    Lalgoritmo che implementeremo si basa sui seguenti passiG considero il numero in valore assoluto, cio 12.987654;G valuto log10 del numero: in questo caso ottengo il valore 1.113530710205556, che, se viene arrotondato

    allintero pi vicino per difetto, mi d il valore 1, cio proprio lesponente della base (101);G adesso divido il valore assoluto del numero per 101 in modo da avere la parte frazionaria del numero

    stesso (eventualmente, come in questo caso, in forma normalizzata): 12.987654/101 = 1.2987654;G moltiplico questo valore per 10n , dove n il numero di cifre decimali che ho deciso di avere nella

    rappresentazione finale, in questo caso 4: ottengo 1.2987654e +04 (cio 12987.654)G arrotondo il valore allintero pi vicino: ho 12988;G divido per 10n : ricavo 1.2988;G ora prendo questo valore, lo moltiplico per il segno del numero di partenza e per 101 (lesponente

    che avevo trovato al secondo passo): arrivo al valore 12.988. Il numero non espresso in formanormalizzata, ma in sostanza il numero che andavo cercando (12.988 =1.2988 101).

    Per completare la function ci serve qualcosa che ci permetta di arrotondare allintero pi vicino per difettoe di arrotondare allintero pi vicino. Fortunatamente, in MATLAB , esistono gi due function che fannoqueste cose:G la function floor arrotonda allintero pi vicino per difetto;G la function round arrotonda allintero pi vicino con la regola dellarrotondamento simmetrico.

    Queste function (come altre simili ceil, fix per la cui spiegazione rimandiamo allhelp on line)possono essere applicate a variabili matriciali (vettori e scalari vengono visti come casi particolari di matrici).

    >> floor(2.5)

    ans =

    2

    >> round(2.5)

    ans =

    3

    >> floor(1.1)

    ans =

    1

    >> round(1.1)

    22

  • 1.9. Strutture e cicli

    ans =

    1

    Per avere il segno di una variabile, usiamo la function sign (che vale +1 o -1 a seconda di segno positivoo negativo). Ecco allora la function, che chiamiamo roundnorm

    function y=roundnorm( x , n)% function y=roundnorm( x , n)% input x : puo e s s e r e scalare , v e t t o r e o matrice% n : numero di c i f r e decimali in 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 di x in un sistema normalizzato a n c i f r e decimali% di default , in MATLAB i l numero non viene v i s u a l i z z a t o in virgola% mobile normalizzata .%%% Esempi% x=sin (3)=0.141120008059867% n=4 % 4 c i f r e decimali% y=roundnorm( x , n)= 0.141120000000000% ( in 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% in MATLAB y=roundnorm( x , n)= 55.981999999999999 (= 55.982)% in questo caso , i n f a t t i ,% f *10^e = 5.598200000000000*10=55.981999999999999% in Octave y=roundnorm( x , n)= 55.9820000000000

    xx = abs ( x ) ; % s i considera i l valore assoluto di xe = f loor ( log10 ( xx ) ) ; %esponente di xf = xx . / 1 0 . ^ e ; %parte frazionaria di xf =round ( f *10^n)/10^n ;y=sign ( x ) . * f .*10^ e ;end

    Proviamo a vedere cosa succede se applichiamo questa function per risolvere unequazione di secondogrado. Nelle due function precedenti sulla soluzione di unequazione di secondo grado, dobbiamo andarea convertire le variabili delta, x1 e x2 applicando la function roundnorm: aggiungeremo delle istru-zioni del tipodelta=roundnorm(delta,n); x1=roundnorm(x1,n); x2=roundnorm(x2,n);,

    23

  • 1. INTRODUZIONE

    mentre lintero n viene dato in input.

    Esercizio 1.9.1 Come esercizio si creino, dunque, due nuove function, una che risolve lequazione di se-condo grado senza andare a considerare la correzione del fenomeno di cancellazione numerica e laltra,invece, che corregge la cancellazione numerica, in modo che, in input, oltre ai parametri a,b,c vengachiamato anche lintero n. Allinterno delle function si aggiungano le istruzioni di chiamata alla functionroundnorm.Si trovino, quindi, le radici delle equazioniG 0.1x2 42x +0.3 = 0G x2 56x +1 = 0G x2 18x +0.03 = 0

    Si confrontino i risultati tra le due function, lavorando con n = 4 cifre decimali e utilizzando anche lefunction che lavorano in doppia precisione.

    1.9.2 Ciclo while

    Unaltra struttura molto importante data dal ciclo while. Ci possono essere situazioni in cui determinateistruzioni sono da ripetere fintantoch vera una determinata condizione. Prendiamo in esame lo schemadi bisezione: ad ogni passo del metodo si prende il punto medio dellintervallo, si confronta il valore dellafunzione nel punto medio con il valore agli estremi e si prende, come nuovo sottointervallo, lintervallo cheha come estremi il punto medio e uno dei estremi dellintervallo precedente. Queste istruzioni vanno ripetutefino a quando lampiezza dellintervallo su cui si lavora diventa molto piccola (minore di una certa tolleranzaprefissata) oppure siamo cos fortunati che il punto medio proprio la radice della funzione, oppure nonstiamo arrivando a convergenza ma abbiamo fatto un numero elevato di iterazioni.

    La struttura del cilclo while fatta nel seguente modo

    Ciclo while

    while ( espressione logica ){ istruzione 1 }{ istruzione 2 }{ . . . }{ is truzione n }

    end

    Le istruzioni 1, 2, . . . , n vengono ripetute ciclicamente e non una sola volta come accade nel ciclo if: infattiogni volta che si esegue lultima istruzione allinterno del ciclo while, si torna poi allespressione logica postasubito dopo la parola while e se vera si eseguono di nuovo le istruzioni 1, 2, . . . , n, se falsa, invece, si escedal ciclo. importante, dunque, avere unespressione logica che eviti di creare cicli infiniti, che farebberoentrare in stallo lesecuzione di uno script o di una function!

    Vediamo un esempio di ciclo while, scrivendo una function che implementa lo schema delle bisezioni.Vedendo questa function, impareremo nuove potenzialit di 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 radice del la funzione fun d e f i n i t a% nell i n t e r v a l l o [ a , b ]% input : function fun : puo e s s e r e una function inline , una% function .m ( in questo caso i l nome del la function% va s c r i t t o tra apici ) oppure una function_handle% estremi del l i n t e r v a l l o a e b

    24

  • 1.9. Strutture e cicli

    % tolleranza t o l l% numero massimo di i t e r a z i o n i itmax% output : approssimazione del la radice data dalla v a r i a b i l e c% numero di 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 . * xcos ( x ) + 1 ) ;% a=6; b=4; t o l l =1. e10; 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.4552e11% i t e r =36% scarto =7.2760e11%% f = i n l i n e ( x.^2 sin (3x ) + 2 ) ;% a=2; b=1; t o l l =1. e10; 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. e10; 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.7311e11%aux= f ev a l ( fun , a ) * f ev a l ( 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% del la funzione a g l i estremi a e b%f e v a l e una function che permette di valutare% i l valore del la funzione fun nella v a r i a b i l e a% ( f e v a l ( fun , a ) ) oppure fun ( b ) in f e v a l ( fun , b ) )

    i f aux>=0disp (estremi dello stesso segno)c =[ ] ;i t e r =[ ] ;scarto =[ ] ;return % l i s t r u z i o n e return interrompe l esecuzione del la 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 i

    endi t e r =0; % i t e r e la v a r i a b i l e intera 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 (ba ) * 0 . 5 ; % v a r i a b i l e che permette di c o n t r o l l a r e di quanto c i

    % s i sta avvicinando al l a radicewhile i t e r t o l l

    i t e r = i t e r +1;aux= f ev a l ( fun , a ) * f ev a l ( fun , c ) ;

    i f aux

  • 1. INTRODUZIONE

    b=c ;else

    a=c ;endc =(a+b ) * 0 . 5 ;scarto=abs (ba ) * 0 . 5 ;

    endi f ( i t e r >itmax )

    disp (raggiunto il numero massimo di iterazioni)end

    Oltre alluso del ciclo while (e di un ciclo if allinterno del ciclo while), la novit nella function funbisez dato dal fatto che, tra i parametri di input, compare la funzione di cui si vuole approssimare una radice. Inlinea di massima il nostro schema pu essere applicato su una generica funzione f (x) (funzione reale di unasola variabile reale), al fine di poter approssimare (se esiste) una sua radice. Possiamo scrivere la funzione delnostro problema utilizzando una function (quindi scrivere un file e salvarlo con lestensione .m). Esempio

    function y=fun ( x )% function y=fun ( x )% function da usare nel metodo di b i s e z i o n i% function di esempioy =2.* xcos ( x)+1end

    Questa function la salviamo come fun.m e la chiamiano tra i parametri di input della function funbiseztra apici [c, iter ,scarto]=funbisez(fun,a,b,toll,itmax) In tal modo, noi diamo il nome della function su cuiapplicheremo il metodo di bisezione. Potremmo chiamare la nostra function anche in modo diverso, nonfun.m ma, ad esempio, g.m: limportante mettere tra apici il nome della function. Daltra parte, non importante il nome dato alla variabile ma il significato di ciascuna variabile e lordine con cui compare.

    corretto chiamare la function in questo modo [x, it ,sc]=funbisez(fprova,extra,extrb,toller,maxit) Cisignifica che fprova.m la function di cui vogliamo calcolare lo zero, extra e extrb sono gli estremidellintervallo, etc etc. Ogni variabile ha un nome diverso rispetto a quello che abbiamo scritto nella functionma il significato corrisponde.

    Non corretto invece 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 modi per inserire una funzione tra i parametri di ingresso di una function. Se la fun-zione gi predefinita 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 inline function. Sulla Command Window (oallinterno di uno script che poi chiamer la funbisez) scriviamo il seguente comando

    >> f=inline(2.*x-cos(x)+1)

    f =

    Inline function:f(x) = 2.*x-cos(x)+1

    La function di MATLAB inline ci permette di creare una function che dipende da una o pi variabili.Esempi:

    f=inline(cos(x)-2) (dipende da una sola variabile),f=inline(cos(x)+sin(y)) (dipende da due variabili).

    Rispetto alle function .m, questa function caratterizzata da una sola istruzione (non possiamo costrui-re function che dipendono da cicli o da pi righe di istruzioni). Una volta che chiudiamo la session diMATLAB , perdiamo questa function (se ci serve in unaltra sessione dovremo riscriverla).

    26

  • 1.9. Strutture e cicli

    Un altro modo per passare una funzione tra i parametri di una function di usare una cosiddetta functionhandle: una function handle si costruisce mettendo il simbolo @ prima del nome della function gi definita(ad esempio @sin, @cos) oppure definita dallutente 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 definito noi. In maniera equivalente, si pu assegnare ad unavariabile il nome di una function handle nella Command Window o in uno script. Esempio:

    >> f=@fun

    f =

    @fun

    >> [c,iter,scarto]=funbisez(f,a,b,toll,itmax);

    Ora che abbiamo visto che una funzione pu essere chiamata tra i parametri di input di una function,vediamo come valutarla al suo interno Nellesempio che stiamo considerando, come valutare allinterno dellafunbisez la funzione fun (che pu essere un M-file, una function inline o una function handle)? Si usa laseguente istruzione (che possiamo leggere nella function funbisez) feval(fun,a) dovefun il nome che diamoalla funzione allinterno della function nellesempio, funbisez, mentre a la variabile in cui dobbiamovalutare lafun. Quindifeval una function di MATLAB che permette di valutare il valore di una function:corrisponde a fun(a). Se la funzione una funzione di pi variabili, vanno messe tutte le variabili da cuidipende: feval(fun,x1,x2 ,...)

    Esercizio 1.9.2 Si applichi il metodo di bisezione per trovare gli zeri di funzione delle seguenti funzioni,imponendo una tolleranza pari a 1010 e fissando itmax=100:G f (x) = ln(x)+x2 x (ammette come radice = 1)G f (x) = e1x2 x sin(x) (ammette pi di una radice)

    Se risolviamo lesercizio precedente, ci accorgiamo che non sempre facile trovare un intervallo in cui lafunzione assegnata abbia segno opposto agli estremi. utile quindi avere unidea del grafico della funzionestessa. In questo senso MATLAB ci permette di visualizzare facilmente una funzione tramite la functionezplot. La function ezplot pu avere uno o pi argomenti di input. Si pu dare solo la funzione (inline,m-file o function handle) da visualizzare, e il grafico viene fatto di default per x che varia in [6,6] (se definita per valori negativi) o in [0,6] se non definita per valori negativi. Possiamo cambiare gli estremidellintervallo, aggiungendo come variabile lintervallo stesso.

    Esempiezplot(f) %f e una function inline o una function handle

    ezplot(f) %f e una function Mfile definita dallutente o di MATLABezplot(f ,[ a,b]) %si visualizza il grafico della f per x in [a,b]

    Per visualizzare tutte gli usi della function ezplot si controlli mediante lhelp sulla Commans Window.Del tutto simile a ezplot la function fplot in cui, tuttavia, va specificato lintervallo [a,b]. Vedremo,comunque, che ci sono altri modi per fare grafici.

    Ora, seguendo le stesse linee 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 avvicinando a convergenza, controlliamo la differenza in valoreassoluto tra due approssimazioni successive. Quindi, la variabile scarto assume davvero il significato delnome (al contrario di quanto abbiamo fatto in funbisez). Nella function diamo anche una stima del fattoredi convergenza (o costante asintotica di convergenza) M tramite le variabili asint1 e asint2. Vediamoquesta function

    27

  • 1. INTRODUZIONE

    function [ xkp1 , i t e r , scartokp1 , asint1 , asint2 ]= pfisso0 ( fun , dfun , x0 , t o l l , itmax )%function [ xkp1 , i t e r , scartokp1 , asint1 , asint2 ]= 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 di i t e r a z i o n i% t o l l : tol leranza 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 del la successione% xk : approssimazione al passo k% xkp1 : approssimazione al passo k+1% scartok : scarto al l 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% asint1 : scartokp1 / scartok approsimazione del f a t t o r e di convergenza M% asint2 : abs ( dfun ( xkp1 ) ) approssimazione del f a t t o r e di convergenza M% fun : funzione di cui s i vuole c a l c o l a r e un approssimazione del punto f i s s o% dfun : derivata del la funzione fun%% Esempio% x0 = 0 . 1 ; t o l l =1. e12; itmax=100;% dfun= i n l i n e ( sin ( x ) ) ;% [ xkp1 , i t e r , scartokp1 , asint1 , asint2 ]= 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.4613e13% asint1= 0.6735% asint2 =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 )

    disp (raggiunto il numero massimo di iterazioni)endend

    Con questa function implementiamo il metodo del punto fisso e conosciamo lapprossimazione finale delpunto fisso, il numero di iterazioni effettuate, lo scarto finale, una stima della costante asintotica. Con questafunction, tuttavia, non possiamo fare nessun grafico di convergenza perch perdiamo tutte le informazioniintermedie (i valori delle approssimazioni, degli scarti, etc, ad ogni iterazione). In effetti, per alcune variabilipossiamo farci stampare su un file il loro valore in modo da sapere cosa successo ad ogni passo di iterazione.Per altre, invece, utile metterle in un grafico.

    Esaminiamo ciascuna variabile:G i valori x0,xk,xkp1 rappresentano i valori dellapprossimazione iniziale al passo 0, al passo prece-

    dente iter e al nuovo passo di iterazione iter+1. Questi valori ci servono per calcolare lo scarto adogni iterazione e per approssimare il fattore di convergenza tramite la variabileasint2. Potremmo so-lo stampare questi valori ad ogni passo oppure salvarceli in un vettore (e calcolare la variabile asint2

    28

  • 1.9. Strutture e cicli

    come vettore applicando il valore assoluto della derivata della funzione di punto fisso al vettore delleapprossimazioni).

    G gli scarti scartok e scartokp1 servono per calcolare asint1 ma soprattutto se vogliamo fare ungrafico di convergenza! Quindi ci servono i valori degli scarti ad ogni iterazione. Possiamo creareun vettore in cui la componente i -sima corrisponde allo scarto al passo i . In tal modo potremo siacalcolare asint1 in modo vettoriale, sia fare un grafico semilogaritmico di convergenza.

    G la variabileiter un contatore scalare. Quando occorre, creeremo il vettore che ha come componentigli interi 1,2, . . . , i ter dove i ter rappresenter il numero finale delle iterazioni effettuate.

    Modifichiamo quindi la function lavorando su vettori (la possibilit di scrivere alcuni risultati su file lalasciamo per il seguito). Scriviamo il seguente file pfisso.m.

    function [ x , i t e r , scarto , asint1 , asint2 ]= pf isso ( fun , dfun , x0 , t o l l , itmax )%function [ x , i t e r , scarto , asint1 , asint2 ]= 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 di i t e r a z i o n i% t o l l : tol leranza 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 del la 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% asint1 : v e t t o r e che approssimazione i l f a t t o r e di convergenza M usando% i l v e t t o r e d e g l i s c a r t i% asint2 : v e t t o r e che approssima i l f a t t o r e di convergenza M usando% i l valore assoluto del la derivata prima del la funzione di punto% f i s s o% fun : funzione di cui s i vuole c a l c o l a r e un approssimazione del punto f i s s o% dfun : derivata del la funzione fun% Esempio% x0 = 0 . 1 ; t o l l =1. e12; itmax=100;% dfun= i n l i n e ( sin ( x ) ) ;% [ x , i t e r , scarto , asint1 , asint2 ]= 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 di 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 asint1% i l v e t t o r e asint2% per f a r e i l g r a f i c o di 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 )

    disp (raggiunto il numero massimo di iterazioni)end

    29

  • 1. INTRODUZIONE

    end

    Osserviamo in che modo abbiamo creato i due vettori asint1 e asint2.

    Per il vettore asint1 la generica componente i -sima deve essere uguale ascar toi

    scar toi1. Supponiamo

    che il vettore scarto abbia queste componenti: scarto=[ 2 0.90 0.45 0.31 0.20 0.14] do-ve scarto(1) corrisponde al valore che si ha alliterazione 0 (il valore che, nella function, abbiamo postouguale a 2*tol in modo da poter entrare nel ciclo while). Per approssimare il fattore di convergenza al pri-mo passo di iterazione dobbiamo fare il rapporto tra lo scarto alliterazione 1 e lo scarto alliterazione 0, cio0.90

    2. Alla seconda iterazione dobbiamo fare il rapporto tra lo scarto corrente e lo scarto al passo precedente,

    cio0.45

    0.90e cos via. Nel vettore scarto abbiamo 6 componenti, la prima corrisponde alliterazione 0, ci vuol

    dire che sono state effettuate 5 iterazioni. Dobbiamo fare dunque 5 rapporti per approssimare il fattore diconvergenza ad ogni iterazione:

    0.90

    2,

    0.45

    0.90,

    0.31

    0.45,

    0.20

    0.31,

    0.14

    0.20.

    A tal fine costruiamo il vettore (a cui ora per comodit diamo il nome sc1) che ha come componen-ti quelle del vettore scarto dalla seconda componente in 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 dire sc2=[2 0.90 0.45 0.31 0.20]. Ora, se di-

    vidiamo i due vettorisc1

    sc2componente per componente, abbiamo proprio i rapporti che abbiamo scrit-

    to prima. Questa operazione si pu fare senza dover introdurre nuovi vettori. Possiamo scrivere, infatti,asint1= scarto(2:iter )./scarto(1:iter1);

    Per quanto riguarda asint2, abbiamo semplicemente valutato la funzione dfun nel vettore delleapprossimazioni x.

    Poi, poich la prima componente che abbiamo dato al vettore scarto non ci interessa, la togliamoandando ad aggiornare il vettore scarto=scarto(2:iter);

    Questa istruzione ci permette di prendere il vettore che ha come componenti quelle del vettore scartodalla seconda componente in poi e di chiamare questo vettore di nuovo con la stessa variabile.

    Infine, aggiorniamo il numero delle iterazioni, togliendo ununit perch eravamo partiti dal contatoredelle iterazioni pari a uno in corrispondenza delliterazione 0.

    A questo punto, in uscita abbiamo dei vettori.Per fare il grafico di convergenza dello schema, ci serve fare un grafico semilogaritmico dove, sullas-

    se delle ascisse ci sono le iterazioni effettuate e sullasse delle ordinate i logaritmi (in base 10) degli scar-ti. La function di MATLAB che ci permette di fare grafici in scala semilogaritmica sullasse delle ordinateprende il nome di semilogy. Nel nostro caso, basta creare il vettore delle ordinate, 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, in modo equivalente,semilogy([1:1:iter], scarto) (si veda figura 1.6).

    Introduzione alla grafica

    Abbiamo visto le function ezplot, fplot, semilogy. Vediamo ora le altre function di base perpoter fare un grafico. Abbiamo semilogx (analogo di semilogy, il grafico semilogaritmico sullassedelle ascisse), loglog (il grafico in scala logaritmica su entrambi gli assi) e infine plot.

    Le function plot, semilogx, semiloy e loglog hanno le stesse caratteristiche. Vediamo quindigli elementi principali di 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 dimensione, produce il grafico in cui sullasse delle ascissec il vettore x e sullasse delle ordinate il vettore y.

    Esempio:

    30

  • 1.9. Strutture e cicli

    Figura 1.6: Grafico generato dallistruzione semilogy(it, scarto). per lo schema di punto fisso applicato allafunzione di punto fisso g (x) = cos(x), con x0 = 0.1.

    >> x=[0, 0.1 , 0.2, 0.3, 0.4, 0.5];>> y=sin(x);>> plot(x,y)

    I comandi precedenti producono il grafico di figura 1.7Si pu anche usare semplicemente listruzione plot(y) che produce il grafico del vettore in funzione degli

    indici delle componenti del vettore (quindi sullasse delle ascisse ci saranno gli indici 1,2, . . . ,n del vettore ymentre sullasse delle ordinate le componenti del vettore y di lunghezza n).

    Si possono fare pi grafici sovrapposti in diversi modi. Uno di questi di avere pi coppie di vetto-ri x1,y1, x2, y2 e cos via e scrivere listruzione plot(x1,y1,x2,y2, ...) Un altro modo di sovrascrive-re i grafici luno sullaltro mediante il comando hold on Abbinato poi il comando hold off che chiude ilprocesso.

    Vediamo degli esempi

    >> x1=[0, 0.1 , 0.2, 0.3, 0.4, 0.5];>> y1=sin(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 ce piu ma si crea questo>> hold on>> plot(x2,y2)>> hold off

    Per esercizio si provino i comandi precedenti. La figura generata nel primo caso mostra le due curve dicolore diverso, mentre nel secondo caso le curve hanno lo stesso colore.

    31

  • 1. INTRODUZIONE

    Figura 1.7: Esempio di uso della function plot con x=[0, 0.1 , 0.2, 0.3, 0.4, 0.5] ey=sin(x).

    Per cambiare colore e tipo di linea della curva, oppure fare un grafico per punti, si possono fare le mo-difiche direttamente dal menu che si presenta sulla finestra del grafico oppure tramite comandi in linea.Vediamo questi ultimi (comuni ad Octave).

    Listruzione plot(x1,y1,s1,x2,y2,s2, ...) dove s1, s2, ... sono delle stringhe di caratteri (da scriveretra apici, quindi) permette di cambiare colore, linea o punto della curva.

    Esempi: plot(x,y,g:) produce il grafico in cui la curva di colore verde (green) e la curva a puntini.plot(x,y,r-.) d come risultato una curva di colore rosso con linea fatta a tratteggio del tipo -.-.-..plot(x,y,yo) produce una curva dove i punti non sono legati tra loro mediante una linea ma per punti,

    ciascuno dei quali ha la forma di un cerchietto (o) mentre il colore giallo (yellow)plot(x,y,c--*) combina la linea di tipo tratteggio con i punti a forma di asterisco * mentre il colore il

    celeste (cyan). Per vedere tutti i colori, punti e linee a disposizione basta fare help plot dalla CommandWindow.

    Altri comandi utili sonoG inserire un titolo al grafico, mediante la function title.

    Esempio: title (grafico di prova)G inserire una descrizione sullasse delle x (e delle y) mediante la function xlabel (ylabel).

    Esempio: xlabel(iterazioni), ylabel(scarti);G Inserire una legenda mediante la function legend.

    Esempio: abbiamo fatto un grafico con listruzione plot(x,y1,x,y2) dove y1 corrisponde aduna certa funzione f mentre y2 corrisponde ad una certa funzione g . Con listruzione

    legend(funz f, funz g) sul grafico compare la legenda che abbiamo scritto unita al tipo di lineao punti associati a quel vettore.

    G inserire una griglia di fondo al grafico o toglierla, mediante il comando gridEsempio: grid on introduce linee di griglia; grid off le toglie.

    Per ciaascuno di queste function fare delle prove e controllare lhelp in linea.Negli esempi fatti, tuttavia, abbiamo creato dei vettori di lunghezza molto ridotta. Se avevamo in mente

    di fare il grafico della funzione sin(x) o cos(x), il risultato che abbiamo avuto stato molto povero perch

    32

  • 1.9. Strutture e cicli

    avevamo pochi punti a disposizione. 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 in pi sui vettori.

    Nel fare il grafico semilogaritmico, abbiamo visto un modo per creare un vettore, mediante listruzione[1:1: iter ].

    Listruzione x=[x0: incr: xf] produce un vettore che ha come valore iniziale x0 e come valore finale xfe le altre componenti sono date a partire da x0 con incremento dato dal valore incr: x0, x0+incr,x0+2incr, ...., 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 di righe e di colonne della variabile x. Si puanche usare listruzione length(x) che restituisce, invece, la lunghezza del vettore.

    >> x=[0:0.1:1]

    x =

    Columns 1 through 6

    0 0.1000 0.2000 0.3000 0.4000 0.5000

    Columns 7 through 11

    0.6000 0.7000 0.8000 0.9000 1.0000

    >> size(x)

    ans =

    1 11

    >> length(x)

    ans =

    11

    Un altro modo di creare vettori dato dalla function linspace, il cui uso il seguente: x=linspace(a,b);crea, di default, un vettore (in questo caso x) che ha 100 componenti,con valori equidistanti a partire da aper finire a b: quindi il vettore ha come prima componente a, poi a + (b-a)/99, ..., fino ad arrivare allacentesima componente che vale b. Si applica la formula xi = x1 + (i 1)h, per i = 2,3, . . . ,100 , dove x1 = a eh = b a

    99(in tal modo: x2 = x1 +h; x3 = x1 +2h = x2 +h, fino ad arrivare a x100 = x1 +99h = a + (b a) = b.

    Se vogliamo un vettore con un certo numero n di punti equidistanti tra a e b, si scrive listruzionex=linspace(a,b,n);

    A questo punto, vediamo anche un altro modo per creare dei vettori, utilizzando un ciclo che nonabbiamo visto fino ad ora, e che prende il nome di ciclo for.

    1.9.3 Ciclo for

    Il ciclo for strutturato nel modo seguente

    33

  • 1. INTRODUZIONE

    Ciclo for

    for ind= v a l i n i z : incr : v a l f i n{ i s t r u z i o n i }end

    Un esempio di ciclo for per creare un vettore di 11 elementi con componenti equidistanti tra 0 e 1 puessere il seguente

    x ( 1 ) = 0 ;for i =2:11

    x ( i )= x ( i 1)+0.1;end

    Osserviamo che usare un ciclo for per creare vettori non conveniente n ottimale. Questo non vuol direche non lo useremo mai e che possiamo dimenticarci che esiste! Dobbiamo solo prestare molta attenzionequando lo usiamo e usarlo solo quando effettivamente serve!!!!

    Vediamo un esempio, in cui misuriamo il tempo che impiega MATLAB per creare un vettore di lun-ghezza n con n grande, usando la forma compatta x=[x0:incr:xn], la function linspace e il ciclofor.

    Per misurare il tempo che impiega ciascuno procedimento, applichiamo due functions di MATLABtice toc che sono da usare combinate insieme perch permettono di misurare il tempo per effettuare leistruzioni che si trovano nel mezzo.

    Scriviamo uno script allo scopo di creare un vettore x di lunghezza n=100001 tra a=0 e a=1 applicando

    i diversi approcci che abbiamo visto. La distanza tra due componenti del vettore data da h = 1100000

    = 105.

    cleart i cx = [ 0 : 1 . e5 : 1 ] ;tocdisp (lunghezza vettore)disp ( length ( x ) )clear xt i cx=linspace (0 ,1 ,100001) ;tocdisp (lunghezza vettore)disp ( length ( x ) )clear xt i cx ( 1 ) = 0 ;for i =2:100001

    x ( i )= x ( i 1)+1.e5;endtocdisp (lunghezza vettore)disp ( length ( x ) )

    Eseguiamo questo script (salviamolo prima dandogli un nome con lestesione .m, in questo casoconfrontotictoc.m). In MATLAB otteniamo

    >> confrontotictocElapsed time is 0.000631 seconds.lunghezza vettore

    100001

    34

  • 1.9. Strutture e cicli

    Elapsed time is 0.003618 seconds.lunghezza vettore

    100001

    Elapsed time is 0.058935 seconds.lunghezza vettore

    100001

    Vediamo cosa succede in ambiente Octave:

    octave:3> confrontotictocElapsed time is 2.90871e-05 seconds.lunghezza vettore100001

    Elapsed time is 0.001910925 seconds.lunghezza vettore100001

    Elapsed time is 1.404992 seconds.lunghezza vettore

    100001

    Come possiamo osservare dai risultati, il primo approccio per scrivere i vettori quello che vadecisamente meglio.

    1.9.4 Introduzione a file di scrittura dati

    Riprendiamo a studiare lo schema di punto fisso e i risultati ottenuti. Immaginiamo di volerli stamparesu un file per poterli studiare ed esaminare con calma. La function pfisso ci ha dato dei vettori, noi abbia-mo fatto il grafico di convergenza. Ora vogliamo salvare, per ogni iterazione, i valori delle approssimazioni,degli scarti e delle stime asint1 e asint2 inserendoli in una tabella con una riga di intestazione in cuiscriviamo il significato della colonna corrispondente. Vediamo un modo compatto per fare tutto ci. Creia-mo una matrice in cui ciascuna riga corrisponde a ci che vogliamo mettere in tabella: la prima riga avr leiterazioni fatte, la seconda i valori approssimati, la terza gli scarti, la quarta le stime asint1 e la quinta lestime asint2. La matrice deve avere lo stesso numero di colonne, quindi dobbiamo stare attenti al fatto chealcuni vettori hanno come prima componente un valore che corrisponde alliterazione 0.

    Per scrivere su un file di 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 di sola lettura, w per file discrittura,... si faccia help fopen). Loutput della function una variabile scalare di tipo intero, a cui diamonome fid (file identifier). Questa variabile sar usata come identificatore del file su cui dobbiamo andarea scrivere mediante la function fprintf. Una volta che si scritto, si chiude il file mediante la functionfclose, scrivendo semplicemnte fclose(fid).

    La functionfprintfpermette di scrivere su un file utilizzando un certo formato. Ci che diciamo adessoserve in maniera analoga per la functionsprintf che permette di scrivere con un certo tipo di formato sullaCommand Window.

    I dati di input di fprintf sono la variabile fid, alcune istruzioni che riguardano il formato, da scriveretra apici, e una o pi matrici. Se, si pone fid=1 loutput sar lo schermo della Command Window. Quindilistruzione da dare fprintf(fid, formato, A, B, ...) conA,Bmatrici o array (un array puessere un vettore o una matrice fatta di numeri o di stringhe di 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 stringa di caratteri da scrivere tra apici che possono avere diversi significati: c il formatoassociato al tipo di rappresentazione della variabile (se in formato esponenziale, fisso, di tipo intero, di stringa

    35

  • 1. INTRODUZIONE

    di caratteri...) che si scrive nella forma %e (formato esponenziale) o %12.6e (formato esponenziale cui sonoriservati 12 spazi di cui 6 per la mantissa)...; ci sono i caratteri che hanno il significato di riga bianca, andarea capo, ... che sono preceduti dal simbolo \ ( \n, nuova linea, \r andare a capo,...); ci possono essere stringhedi caratteri. In tabella vediamo i principali simboli che ci interessano.

    formato Significato%s stringhe di caratteri%d formato intero%f formato decimale in virgola fissa%e formato esponenziale (del tipo 3.5e +00)%E formato esponenziale (del tipo 3.5E +00)%g formato che una via di mezzo tra %f e %e senza gli zeri che non servono\ n nuova linea (il risultato come schiacciare il tasto di invio)\ r per andare a capo\\ \

    Il significato associato a \ n molto importante, perch permette di 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