Uso dei cicli n Un uso dei cicli

  • Slides: 20
Download presentation
Uso dei cicli n Un uso dei cicli può essere quello di creare una

Uso dei cicli n Un uso dei cicli può essere quello di creare una serie storica per cui yt=c+tyt-1+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;

Uso dei cicli n n Va ricordato che nel ciclo il “passo” del contatore

Uso dei cicli n n 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 6 x 6 possiamo identificare 6 sottomatrici 2 x 2 sulle quali costruire un loop. Poniamo di aver creato con il comando rand una matrice 6 x 6 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:

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:

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; n n 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:

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

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; n 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) è:

Uso dei cicli i=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;

Uso dei cicli i=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;

Uso dei cicli n n n Quindi inizia il ciclo delle righe, si esaurisce

Uso dei cicli n n n 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 2 x 2 diventi la prima nella nuova matrice e così via. Il grado di complessità risiede solamente nel modificare gli elementi presi in considerazione:

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

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; 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!

Cicli n n I cicli for sono generalmente più efficienti dei cicli while, in

Cicli n n 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 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;

If statement n Il comando if valuta quando una certa condizione è vera e

If statement n 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) …. else (se non è successo niente delle precedenti cose) …. (fai questo) end

If statement n n I comandi if ed end (che termina l’if) devono necessariamente

If statement n n 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” else stampa a video “rettangolare” end

If statement n Associando al codice una funzione chiamo cm (da check matrix) potrebbe

If statement n Associando al codice una funzione chiamo cm (da check matrix) potrebbe essere function[] = cm(A); if size(A, 1) == size(A, 2); ‘quadrata’ else; ‘rettangolare’ end

Relazioni logiche n n Nell’uso di if risultano di fondamentale utilizzo i comandi che

Relazioni logiche n n 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

Relazioni logiche n n Così se scriviamo >> 5 > 3 la risposta è

Relazioni logiche n n 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 n Nell’ambito delle relazioni logiche e dell’algebra delle matrici, due comandi risultano

Relazioni logiche n 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 a 2, 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

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 n L’utilità di questi operatori è grande nell’ambito matriciale e con l’if.

Relazioni logiche n 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. 5 otteniamo 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.

Relazioni logiche n Un altro esempio. Poniamo di voler considerare di una matrice B

Relazioni logiche n 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 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.

Relazioni logiche n Il primo codice è brevissimo: function[j]=mc(a); b=a(a>0. 2 & a<0. 3);

Relazioni logiche n Il primo codice è brevissimo: function[j]=mc(a); b=a(a>0. 2 & a<0. 3); j=length(b); n 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]=mc 2(A); b=0; for i=1: size(A, 1); for j=1: size(A, 2) if

Relazioni logiche function[b]=mc 2(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 n Un modo per valutare la velocità computazionale in termini di tempo di una funzione è scrivere nel command tic , (funzione) , toc

Relazioni logiche n Provando a creare una matrice A=rand(100, 200) e applicando le due

Relazioni logiche n 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, mc 2(a), toc ans = 2029 elapsed_time = 0. 2200