MATLAB: Strutture di controllo - Intranet...

35
MATLAB: Strutture di controllo Informatica B Informatica B Prof. A. Prof. A. Morzenti Morzenti

Transcript of MATLAB: Strutture di controllo - Intranet...

MATLAB: Strutture di controllo

Informatica B Informatica B –– Prof. A. Prof. A. MorzentiMorzenti

Tipo di dato logico

È un tipo di dato che può avere solo due valoritrue (vero) 1false (falso) 0

I valori di questo tipo possono essere generatidirettamente da due funzioni speciali (true e false)dagli operatori relazionalidagli operatori logici

I valori logici occupano un solo byte di memoria (i numeri ne occupano 8)Esempio:

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

>>whos aName Size Bytes Class Attributesa 1x1 1 logical

>>whos aName Size Bytes Class Attributesa 1x1 1 logical

22

Operatori relazionali

Gli operatori relazionali operano su tipi numerici o stringheForma generale: a OP b

a,b possono essere espressioni aritmetiche, variabili, stringhe (della stessa dimensione)OP: ==, ~=, >, >=, <, <=

Esempi:3<4 true (1)3==4 false (0)‘A’<’B’ 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 33

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 -> 1sin(pi) == 0 -> 0eppure logicamente sono vere entrambe!!

Per i numeri piccoli conviene usare una sogliaabs( sin(pi) ) <= eps

44

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]

55

Operatori logici

Forma generale: a OP1 b oppure OP2 aa,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 falsetutti i numeri diversi da 0 come true

a b 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

66

&& vs & e || vs |

&& (||) funziona con gli scalari e valuta prima l’operando più a sinistra. Se questo è sufficiente per decidere il valore di verità dell’espressione non va oltre

a && b: se a è falso non valuta ba || b: se a è vero non valuta b

& (|) funziona con scalari e vettori e valuta tutti gli operandi prima di valutare l’espressione complessivaEsempio: 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

77

Ordine tra gli operatori

Un’espressione viene valutata nel seguente ordine:

operatori aritmeticioperatori relazionali da sinistra verso destra

NOT (~)AND (& e &&) da sinistra verso destra

OR (| e ||) e XOR da sinistra verso destra

88

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)

99

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

>>

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

>> x(x<y)

ans = 6

>>

più concisamente

1010

Vettori logici e selezione (2)

Altro modo di creare un array logico: confrontando con una costanteMediante 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

1 1 1

>> a(b)

ans =

7

8

6

9

>> sqrt(a(b))

ans = 2.6458

2.8284

2.4495

3.0000

>> a(b)=sqrt(a(b))

a = 1.0000 2.0000 3.0000

4.0000 5.0000 2.4495

2.6458 2.8284 3.0000

>>

poi …

NB: i due vettori a sx e NB: i due vettori a sx e NB: i due vettori a sx e NB: i due vettori a sx e a dx di a dx di a dx di a dx di ‘‘‘‘====‘‘‘‘ devono avere devono avere devono avere devono avere uguale dimensioneuguale dimensioneuguale dimensioneuguale dimensione

versione versione versione versione linearizzatalinearizzatalinearizzatalinearizzata: : : : elementi ottenuti con elementi ottenuti con elementi ottenuti con elementi ottenuti con scansione di a da alto scansione di a da alto scansione di a da alto scansione di a da alto a basso e da sinistra a a basso e da sinistra a a basso e da sinistra a a basso e da sinistra a destradestradestradestra 1111

Vettori logici e selezione (3)

la scansione per selezionare gli elementi segue la forma linearizzata della matrice (per colonne dall’alto 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

>>

>> b(b>5)

ans =

6

7

8

9

>> a(a>5)=b(b>5)

a =

1 2 3

4 5 8

6 7 9

>>

poi …

1212

Find

ind = find(x) restituisce gli indici degli elementi non nulli dell’array x. x può essere un’espressione 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 valoriEsempio: (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 i valori di y(k) per quei k tali i valori di y(k) per quei k tali i valori di y(k) per quei k tali che x(k)&y(k), cioche x(k)&y(k), cioche x(k)&y(k), cioche x(k)&y(k), cioèèèè x(k) e y(k) x(k) e y(k) x(k) e y(k) x(k) e y(k) sono entrambi non nullisono entrambi non nullisono entrambi non nullisono entrambi non nulli

gli indici k tali che x(k)&y(k), gli indici k tali che x(k)&y(k), gli indici k tali che x(k)&y(k), gli indici k tali che x(k)&y(k),

1313

Funzioni logiche

-- 1414 --

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

Il costrutto if

if espressione1 I rami elseif e else non sono obbligatori!istruzione 1-1istruzione 1-2..........

elseif espressione2 Le istruzioni 1-1 e 1-2 vengonoistruzione 2-1 eseguite solo se vale espressione 1istruzione 2-2 Le istruzioni 2-1 e 2-2 vengono.......... eseguite solo se vale espressione 2

.....else

istruzione k-1 Le istruzioni k-1 e k-2 vengonoistruzione k-2 eseguite solo se non vale nessuna.......... delle espressioni sopra indicate

end1515

Il costrutto switch

L’istruzione condizionale switch consente una scrittura alternativa ad if/elseif/elseQualunque struttura switch può essere tradotta in un if/elseif/else equivalente

switch variabile (scalare o stringa)case valore1

istruzioni caso 1case valore2

istruzioni caso 2...otherwise

istruzioni per i restanti casiend

1616

Il ciclo while

while espressioneistruzioni da ripetere finché espressione è vera

endespressione deve essere inizializzata (avere un valore) prima dell’inizio del cicloIl valore di espressione deve cambiare nelle ripetizioniEsempio: Calcoliamo gli interessi fino al raddoppio del capitalevalue = 1000;

year = 0;while value < 2000

value = value * 1.08

year = year + 1;fprintf('%g years: $%g\n', year,value)

end

1717

Il ciclo for

for indice = espressioneistruzioni

endEsempio – 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 seconditime = input('how long? ');for count = time:-1:1

pause(1);fprintf('%g seconds left \n',count);

enddisp('done');

1818

Il ciclo for

Il ciclo for usa un array per assegnare valori alla variabile diconteggio

Questo array può essere generato “al volo” con un’espressione del tipo “init:delta:fin”

Nel primo esempio del lucido precedente l’array è [1 2 3 4 5 6 7]

L’array può anche essere inizializzato con altri meccanismi (si vedano gli esempi nel lucido seguente)Se l’array è una matrice alla variabile di conteggio vengono assegnate in sequenza le sua colonne

1919

Esempi

Inizializzazione dell’indice del for a partire da una matriceboard = [ 1 1 1 ; 1 1 -1 ; 0 1 0 ];for x = board

x alla prima iterazione x e` il vettore colonna

endInizializzazione dell’indice del for a partire da una stringafor x = 'EGR106‘

disp(x) %alla prima iterazione x vale ‘E’

end

110

2020

In molti casi è possibile sostituire un for con l’uso di un opportunovettore. 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;

square=ii.^2;

versione equivalente che fa uso della notazione dei sottoarrayn=1:100;

square(n)= n .^ 2;

La versione con il for può essere fino a 15 volte più lenta della versione con la vettorizzazione!

Vettorizzazione (1)

2121

NB: bisogna usare la versione ‘.^’che opera elemento per elemento

Vettorizzazione (2)

Riprendiamo l’esempio b = a>5sqrt(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 dell’altro

2222

Break e Continue

I cicli contengono una serie di istruzioni che vogliamo ripeterePerò potremmo aver bisogno di:

Saltare all’iterazione successivaTerminare il ciclo

Continue salta all’iterazione successivaBreak interrompe l’esecuzione del ciclo

2323

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 vuotofor count = 1:1000 %Raccoglierà al max 1000 valori

value = input('next number ');if value < 0

break %Se value negativo usciamo dal ciclo

elsevector(count) = value;

endendvector %permette di visualizzare il contenuto di vector

2424

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 1×1) a un vettore (matrice 1×n)Ci sono due modi per creare una struttura:

Campo per campo mediante assegnamentoTutto in una volta mediante la funzione struct

2626

Creazione di una struttura campo per campo

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

Name Size Bytes Class Attributesstudente 1x1 568 struct

%aggiungo un nuovo studente… -> array 1x2studente(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 [])

2727

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, '>> rilieviAltimetrici=struct('latitudine',20,'longitudine',30, '>> rilieviAltimetrici=struct('latitudine',20,'longitudine',30, '>> rilieviAltimetrici=struct('latitudine',20,'longitudine',30, 'altitudine', 1300)altitudine', 1300)altitudine', 1300)altitudine', 1300)

rilievoAltimetrico = rilievoAltimetrico = rilievoAltimetrico = rilievoAltimetrico = latitudine: 20latitudine: 20latitudine: 20latitudine: 20longitudine: 30longitudine: 30longitudine: 30longitudine: 30altitudine: 1300altitudine: 1300altitudine: 1300altitudine: 1300

2828

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’ []

EsempiorilieviAltimetrici(1000)=struct('latitudine',80,'longitudine',[], 'altitudine', 1450)

rilieviAltimetrici = 1x1000 struct array with fields:

latitudinelongitudinealtitudine

Array vuoto. Attenzione: se si Inserisce un valore (es. 20), questo viene assunto dal campo longitudine dell’elemento 1000, ma non dallo stesso campo degli altri elementi dell’array

2929

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 dell’array

3030

Uso dei dati nelle strutture

Notazione con il “punto”, uguale al C. Esempistudente(2).nomestudente(2).esami(2)unNome = studente(1).nomestudente(2).indirizzo=studente(1).indirizzo

%mean calcola la media degli elementi di un arraymean(studente(2).esami)

Estrazione dei valori che un campo assume in tutti gli elementi di un array di strutture (NB: ipotizziamo che le strutture dell’array studente abbiano un campo ‘media’ e che l’array abbia due componenti)

a = [studente.media] a = [25 30]3131

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

3232

Esercizio

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

3333

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

3434

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;

endenddisp(['la media degli elementi selezionati e` ' num2str(mean(elemSelez))]);

3535