for
Il nostro obiettivo è formulare algoritmi, giusto?
Proviamo a capire se possiamo farlo con i costrutti visti finora
Proviamo a calcolare la somma degli elementi di un vettore
Come fare?
Abbiamo gli strumenti per codificarlo?
Vediamo come usare queste informazioni per il nostro algoritmo
v
ii
avrà raggiunto il valore length(v)
…s
conterrà la sommaCi rimane da capire come gestire l’indice
ii
P.S: Notate il “;” dopo s = 0
:
for
Matlab ci permette di gestire ii
utilizzando una particolare istruzione
Una istruzione è una notazione che, quando viene eseguita, ordina all’elaboratore di fare qualcosa
La definizione è un po’ vaga…
Un esempio: espressione + [INVIO] = una istruzione
for
Matlab ci permette di gestire ii
utilizzando una particolare istruzione
Una istruzione è una notazione che, quando viene eseguita, ordina all’elaboratore di fare qualcosa
Ora vediamo un nuovo tipo di istruzioni:
Istruzioni di iterazione o “cicli”: permettono di eseguire ripetutamente una porzione di codice
for
La nostra prima istruzione di iterazione si chiama “ciclo for
”
Sintassi:
<corpo>
è una sequenza di istruzioni<vettore>
Ad ogni ripetizione (i.e. iterazione):
<variabile>
assume il valore di un elemento di <vettore>
Nota: il simbolo “=
” in questo caso non ha il solito significato…
for
Un esempio semplice:
Di solito, i cicli for compaiono in file di script
Se inserite una istruzione for
nella finestra dei comandi:
end
Solo allora l’istruzione for
è completa (e quindi eseguibile)
for
e Somma di un VettoreIl ciclo for
ci permette di sommare gli elementi di v
:
Oppure, in modo ancora più semplice:
C’è una funzione predefinita che fa esattamente questo:
Si chiama sum
è viene invocata con:
for
InnestatiAlziamo un po’ il livello di difficoltà
Supponiamo di voler sommare gli elementi di una matrice
Un possibile algoritmo:
Come iterare sugli elementi di una matrice?
for
…Vediamo cosa succede iterando con un for
su una matrice:
M = [1, 2, 3; 4, 5, 6; 7, 8, 9]; % [1, 2, 3;
% 4, 5, 6;
% 7, 8, 9]
for w = M
w % giusto per stampare w
end
La variabile w
assume i valori:
[1; 4; 7]
, poi [2; 5; 8]
, poi [3; 6; 9]
Ossia le colonne di M
!
Come possiamo fare per iterare sugli elementi?
Una soluzione semplice: usare due cicli for
M = [1, 2, 3; 4, 5, 6; 7, 8, 9];
for C = M % itero sulle colonne
for v = C % poi sugli elementi della colonna
v
end % fine ciclo interno
end % fine ciclo esterno
for
è una istruzione…for
può contenere un altro for
!I due cicli si dicono innestati
end
si riferisce sempre all’ultimo for
non ancora chiusoPossiamo anche fare iterare due indici:
M = % la nostra matrice
s = 0;
[n, m] = size() % Recupero le due dimensioni
for ii = 1:n % Itero sulle righe
for jj = 1:m % Itero sulle colonne
s = s + M(ii, jj);
end
end
Da notare:
size(M)
restituisce un vettore [<nrighe>, <ncolonne>]
…
=
…Riprenderemo questo comportamento nella prossima lezione
Possiamo anche fare iterare due indici:
M = % la nostra matrice
s = 0;
[n, m] = size() % Recupero le due dimensioni
for ii = 1:n % Itero sulle righe
for jj = 1:m % Itero sulle colonne
s = s + M(ii, jj);
end
end
Da notare (2):
Vedete che il corpo di ogni for
è leggermente indentato?
In alternativa, possiamo usare la funzione sum
Ci vuole però qualche accortezza:
sum
calcola la somma colonna per colonnaPer avere la somma di tutti gli elementi:
sum
ottiene la somma della colonneSupponiamo di voler calcolare il massimo di un vettore
Cosa riusciamo a scrivere con le istruzioni che conosciamo?
V = % il nostro vettore
y = V(1) % primo tentativo: max = il primo elemento
for ii = 2:length(V) % iteriamo sul resto del vettore
<se V(ii) è maggiore di y, allora y = V(ii)>
end
Abbiamo bisogno di un costrutto che:
V(ii)
è maggiore di y
…y = V(ii)
Questa funzionalità è fornita dalle istruzioni condizionali
if
Noi utilizzeremo una sola istruzione condizionale, chiamata if
Sintassi:
<espressione>
viene valutata ed interpretata come valore logico<corpo1>
e <corpo2>
sono sequenze di istruzioni<corpo1>
esegue se <espressione>
denota true
(o $\neq 0$
)<corpo2>
esegue se <espressione>
denota false
(o $0$
) if
nel Nostro AlgoritmoGrazie all’istruzione if
possiamo formulare il nostro algoritmo:
Ricordate:
Possiamo esprimere condizioni complesse con gli operatori logici
Per esempio:
E se dobbiamo verificare una condizione su un intero vettore?
V
contiene almeno uno 0
Una prima soluzione
all
e any
Seconda soluzione: usare due funzioni predefinite:
all(<vettore>) % true se tutti gli elementi sono true
any(<vettore>) % true se almeno un elemento è true
Qualche esempio:
a = [1, 2, 3];
all(a < 3) % all([true, true, false]) --> false
any(a < 2) % any([true, false, false]) --> true
a < 3
e a < 2
restituiscono vettori di valori logiciall
ed any
lavorano su di essiSe applicate a matrici, all
ed any
operano colonna per colonna
sum
…any(any(...))
break
, Programmazione StrutturataSupponiamo di voler calcolare la somma della serie (con \(s > 1\)):
\[ \zeta(s) = \sum_{n=1}^\infty \frac{1}{n^s} \]
Supponiamo di voler calcolare la somma della serie (con \(s > 1\)):
\[ \zeta(s) = \sum_{n=1}^\infty \frac{1}{n^s} \]
La serie ha infiniti termini!
Supponiamo di voler calcolare la somma della serie (con \(s > 1\)):
\[ \zeta(s) = \sum_{n=1}^\infty \frac{1}{n^s} \]
Un approccio tipico:
Più nel dettaglio:
Vediamo un possibile algoritmo (approssimato):
z = 0; % val. della somma
old_z = -Inf; % vecchio z
for n = 1:1e5 % 1e5 = iterazioni massime
z = z + 1 ./ n.^s;
if abs(z - old_z) < 1e-6 % 1e-6 è la tolleranza
break % Interrompe il ciclo
end
old_z = z; % rimpiazzo il vecchio z
end
Inf
è un valore speciale che denota \(\infty\)L’istruzione
break
, quando eseguita, interrompe il ciclo corrente
break
Un altro esempio con break
: controllare se un vettore V
contiene 0
break
Un altro esempio con break
: controllare se un vettore V
contiene 0
break
Un altro esempio con break
: controllare se un vettore V
contiene 0
break
Possiamo migliorare l’algoritmo:
0
, non serve controllare il resto del vettore!break
break
rende il codice un po’ più efficienteLe istruzioni condizionali e di iterazione:
Teorema del Programma Strutturato: la possibilità di comporre istruzioni per sequenza, condizione ed iterazione è sufficiente a codificare qualunque algoritmo
Quasi tutti i linguaggi si basano su questi tre metodi di composizione
Estraete lo start-kit per questa lezione:
my_prod.m
La funzione rand
zeros
, ones
, etc.Analogamente, le funzioni:
1
e MAX
Nel file di script my_prod.m
Calcolate il prodotto degli elementi del vettore x
prod
Nel file di script my_dot.m
Scrivere uno script che calcoli il prodotto scalare:
\[ X \cdot Y = \sum_{i = 1}^n X_i Y_i \]
Matlab permette di calcolarlo in due modi:
Matlab fornisce la funzione:
N
è primoNel file di script my_isprime.m
:
X
da usare come esempioprime
vale ancora true
…In matematica, l’operatore modulo:
\[ z = x \mod y \]
$x$
per $y$
x
è divisibile per y
se e solo se il resto è 0
Matlab permette di calcolare la divisione intera con:
Esempio:
Nel file di script my_norm.m
Scrivere uno script che calcoli la norma: \[ \| x \| = \sqrt{\sum_{i=1}^n x_i^2} \]
Matlab fornisce una funzione per calcolare la norma di un vettore:
X
è il vettore, P
è l’ordine della normaP = 2
, la funzione calcola la distanza euclidea dall’origineConfrontate il vostro risultato con quello di Matlab
Matlab permette di costruire una matrice diagonale con:
X
\[ \left(\begin{array}{cccc} x_1 & 0 & \ldots & 0 \\ 0 & x_2 & \ldots & 0 \\ \ldots & \ldots & \ldots & \ldots \\ 0 & 0 & \ldots & x_n \\ \end{array}\right) \]
Nel file di script my_diag.m
:
X
(fornito) come diagonale principaleConfrontate il vostro risultato con quello di Matlab
rand
/randi
per ottenere dei vettori di test