Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
vuoi
o PayPal
tutte le volte che vuoi
Nota: a volte Matlab vi sottolinea questi operatori dicendovi di utilizzare && e ||. Vanno bene
entrambi i metodi.
Esempi comuni
Esistono vari blocchi di istruzioni standard o procedure che è giusto sapere per risolvere
problemi più complicati.
- Scambio:
è un operazione basilare ma non banale della programmazione: consiste nello scambiare i
valori di due variabili o di due caselle di un vettore o di una matrice. Per farlo è necessario
usare una terza variabile chiamata comunemente tmp (abbreviazione di temporanea, ma può
essere chiamata con qualsiasi nome) che memorizzerà temporaneamente il valore di una
delle due variabili/caselle. Vediamo perché:
a=5; Il programma a sinistra è sbagliato, poiché una volta a=5;
b=11; eseguito entrambe le variabili varranno 11, e il b=11;
a=b; valore 5 andrà perduto. tmp=a;
b=a; Cosa che non succede nel programma a destra; in a=b;
questo caso il valore 5 viene salvato nella variabile b=tmp;
tmp, quindi a prende il valore di b e infine tmp
restituisce il valore giusto a b.
- Scorrimento di un vettore: 13
Uno degli utilizzi principale del ciclo for sta nello scorrere un vettore. Infatti definito un vettore
V di lunghezza n, possiamo compiere moltissime operazioni su di esso mediante un ciclo for
con i = 1:n. Possiamo quindi richiamare una alla volta tutte le caselle del vettore scrivendo
V(i) a seconda del giro del ciclo. Sapendo questo possiamo svolgere tutte le operazioni
semplici sul vettore come la somma e il prodotto di tutti i suoi elementi.
%Prodotto degli elementi di un vettore
n=10;
V=rand(1,n)*10;
prodotto=1; %importante!
for i=1:n
prodotto=prodotto*V(i);
end
disp(‘Il prodotto degli elementi del vettore è:’);
disp(prodotto);
A volte può tornare utile scorrere un vettore all’incontrario, ovvero dall’ultima casella fino alla
prima. In questo caso esistono due metodi, ognuno dei quali modifica solo il ciclo for:
1) Considerare invece di V(i) la casella V(n-i).
2) Considerare sempre la casella V(i) però modificare il valore di i i = 10 : -1 : 1 (fa girare
il ciclo al contrario).
- Scorrimento di una matrice:
Analogamente, è possibile scorrere una matrice usando 2 cicli for concatenati. Data quindi la
nostra matrice M n m…
x
%Prodotto degli elementi di una matrice
n=5;
m=8;
M= rand(n,m)*10;
prodotto=1;
for i=1:n
for j=1:m
prodotto=prodotto*M(i,j);
end
end
disp(‘Il prodotto degli elementi della matrice è:’);
disp(prodotto);
In questo caso, il programma scorre la matrice per righe (scorre prima tutte le caselle della
prima riga e poi passa alla riga sottostante). In alcuni casi potrebbe essere necessario
scorrere la matrice per colonne (prima tutte le caselle della prima colonna e poi passa alla
colonna a destra). Per far ciò basta invertire gli indici con cui si richiama la casella della
matrice, ovvero invece di M(i,j) dobbiamo scrivere M(j,i). Un altro modo è anche quello di
invertire i cicli.
- Scorrimento di un vettore parte 2
Per alcune operazioni più complicate come l’ordinamento in ordine crescente di un vettore
può essere necessario l’utilizzo di due cicli for. Però delle volte, come in questo esercizio,
l’indice del secondo for non deve per forza iniziare da 1:
%Ordinare in ordine crescente gli elementi di un vettore
n=10;
V=fix(rand(1,n)*11);
for i=1:n 14
for j=i+1:n
if V(i) > V(j)
tmp=v(i);
v(i)=v(j);
v(j)=tmp;
end
end
end
Per ordinare in ordine crescente il vettore si cerca prima qual’è il valore più piccolo all’interno
del vettore e si scambia con quello contenuto nella prima casella. Fatto questo si cerca il
secondo valore e lo si scambia con quello della seconda casella e così via. Quindi l’indice j si
occuperà di scorrere ogni volta le caselle del vettore per cercare quella che ha il valore più
piccolo da inserire nella casella V(i). Il motivo per cui j non parte da 1 ma da i+1 è che non è
necessario: il primo giro j controlla tutte le caselle tranne la prima, poiché non avrebbe senso
confrontare la stessa casella (spiegato il motivo del +1). Nel secondo giro la prima casella
conterrà già il valore più piccolo e quindi j non ha senso che la confronti con la seconda
casella individuata da V(i) (visto che al secondo giro i varrà 2), quindi j dovrà partire sempre
dalla casella a destra di quella designata da V(i) (con giro in questi casi intendevo i giri del
ciclo for più esterno, quelli scanditi dalla i). L’ordinamento decrescente del vettore è simile ma
vanno apportate delle piccole modifiche:
%Ordinare in ordine decrescente gli elementi di un vettore
n=10;
V=fix(rand(1,n)*11);
for i=0:n-1
for j=i+1:n-1
if V(n-i) > V(n-j)
tmp=V(n-i);
V(n-i)=V(n-j);
V(n-j)=tmp;
end
end
end
Ovviamente questi non sono gli unici modi per ordinare il vettore, ma sono fra i più efficienti.
In matlab il modo migliore per ordinare un vettore in senso crescente è l’utilizzo del comando
sort(V).
Per ora abbiamo visto alcuni modi con cui si scorrono i vettori e ognuno sfruttava in modo
diverso il o i cicli for. Se ci troviamo di fronte ad un problema che ci vuole far modificare o
lavorare con un vettore o una matrice, è ovvio che dovremmo usare uno o più cicli for. Per
capire però come definire i range degli indici, ovvero i valori iniziali e finali e come utilizzarli
per richiamare le caselle (M(i,j) ?, M(j,i) ?,V(i+1) ?,…) il trucco sta nel cercare di trovare cosa
hanno in comune le caselle del vettore o della matrice con determinati indici, oppure in altri
casi cosa hanno in comune le caselle interessate dal problema. Chiariamo meglio questi
problemi con questi due esempi:
Es. 1: Rovesciamento di un vettore: il valore della prima casella deve scambiarsi
con quello dell’ultima, il secondo con il penultimo,ecc..
1) inizio scrivendo il clear, scelgo la lunghezza del vettore e l’associo ad una variabile n e
definendo il vettore V.
clear
n=10;
V=fix(rand(1,n)*11);
2)Cerco di capire cosa hanno in comune la prima e l’ultima casella, la seconda e la 15
penultima… La prima casella è la 1 e l’ultima è la 10, ovvero n; la seconda casella è la 2 e
l’ultima è la 9, ovvero n-1. Se introduciamo l’indice i dell’inevitabile ciclo for che ci servirà a
lavorare con questo vettore noto che nel primo giro la prima casella è V(i) e l’ultima è V(n) o
V(n-i+1). Seguendo questa logica noto che la seconda casella al secondo giro sarà sempre
V(i) e la penultima sempre V(n-i+1). Se provo con tutte le altre caselle questo metodo
funziona ancora e quindi è approvato.
Inserisco quindi all’interno del mio ciclo for il blocco istruzioni dello scambio sfruttando le
proprietà delle caselle trovate.
clear
n=10;
V=fix(rand(1,n)*11);
for i=1:n
tmp=V(i);
V(i)=V(n-i+1);
V(n-i+1)=tmp;
end
3) Provo a girare il programma una decina di volte e mi torna sempre. Mi accorgo però che
potrebbe essere reso più efficiente: non c’è bisogno di scorrere la i fino a n poiché già quando
arriva a 5, ovvero n/2, il vettore è invertito.
clear
n=10;
V=fix(rand(1,n)*11);
for i=1:n/2
tmp=V(i);
V(i)=V(n-i+1);
V(n-i+1)=tmp;
end
Es. 2: Rovesciamento di un vettore di lunghezza n scelta dall’utente: il valore della
prima casella deve scambiarsi con quello dell’ultima, il secondo con il
penultimo,ecc..
1) Posso riscrivere direttamente il programma usato prima con l’unica differenza che questa
volta n lo definisco grazie a input:
clear
n=input(‘inserire la lunghezza del vettore’);
V=fix(rand(1,n)*11);
for i=1:n/2
tmp=V(i);
V(i)=V(n-i+1);
V(n-i+1)=tmp;
end
2) Cerco di pensare a cosa potrebbe essere cambiato con il fatto che n non sia più 10 ma un
numero intero qualsiasi. Mi rendo conto che 10 è un numero pari e che forse il mio
programma potrebbe non funzionare con numeri dispari. Noto subito che per esempio n/2 di
un numero dispari non è un intero e che non esistono caselle non intere nei vettori (per
esempio la casella 2.5). Posso risolvere con il fix.
clear
n=input(‘inserire la lunghezza del vettore’);
V=fix(rand(1,n)*11);
for i=1:fix(n/2)
tmp=V(i);
V(i)=V(n-i+1);
V(n-i+1)=tmp; 16
end
3) Controllo se ci sono altri problemi: il fix approssimerà n/2 sempre all’intero più piccolo, di
conseguenza la casella centrale del vettore non verrà mai controllata. Ma a noi non ci
interessa poiché la casella centrale di un vettore dispari è la stessa dello stesso vettore ma
invertito.
Es.3: Creare una matrice identità:
1) La matrice identità è una matrice composta da 0 in tutte le caselle eccetto quelle della
diagonale che va dalla casella in alto a sinistra fino a quella in basso a destra, le quali hanno
come valore 1.
Possiamo quindi iniziare generando una matrice piena di 0:
clear
n=5;
M=zeros(n); % poiché le matrici identità devono essere per forza quadrate
2) Fatto ciò dobbiamo solo cambiare i valori della diagonale in 1. Dobbiamo quindi capire cosa
hanno in comune tutte le caselle della diagonale: esse sono la casella M(1,1), M(2,2), M(3,3),
M(4,4), ecc.. Semplicemente elencandole si può dedurre che la caratteristica di queste caselle
è il fatto di avere sempre lo stesso indice di riga e di colonna. Quindi possiamo scrivere un
ciclo for che:
clear
n=5;
M=zeros(n);
for i=1:n
M(i,i)=1;
end
3) Se invece avessimo voluto modificare i valori dell’altra diagonale avremmo dovuto
considerare le caselle
M(i,n-i+1) poiché le caselle interessate sarebbero state la M(1,10), M(2,9), M(3,8), ecc..
clear
n=5;
M=zeros(n);
for i=1:n
M(i,n-i+1)=1;
end
Es.4: Creare una matrice simmetrica rispetto alla prima diagonale (ovvero la stessa
della matrice identità):
1) Creiamo una matrice M di valori casuali interi n n:
x
Clear
n=5;
M=fix(rand(n)*11);
2) chiediamoci cosa vogliamo fare: dobbiamo copiare i valori della parte in alto a destra della
matrice nelle corrispondenti caselle simmetriche rispetto alla prima diagonale in basso a
sinistra. Quindi la casella M(2,1) dovrà assumere il valore della casella M(1,2), la casella
M(3,1) quello della M(1,3), ecc.. Notiamo quindi che basta invertire gli indici per trovare le
caselle simmetriche.
Clear
n=5;
M=fix(rand(n)*11); 17
for i=1:n
for j=1:n
<