Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
lottimizzazione dinamica
Introduzione a MATLAB
Giovanni Di Bartolomeo
Universit di Teramo
email: gdibartolomeo@unite.it
I.
Ambito di applicazione
Nellanalisi dei fenomeni economici e finanziari indispensabile
conoscere e saper programmare software econometrico
statistici, che siano in grado di risolvere problematiche di
carattere matematico e statistico pi o meno complesse,
altrimenti impossibili da trattare per la loro difficolt
computazionale.
La programmazione
Programmare significa scrivere in un particolare linguaggio un
testo in grado di essere letto dal software, che contenga delle
istruzioni che il software dovr eseguire al fine di produrre un
risultato numerico.
Per questo motivo la fase di programmazione potrebbe in linea
di principio essere eseguita su un qualsiasi editor di testo (es.
Word, txt,..), per poi essere letta con il programma prescelto.
II.
Struttura di MATLAB
Struttura di MATLAB
Matlab pu venir utilizzato per:
Applicazioni matematiche e calcoli numerici
Procedure
Simulazioni
Analisi di dati
Grafici
..
Struttura di MATLAB
Allapertura di MATLAB ci troviamo sulla finestra del command:
command
questo significa che sulla riga in cui lampeggia lindicatore di
testo possiamo digitare le operazioni, che verranno
immediatamente recepite dal programma ed eseguite
premendo INVIO.
Quanto scritto nel command durante tutta la sessione di lavoro
pu essere ripreso durante la stessa ponendosi su una linea e
premendo la freccia in alto;
alto premendo tale tasto in
continuazione viene visualizzato quanto digitato
precedentemente.
Quando la finestra di command su cui sono state eseguite le
operazioni risulta troppo piena e si vuole cancellarla, si digita
clc e si preme invio. La cancellazione non preclude lutilizzo
della funzione precedente (freccia in su).
Struttura di MATLAB
Le operazioni immesse nel command vengono immediatamente
eseguite da MATLAB, che fornisce il risultato premendo il tasto
INVIO al termine della operazione da eseguire: es.
>> 7/5 (INVIO)
ans=
1.400000
Oppure, nella stragrande maggioranza dei casi, abbiamo
bisogno di definire delle variabili che rimarranno in memoria in
MATLAB per tutta la sessione di lavoro poich vengono da
questo immagazzinate in una memoria temporanea: es.
>> A=7.5
Da questo momento in poi ad A sar associato il valore 7.5.
Quindi se digitiamo
>> A*2
ans=
15
Struttura di MATLAB
Qualora digitassimo:
>> A=6
ans=
6.000000
dora in poi ad A sar associato il valore 6 e verr riscritto sul
valore precedente.
ATTENZIONE:
1.
MATLAB distingue tra lettere maiuscole e lettere
minuscole, per cui se avessimo per sbaglio digitato prima
>> a*2
??? Undefined function or variable a
2.
Non si pu nominare una variabile come pi, cui
associato il numero 3.1416
Struttura di MATLAB
Qualora nel command si voglia effettuare una operazione senza
che MATLAB ne stampi a video il risultato bisogna porre alla fine
della riga un punto e virgola ;. Ovviamente questo ha senso solo
se sto lavorando con variabili definite, altrimenti rende inutile
loperazione. Es. se digito:
>> 1+2;
>>
MATLAB ha calcolato 1+2 ma siccome non coinvolta nessuna
variabile non abbiamo visto il risultato delloperazione e non
successo nulla, non possiamo usare il risultato in quanto ad esso
non associata alcuna variabile utilizzabile nelle righe successive.
Se invece digito:
>>r=3+4;
>>r*2
ans=
14
e qui ho utilizzato (ma non stampato a video) il risultato di 3+4.
Struttura di MATLAB
Qualora il testo da inserire risultasse troppo lungo per essere
visualizzato su una riga, possibile scrivere un testo su pi righe
utilizzando uno spazio e i tre punti sulla riga su cui poi si va a
capo. Quindi scrivere:
>> r=3+4/2-7+9
r=
7
lo stesso di scrivere
>> r=3+4/2
-7+9
r=
7
Volendo che MATLAB stampi a video una stringa di lettere (delle
parole) e non numeri, ad es. la parola ciao, basta racchiudere la
stessa tra apostrofi . Es:
>> ciao
ans=
ciao
Struttura di MATLAB
Volendo introdurre un testo che non sia invece considerato dal
programma lo si deve racchiudere tra %. Es.
>> 4+2 %ciao%
ans=
6
e il programma lo ignora. (Questa funzione risulter molto utile
nelledit.)
Edit
Lopportunit di lavorare sulledit risiede nella possibilit di
salvare quanto scritto su un file di estensione .m,
.m che poi in
qualsiasi altro momento pu essere recuperato e modificato. Tali
files vengono pertanto definiti M-files.
Quindi:
Per codici che coinvolgono un breve numero di operazioni si
pu agire direttamente sul command;
command
Per codici che vogliono essere salvati per poi essere
riutilizzati o per codici che consistono in parecchie operazioni
dobbiamo lavorare sulledit
Edit
Per quanto detto, 3 sono le operazioni possibili allapertura di
MATLAB:
Lavorare direttamente sulla finestra aperta (il command);
Aprire un nuovo file di edit digitando
File > New > M-file
che apre una nuova finestra di edit su cui possiamo lavorare
Aprire un file di edit precedentemente creato digitando
File > Open >
che va nella cartella work,
work la cartella destinata ad accogliere
tutti i personali m-files.
Edit
Una volta aperto il file di edit, possiamo su di esso digitare tutte
le operazioni che vedremo in seguito (manipolazione di matrici,
loop,).
Se vogliamo vedere il risultato delle operazioni, dobbiamo far
correre, girare il programma premendo nelledit, dopo aver
salvato il file:
Debug (o Tools) > Run
o pi semplicemente premendo il tasto F5. In questo modo
otterremo nel command i risultati delle operazioni della finestra
di edit, che non verr cos toccata dai risultati.
Possiamo durante la sessione passare sempre da edit a
command e viceversa: sulledit abbiamo il testo delle operazioni,
sul command il risultato.
Edit
Una volta scritto nelledit un codice completo e volendo salvarlo
per averlo a disposizione in futuro, possiamo digitare nelledit:
File > Save as
che va a salvare il file con estensione .m nella cartella work, dove
sar possibile riaprirlo in futuro digitando come detto File > Open
>
Il percorso o path nel quale MATLAB legge e salva i files pu
essere visto digitando nel command il comando path.
Tale percorso pu essere modificato inserendo o eliminando le
cartelle nelle quali MATLAB cerca le funzioni e i files digitando
File > Set Path
III.
Linguaggio matriciale
Come detto, il linguaggio matriciale costituisce il nucleo
essenziale della programmazione. Vediamo ora i comandi
principali che riguardano creazione e manipolazione delle
matrici.
Va tenuta a mente una cosa fondamentale: MATLAB lavora su
matrici e in tutte le operazioni in cui possibile utilizzarlo il
linguaggio matriciale, anzich codici con loop, if., risulta di
gran lunga il modo pi veloce ed efficiente di programmare.
Le matrici possono essere registrate:
Introducendo un elenco di numeri
Creando le matrici in M-files
Caricando i dati da files esterni
Facendo generare i dati da MATLAB
Linguaggio matriciale
Consideriamo linserimento manuale di dati nel command di
MATLAB; sono tre le indicazioni da seguire:
Gli elementi della matrice devono essere racchiusi tra
parentesi quadre []
Gli elementi di una stessa riga vanno separati da uno
spazio
Il passaggio da una riga allaltra avviene con il punto e
virgola
Quindi per registrare la matrice
1 2 -6
4 -4 5
che chiamiamo A va digitato nel command
A=[1 2 -6; 4 -4 5] e invio.
Linguaggio matriciale
Per ottenere un elemento della matrice, va indicata tra
parentesi tonde la posizione dello stesso nel modo
seguente:
m = A(2,2) e invio
ottenendo cos lelemento che occupa la posizione 2,2 nella
matrice A. Se commettessimo lerrore di digitare
n = A(2,6) e invio
avremmo un messaggio di errore, date le dimensioni della
nostra matrice.
Linguaggio matriciale
Il comportamento di MATLAB non invece lo stesso se si
immagazzina un nuovo numero in una posizione che, per le
dimensioni di partenza della matrice, non dovrebbe esistere.
Se infatti digitiamo:
A(2,4)=7 e invio
attribuiamo valore 7 allelemento di posizione (2,4), che non
esisterebbe date le dimensioni (2x3) della matrice.
MATLAB
allora allarga la matrice, inserendo lelemento 7 nella
posizione scelta e ponendo zeri nella colonna (o riga) che
stata aggiunta.
Linguaggio matriciale
Tra gli operatori matriciali, ruolo importante attribuito ai
due punti : , che indica
Tutta la riga o colonna
A(1,:) e invio
fornisce come output tutti gli elementi della prima riga
Tutte le colonne/righe da .. a
A(1 , 2:3) e invio
fornisce come output tutti gli elementi della prima riga e
delle colonne dalla seconda alla terza
Linguaggio matriciale
Un utilizzo altrettanto fondamentale quello di servire per
costituire una sequenza,
sequenza nel modo
start:step:stop
ossia viene creata in un vettore riga una sequenza di
numeri che iniziano dal numero start, vengono incrementati
del valore step e si fermano quando raggiungono lo stop.
Ad esempio
1:2:20 e invio
crea una sequenza di valori che partono da 1 e vengono
incrementati di 2 fino ad arrivare a 20: 1 3 5 19. Se non
indicato, il passo di default 1.
Concatenazione di matrici
Due matrici con ugual numero di righe possono essere
concatenate orizzontalmente, cio affiancate orizzontalmente
per formare una matrice unica. Definite A (2x3) e B (2x4),
possiamo definire C (2x7) come la matrice che otteniamo
affiancandole con le parentesi quadre e lo spazio. Quindi le
trattiamo come gli elementi di una matrice:
>> C=[A B];
Due matrici con ugual numero di colonne possono essere
concatenate verticalmente, cio affiancate verticalmente per
formare una matrice unica. Definite D (2x3) e F (4x3), possiamo
E (6x3) come la matrice che otteniamo affiancandole con le
parentesi quadre e il punto e virgola. Quindi scriviamo:
>> E=[D ; F];
Matrici fondamentali
Le tre matrici pi importanti per la programmazione sono le
matrici di zeri e di uno, ottenibili con i comandi:
zeros(i,j), che permette di creare una matrice di zeri con i
righe e j colonne
ones(i,j), che permette di creare una matrice di tutti uno con i
righe e j colonne
eye(i,j), che permette di creare una matrice di i righe e j
colonne con uno sulla diagonale principale e zero altrove
Matrici fondamentali
Se per esempio dobbiamo creare una matrice 3x4 con tutti 5,
possiamo applicare la moltiplicazione scalare ed usare il
comando precedente digitando:
>> M=5*ones(3,4);
Altri comandi
Altri comandi utilizzabili in ambito matriciale sono:
abs() => calcola il valore assoluto di un numero o la matrice
contenente i valori assoluti della matrice cui
applicato
fix() => tronca un numero allintero
round() => calcola larrotondamento per eccesso/difetto
max() e min()=> calcola di un vettore il max o min elemento; di
una matrice produce un vettore con il max o min degli elementi
per colonne
fliplr() => inverte lordine degli elementi di un vettore
Altri comandi
norm() => calcola la norma 2 di un vettore o matrice
eig() => calcola gli autovalori di una matrice quadrata
rank(), che calcola il rango di una matrice
trace(), che calcola la traccia di una matrice
cumprod(x) restituisce un vettore o una matrice con il prodotto
cumulato per colonna
cumsum(x) restituisce un vettore o una matrice con la somma
cumulata per colonna
La creazione di funzioni
Quando scriviamo nelledit di MATLAB noi digitiamo una serie di
operazioni che poi, alla riapertura del file, possono essere
riutilizzate.
La maggior utilit delledit risiede nella possibilit di creare
funzioni, allo stesso modo delle funzioni create da MATLAB
stesso e presenti nei vari toolbox.
Una funzione, come ad esempio i comandi relativi alla
manipolazione di matrici, consta di una serie di operazioni
racchiuse in un file .m che vengono effettuate su di un input
richiamando un comando che d poi un output numerico.
Le funzioni risiedono in files .m denominati con lo stesso nome
della funzione stessa es. mean.m
La creazione di funzioni
Ad es. la funzione sqrt(m) una funzione che richiede 1 input (la
matrice o il vettore) e fornisce 1 output
Caratterizzanti delle funzioni sono:
Il nome della funzione, che interno a MATLAB
Il numero di input
Il numero di output (se desiderati)
Limportante che una volta salvato il file contenente la funzione,
essa immediatamente e per sempre utilizzabile sia nel
command che nelledit, senza bisogno di caricare il file.
Ad esempio se creo e salvo in una directory di MATLAB una mia
funzione, potr dora in poi sempre usarla.
La creazione di funzioni
Le funzioni vengono dunque create in M-files, consistono in una
serie di operazioni e richiedono necessariamente argomenti di
entrata (ossia input) e se desiderati anche argomenti di uscita
(output).
La creazione di funzioni
quindi:
Il nome funzione il nome che noi attribuiamo alla funzione e
con la quale essa verr richiamata (es. mean), che dovr
coincidere con il nome del file
Gli input devono essere racchiusi tra parentesi tonde () e
devono essere separati da virgole; gli input sono locali, cio
non dipendono dal nome che avr poi in concreto la variabile
quando applicher la funzione!
Gli output devono essere racchiusi tra parentesi quadre [] e
devono essere separati da virgole
La creazione di funzioni
Qualora non fosse necessario indicare un output, la sintassi
function[]= nome funzione(input1, input2,..)
Qualora non venga assegnato nessun output non sar possibile
richiamare il risultato quando calcoliamo la funzione
Proviamo ad esempio a creare una funzione che chiamiamo
areacer che dato il raggio del cerchio me ne calcoli larea; quindi
Esiste un input: il raggio del cerchio
Posso o meno decidere che mi stampi semplicemente a
video il risultato del calcolo oppure posso ad esso associare
una variabile di output
La creazione di funzioni
Se vogliamo che la funzione dia un output (il valore numerico
dellarea) scriveremo:
function[area]=areacer(r)
altrimenti
function[]=areacer(r)
Il codice pi semplice da scrivere
1- function[area]=areacer(r)
2- area=pi*r^2;
Una volta salvato il file, denominato areacer.m, la funzione
areacer() dar come risultato il quadrato dellinput moltiplicato per
pi greco, ossia larea del cerchio con quellinput.
La creazione di funzioni
Se non inserisco variabili di output, non posso richiamare la
funzione attribuendole una funzione, altrimenti mi segna errore.
Ad es. se il mio codice :
1- function[]=areacer(r)
2- area=pi*r^2
in questo caso la variabile area locale, cio interna alla
funzione! Essa stampata a video in quanto al termine della
riga non compare il ; ma non indicata come variabile di
output, in quanto function[]. Quindi se io scrivessi nel
command, dopo aver salvato il file con la funzione,
>> y=areacer(3)
mi darebbe errore in quanto per definizione la funzione areacer
non ammette variabili output.
La creazione di funzioni
Quando io digito help seguito da il nome della funzione mi
compare, come detto in precedenza, una serie di indicazioni
circa luso della funzione stessa. Come detto queste righe
coincidono con le righe di commento che seguono
immediatamente la definizione della funzione racchiuse tra %.
Per cui se scrivevo:
1- function[]=areacer(r)
2- % serve per calcolare
3- % larea di un cerchio di raggio r
4- area=pi*r^;
salvando e digitando poi help areacer otterrei la stampa a video
delle righe tra %. Attenzione che ogni riga di commento deve
iniziare con la %.
La creazione di funzioni
Se abbiamo una funzione con pi di 1 output, ad es.
1- function[ac,aq]=areacerq(r)
2- % serve per calcolare
3- % larea di un cerchio di raggio r
4- % e larea di un quadrato di lato l=r
5- ac=pi*r^2;
6- aq=r^2;
quando nel command richiamo la funzione, avendo 2 output
devo scrivere
>> [a,b] = areacerq(5)
oppure se mi interessa solo il primo input posso scrivere solo
>> a = areacerq(5)
La creazione di funzioni
Proviamo ora a definire altre funzioni, per esempio in ambito
dellalgebra matriciale. Considerata una matrice che presenti
elementi solo sulla diagonale principale, il suo determinante per
il teorema di Laplace coincide con il prodotto degli elementi sulla
diagonale stessa. Per questo, avvalendoci dei comandi diag e
prod presenti nel toolbox matematico, possiamo definire una
funzione del tipo:
function[dd]=mydd(A)
di=diag(A);
dd=prod(di);
Quindi estraiamo la diagonale principale e moltiplichiamo gli
elementi del vettore di. La funzione non completamente
precisa: dovremmo verificare che la matrice sia quadrata e che
sia diagonale! Vedremo come questo sar possibile con il
comando if.
Importazione di dati
Nellambito dellutilizzo di qualsiasi software statistico una
necessit quella di importare dati esterni forniti dallutilizzatore
per analizzarli.
Se i dati sono contenuti in un file .txt separati da spazi vuoti
possibile caricarli in MATLAB attraverso il comando load,
load
utilizzandolo nel modo seguente:
load + percorso del file
e la matrice di dati viene salvata in MATLAB con il nome del file.
poi possibile ridenominarla come una qualsiasi matrice.
Se i dati sono contenuti in un file .m salvato nella directory work
di MATLAB basta semplicemente digitarne il nome sul command
di MATLAB che automaticamente lo legger
Possiamo quindi creare una matrice di dati in un file .m, salvarlo
nella directory work affinch questa matrice venga per sempre
associata da MATLAB alla variabile.
Esportazione di dati
Il comando save salva i dati in un file con estensione .mat nella
directory work utilizzandolo nel modo seguente:
save + nome del file + nome della variabile da salvare
Tale variabile pu essere ripresa con il comando load oppure
riaprendo il file dalla cartella work.
possibile in alternativa aprire un file, scrivergli sopra e poi
richiuderlo con una serie di comandi. Poniamo di voler porre la
nostra matrice P di 2 colonne in un file di percorso c:\outp.txt:
nomeint = fopen(file.txt, wt)
dove nomeint un nome interno che diamo noi (quindi poteva
esserci scritto al suo posto qualsiasi altra cosa), fopen il
comando di MATLAB e wt sta per to write, perch apriamo il
file per scrivergli sopra;
fprintf(nomeint, %g %g, P)
dove ogni %g fa salvare la colonna di P, P la nostra matrice
fclose(nomeint)
per chiudere il file aperto con nome interno nomeint.
Cicli
Molto spesso abbiamo bisogno nellambito della programmazione
di cicli basati su contatori; si tratta di meccanismi che permettono
di indicizzare alcune variabili in modo da creare operazioni per un
numero determinato di volte.
Ad esempio, poniamo di avere una matrice e di voler calcolare la
media di ogni riga, elevarle alla seconda e porle in un vettore. Ci
serve un modo per selezionare la prima riga, calcolare la media,
elevarla al quadrato e porre il risultato nel primo elemento del
vettore; selezionare la seconda riga, calcolare la media, elevarla
al quadrato e porre il risultato nel secondo elemento del vettore,
etc. Vediamo come fare.
Cicli: for
Il ciclo con il for sfrutta la seguente sintassi:
for i = start:step:stop;
. comandi che contengono i .
end;
Il contatore i e il suo nome non fisso, determinato
dallutilizzatore (poteva essere a,b,c,d). Quando il
programma gira succede questo:
1.
2.
Cicli: for
Vediamo in concreto il meccanismo scrivendo il codice di
prima. Prima di tutto creiamo un vettore di zeri con tante righe
quante quelle della matrice (m) che accoglier i quadrati delle
medie per riga. Poi scriviamo il ciclo:
3.
v=zeros(size(m,1),1)
for k=1:length(v);
v(k)=mean(m(k,:))^2
4.
end;
1.
2.
k va da 1 alla lunghezza di v
nel posto k-esimo la media
della riga k-esima ^2
Cicli: while
Il ciclo con il while usa la seguente sintassi:
p = start
while p <= stop;
. comandi che contengono p .
p= p+step
end;
il codice precedente sarebbe
1.
2.
3.
4.
5.
k=1;
While k<= length(v)
v(k)=mean(m(k,:))^2
k=k+1
End;
k va da 1
alla lunghezza di v
nel posto k-esimo la media
della riga k-esima ^2
k lo aumento di 1 alla volta
Cicli
I cicli for sono generalmente pi efficienti dei cicli while, in
termini di velocit di calcolo.
Entrambi i tipi di cicli (for e while) possono essere bloccati
allinterno con il comando break. Questo comando risulta
particolarmente utile utilizzandolo con if (v. dopo). La struttura
del ciclo sarebbe del tipo:
for / while
if
(se succede questo)
..
(continua il loop e calcola questo)
elseif
(se invece succede questaltro)
break (termina il ciclo)
end;
Cicli
I cicli for sono generalmente pi efficienti dei cicli while, in
termini di velocit di calcolo.
Entrambi i tipi di cicli (for e while) possono essere bloccati
allinterno con il comando break. Questo comando risulta
particolarmente utile utilizzandolo con if (v. dopo). La struttura
del ciclo sarebbe del tipo:
for / while
if
(se succede questo)
..
(continua il loop e calcola questo)
elseif
(se invece succede questaltro)
break (termina il ciclo)
end;
If statement
Il comando if valuta quando una certa condizione vera e in tal
caso esegue il comando. La struttura del comando :
if (se) (succede questo)
. (fai questo)
elseif (se invece) . (succede questaltro)
. (fai questo)
elseif (se invece) . (succede questaltro)
. (fai questo)
.
else (se non successo niente delle precedenti cose)
. (fai questo)
end
If statement
I comandi if ed end (che termina lif) devono necessariamente
esserci, elseif ed else possono o meno esserci.
Facciamo un esempio. Possiamo scrivere un codice che mi dia
come output la parola quadrata se una matrice nxn, la parola
rettangolare se la matrice rxc, con r diverso da c.
Riprendendo la struttura di prima e considerando che una
matrice o quadrata o rettangolare (per cui posso usare else)
la struttura (non il codice!) la seguente:
if n righe di A = n colonne di A
stampa a video quadrata
else
stampa a video rettangolare
end
If statement
Associando al codice una funzione che chiamo cm (da check
matrix) potrebbe essere
function[] = cm(A);
if size(A,1) == size(A,2);
quadrata
else;
rettangolare
end
Relazioni logiche
Nelluso di if risultano di fondamentale utilizzo i comandi che
permettono di stabilire relazioni logiche (maggiore di, minore di
e eguale a). Loutput di questi comandi sempre costituito da
numeri, vettori o matrici logiche, ossia composti da zeri ed uno:
Lo zero compare quando la relazione non rispettata
Luno compare se la relazione rispettata.
I simboli da utilizzare sono:
==
uguale
~=
diverso
<
minore
>
maggiore
<=
minore o uguale
>
maggiore o uguale
Relazioni logiche
Cos se scriviamo
>> 5 > 3
la risposta 1,
>> 4 ~= 2
la risposta 1, etc.
Diversi sono invece i connettivi logici, ossia operatori che
collegano due espressioni, che sono:
and (e anche)
&
or
(oppure)
not (non)
Relazioni logiche
Nellambito delle relazioni logiche e dellalgebra delle matrici,
due comandi risultano molto utilizzati:
Il comando find(..), applicato ad una matrice/vettore, fornisce
la posizione degli elementi della matrice/vettore che
soddisfano la condizione tra parentesi. Ad es.:
>> B = randn(10,4);
>> v = find(B>0.3);
v il vettore contenente la posizione (quindi non un vettore
logico!!) degli elementi >0.3. se applicato a matrici gli indici
scorrono in verticale, nel senso che il numero 2 associato
allelemento a2,1. Se non indicata alcuna relazione logica
ma solo la matrice, fornisce la posizione degli elementi
diversi da zero.
Relazioni logiche
Il comando any(..), applicato ad un vettore, fornisce 1 se
qualche (almeno un) elemento del vettore diverso da zero,
e quindi fornisce zero solo se tutti gli elementi del vettore
sono nulli. Applicato ad una matrice fornisce un vettore con
tanti elementi quanti i vettori colonna della matrice, con 1 se
la colonna ha almeno un elemento diverso da zero e 0 se ha
tutti elementi diversi da zero. Specificando any(matrice,k) la
funzione lavora solo sulla k-esima riga.
Relazioni logiche
Lutilit di questi operatori grande nellambito matriciale e
con lif. Ad esempio se ci stiamo chiedendo se gli elementi
di una matrice A siano o meno maggiori di 0.5, digitando
>> A>0.5
otteniamo una matrice logica di zeri ed uno, in cui l1
associato a elementi > di 0.5. Se volessimo da una
matrice ottenere solo gli elementi > di 0.5 basta fare
>> A(A>0.5)
In tal modo prima otteniamo la matrice logica, poi
selezioniamo di A solo gli elementi cui associato 1.
Otteniamo cos un vettore con tutti e soli gli elementi che
rispettano la condizione.
Relazioni logiche
Un altro esempio. Poniamo di voler considerare di una
matrice B
0.03
0.5
0.02
0.45
0.05
0.23
0.01
0.58
0.07
0.25
0.29
0.15
Relazioni logiche
Il primo codice brevissimo:
function[j]=mc(a);
b=a(a>0.2 & a<0.3);
j=length(b);
vengono selezionati gli elementi della matrice che siano
maggiori di 0.2 e anche minori di 0.3 (quindi compresi tra 0.2 e
0.3), e poi si estraggono da A i corrispondenti elementi, che
vengono posti in un vettore b. Dopodich ne calcolo la
lunghezza, che coincide con il numero di elementi che
soddisfano la condizione.
Un codice con loop e if sarebbe il seguente, ma rispetto al primo
molto pi lungo e quindi inefficace:
Relazioni logiche
function[b]=mc2(A);
b=0;
for i=1:size(A,1);
for j=1:size(A,2)
if A(i,j)>0.2 & A(i,j)<0.3;
b=b+1;
end
end
End
Un modo per valutare la velocit computazionale in termini di
tempo di una funzione scrivere nel command
tic , (funzione) , toc
Relazioni logiche
Provando a creare una matrice A=rand(100,200) e applicando
le due funzioni troverete che la prima funzione decisamente
pi veloce.
>> tic, mc(a), toc
ans =
2029
elapsed_time =
0.0500
>> tic, mc2(a), toc
ans =
2029
elapsed_time =
0.2200
Trimr
Gauss, tra le altre, fornisce una preziosissima funzione che risulta
di estrema utilit nellambito matriciale. Questa funzione,
chiamata trimr(x,t,b), considerata una matrice x, restituisce una
matrice ottenuta tagliando da x le prime t righe e le ultime b righe.
In MATLAB questa funzione non implementata, e costituisce
quindi un utile esercizio scriverne il codice tenendo in
considerazione che la funzione deve dare un messaggio di errore
qualora si stia trimmando troppo. Il codice potrebbe dunque
essere il seguente:
Trimr
function [y]= mytrim(x,a,b);
if (a>size(x,1) | b>size(x,1) | (a+b)>size(x,1));
y=' trim too much ';
else;
y=x((a+1):(size(x,1)-b),:);
end;
Leccesso di trim pu avvenire se a o b sono > del totale delle
righe di x, o se lo la loro somma. Notiamo luso di | tra le
singole condizioni e il comando x((a+1):(size(x,1)-b),:), che
seleziona tutte le righe di x da a+1 fino alla riga = n righe b.
Lag
Unaltra funzione utilissima nellambito dellanalisi delle serie
storiche la funzione presente in Gauss come lagn(x,k), che
ripropone in linguaggio di programmazione loperatore lag (L).
Se k positivo, loperatore restituisce una matrice della stessa
lunghezza (come righe) di x in cui la prima riga quella che
occupava il posto k+1 in x e le ultime k righe sono missing
values (ossia dati mancanti, indicati in Gauss con un punto).
Abbiamo cos tagliato le prime k osservazioni, spostando la
matrice x in alto di k righe.
Se k negativo, loperatore restituisce una matrice della stessa
lunghezza (come righe) di x in cui le prime k righe sono missing
values, la riga di posto k+1 coincide con la prima riga di x e
quindi le ultime k righe di x vengono perse.
Vediamone in concreto lutilit. Possiamo di voler stimare un
modello di regressione del tipo AR(2):
Lag
yt=a+b1yt-1+b2yt-2+e
Senza scendere nei particolari, diciamo che vogliamo capire
come i valori ritardati di 1 e 2 periodi influenzano la variabile al
tempo corrente. Ovviamente se abbiamo una serie storica di
t=100 osservazioni, di queste possiamo sfruttarne solo 98,
perch alpi partiamo dalla terza e la regrediamo sulla seconda
e sulla prima, la quarta su terza e seconda e cos via.
In MATLAB i missing values si indicano con NaN= not a
number.
Proviamo ora a scrivere questa funzione in MATLAB, con
lavvertenza di predisporre un messaggio di errore se stiamo
laggando troppo, e distinguere tra k>0 e k<0:
Trimr
function [y]= mylag(x,k);
if abs(k)>size(x,1);
y=' trim too much ';
elseif k>0;
y=[x((k+1):size(x,1),:) ; NaN*ones(k,size(x,2))];
elseif k<0;
y=[NaN*ones(abs(k),size(x,2)) ; x(1:(size(x,1) - abs(k)),:)];
end;
Notiamo che y ha sempre la stessa lunghezza di x, in quanto
concatenazione verticale tra un vettore lungo k e tante righe di
x quante il numero delle sue righe meno k. Attenzione che
Dove k <0 dobbiamo utilizzare abs(k)!!!!
Trimr e lag
Se, per calcolare gli stimatori della regressione o ad es. una
semplice matrice di covarianza, ho la necessit di creare una
matrice che raccolga i valori della variabile, i ritardi fino allordine
2 ma ovviamente non voglio lavorare con missing values, posso
combinare le due funzioni appena viste sul vettore x che
contiene la serie storica in questo modo:
posso formare una matrice con lag
y=[x mylag(x,-1) mylag(x,-2)]
e poi trimmare le prime 2 righe che sicuramente contengono
missing values, essendomi spostato in basso (k=-1 e -2):
z=mytrim(y,2,0)
z (1,1) sar il terzo valore della serie storica di x, z(1,2) il
secondo valore e z(1,3) il primo valore della serie storica!.
Trimr e lag
Possiamo estendere utilmente il meccanismo di generazione di
suddetta matrice con un loop for, il cui indicatore sar
ovviamente collegato allordine k dei ritardi che vogliamo
inserire. preferibile racchiudere il tutto in una funzione, i cui
input saranno: il vettore e il numero di ritardi. Loutput di detta
funzione sar costituito dalla matrice la cui prima colonna sar
costituita dai valori di x dal k-esimo fino allultimo.
La funzione che chiamiamo essr (estrazione serie storica
ritardata) pu essere scritta cos:
Trimr e lag
function [y]=essr(x,k);
if k<0;
y='errore, k non pu essere negativo';
elseif k> size(x,1);
y='errore, k non pu eccedere il numero di righe di x';
else;
y=[x zeros(size(x,1),k)];
creo a priori y
for i=1:k;
y(:,i+1)=mylag(x,-i);
end;
y=mytrim(y,k,0);
trimmo alla fine del loop altrimenti
end;
non coincidono le lunghezze dei
vettori!
La creazione di grafici
MATLAB molto completo anche per quello che riguarda la
creazione di grafici. Il comando per grafici in bidimensionale
plot:
plot
Se x un vettore, plot(x) lo stampa a video in ordinata (Y) il
valore degli elementi e in ascissa (X) lindice (1,2,3,..) della
loro posizione nel vettore.
Se x e y sono due vettori, plot(x,y) stampa a video in
ordinata (Y) il valore degli elementi di y e in ascissa (X) il
valore degli elementi di x.
Nel caso di grafici multipli, MATLAB usa di default colori diversi:
plot(x,y,x,z)
stampa sulla stessa finestra prima x e y poi x e z, con colori
diversi.
La creazione di grafici
Possiamo definire a piacere il tipo di linea in 3 caratteristiche:
plot(x,y,puntatore-stile-colore)
Quanto ai colori
c
m
y
r
g
b
w
k
cyano
magenta
giallo
rosso
verde
blu
bianco
nero
La creazione di grafici
Quanto ai puntatori abbiamo +,o,*,x
La creazione di grafici
Se invece vogliamo suddividere la finestra in pi celle sulle quali
vengono stampati diversi grafici, il comando appropriato
subplot(r,c,i). Questo comando suddivide la finestra in una
matrice rxc e di essa ne seleziona la cella i esima.
Ad es. possiamo creare una sequenza molto fitta di valori che
vada da 0 a 2 pigreco con incrementi di 0.1, tracciare sulla
prima finestra il coseno, sulla seconda il seno, sulla terza la
tangente e sulla quarta la cotangente usando puntatori, colori e
stili di linea diversi per ogni sottofinestra con i comandi appena
visti e il comando subplot. Possiamo addirittura creare una
funzione che chiamiamo mytrig, nel modo seguente:
NB: se non ricordo i comandi per le funzioni trigonometriche
posso digitare help, poi osservo e digito help matlab\elfun
La creazione di grafici
Creiamo prima di tutto la funzione nelledit:
function[]= mytrig(s)
co=cos(s);
se=sin(s);
t=tan(s);
ct=cot(s);
subplot(2,2,1)
plot(s,co,'y:+')
subplot(2,2,2)
plot(s,se,'b-*')
subplot(2,2,3)
plot(s,t,'k--x')
subplot(2,2,4)
plot(s,ct,'m:o')
La creazione di grafici
Dopodich andiamo nel command, creiamo la nostra sequenza
come vettore colonna e applichiamo la funzione:
>> k=0:0.1:2*pi;
>> mytrig(k)
Il programma gira ma fornisce anche un messaggio di errore.
Questo perch le funzioni tangente e cotangente hanno alcuni
punti in cui non possono essere calcolate!!!
Digitando alla fine della funzione
print dbmp16m fig.bmp
salvo la figura con il nome fig ed estensione .bmp (posso anche
porre .gif o .jpeg) nella cartella work.
La creazione di grafici
Altri comandi per caratterizzare il grafico sono:
axis([min xmax ymin ymax])
axis square
axis auto
rispettivamente per definire la lunghezza degli assi, renderla
uguale o lasciare quella automatica;
xlabel()
ylabel()
title()
rispettivamente per dare un nome allasse x, allasse y o al titolo
del grafico;
La creazione di grafici
La funzione
text(x,y,)
inserisce invece un testo nel grafico che inizia in corrispondenza
della coordinata (x,y)
Polinomi, integrazione e
ottimizzazione
Polinomi
Nellambito dellalgebra dei polinomi, alcune funzioni possono
risultare di una certa utilit.
La funzione roots funziona roots(v), dove v un vettore con i
coefficienti della incognita, dal termine di pi alto grado al
termine noto, ed estrae le radici del polinomio. Ad esempio se
abbiamo il polinomio x5-x4-7x3+7x2+12x-12 e vogliamo trovarne
le radici, ossia i valori di x che la azzerano, dobbiamo scrivere
roots([1
-1
-7
12 -12])
Polinomi
La funzione polyval funziona polyval(v,k), dove v un vettore con
i coefficienti della incognita, dal termine di pi alto grado al
termine noto, k un numero e calcola il polinomio in
corrispondenza di k (ossia sostituisce x=k). Ad esempio se
abbiamo il polinomio -3x4-2x3+6x2+2x-1 e vogliamo calcolarlo in
x=-1, dobbiamo scrivere
polyval([-3 -2 6 2 -1],-1)
e MATLAB restituisce 2.
Polinomi
La moltiplicazione tra due polinomi, indicati sempre attraverso i
vettori contenenti i coefficienti, avviene con il comando conv;
se moltiplico x3-2 per x2+3x-5 devo fare:
x=[1 0 0 -2];
y=[1 3 -5];
z=conv(x,y);
e MATLAB restituisce 1 3 -5 -2 -6 10, ossia il
polinomio (ovviamente di 5 grado) x5+3x4-5x3-2x2+6x+10.
La divisione tra due polinomi, indicati sempre attraverso i
vettori contenenti i coefficienti, avviene con il comando
deconv,che funziona come conv e d anche un vettore con
leventuale resto.
Integrazione numerica
Per quanto riguarda lintegrazione numerica in 2 variabili, il
valore di un integrale definito del tipo
b
f ( x)dx
a
3 x
e
cos(2 x )dx
0
Integrazione numerica
definiamo la funzione e la calcoliamo nel modo seguente
>> f=inline(exp(-3*x).*cos(2*x));
>> quad8(f,0,);
e MATLAB calcola 0.2308. Notiamo che:
La funzione inline riconosce x come variabile e vuole il
suo argomento (la funzione) tra ;
La funzione quad8 funziona quad8(funzione, estremo inf,
estremo sup)
Matlab integra fino ad un massimo di 3 variabili (funzione
dblquad; per pi di 3 variabili dobbiamo ricorrere alla
simulazione numerica (Monte Carlo).
oppure
min f(x)
x
Ottimizzazione vincolata
Per risolvere un problema di ottimizzazione vincolata di
1grado,
1grado ossia di programmazione lineare del tipo
max
sub
c' x
min c' x
sub Ax b
Ax b
oppure
Ax = b
Ax = b
ix s
ixs
Ottimizzazione vincolata
Linprog funziona:
X=LINPROG(c,A,b,Aeq,Beq,LB,UB,X0,OPTIONS), dove:
c il vettore dei pesi delle variabili
A la matrice in Ax<b
b il vettore in Ax<b
Aeq la matrice in Ax=b
beq il vettore in Ax<b
lb lestremo inferiore dellintervallo di x
ub lestremo superiore dellintervallo di x
X0 il punto di partenza dellalgoritmo
options => v. optimset functions
Ottimizzazione vincolata
Dovendo risolvere il problema
min 2 x 1 3x2
sub x 1 + x 2 3
x1 0
Ottimizzazione vincolata
Per risolvere un problema di ottimizzazione vincolata di
2grado,
2grado ossia di programmazione quadratica del tipo
max
sub
1
1
min
x ' Hx + c' x
x ' Hx + c' x
2
2
Ax b
oppure sub Ax b
Ax = b
Ax = b
ixs
ixs
Ottimizzazione vincolata
quadprog funziona:
x=quadprog(H,f,A,b,Aeq,beq,LB,UB) dove:
H la matrice dei pesi nella forma quadratica
c il vettore dei pesi delle variabili di 1 grado
A la matrice in Ax<b
b il vettore in Ax<b
Aeq la matrice in Ax=b
beq il vettore in Ax<b
lb lestremo inferiore dellintervallo di x
ub lestremo superiore dellintervallo di x
Ottimizzazione vincolata
Dovendo risolvere il problema
min
sub
x12 3x 22 + 3x1 x2
x1 0
x2 0
x 1 + 2 x2 = 4
ottimizzazione:
Ottimizzazione vincolata
>> H = [2 0 ; 0 6];
>> c = [3 -1];
>> Aeq=[1 2];
>> beq=4;
>> lb=[0 0];
>> x = quadprog(H,c,[],[], Aeq,beq,lb)
Il risultato
x=
0.2857
1.3571
Fine introduzione
Grazie