Sei sulla pagina 1di 35

MATLAB: Strutture di controllo

Informatica B Prof. A. Morzenti

Tipo di dato logico


un tipo di dato che pu avere solo due valori
true (vero) 1
false (falso) 0

I valori di questo tipo possono essere generati


direttamente da due funzioni speciali (true e false)
dagli operatori relazionali
dagli operatori logici

I valori logici occupano un solo byte di memoria (i


numeri ne occupano 8)
>>whos a
Esempio:
Name
a

Size
1x1

Bytes
1

Class
logical

Attributes

a=true;
a un vettore 1x1 che occupa 1 byte e appartiene alla
classe tipo logico
2

Operatori relazionali
Gli operatori relazionali operano su tipi numerici o stringhe
Forma generale: a OP b
a,b possono essere espressioni aritmetiche, variabili,
stringhe (della stessa dimensione)
OP: ==, ~=, >, >=, <, <=

Esempi:
3<4
3==4
A<B

true (1)
false (0)
true (1)

Operatori relazionali possono essere usati per confrontare


vettori con vettori della stessa dimensione o con scalari
Nel secondo caso il risultato un vettore di booleani che
contiene i risultati dei confronti di ogni elemento del vettore
con lo scalare
3

Note
Non confondere == e =: esattamente come in C
== un operatore di confronto
= un operatore di assegnamento

La precisione finita pu far commettere errori con ==


e ~=
sin(0) == 0 -> 1
sin(pi) == 0 -> 0
eppure logicamente sono vere entrambe!!

Per i numeri piccoli conviene usare una soglia


abs( sin(pi) ) <= eps

Vettori e stringhe
Esempi:
[1 0; -2 1] < 0 d [0 0; 1 0] ([false false; true false])
[1 0; -2 1] >= [2 -1; 0 0] d [0 1; 0 1]

Si possono confrontare stringhe di lunghezza uguale


pippo==pluto d [1 0 0 0 1]

Operatori logici
Forma generale: a OP1 b oppure OP2 a
a,b possono essere variabili, costanti, espressioni da
valutare, scalari o vettori (dimensioni compatibili)
OP1: AND (&& o &), OR (|| o |), XOR (xor) e OP2: NOT (~)

Se a e b sono numerici verranno interpretati come


logici:
0 come false
tutti i numeri diversi da 0 come true
a

a AND b

a OR b

NOT a

a XOR b

false false

false

false

true

false

false true

false

true

true

true

true false

false

true

false

true

true true

true

true

false

false

&& vs & e || vs |
&& (||) funziona con gli scalari e valuta prima
loperando pi a sinistra. Se questo sufficiente per
decidere il valore di verit dellespressione non va
oltre
a && b: se a falso non valuta b
a || b: se a vero non valuta b

& (|) funziona con scalari e vettori e valuta tutti gli


operandi prima di valutare lespressione complessiva
Esempio: a/b>10
se b 0 non voglio eseguire la divisione
(b~=0)&&(a/b>10) la soluzione corretta: && controlla
prima b~=0 e se questo falso non valuta il secondo
termine
7

Ordine tra gli operatori

Unespressione viene valutata nel


seguente ordine:
operatori aritmetici
operatori relazionali da sinistra verso
destra
NOT (~)
AND (& e &&) da sinistra verso destra
OR (| e ||) e XOR da sinistra verso destra

Esempi
Hai tra 25 e 30 anni?
(eta>=25) & (eta<=30)

Con i vettori:
Voto = [ 12, 15, 8, 29, 23, 24, 27 ]
C = (Voto > 22) & (Voto < 25) -> C = [ 0 0 0 0 1 1 0 ]

Utile per contare quanti elementi soddisfano una


condizione
N_votiMedi = sum (Voto > 22 & Voto < 25)

Vettori logici e selezione (1)


Gli operatori relazionali possono essere usati per
generare direttamente un vettore logico (cio un vettore di
valori logici), che poi si pu usare a sua volta per
selezionare gli elementi di un vettore
espressioni vengono quindi usate come una sorta di filtro

Esempio: troviamo tutti gli elementi di un vettore x minori


del corrispondente elemento in un array y della stessa
dimensione di x
>> x = [6,3,9]; y = [14,2,9];
>> a=x<y
a=1 0 0
>> z=x(a)
z= 6
>>

pi concisamente

10

>> x = [6,3,9]; y = [14,2,9];


>> x(x<y)
ans = 6
>>

Vettori logici e selezione (2)


Altro modo di creare un array logico: confrontando con una
costante
Mediante un array logico possibile selezionare gli elementi
di a ai quali applicare una certa operazione. Esempio:
operazione di sqrt e anche operazione di assegnamento
>> a= [1 2 3; 4 5 6; 7 8 9];
>> b=a>5
b=0 0 0
0 0 1
poi
1 1 1
>> a(b)
ans =
7
versione linearizzata:
8
elementi ottenuti con
6
scansione di a da alto
a basso e da sinistra a
9
destra

>> sqrt(a(b))
ans = 2.6458
2.8284
2.4495
3.0000
>> a(b)=sqrt(a(b))
a = 1.0000 2.0000
4.0000 5.0000
2.6458 2.8284
>>
11

NB: i due vettori a sx e


a dx di = devono avere
uguale dimensione

3.0000
2.4495
3.0000

Vettori logici e selezione (3)


la scansione per selezionare gli elementi segue la forma
linearizzata della matrice (per colonne dallalto al basso e
considerando le colonne da sinistra a destra). Esempio:
>> a=[1 2 3;4 5 6;7 8 9]
a=
1 2 3
4 5 6
7 8 9
>> b=a'
b=
1 4 7
2 5 8
3 6 9
>> a(a>5)
ans =
7
8
6
9
>>

poi

12

>> b(b>5)
ans =
6
7
8
9
>> a(a>5)=b(b>5)
a=
1 2 3
4 5 8
6 7 9
>>

Find
ind = find(x) restituisce gli indici degli elementi non nulli
dellarray x. x pu essere unespressione logica. Esempio
a = [ 5 6 7 2 10 ]
find(a>5) -> ans = 2 3 5

NB: find restituisce gli indici e non i valori degli array mentre
usando i vettori logici come indici si ottengono i valori
Esempio: (NB: tutti i valori diversi da zero corrispondono a
true)
x = [5, -3, 0, 0, 8];y = [2, 4, 0, 5, 7];
v = y(x&y) -> v = [2 4 7]
ind = find(x&y) -> ind = [1 2 5]

i valori di y(k) per quei k tali


che x(k)&y(k), cio
cio x(k) e y(k)
sono entrambi non nulli
gli indici k tali che x(k)&y(k),

13

Funzioni logiche
Nome della
funzione

Elemento restituito

all(x)

un vettore riga, con lo stesso numero di colonne della matrice x, che contiene 1, se la
corrispondente colonna di x contiene tutti elementi non nulli, o 0 altrimenti;
NB: applicato a un vettore d un solo valore logico, 1 sse tutti gli elementi sono veri

any(x)

un vettore riga, con lo stesso numero di colonne della matrice x, che contiene 1, se la
corrispondente colonna di x contiene almeno un elemento non nullo, 0 altrimenti;
NB: applicato a un vettore d un solo valore logico, 0 sse tutti gli elementi sono falsi

isinf(x)

un array delle stesse dimensioni di x con 1 dove gli elementi di x sono inf, 0 altrove

isempty(x)

1 se x vuoto (cio uguale a []), 0 altrimenti

isnan(x)

un array delle stesse dimensioni di x con 1 dove gli elementi di x sono NaN, 0 altrove

finite(x)

un array delle stesse dimensioni di x, con 1 dove gli elementi di x sono finiti, 0 altrove

ischar(x)

1 se x di tipo char, 0 altrimenti

isnumeric(x)

1 se x di tipo double, 0 altrimenti

isreal(x)

1 se x ha solo elementi con parte immaginaria nulla, 0 altrimenti

- 14 -

Il costrutto if
if espressione1
istruzione 1-1
istruzione 1-2
..........
elseif espressione2
istruzione 2-1
istruzione 2-2
..........
.....
else
istruzione k-1
istruzione k-2
..........
end

I rami elseif e else non sono obbligatori!

Le istruzioni 1-1 e 1-2 vengono


eseguite solo se vale espressione 1
Le istruzioni 2-1 e 2-2 vengono
eseguite solo se vale espressione 2

Le istruzioni k-1 e k-2 vengono


eseguite solo se non vale nessuna
delle espressioni sopra indicate
15

Il costrutto switch
Listruzione condizionale switch consente una scrittura
alternativa ad if/elseif/else
Qualunque struttura switch pu essere tradotta in un
if/elseif/else equivalente
switch variabile (scalare o stringa)
case valore1
istruzioni caso 1
case valore2
istruzioni caso 2
...
otherwise
istruzioni per i restanti casi
end

16

Il ciclo while
while espressione
istruzioni da ripetere finch espressione vera
end
espressione deve essere inizializzata (avere un valore) prima
dellinizio del ciclo
Il valore di espressione deve cambiare nelle ripetizioni
Esempio: Calcoliamo gli interessi fino al raddoppio del capitale
value = 1000;
year = 0;
while value < 2000
value = value * 1.08
year = year + 1;
fprintf('%g years: $%g\n', year,value)
end
17

Il ciclo for
for indice = espressione
istruzioni

end
Esempio leggi 7 numeri e mettili in un vettore di nome number:
for n = 1:7
number(n) = input('enter value ');
end
Esempio - conto alla rovescia in secondi
time = input('how long? ');
for count = time:-1:1
pause(1);
fprintf('%g seconds left \n',count);
end
disp('done');
18

Il ciclo for
Il ciclo for usa un array per assegnare valori alla variabile di
conteggio
Questo array pu essere generato al volo con unespressione
del tipo init:delta:fin
Nel primo esempio del lucido precedente larray [1 2 3 4 5 6 7]

Larray pu anche essere inizializzato con altri meccanismi (si


vedano gli esempi nel lucido seguente)
Se larray una matrice alla variabile di conteggio vengono
assegnate in sequenza le sua colonne

19

Esempi
Inizializzazione dellindice del for a partire da una matrice
board = [ 1 1 1 ; 1 1 -1 ; 0 1 0 ];
1
for x = board
1
x
alla prima iterazione x e` il vettore colonna
0
end
Inizializzazione dellindice del for a partire da una stringa
for x = 'EGR106
disp(x) %alla prima iterazione x vale E
end

20

Vettorizzazione (1)
In molti casi possibile sostituire un for con luso di un opportuno
vettore. Esempio
%calcolo del quadrato degli interi tra 1 e 100
for ii=1:100
square(ii)=ii^2;

end
%frammento di codice equivalente: vettorizzazione
ii=1:100;
NB: bisogna usare la versione .^che opera elemento per elemento
square=ii.^2;

versione equivalente che fa uso della notazione dei sottoarray


n=1:100;
square(n)= n .^ 2;

La versione con il for pu essere fino a 15 volte pi lenta della versione


con la vettorizzazione!

21

Vettorizzazione (2)
Riprendiamo lesempio
b = a>5
sqrt(a(b))
a(b)=sqrt(a(b))

Esecuzione dello stesso calcolo con i cicli


[r, c]=size(a); %usata in questo modo size d righe e colonne di una matrice
for h = 1:r
for k = 1:c
if a(h, k)>5
a(h, k)=sqrt(a(h, k));
end
end
end

Anche qui il codice che sfrutta la vettorizzazione molto


pi efficiente dellaltro
22

Break e Continue
I cicli contengono una serie di istruzioni che vogliamo
ripetere
Per potremmo aver bisogno di:
Saltare alliterazione successiva
Terminare il ciclo

Continue salta alliterazione successiva


Break interrompe lesecuzione del ciclo

23

Esempio
Acquisiamo numeri da tastiera finch non viene
inserito un numero negativo. In ogni caso non
accettiamo pi di mille numeri:
vector = [ ]; %crea il vettore vuoto
for count = 1:1000 %Raccoglier al max 1000 valori
value = input('next number ');
if value < 0
break %Se value negativo usciamo dal ciclo
else
vector(count) = value;
end
end
vector %permette di visualizzare il contenuto di vector
24

Strutture

Strutture (e array di strutture)


Una struttura un tipo di dato composto da elementi
eterogenei
Ogni elemento individuale chiamato campo e ha un
nome
Come con gli scalari, si pu passare da un elemento
singolo (matrice 11) a un vettore (matrice 1n)
Ci sono due modi per creare una struttura:
Campo per campo mediante assegnamento
Tutto in una volta mediante la funzione struct

26

Creazione di una struttura campo per


campo
Esempio: la struttura studente
studente.nome = Giovanni Rossi;
studente.indirizzo = Via Roma 23;
studente.citta = Cosenza;
studente.media = 25;
whos studente
Name
studente

Size
1x1

Bytes Class
568 struct

Attributes

%aggiungo un nuovo studente -> array 1x2


studente(2).nome = Giulia Gatti;
studente(2).media = 30;

Nota: quando un elemento viene definito, tutti i suoi campi


sono creati e inizializzati a valore nullo (vettore vuoto [])
27

Creazione di una struttura mediante la


funzione struct
Consente di preallocare una struttura o un array di
strutture
str_array = struct(campo1, val1, campo2, val2, )

Esempio
>> rilieviAltimetrici=struct('latitudine',20,'longitudine',30, 'altitudine',
'altitudine', 1300)
rilievoAltimetrico =
latitudine: 20
longitudine: 30
altitudine: 1300

28

Creazione di array di strutture


Se si allunga un array assegnando un valore a una
componente di indice > dimensione corrente
i nuovi elementi, in posizione precendente a quello inserito
esplicitamente, vengono inizializzati al solito valore nullo []

Esempio
rilieviAltimetrici(1000)=struct('latitudine',80,'longitudine',[],
'altitudine', 1450)
rilieviAltimetrici =
1x1000 struct array with fields:
latitudine
longitudine
altitudine
29

Array vuoto. Attenzione: se si


Inserisce un valore (es. 20),
questo viene assunto dal campo
longitudine dellelemento 1000,
ma non dallo stesso campo degli
altri elementi dellarray

Aggiunta di campi
Aggiunta di un campo: facciamo riferimento alla
definizione di studente delle slide precedenti
studente(2).esami = [20 25 30];

Il campo esami viene aggiunto a tutte le strutture che


fanno parte di studente
Avr un valore iniziale per studente(2). Sar vuoto per
tutti gli altri elementi dellarray

30

Uso dei dati nelle strutture


Notazione con il punto, uguale al C. Esempi
studente(2).nome
studente(2).esami(2)
unNome = studente(1).nome
studente(2).indirizzo=studente(1).indirizzo
%mean calcola la media degli elementi di un array
mean(studente(2).esami)

Estrazione dei valori che un campo assume in tutti gli


elementi di un array di strutture (NB: ipotizziamo che
le strutture dellarray studente abbiano un campo
media e che larray abbia due componenti)
a = [studente.media]

a = [25 30]
31

Array di strutture innestati


Un campo di un array di strutture pu essere di
qualsiasi tipo (come in C)
E` quindi possibile avere un campo che , di nuovo,
una struttura. Esempio
studente(1).corso(1).nome=InformaticaB;
studente(1).corso(1).docente=Von Neumann;
studente(1).corso(2).nome=Matematica;
studente(1).corso(2).docente=Eulero;

32

Esercizio
Si sviluppi un programma in matlab che acquisisce
da tastiera i dati relativi a rilievi altimetrici e stampa a
video laltitudine media di tutti quelli che hanno
latitudine compresa tra 10 e 80 e longitudine tra 30 e
60

33

Soluzione (1)
more = input('vuoi inserire valori altimetrici? (s/n)');
ii=1;
while more=='s'
arch(ii).altitudine = input('altitudine ');
arch(ii).longitudine = input('longitudine ');
arch(ii).latitudine = input('latitudine ');
ii = ii+1;
more = input('vuoi inserire altri valori altimetrici? (s/n)');
end

34

Soluzione (2)
jj=1;
for ii=1:length(arch)
%attenzione: la condizione deve essere scritta sulla stessa linea
if arch(ii).latitudine>=10&&arch(ii).latitudine<=80 &&
arch(ii).longitudine>=30&&arch(ii).longitudine<=60
elemSelez(jj) = arch(ii).altitudine;
jj=jj+1;
end
end
disp(['la media degli elementi selezionati e` ' num2str(mean(elemSelez))]);

35