Introduzione a Matlab II - Dipartimento di Matematica
Transcript
Introduzione a Matlab II - Dipartimento di Matematica
Complementi di Matematica e Calcolo Numerico A.A. 2012-2013 Laboratorio 2 - 17/3/2014 Programmare con Matlab: Script-files Che cos’ è uno script-file? • È un file con estensione .m (ad esempio: myfile.m). • Contiene una sequenza di istruzioni Matlab, scritte come se fossero digitate in modalità interattiva. • Digitando il nome di uno script-file a destra del prompt: >> myfile vengono eseguite in successione tutte le istruzioni contenute nel file. • Le variabili assegnate in uno script-file sono visibili dall esterno, ovvero persistono in memoria al termine dell esecuzione. Alcune buone regole • Il nome di uno script-file deve essere diverso dai nomi delle variabili che esso elabora e dai nomi delle variabili presenti in Workspace, altrimenti non verrà eseguito. • Non assegnare ad uno script-file il nome di una funzione predefinita di Matlab. Per verificare se un nome esiste già: >> exist(’nome’) Esempio Scrivere uno script-file che dato n ∈ N, calcoli il fattoriale n! = 1 · 2 · 3 · . . . (n − 1) · n Per genereare un nuovo script-file selezioniamo dal menu: file −→ new −→ Mfile fattoriale.m n=input(’inserisci numero intero positivo’) fact=prod([1:n]) disp(’fattoriale=’) disp(fact) 2 Aritmetica finita ed errori Una conseguenza dell’approssimazione dei numeri reali con numeri macchina è la costante presenza di errori di arrotondamento che con l’esecuzione di successive operazioni aritmetiche si possono propagare ed accumulare, per questo motivo in aritmetica finita il risultato calcolato dipenderà dalla sequenza con cui vengono eseguite le varie operazioni. Se x è una quantità esatta ed x̃ è una sua approssimazione |x̃ − x| |x| |x̃ − x|, sono detti rispettivamente errore assoluto ed errore relativo. L’errore relativo che si commette approssimando un numero reale x con il numero floating point f l(x) è tale che |f l(x) − x| ≤ C ǫM |x| ǫM = β 1−t è detto epsilon macchina, dove β è la base e t il numero di cifre significative dell’insieme dei numeri macchina considerato. Nel caso della doppia precisione β = 2 e t = 53. ǫM non va confuso con il più piccolo numero rappresentabile in un sistema floating point, esso definisce invece una stima di quanto può variare al più l’errore relativo quando si approssima un numero reale con un numero macchina. 3 ǫM può anche essere definito come il più piccolo numero macchina positivo tale che f l(1 + x) > 1. In Matlab è predefinita la variabile eps contenente il valore dell’epsilon macchina ǫM . >> eps ans = 2.2204e-16 Esercizio Scrivere uno script-file che calcoli ǫM attraverso la seguente ricorrenza: e0 = 1/2, k = 0 (1) se ek + 1 > 1 → ek+1 = ek /2 altrimenti STOP Soluzione: Come ogni linguaggio di programmazione Matlab possiede istruzioni per effettuare cicli. Nel codice sotto riportato vediamo un esempio di utilizzo dell’istruzione while, che permette di ripetere ciclicamente un certo insieme di istruzioni fintanto che una data condizione è verificata. epsmacchina.m e=1/2; k=0; while (e+1)>1 e=e/2; k=k+1; end e=2*e, k 4 Esempio di non associatività. Alcune proprietà delle operazioni in aritmetica esatta possono non valere in aritmetica finita in virgola mobile (floating point). Ad esempio: >> a=1.0e+308; >> b=1.1e+308; >> c=-1.001e+308; >> (a+b)+c ans = Inf >> a+(b+c) ans = 1.0990e+308 Esempio di cancellazione numerica. In aritmetica esatta, usando la nota identità (a+b)(a−b) = a2 −b2, si ottiene facilmente √ 1 ∀x ∈ R . (2) x2 + 1 − x = √ x2 + 1 + x Calcolando con Matlab: >> x=77777777; >> y1=sqrt(x^2+1)-x y1 = 0 >> y2=1/(sqrt(x^2+1)+x) y2 = 5 6.4286e-09 >> err=abs((y1-y2)/y2) err = 1 In vista della uguaglianza (2), in aritmetica esatta i valori y1 e y2 dovrebbero essere uguali, e l’errore relativo err nullo. In realtà si osserva che i risultati ottenuti (y1 e y2) sono assai diversi. Il risultato finale dipende fortemente da come viene effettivamente calcolata la funzione (errore di arrotondamento, dovuto all’artitmetica finita del calcolatore). Il risultato “corretto” è y2, mentre il risultato dato da y1 è soggetto a un fenomeno di cancellazione. Esercizio 1 (Esempio di errore dovuto all’aritmetica finita.) In aritmetica esatta è ben noto il seguente limite n 1 lim 1 + =e, n→∞ n dove e = 2, 718.. rappresenta il numero di Nepero. Si scriva uno script file Matlab che una volta letto da tastiera un n valore per n calcoli en = 1 + n1 e l’errore assoluto ean = |en −e| commesso. Per approssimare e si esegua ripetutamente tale script file per n = 102, 104, 108, 1012 , 1014, 1016 . In aritmetica esatta, i valori ean dovrebbero tendere a zero in quanto le en sopra calcolate tendono a e. Cosa accade invece? 6 Grafici-2D Il più semplice comando Matlab per disegnare un grafico è : plot(x,y) dove x = (x1, . . . , xn) e y = (y1, . . . , yn) sono 2 vettori di ugual dimensione. Il comando plot(x,y) rappresenterà in una finestra grafica una linea che collega i punti di coordinate (xi, yi), i = 1, . . . , n Esempio Disegnare il grafico della funzione f (x) = 2 sin(x) cos(x) + 2x nell’intervallo [0, π/2] >> x=linspace(0, pi/2,10); >> y=2*sin(x).*cos(x)+2*x; >> plot(x,y) Basta un solo comando per valutare f in un vettore di punti grazie alle operazioni componente per componente; inoltre le funzioni matematiche (quali sin e cos) applicate a vettori eseguono l’operazione componente per componente. Se cambio il vettore delle ascisse x devo ricalcolare il vettore y contenente i valori assunti dalla funzione f nei nuovi punti prima di fare il grafico: >> x=linspace(0,pi); >> y=2*sin(x).*cos(x)+2*x; >> plot(x,y) 7 Sarà utile, per non dover manualmente ripetere la successione di istruzioni ogni volta che si cambia un parametro, memorizzare il lavoro in uno script-file. 3.5 3 2.5 2 1.5 1 0.5 0 0 0.2 0.4 0.6 0.8 1 1.2 1.4 1.6 7 6 5 4 3 2 1 0 0 0.5 1 1.5 2 8 2.5 3 3.5 Il comando plot prevede la possibilità di scegliere il tipo di linea, il suo colore, ecc (vedi help plot). La sintassi generale è: plot(x1, y1,’specifiche linea1’) Per esempio per una linea rossa tratteggiata plot(x,y,’r--’) Il comando doc LineSpec mostra una lista di tutte le opzioni disponibili per specificare lo stile della linea. L’istruzione plot crea una nuova finestra grafica solo se non ci sono finestre grafiche già aperte, altrimenti utilizza l’ultima finestra creata, e sovrascrive il nuovo grafico a quello creato in precedenza. Pertanto se vogliamo visualizzare contemporaneamente i grafici di due funzioni f (x) = sin(x) + x, g(x) = x2 + cos(x) x ∈ [0, π] abbiamo due possibilità: • possiamo disegnare il grafico di f e aggiungere successivamente il grafico di g specificando a Matlab di non cancellare il primo grafico tramite il comando hold on >> >> >> >> >> >> x=linspace(0,pi); fx=sin(x)+x; plot(x,fx,’r’) hold on gx=x.^2+cos(x); plot(x,gx,’b’) 9 • possiamo disegnare i due grafici con un solo comando plot >> >> >> >> x=linspace(0,pi); fx=sin(x)+x; gx=x.^2+cos(x); plot(x,fx,’r’,x,gx,’b’) 9 8 7 6 5 4 3 2 1 0 0 0.5 1 1.5 2 2.5 3 3.5 Il comando figure genera una nuova finestra, la numera come indicato e ci permette di disegnare i 2 grafici in 2 diverse finestre: x=linspace(0,pi); fx=sin(x)+x; gx=x.^2 +cos(x); figure(1) plot(x,fx) figure(2) plot(x,gx) 10 I comandi title, xlabel,ylabel,legend ci permettono di completare il nostro grafico con un titolo, delle etichette sugli assi e una legenda: >> >> >> >> >> >> >> >> x=linspace(0,pi); fx=sin(x)+x; gx=x.^2 +cos(x); plot(x,fx,’r’, x,gx,’b’) title(’Grafici di funzioni’) xlabel(’Asse x’) ylabel(’Asse y’) legend(’f’,’g’) Grafici di funzioni 9 f g 8 7 Asse y 6 5 4 3 2 1 0 0 0.5 1 1.5 2 2.5 3 3.5 Asse x Il comando grid on inserisce una griglia sul grafico. 11 Esercizio 2 Scrivere uno script-file Matlab che, letti da tastiera gli estremi a e b di un intervallo, disegni il grafico della funzione sin(x) per x ∈ [a, b]. A tale scopo si generi un vettore z di 50 punti equispaziati in [a, b], si valuti la funzione nei punti di z e si disegni il grafico usando la funzione plot. Esercizio 3 Disegnare il grafico delle seguenti funzioni: • f (x) = 2 log(x+2) √ x+1 • g(x) = x2 +2x+1 x2 +1 x ∈ [1, 2] linea blu tratteggiata x ∈ [0, 5] linea rossa continua con le seguenti modalità: • disegnare due grafici distinti nella stessa figura • disporre i due grafici in due finestre distinte. Esercizio 4 (Esempio grafico di cancellazione numerica.) Per disegnare il grafico del polinomio p(x) = (x − 1)6 si osservi che sviluppando la potenza del binomio si ha la seguente uguaglianza (x − 1)6 = x6 − 6x5 + 15x4 − 20x3 + 15x2 − 6x + 1 . (3) Si utilizzino le due espressioni sopra citate per calcolare p(x) nei punti x=[0.995:0.00001:1.005]; in due finestre distinte si disegni nei due casi il grafico del polinomio utilizzando il comando plot. 12 Si osservi che, in aritmetica esatta, a causa dell’identità (3) i due grafici disegnati dovrebbero essere identici. Invece, a causa degli effetti di cancellazione nel calcolo del termine di destra il grafico presenta forti oscillazioni artificiali. 13 Funzioni Simboliche (inline) Assegnata una funzione del tipo f (x) = (sin(x) + x)2 vogliamo valutare i valori assunti da f per diversi valori di x. Quando l’espressione della funzione è lunga e/o complessa e la funzione deve essere valutata in istanti successivi per diversi valori delle variabili da cui dipende, è utile poter definire la funzione una volta per tutte senza dover riscrivere la sua espressione ogni volta che la si vuole valutare in punti differenti. In Matlab è possibile definire una funzione in modo simbolico. Il comando inline definisce una funzione in linea, ovvero direttamente nello spazio di lavoro, senza ricorrere a file esterni. Per esempio, definiamo: >> f=inline(’(sin(x)+x).^2’,’x’) dove il primo elemento in input ’(sin(x)+x).^2’ è una stringa che definisce l’espressione matematica che deve essere trasformata in funzione, mentre i successivi elementi in input (nel nostro caso solo ’x’) sono l’elenco ordinato delle variabili da cui deve dipendere la funzione. Attenzione: ricordarsi di utilizzare operazioni con i punti se si vuole che la funzione operi sui vettori! 14 Ad una funzione cosı̀ definita non sono associati dei valori numerici (verificare con whos f). Per associarle valori numerici scriviamo, per esempio >> x=0:0.01:2*pi; >> y=f(x); Tali valori numerici vengono conservati nel vettore y (verificare con whos y). Possiamo poi usarli, per esempio, per disegnare il grafico di f con il comando >> plot(x,y) Attenzione: perchè il comando >> plot(x,f) non funziona? È possibile definire funzioni che dipendono da più variabili o parametri >> f=inline(’2*x+a’,’a’,’x’); Attenzione: y = f (2, 10) è diverso da z = f (10, 2). 15 Esercizio 5. Dopo averle definite con il comando inline, fare un grafico delle seguenti funzioni: a) f (x) = 2 log(x+2) √ x+1 2 in [1, 2], linea nera tratteggiata; b) f (x) = (x − 1)e 1 x2 −1 in [1, 10], linea rossa continua. Esercizio 6. Dopo aver definito la funzione f (a, x) = e − ax con il comando inline come funzione di due variabili, disegnare i grafici di f in [−1, 1] per a = 1 e per a = −1 nella stessa finestra utilizzando 2 colori diversi e corredandola di legenda; Esercizio 7. Dopo aver definito la funzione f (k, x) = cos(kπx) con il comando inline come funzione di due variabili k = 1, 2, 3 e x ∈ [−1, 1] disegnare i grafici di f per i differenti valori di k disponendoli in 3 finestre distinte e corredando le figure di titoli, ed etichette sugli assi. 16 Equazioni non lineari (fzero) Sia f : R −→ R una funzione che ammette una radice α, ovvero t.c. f (α) = 0, possiamo utilizzare la funzione predefinita di Matlab fzero per calcolare un’approssimazione di α. Sintassi: alfa = fzero(f,[a,b],toll) input: f è indifferentemente la funzione definita con inline oppure la stringa che la descrive [a, b] sono gli estremi di un intervallo contenente la radice cercata che soddisfino f (a) ∗ f (b) < 0 toll precisione richiesta (opzionale, se omesso toll = 1e-6) output: alfa approssimazione della radice calcolata Osservazione: È possibile utilizzare fzero dando in input, al posto dell’intervallo [a, b], un solo valore x0, a partire dal quale l’algoritmo cercherà la radice di f : alfa = fzero(f, x0, toll) Att.ne! Se x0 non viene scelto in maniera opportuna, l’algoritmo potrebbe non convergere o, in caso di più radici, potrebbe convergere ad una radice diversa da quella cercata; questo rischio non si corre utlizzando la modalità precedente ed avendo l’accortezza di scegliere come [a, b] un intervallo che contenga solo la radice voluta. 17 In caso si volessero trovare più radici della stessa funzione è necessario ripetere la procedura per ogni singola radice. Onde localizzare ogni radice e scegliere un intervallo [a, b] che la contenga è utile tracciare preliminarmente un grafico della funzione f. Limitazioni • La funzione fzero definisce uno zero come un punto in cui la funzione assegnata attraversa l’asse x. Punti in cui la funzione tocca ma non attaversa l’asse x non sono considerati zeri validi. Ad esempio la parabola f (x) = x2 ha una radice doppia in 0 e quindi tocca ma non attraversa l’asse x pertanto fzero non è in grado di determinare tale radice di f . >> f=inline(’x.^2’,’x’); >> x=fzero(f,[-1,1]) ??? Error using ==> fzero at 293 The function values at the interval endpoints must differ in sign. >> x=fzero(f,0.005) Exiting fzero: aborting search for an interval containing a sign change because NaN or Inf function value encountered during search. (Function value at -1.55333e+154 is Inf.) 18 Check function or try again with a different starting value. x = NaN • La funzione fzero(f,x0) cerca di individuare punti in un intorno di x0 in cui la f cambia segno, se la funzione assegnata è continua un tale punto corrisponde ad una radice di f altrimenti fzero può ritornare un punto di discontinuità anziché uno zero di f . Ad esempio >> f=inline(’tan(x)’,’x’); >> alfa=fzero(f,1) alfa = 1.5708 Esercizio 8 Eseguire il grafico delle seguenti funzioni negli intervalli specificati ed in seguito, con la funzione fzero, trovarne le radici: a. f (x) = e−x − sin(x) b. f (x) = (x3 − 3x + 2)ex, x ∈ [−1, 5] x ∈ [−3, 1.5] 19