Sei sulla pagina 1di 57

Strumenti per il calcolo numerico

MATLAB/Octave
Array, matrici, vettorizzazione e struct

Informatica B
Array e variabili

-2-
Array e variabili
!  L’unità fondamentale di dati in MATLAB è l’array
! Una variabile in MATLAB è una regione di memoria che
contiene un array
!  Ha un nome definito dall’utente
!   Per i nomi valgono regole simili a quelle del C
!  C è un linguaggio a tipizzazione forte
!   Le variabili vanno dichiarate prima dell’uso
!  MATLAB è un linguaggio a tipizzazione debole
!   Le variabili vengono create assegnando ad esse dei valori
!   Il loro tipo è determinato dal tipo dei valori assegnati

>> x = [1 2 3];
>> whos x;
Name Size Bytes Class Attributes

x 1x3 24 double
-3-
Tipo double

!  Una variabile di tipo double contiene uno scalare o


un array di numeri espressi in 64 bit con doppia
precisione
!  Questi numeri possono essere
!  Reali, es var1 = -10.7;
!  Immaginari, es var2 = 4i; var3 = 4j;
!  Complessi, es var3 = 10.3 + 10i;
!  Es: x = [-1.3 3.1+5.3j 0]
!  Le parti reali e immaginarie possono essere positive
e negative nell’intervallo di valori [10-308, 10308]

-4-
Tipo char

!  Una variabile di tipo char contiene uno scalare o un


array di valori a 16 bit (8 bit in Octave), ciascuno dei
quali rappresenta un carattere
!  Es: commento = ‘questa e` una stringa’;

Nome della variabile Array di 1x21 caratteri

!  (NB: stringhe racchiuse tra apici singoli)


!   whos commento;
Name Size Bytes Class Attributes
commento 1x21 42 char

-5-
Creazione e inizializzazione di una
variabile
!  Le variabili sono create al momento
dell’inizializzazione
!  Modi di inizializzazione
!  Assegnamento
!  Lettura dati da tastiera
!  Lettura da file

-6-
Assegnamento

!  variabile = espressione
!  Esempi
!  a = [0 7+1]; contenuto di a
!  b = [a(2) 5 a];
secondo elemento di a
!  Risultato
!  a = [0 8]
!  b = [8 5 0 8]
!  Non tutti gli elementi devono essere specificati alla
creazione…
!  c(2, 3) = 5; 0 0 0
0 0 5

-7-
Assegnamento (2)
!  L’array può essere esteso successivamente …
!  d = [2 5]; d(4)=2; d = [2 5 0 2]
!  Operatore di trasposizione
!  g = d’; 2
5
0
2
!  Creare un vettore enumerando i valori di un insieme:
uso dell’operatore ‘:’
!  x = 1:2:10; x = [1 3 5 7 9]
!  n = 1:3; n = [1 2 3]
1  1
!  m = [n’ n’] 2  2
3  3
-8-
Tabella delle funzioni predefinite
Funzione Significato
zeros (n) Genera una matrice nxn di zeri
zeros (m,n) Genera una matrice mxn di zeri
zeros (size(arr)) Genera una matrice di zeri della stessa dimensione di arr
ones(n) Genera una matrice nxn di uno
ones(m,n) Genera una matrice mxn di uno
ones(size(arr)) Genera una matrice di uno della stessa dimensione di arr
eye(n) Genera la matrice identità nxn
eye(m,n) Genera la matrice identità mxn
length(arr) Ritorna la dimensione più lunga del vettore
size(arr) Ritorna un vettore [r c] con il numero r di righe e c di colonne
della matrice; se arr ha più dimensioni ritorna array con
numero elementi per ogni dimensione
v(end) ultimo elemento di vettore v; ultimo elemento dell’ultima riga
m(end, end) di matrice m; la costante end, come indice in un array, denota il
più alto valore possibile dell’indice
-9-
Funzioni predefinite

!  Esempi 0 0
!  a = zeros(2); 0 0

!  b = zeros(2,3); 0 0 0
0 0 0

!  c = [1 2; 3 4];
!  d = zeros(size(c)); 0 0
0 0

- 10 -
Esempio dalla I prova in itinere 2013
Qui lo facciamo in MATLAB

!  Si implementi (in C) un programma che svolga le


seguenti operazioni:
!  Chieda all’utente di inserire due valori interi R e C
(entrambi maggiori di 0 e non più grandi di 100). Nel
caso di inserimento di un valore non ammissibile, il
programma deve chiedere all’utente di immettere
nuovamente il valore.
!  Chieda all’utente di popolare una matrice M di
dimensioni massime 100x100 con RxC interi positivi
letti da tastiera. Nel caso di inserimento di un valore
non ammissibile, il programma deve chiedere all’utente
di immettere nuovamente il valore.
!  Individui la colonna di M con il maggior numero di
valori pari e stampi a video tale numero.
- 11 -
Soluzione parte 1

% lettura R e C con controllo


R = input('Inserisci il numero di righe: ');
while (R<=0 || R>100)
R = input('Inserisci il numero di righe: ');
end
C = input('Inserisci il numero di colonne: ');
while (C<=0 || C>100)
C = input('Inserisci il numero di colonne: ');
end

- 12 -
Soluzione parte 2

% acquisizione della matrice RxC con controllo


M = zeros(R,C);
for ii=1:R
for jj=1:C
M(ii,jj) = input('inserisci un valore positivo: ');
while(M(ii,jj)<0)
M(ii,jj) = input('inserisci un valore positivo: ');
end
end
end

- 13 -
Soluzione parte 3, versione 1

% uso di A
A = zeros(1,C);
for jj=1:C
for ii=1:R
if (mod(M(ii,jj), 2)==0)
A(jj)++;
end
end
end
maxVal = A(1);
for ii=2:C
if (A(ii)>maxVal)
maxVal=A(ii);
end
end

disp(['il maggior numero di numeri pari per colonna e` ',


num2str(maxVal)]);
- 14 -
Soluzione parte 3, versione 2

maxPari = 0;
for jj=1:C
nPariColonna = 0;
for ii=1:R
if (mod(M(ii,jj), 2)==0)
nPariColonna++;
end
end
if(nPariColonna > maxPari)
maxPari = nPariColonna;
end
end

disp(['il maggior numero di numeri pari per colonna e` ', …


num2str(maxPari)]);

- 15 -
sottoarray: applicazione a vettori

Si denota un sottoinsieme di un array usando vettori per valori degli indici

>> v=[6 8 4 2 4 5 1 3]
v = 6 8 4 2 4 5 1 3
>> v([1 4 7]) primo, quarto settimo elemento
ans = 6 2 1

>> v(2:2:6) 2:2:6 è il vettore [2, 4, 6]: indica


ans = 8 2 5 secondo, quarto, sesto elemento

>> v(3:end-2) dal terzo al terz’ultimo elemento


ans = 4 2 4 5
i valori di v usati come indice
>> v(v)
ans = 5 3 2 8 2 4 6 4
>>

- 16 -
sottoarray: applicazione a matrici
m = 9 8 7
6 5 4
3 2 1
0 11 12
0 0 0 tutti gli elementi sulle righe 1 e 4 e sulle
>> m([1 4], [2 3]) colonne 2 e 3
ans = 8 7
11 12
>> m(1:2:5, 1:end) tutti gli elementi delle righe 1, 3 e 5
ans = 9 8 7
3 2 1
0 0 0
>>>> m(1:2:5, :) notazione ‘:’ abbreviata per 1:end, cioè tutti i
ans = 9 8 7 valori di quell’indice
3 2 1
0 0 0
>> m(2:2:4, :) = [-1 -2 -3; -4 -5 -6];
>> m
m = 9 8 7 uso della notazione dei sottoarray per
-1 -2 -3 individuare elementi oggetto di assegnamento
3 2 1
-4 -5 -6
0 0 0
>> - 17 -
Uso di uno scalare per assegnare valori a un array

!  Esempio 3 3 3
!  m(1:4, 1:3) = 3 3 3 3
3 3 3
3 3 3

!  Il modo con cui uno scalare viene assegnato a un


array dipende dalla forma dell’array che viene
specificata a sinistra dell’assegnamento
!  Esempio 2 4 4 3
!  m(1:2, 1:2) = 4 4 4 3
3 3 3
3 3 3

- 18 -
Esempio da un tema d’esame

% esempioSottoArray mostra un esempio di uso dei sotto-array


% Docenti di InfoB anno 2010
% variabili di input: A deve ricevere in ingresso una matrice
% variabili di output: P contiene solo le righe con indice pari
% della matrice A, D contenente solo le righe con indice dispari
% della matrice A.

A=input('Inserire matrice: ');


P=A(2:2:end,:)
D=A(1:2:end,:)

- 19 -
uso dell’array vuoto [] per cancellare elementi di un array
Un array vuoto [] assegnato a un elemento di un vettore non crea un ‘buco’
ma cancella un elemento e ricompatta il vettore

Un array vuoto [] non è assegnabile a singoli elementi di matrici (non si possono “creare buchi”)
È assegnabile a intere righe o colonne di matrici, che vengono cancellate (ricompattando la matrice)

>> m=[16 2 3 13; 5 11 10 8; 9 7 6 12; 4 14 15 1]


m = 16 2 3 13
5 11 10 8
9 7 6 12
>> a=[1 2 3 4 5]; 4 14 15 1
>> length(a) >> m(3,4)=[]
ans = 5 ??? Subscripted assignment dimension mismatch.
>> a(3) >> m(3,:)=[]
ans = 3 m = 16 2 3 13
>> a(3)=[] 5 11 10 8
a = 1 2 4 5 4 14 15 1
>> a(3) >> [r,c]=size(m)
ans = 4 r = 3
>> length(a) c = 4
ans = 4 >> m(:,2)=[]
m = 16 3 13
5 10 8
4 15 1
>> [r,c]=size(m)
r = 3
c = 3

- 20 -
Array: memorizzazione nella RAM

!  Array memorizzati in forma lineare nella RAM variando


! più velocemente i primi indici
! più lentamente quelli successivi
!  NB: opposto a quanto avviene in C

...
1
3
1 2
5
3 4
2
5 6
4
6
...

- 21 -
Array: forma linearizzata
!  Si può accedere a un array a più dimensioni come se
ne avesse una sola
!  Usando un unico indice si segue l’ordine della
memorizzazione
!  Da NON usare nella programmazione
!  ma aiuta a capire certi costrutti....
>> a = [1 2 3; 4 5 6; 7 8 9; 10 11 12]
a =
1 2 3
4 5 6
7 8 9
10 11 12
>> a(3, 2)
ans =
8
>> a(10)
ans =
6
>>
- 22 -
Variabili predefinite

!  Matlab definisce un insieme di variabili predefinite (es, pi)


!  Queste variabili spesso rappresentano importanti costanti
della matematica (pi è pigreco, i e j sono sqrt(-1) )
!  Attenzione! Il valore di queste variabili può essere modificato,
per esempio
!  circ1=2*pi*10;
!  pi = 3;
!  circ2=2*pi*10;
!  Il valore di circ2 non sarà più la circonferenza di un cerchio
! E` fortemente sconsigliato modificare il valore di una variabile
predefinita (⇒ evitare di usare variabili i e j come contatori)

- 23 -
Variabili predefinite più comuni
Variabile Scopo

pi contiene 15 cifre significative di π

i, j contiene il valore i ( − 1)

inf (o Inf) rappresentazione dell’infinito


(ottenuto di solito come risultato di
una divisione per 0)

nan Not-A-Number è il risultato di una


operazione matematica non definita,
es 0/0

clock contiene la data e l’orario corrente.


E` un vettore di sei elementi (anno,
mese, giorno, ora, minuti, secondi)

date contiene la data corrente sotto


forma di stringa

eps epsilon: la più piccola differenza


rappresentabile tra due numeri

ans Variabile speciale usata per


immagazzinare risultati non
assegnati ad altre variabili

- 24 -
Operazioni con scalari e array

!  Operazioni per gli scalari: + - * / ^ Elevamento a potenza

!  Operazioni per gli array


!  Array operation: eseguita sugli elementi corrispondenti degli array
coinvolti (devono avere lo stesso numero di righe e colonne); si indica
aggiungendo un punto prima dell’operatore aritmetico

1 2 2 3 2 6
!  a= b= a .* b=
3 4 5 7 15 28

!  Matrix operation: segue le regole dell’algebra lineare


(esempio: prodotto righe per colonne)

1 2 2 3 12 17
!  a= 3 4 b= 5 7 a*b = 26 37 (a * b)ij = ∑k aik * bkj

- 25 -
Operazioni tipiche per gli array
Operazione Sintassi Commenti
Matlab
Array addition a+b Array e matrix addition sono
identiche
Array subtraction a–b Array e matrix subtraction sono
identiche
Array multiplication a .* b Ciascun elemento del risultato è
pari al prodotto degli elementi
corrispondenti nei due operandi
Matrix multiplication a*b Prodotto di matrici
Array right division a ./ b risultato(i,j)=a(i,j)/b(i,j)
Array left division a .\ b risultato(i,j)=b(i,j)/a(i,j)
Matrix right division a/b a*inversa(b)
Matrix left division a\b inversa(a)*b
Array exponentiation a .^ b risultato(i,j)=a(i,j)^b(i,j)

- 26 -
Matrix left division

!  Serve per risolvere sistemi di equazioni lineari


a11x1+a12x2+a13x3=b1
a21x1+a22x2+a23x3=b2
a31x1+a32x2+a33x3=b3
! può essere espresso come Ax=B con
a11 a12 a13 b1 x1
A= a21 a22 a23 B= b2 x = x2
a31 a32 a33 b3 x3

!  di conseguenza, x = A-1B=inversa(A)*b=A\B

- 27 -
Altre funzioni

Funzione Scopo

ceil(x) approssima x all’intero immediatamente maggiore

floor(x) approssima x all’intero immediatamente minore

fix(x) approssima x all’intero più vicino verso lo zero

max(x) se x è un vettore, ritorna il valore massimo in x e, opzionalmente, la collocazione


di questo valore in x; se x è matrice, ritorna il vettore dei massimi delle sue
colonne

min(x) se x è un vettore, ritorna il valore minimo nel vettore x e, opzionalmente, la


collocazione di questo valore nel vettore; se x è matrice, ritorna il vettore dei
minimi delle sue colonne

mean(x) se x è un vettore ritorna uno scalare uguale alla media dei valori di x; se x è una
matrice, ritorna il vettore contentente le medie dei vettori colonna di x;

mod(m,n) mod(m,n) è m - q.*n dove q = floor(m ./ n) se n ~= 0

round(x) approssima x all’intero più vicino

rand(N) genera una matrice di NxN numeri casuali

- 28 -
funzioni min (e anche max) applicate a vettori e matrici

>> b = [4 7 2 6 5]
b = 4 7 2 6 5
(con un solo risultato) dà il valore del minimo
>> min(b)
ans = 2
>> [x y]=min(b) con due risultati dà anche la posizione del minimo
x = 2
y = 3
>>

>> a = [24 28 21; 32 25 27; 30 33 31; 22 29 26]


a = 24 28 21
32 25 27
30 33 31
22 29 26
>> min(a) per una matrice dà vettore dei minimi nelle colonne
ans = 22 25 21

>> [x y]=min(a) per una matrice, con due risultati dà due vettori dei valori
x = 22 25 21 minimi nelle colonne e della loro posizione (riga)
y = 4 2 1
>>

- 29 -
Problema I prova 2013, parte 3
nuova soluzione
N = ~mod(M, 2); % N è la matrice che contiene 1 in
% corrispondenza degli elementi di M
% divisibili per 2
A = sum(N); % A è un vettore che contiene la somma degli
% elementi di ciascuna colonna di N
maxVal = max(A);

disp(['il maggior numero di numeri pari per colonna e` ', …


num2str(maxVal)]);

- 30 -
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 Size Bytes Class Attributes
!  a=true; a 1x1 1 logical

!  a è un vettore 1x1 che occupa 1 byte e appartiene alla


classe “tipo logico” 31
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 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 32
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

33
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]

34
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 b a AND b a OR b NOT a a XOR b
fals fals false false true false
e e
fals true false true true true
e
true fals false true false true
e
true true true true false false

35
&& 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 b
!  a || b: se a è vero non valuta b
!  & (|) funziona con scalari e vettori e valuta tutti gli
operandi prima di valutare l’espressione
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
36
Ordine tra gli operatori

!  Un’espressione 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

37
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)

38
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 >> x = [6,3,9]; y = [14,2,9];
a=1 0 0 più concisamente >> x(x<y)
>> z=x(a) ans = 6
z= 6 >>
>> 39
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]; >> sqrt(a(b))
>> b=a>5 ans = 2.6458 NB: i due vettori a sx e a
b=0 0 0 2.8284 dx di ‘=‘ devono avere
0 0 1 2.4495 uguale dimensione
poi …
1 1 1 3.0000
>> a(b) >> a(b)=sqrt(a(b))
ans = a = 1.0000 2.0000 3.0000
7 versione linearizzata: 4.0000 5.0000 2.4495
8 elementi ottenuti con 2.6458 2.8284 3.0000
6 scansione di a da alto >>
9 a basso e da sinistra a
destra 40
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 >> b(b>5)
4 5 6 ans =
7 8 9 6
>> b=a' 7
b= poi … 8
1 4 7 9
2 5 8 >> a(a>5)=b(b>5)
3 6 9 a=
>> a(a>5) 1 2 3
ans = 4 5 8
7 6 7 9
8 >>
6
9
>> 41
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 valori
!  Esempio: (NB: tutti i valori diversi da zero corrispondono a
true)
x = [5, -3, 0, 0, 8];y = [2, 4, 0, 5, 7]; i valori di y(k) per quei k tali
che x(k)&y(k), cioè x(k) e y(k)
v = y(x&y) -> v = [2 4 7] sono entrambi non nulli
ind = find(x&y) -> ind = [1 2 5]
gli indici k tali che x(k)&y(k),

42
Funzioni logiche
Nome della Elemento restituito
funzione
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

- 43 -
Vettorizzazione come sostituto
più efficiente del for

- 44 -
Vettorizzazione (1)

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

45
Vettorizzazione (2)

! Riprendiamo l’esempio
!  b = a>5
!  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
46
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 assegnamento
!  Tutto in una volta mediante la funzione struct

48
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 Size Bytes Class Attributes
studente 1x1 568 struct
!  %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 [])
49
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', 1300)

rilievoAltimetrico =
latitudine: 20
longitudine: 30
altitudine: 1300

50
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 Array vuoto. Attenzione: se si
Inserisce un valore (es. 20),
!  longitudine questo viene assunto dal campo
longitudine dell’elemento 1000,
!  altitudine
ma non dallo stesso campo degli
altri elementi dell’array
51
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

52
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 dell’array studente abbiano un campo
‘media’ e che l’array abbia due componenti)
!  a = [studente.media] a = [25 30]
53
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’;

54
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

55
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

56
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))]);

57