Facoltà di Ingegneria
Laboratorio di Fondamenti di Informatica Ing. Dario Sguassero - Prof. Paolo Michelini
2ª Lezione 17 novembre 2008
a.a. 2008/09
POLINOMI Un polinomio è un'espressione tipo: P(x) = cnxn + cn-1xn-1 + cn-2xn-2 + ... + c2x2 + c1x + c0 che Matlab rappresenta come particolare vettore riga, i cui elementi sono i coefficienti dei monomi del polinomio in ordine di potenza decrescente: >> p = [cn cn-1 cn-2 ... c2 c1 c0] Es. il polinomio x2 + 7x + 5 viene rappresentato con il vettore riga p = [1 7 5]; Es. rappresentazione del polinomio x4 + 111x3 + 1100x2 + 1000x1 + 4 >> p = [1 111 1100 1000 4] Per i coefficienti non presenti nel polinomio si deve inserire uno zero nel corrispondente elemento del vettore. Es. il polinomio x4 + 7x2 + 3x + 2 viene rappresentato con il vettore riga p = [1 0 7 3 2] Si può calcolare il valore del polinomio usando la funzione polyval, che richiede il vettore con i coefficienti del polinomio e i punti delle x dove calcolare il valore polinomio. Es. trovare il valore del polinomio P(x) = x4 + 5x3 + 3x nel punto x = 2. >> p = [1 5 0 3 0]; >> y = polyval(p, 2) y = 62 Matlab mette a disposizione la funzione roots per la ricerca delle radici di un polinomio. Es. trovare le radici di P(x) = x2 -6x + 5 >> p = [1 -6 5]; x = roots(p); x= [ 5 1 ] infatti polyval(p,1) = polyval(p,5) = 0 E' possibile eseguire anche l'operazione inversa grazie al comando poly, ossia trovare il polinomio (cioè il vettore dei suoi coefficienti, che lo rappresenta) che ha determinate radici. Es. trovare il polinomio con radici 1 e 5. >> x = [1 5]; p = poly(x) restituisce p = [1 -6 5] ovvero il polinomio p = x2 -6x +5 Ancora più versatile è il comando polyfit che definisce i coefficienti necessari a creare un polinomio di grado n qualsiasi che passi attraverso k punti di coordinate (x,y). Per passare questi k punti bisognerà definire i vettori X e Y contenenti le coordinate dei k punti (x1 y1), (x2 y2) ... (xk.1 yk-1) (xk yk) come X = [x1 x2 x3 ... xk-1 xk] e Y = [y1 y2 y3 ... yk-1 yk] Es. trovare il polinomio di grado 2 che passa per i punti (1,0), (5,0) e (3,-4); trovare anche quello che passa per (1,0), (5,0) e (3,4) >> X= [1 5 3]; Y1 = [0 0 -4]; p1 = polyfit(X,Y,2) p1 = [1 -6 5] 2
>> Y2 = [0 0 4]; p2 = polyfit(X,Y,2) p2 = [-1 6 5] Nota: se eseguiamo la combinazione delle due funzioni inverse troviamo il vettore di partenza, ma normalizzato (definito a meno del coefficiente ck) Es. ricalcoliamo il vettore dei coefficienti a partire dalle sue stesse radici >> poly(roots([1 2 3]) ans = 1 2 3 >> poly(roots([2 4 6]) ans = 1 2 3 GRAFICI Qualsiasi funzione o insieme di coordinate è visualizzabile per punti tramite il comando plot. La funzione plot crea grafici bidimensionali: riceve in ingresso due vettori della stessa lunghezza e stampa i punti corrispondenti alle coordinate fornite dai due vettori. Per tracciare il grafico di una qualsiasi funzione, è perciò necessario crearsi un opportuno vettore da usare come ascisse, passarlo alla funzione per ricavare un vettore contenente le ordinate, ed usare la funzione plot sui due vettori così ottenuti. La n-pla di coordinate (x,y) si rappresenta come per il comando polyfit tramite i due vettori delle coordinate X e Y. Es. tracciare la funzione sin(x) tra -4 e 4: >> x=-4:0.01:4; y=sin(x); plot(x,y); Se si usa la funzione plot con un solo parametro complesso, il grafico rappresenterà la parte reale e la parte immaginaria degli elementi del vettore: Es. plot(y); con y complesso, equivale a: >> plot(real(y),imag(y));
Es. definire graficamente i punti p1 = (2, 3), p2 = (3,5) e p3 = (4,3) >> x = [2 3 4]; y = [3 5 3]; plot (x,y)
3
5 4.8 4.6 4.4 4.2 4 3.8 3.6 3.4 3.2 3
2
2.2
2.4
2.6
2.8
3
3.2
3.4
3.6
3.8
4
Per default i punti vengono uniti tramite una spezzata, ma è possibile passare al comando plot dei parametri per personalizzare la visualizzazione del grafico. Es. rappresentare le tre coordinate precedenti mediante dei cerchi di colore rosso >> plot (x,y,'rO') 5 4.8 4.6 4.4 4.2 4 3.8 3.6 3.4 3.2 3
2
2.2
2.4
2.6
2.8
3
3.2
3.4
3.6
3.8
4
Se questi punti rappresentano l'andamento di una funzione è preferibile rappresentarla con una densità notevolmente maggiore di punti. Sapendo che la funzione è un polinomio di grado n si può definire il polinomio mediante polyfit, quindi si crea un asse X molto fitto di punti, e poi si valuta in questi punti il polinomio mediante il comando polyval Es. rappresentare la parabola che ha il vertice in (4,4) e taglia l'asse delle x nei punti 2 e 6 4
>> x = [2 4 6]; y = [0 4 0]; X = [-2:0.1:10]; p = polyfit(x,y,2); Y = polyval(p,X); plot(X,Y) 5 0 -5 -10 -15 -20 -25 -30 -35 -2
0
2
4
6
8
10
Per sovrapporre i valori originali dei tre punti con l'andamento del grafico si utilizza il comando hold on tra i due grafici (disattiva il reset della schermata tra i due grafici, sovrapponendone l'andamento). hold off per disattivare questa funzione. Es. sovrapporre di due grafici precedenti >> x = [2 4 6]; y = [0 4 0]; plot(x,y,'rO'); hold on >> X = [-2:0.1:10]; p = polyfit(x,y,2); Y = polyval(p,X); plot(X,Y)
5
5 0 -5 -10 -15 -20 -25 -30 -35 -2
0
2
4
6
8
10
Quando invece non esiste una funzione conosciuta si può tentare di approssimarla giocando con il grado n del polinomio. Es. supponiamo che l'andamento del prezzo della benzina negli ultimi giorni, rilevato ogni fine settimana, sia stato: il giorno 2 prezzo € 1,15, il giorno 9 prezzo € 1,10, il giorno 16 prezzo €1,09, il giorno 23 prezzo €1,12. Provare ad anticipare il prezzo della benzina per il giorno 25 assumendo una funzione interpolatrice di 2°, 3° o 4° grado. >> x = [2 9 16 23]; y = [1.15 1.10 1.09 1.12]; p1 = polyfit(x,y,1); p3 = polyfit(x,y,3); p4 = polyfit(x,y,4); Innanzitutto veniamo avvisati che nel caso di p4 il numero di punti non è sufficiente per definire in modo univoco il polinomio: "Warning: Polynomial is not unique; degree >= number of data points". >> X = [1:0.1:31]; Y1 = polyval(p1,X); Y3 = polyval(p3,X); Y4 = polyval(p4,X); >> plot (X,Y1); hold on; plot (X,Y3); plot (X,Y4);
6
2
0
-2
-4
-6
-8
-10
-12
-14
0
5
10
15
20
25
30
35
I valori per il giorno 25 sono: >> giorno = X(241), y1 = Y1(241), y3 = Y3(241), y4 = Y4(241) giorno = 25 y1 = 1.0971 y3 = 1.1359 y4 =-0.0357 Per sommare o sottrarre due polinomi si sommano o sottraggono i corrispondenti vettori riga con l'accortezza di rappresentare ambedue i polinomi come polinomi dello stesso ordine. La funzione conv è utilizzata per la moltiplicazione di due polinomi. La funzione conv moltiplica due vettori e quindi due polinomi. 2
2
Es. il prodotto tra polinomi (x +x+1) * (x +111x+1000) viene effettuato con: prod = conv([1 1 1],[1 111 1000]); che dà come risultato il vettore [1 112 1112 1111 1000] 2
4
2
Es. il prodotto tra polinomi (x + x + 1)*(x + 7x + 3x + 2) fornisce come risultato il vettore Prod = [1 1 8 10 12 5 2] Per moltiplicare più di 2 polinomi, occorre utilizzare più istruzioni conv in forma annidata. La funzione deconv è utilizzata per la divisione di due polinomi. Es. dividere prod per y equivale ad ottenere x: [xx,R]=deconv(prod,y); fornisce come risultato il vettore quoziente xx=[1 1 1] ed il vettore resto R=[0 0 0 0 0 0 0].
Per sovrapporre più grafici nello stesso momento si può evitare di utilizzare il comando hold sfruttando le potenzialità del comando plot di accettare una molteplicità di vettori in ingresso. Es. nel caso dell'esercizio precedente l'ultima riga si può scrivere anche come >> plot (X,Y1,X,Y3,X,Y4); con il vantaggio che i tre grafici vengono già rappresentati con colori differenti
7
2
0
-2
-4
-6
-8
-10
-12
-14
0
5
10
15
20
25
30
35
PERSONALIZZAZIONE DEI GRAFICI Per creare manualmente grafici di colori diversi, usando caratteri diversi dal punto o con linee di unione diverse, si può specificare dopo le coordinate una stringa di 1-3 elementi. Il primo è il colore del grafico, il secondo il simbolo usato per contrassegnare i punti, il terzo il carattere di unione. Questa opzione può essere usata nei casi di grafici sovrapposti da stampare (se la stampante a disposizione non è a colori e se non si cambia il tipo di simbolo, il grafico può risultare poco leggibile). Es. creare tre grafici sovrapposti e differenziali graficamente >> x=[0:0.2:5];y1=sin(x);y2=cos(x);y3=sin(x).*cos(x); >>plot(x,y1,'gO',x,y2,'rp:',x,y3,'b.-');
8
1
0.8
0.6
0.4
0.2
0
-0.2
-0.4
-0.6
-0.8
-1
0
0.5
1
1.5
2
2.5
3
3.5
4
4.5
5
Dal comando help plot si ottiene l'insieme delle opzioni possibili: b g r c m y k w
blue green red cyan magenta yellow black white
. o x + * s d v ^ < > p h
point circle : x-mark -. plus -star (none) square diamond triangle (down) triangle (up) triangle (left) triangle (right) pentagram hexagram
Altri comandi per personalizzare il grafico sono: • • • • • • • •
grid on: sovrappone al grafico una griglia grid off: elimina la griglia title ('testotitolo'): aggiunge un titolo del disegno xlabel ('testoascisse'): aggiunge una legenda per l’asse x ylabel ('testoordinate'): aggiunge una legenda per l’asse y axis([xmin xmax ymin ymax]): riscala gli assi del grafico figure(gcf): mette in mostra l'immagina desiderata clf: cancella il grafico corrente
Es. disegnare un nuovo grafico e personalizzarlo >> clf; x = [0:0.1:10]; y = sin(x) .* cos(x); plot(x,y); >> grid on; title ('Grafico sin(x) cos(x)'); xlabel='tempo'; ylabel='tensione'; 9
solid dotted dashdot dashed no line
>> axis([-1 6 -2 2]); figure(gcf); Grafico sin(x) cos(x) 2
1.5
1
0.5
0
-0.5
-1
-1.5
-2 -1
0
1
2
3
4
5
6
La personalizzazione dei grafici può spingersi molto oltre questi semplici comandi. PLOT MULTIPLI E' possibile suddividere la schermata in più riquadri per visualizzare contemporaneamente una molteplicità di grafici. Il comando subplot consente di effettuare questa divisione e selezionare un riquadro per la prossima operazione di plot. Il primo argomento indica le suddivisioni verticali da apportare alla schermata, il secondo le suddivisioni orizzontali mentre il terzo è il numero di riquadro su cui si continuerà ad operare. Es. creare una figura con 2 riquadri affiancati >> x=[0:0.1:5]; y1=sin(x); y2=cos(x); subplot (1,2,1); plot(x,y1); subplot(1,2,2); plot(x,y2);
10
1
1
0.8
0.8
0.6
0.6
0.4
0.4
0.2
0.2
0
0
-0.2
-0.2
-0.4
-0.4
-0.6
-0.6
-0.8
-0.8
-1
0
0.5
1
1.5
2
2.5
3
3.5
4
4.5
-1
5
0
0.5
1
1.5
2
2.5
3
3.5
4
4.5
5
E' possibile anche utilizzare scale logaritmiche per il solo asse delle x sostituendo il comando plot con l'analogo semilogx, solo per l'asse delle y con semilogy oppure per entrambi gli assi con loglog Es. confrontare un grafico utilizzando assi di tipo diverso >> x=[0:0.1:10]; y=exp(x); subplot(2,2,1); plot(x,y); subplot(2,2,2); semilogx(x,y); ... subplot(2,2,3); semilogy(x,y); subplot(2,2,4); loglog(x,y); 4
2.5
4
x 10
2.5
2
2
1.5
1.5
1
1
0.5
0.5
0
0
1
2
3
4
5
6
7
8
9
0 -1 10
10
5
0
10
1
10
5
10
10
4
4
10
10
3
3
10
10
2
2
10
10
1
1
10
10
0
10
x 10
0
0
1
2
3
4
5
6
7
8
9
10 -1 10
10
0
10
1
10
Mentre linspace (da,a,n) crea un vettore di n elementi compreso tra da e a separati linearmente, la funzione logspace crea lo stesso vettore, con elementi separati logaritmicamente. Si osservi che i primi due parametri da e a sono gli esponenti degli estremi dell’intervallo espressi in base 10.
11
Es. confrontare i due risultati >> x1 = linspace(0.01,100,10), x2 = logspace(-2,2,10) Il comando plotyy permette di sovrapporre due grafici con due asse delle ordinate distinti, uno a destra e l'altro a sinistra. Es. disegnare sovrapposti e scalati verticalmente due grafici y1=sin(x) e y2 = sin(x) cos(y) >> clf; x=[0:0.1:10]; y1=sin(x);y2=sin(x).*cos(x);subplot(1,2,1); plot(x,y1,x,y2); ... subplot(1,2,2);plotyy(x,y1,x,y2); 1
1
0.5
0
0
0.8
0.6
0.4
0.2
0
-0.2
-0.4
-0.6
-0.8
-1
0
1
2
3
4
5
6
7
8
9
-1
10
0
1
2
3
4
5
6
7
8
9
-0.5 10
Il comando axes permette definizioni ancora più accurate della posizione degli assi, ammettendo la sintassi generica axes(proprietà,valore); la proprietà "position" richiede come valori i vertici di un rettangolo definiti in termini relativi (da 0 a 1) rispetto alla finestra corrente; vedere help axes per approfondimenti. Es. sovrappone due grafici al centro della figura >> clf;axes('position',[0.1 0.1 0.6 0.4]); plot(x,y); axes('position',[0.5 0.2 0.4 0.6]);plot(x,y);
12
0.5 0.4 0.3 0.2 0.1 0.5
0 -0.1 -0.2 -0.3
0 -0.4 -0.5
-0.5
0
1
2
3
4
5
0
6
1
7
2
3
8
4
5
9
6
7
8
9
10
10
Il comando annotation permette di aggiungere commenti, didascalie e varie forme all'immagine. Con la proprietà textarrow è possibile disegnare una freccia con un testo, dove le coordinate di partenza e arrivo sono indicate mediante due vettori X= [x1 x2] e Y = [y1 y2] con valori da 0 a 1 sempre relativamente alla dimensione della figura. Es. disegnare un grafico indicando il punto di minimo >> clf; plot(x,y); annotation('textarrow',[0.2,0.31],[0.4,0.11],'String','Punto minimo');
0.5
0.4
0.3
0.2
0.1
0
-0.1 Punto minimo -0.2
-0.3
-0.4
-0.5
0
1
2
3
4
5
6
7
8
9
10
Analogamente è possibile creare rettangoli, ellissi, riquadri con testo, linee, frecce doppie, ecc. vedere help annotation per maggiori informazioni. Es. provare a sovrapporre un po' di figure tramite il comando annotation >> clf; plot(x,y); annotation('rectangle',[0.28 0.1 0.05 0.05]); annotation('ellipse',[0.16 0.9 0.05 0.05]); ... annotation('textbox',[0.2 0.5 0.2 0.2],'String','Legenda: cerchio = punto di massimo, quadrato = punto di minimo');
13
0.5
0.4
0.3
0.2
0.1 Legenda: cerchio = punto di massimo, quadrato = punto di minimo 0
-0.1
-0.2
-0.3
-0.4
-0.5
0
1
2
3
4
5
6
7
8
9
10
In generale le etichette possono essere ulteriormente personalizzate facendo ricorso ai comandi di formattazione TeX, di cui si può trovare amplia bibliografia in rete. Ad esempio le lettere greche α e π possono essere richiamate rispettivamente con le parole chiave \alpha e \pi. Ulteriori possibilità di personalizzazione dei grafici si possono ottenere con i comandi get e set, che richiedono l'handle del grafico (ovvero il suo numero di identificazione, restituito come parametro ad ogni comando plot); get(h) visualizza i valori di tutti i parametri per il grafico con numero di handle h mentre set(h,'nomeparametro',valoreparametro) permette una personalizzazione estremamente dettagliata di qualsiasi grafico. Per approfondimenti consultare l'help get ed help set Es. definire l'handle di un grafico e impostare qualche parametro aggiuntivo >> h = plot(x,y,'rO'); get(h), set(h,'MarkerSize',20);
0.5
0.4
0.3
0.2
0.1
0
-0.1
-0.2
-0.3
-0.4
-0.5
0
1
2
3
4
5
ALTRI COMANDI DI I/O 14
6
7
8
9
10
La funzione error mostra un messaggio di errore ed interrompe l'esecuzione di un file .m Es: mostrare il messaggio di errore "A deve essere simmetrica" >> error('A deve essere simmetrica'); La funzione input mostra un messaggio e permette l'inserimento di dati. Es. chiedere il numero di iterazioni da eseguire e memorizzarlo nella variabile num >> num = input('Inserire il numero di iterazioni: ') Inserire il numero di iterazioni: 10 num = 10 Il comando figure crea una nuova finestra grafica in cui far comparire il disegno; per spostarsi sulla n-esima finestra grafica, basta digitare figure(n), mentre figure(gcf) porta in primo piano la figura corrente. Il comando gtext('stringa') visualizza sul grafico la stringa indicata nella posizione in cui si clicca con il mouse, mentre [x,y] = ginput(n) legge le coordinate di n punti del grafico su cui si clicca. ALTRI TIPI DI GRAFICO Per visualizzare il contenuto di un vettore in modalità diverse dal comando plot è sufficiente cliccare sopra il nome della variabile nella finestra Workspace con il tasto destro, quindi selezionare dal menù la modalità di visualizzazione desiderata (testato con Matlab R2007b). Notare che nella Command Window comparirà il relativo comando di visualizzazione, grazie al quale si può dedurre che per ottenere una visualizzazione con grafico a barre del vettore y è sufficiente impartire il comando hist(y), per un grafico a torta pie(y), un grafico a barre bar(y), ecc.
250
200
150
100
50
0 -350
-300
-250
-200
-150
-100
15
-50
0
50