Uso dei cicli

20
Uso dei cicli Un uso dei cicli può essere quello di creare una serie storica per cui y t =c+ty =c+ty t-1 t-1 +e +e dove poniamo c e t scalari ed e~N(0,1). Realizzare questo processo con un ciclo è immediato e ovviamente richiede di predefinire c e theta, la numerosità n e il primo valore, dal quale far partire la serie. n=30; v=zeros(n,1); v(1)=2.1; theta=0.6; for i=2:n; v(i)=v(i-1)*theta+randn(1,1); end;

description

Uso dei cicli. - PowerPoint PPT Presentation

Transcript of Uso dei cicli

Page 1: Uso dei cicli

Uso dei cicli

Un uso dei cicli può essere quello di creare una serie storica per cui

yytt=c+ty=c+tyt-1t-1+e+e

dove poniamo c e t scalari ed e~N(0,1). Realizzare questo processo con un ciclo è immediato e ovviamente richiede di predefinire c e theta, la numerosità n e il primo valore, dal quale far partire la serie.

n=30;v=zeros(n,1);v(1)=2.1;theta=0.6;for i=2:n;

v(i)=v(i-1)*theta+randn(1,1);end;

Page 2: Uso dei cicli

Uso dei cicli

Va ricordato che nel ciclo il “passo” del contatore non è necessariamente 1 e inoltre può non essere un numero fisso ma collegato ad una variabile; poniamo ad esempio che abbiamo una matrice quadrata di ordine nxm costruita a blocchi, ossia a blocchi quadrati nxn sui quali vogliamo. Pertanto in una matrice 6x6 possiamo identificare 6 sottomatrici 2x2 sulle quali costruire un loop. Poniamo di aver creato con il comando rand una matrice 6x6 di numeri casuali; considerata ora una matrice della stessa dimensione, vogliamo che essa presenti solo i blocchi situati sulla diagonale. Per ottenere questo risultato dobbiamo, come al solito, predeterminare la dimensione della matrice che accoglierà i blocchi sulla diagonale e poi impostare il passo del loop.

Il codice, posto m=3 e n=2 può essere il seguente:

Page 3: Uso dei cicli

Uso dei cicli

n=2;m=3;r=rand((m*n),(m*n));d=zeros((m*n),(m*n));for i=1:n:(m*n);

d(i:i+n-1,i:i+n-1)=r(i:i+n-1,i:i+n-1);end;

Notiamo che la matrice d ha uguali dimensioni di r, e che il passo di i è determinato da n, in quanto devo saltare di n in n per poi considerare le sottomatrici nxn.

Proviamo ora in modo analogo a costruire un codice che trasferisca tutti i blocchi usando un doppio loop:

Page 4: Uso dei cicli

Uso dei cicli

n=2;m=3;c=rand((m*n),(m*n));z=zeros((m*n),(m*n));for i=1:n:(m*n);

for k=1:n:(n*m); z(i:i+n-1,k:k+n-1)=c(i:i+n-1,k:k+n-1) end; end;

Nel caso di doppio loop il programma esegue prima il loop interno e finito il ciclo aggiorna il loop esterno e quindi riinizia con il loop interno. Questo significa che l’ordine con il quale MATLAB attribuisce i valori a i (contatore che agisce sulle righe) e k (contatore che agisce sulle colonne) è:

Page 5: Uso dei cicli

Uso dei ciclii=1;k=1;

i=1;k=3=1+n;

i=1;k=5=1+n+n;

i=3=1+n;k=1;

i=3=1+n;k=3=1+n;

i=3=1+n;k=5=1+n+n;

i=5=1+n+n;k=1;

i=5=1+n+n;k=3=1+n;

i=5=1+n+n;k=5=1+n+n;

Page 6: Uso dei cicli

Uso dei cicli

Quindi inizia il ciclo delle righe, si esaurisce il ciclo delle colonne, si aggiorna il ciclo delle righe, …

Supponiamo ora di volerci cimentare in un loop più complesso: presa una matrice casuale quadrata di ordine n*m, poniamo di voler trasportare su di un’altra matrice i blocchi della prima presi in senso antiorario, e quindi vogliamo che l’ultima sottomatrice 2x2 diventi la prima nella nuova matrice e così via.

Il grado di complessità risiede solamente nel modificare gli elementi presi in considerazione:

Page 7: Uso dei cicli

Uso dei cicli

n=2;m=3;t=rand((m*n),(m*n));g=zeros((m*n),(m*n));for i=1:n:(m*n);

for k=1:n:(n*m); g(i:i+n-1,k:k+n-1)=t((m*n)-i:(m*n)-i+1,(m*n)-k:(m*n)-

k+1);end;

end;

A differenza del loop precedente ora gli indici degli elementi presi delle due matrici sono differenti! Ovviamente consideriamo sempre sottomatrici quadrate, ma a sx partiamo dall’ultima sottomatrice mentre a dx partiamo dalla prima!

Page 8: Uso dei cicli

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 all’interno 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 quest’altro)break (termina il ciclo)

end;

Page 9: Uso dei cicli

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 quest’altro)…. (fai questo)elseif (se invece) …. (succede quest’altro)…. (fai questo)….else (se non è successo niente delle precedenti cose)…. (fai questo)end

Page 10: Uso dei cicli

If statement

I comandi if ed end (che termina l’if) 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”elsestampa a video “rettangolare”end

Page 11: Uso dei cicli

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

Page 12: Uso dei cicli

Relazioni logiche

Nell’uso di if risultano di fondamentale utilizzo i comandi che permettono di stabilire relazioni logiche (maggiore di, minore di e eguale a). L’output 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 L’uno compare se la relazione è rispettata.

I simboli da utilizzare sono:== uguale~= diverso< minore> maggiore<= minore o uguale> maggiore o uguale

Page 13: Uso dei cicli

Relazioni logiche

Così se scriviamo>> 5 > 3la risposta è 1,>> 4 ~= 2la risposta è 1, etc.

Diversi sono invece i connettivi logici, ossia operatori che collegano due espressioni, che sono:

and (e anche) &

or (oppure) |

not (non) ~

Page 14: Uso dei cicli

Relazioni logiche

Nell’ambito delle relazioni logiche e dell’algebra 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 all’elemento a2,1. Se non è indicata alcuna relazione logica ma solo la matrice, fornisce la posizione degli elementi diversi da zero.

Page 15: Uso dei cicli

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.

Page 16: Uso dei cicli

Relazioni logiche

L’utilità di questi operatori è grande nell’ambito matriciale e con l’if. Ad esempio se ci stiamo chiedendo se gli elementi di una matrice A siano o meno maggiori di 0.5, digitando>> A>0.5otteniamo una matrice logica di zeri ed uno, in cui l’1 è 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.

Page 17: Uso dei cicli

Relazioni logiche

Un altro esempio. Poniamo di voler considerare di una matrice B

0.03 0.05 0.070.5 0.23 0.250.02 0.01 0.290.45 0.58 0.15

e di chiedere al programma di stampare a video quanti elementi sono compresi tra 0.2 e 0.3. Possiamo vedere il risultato confrontando due codici: uno che utilizza solo i connettivi logici, un altro che usa anche i loop.

Page 18: Uso dei cicli

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:

Page 19: Uso dei cicli

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 endEnd

Un modo per valutare la velocità computazionale in termini di tempo di una funzione è scrivere nel command

tic , (funzione) , toc

Page 20: Uso dei cicli

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), tocans =

2029elapsed_time =0.0500

>> tic, mc2(a), tocans =2029elapsed_time = 0.2200