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