Flusso di controllo
Controllo condizionale: if, else, switch
Le dichiarazioni condizionali consentono di selezionare, durante l'esecuzione, i blocchi di codici da eseguire. La dichiarazione condizionale più semplice è una dichiarazione if
. Ad esempio:
% Generate a random number a = randi(100, 1); % If it is even, divide by 2 if rem(a, 2) == 0 disp('a is even') b = a/2; end
Le dichiarazioni if
possono includere scelte alternative, tramite le parole chiave opzionali elseif
o else
. Ad esempio:
a = randi(100, 1); if a < 30 disp('small') elseif a < 80 disp('medium') else disp('large') end
In alternativa, per effettuare il test dell'uguaglianza rispetto a una serie di valori noti, utilizzare una dichiarazione switch
. Ad esempio:
[dayNum, dayString] = weekday(date, 'long', 'en_US'); switch dayString case 'Monday' disp('Start of the work week') case 'Tuesday' disp('Day 2') case 'Wednesday' disp('Day 3') case 'Thursday' disp('Day 4') case 'Friday' disp('Last day of the work week') otherwise disp('Weekend!') end
MATLAB®, sia per if
che per switch
, esegue il codice corrispondente alla prima condizione vera, quindi esce dal blocco di codice. Ogni dichiarazione condizionale richiede la parola chiave end
.
In generale, in caso di numerosi possibili valori discreti noti, risulta più semplice leggere le dichiarazioni switch
rispetto a if
. Non è tuttavia possibile effettuare test di disuguaglianza tra i valori di switch
e di case
. Ad esempio, non è possibile implementare questo tipo di condizione con una dichiarazione switch
:
yourNumber = input('Enter a number: '); if yourNumber < 0 disp('Negative') elseif yourNumber > 0 disp('Positive') else disp('Zero') end
Confronto tra array nelle dichiarazioni condizionali
È importante comprendere il funzionamento degli operatori relazionali e delle dichiarazioni if
con le matrici. Per verificare l'uguaglianza tra due variabili è possibile utilizzare
if A == B, ...
Si tratta di codice di MATLAB valido, che funziona come previsto quando A
e B
sono scalari. Ma quando A
e B
sono matrici, A == B
non testa se sono uguali, ma dove sono uguali; il risultato è un'altra matrice di 0 e 1 che dimostra l'uguaglianza di ogni singolo elemento.
A = magic(4); B = A; B(1,1) = 0; A == B ans = 4×4 logical array 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
Il metodo appropriato per verificare l'uguaglianza tra due variabili consiste nell'utilizzare la funzione isequal
:
if isequal(A, B), ...
isequal
restituisce un valore logico scalare di 1
(che significa true
) o 0
(false
), invece di una matrice, come espressione da valutare tramite la funzione if
. Utilizzando le matrici A
e B
sopra riportate, si ottiene
isequal(A,B) ans = logical 0
Ecco un altro esempio per sottolineare questo punto. Se A
e B
sono scalari, il programma seguente non raggiungerà mai la "situazione non prevista". Per la maggior parte delle matrici, inclusi i nostri quadrati magici con colonne scambiate, tuttavia, nessuna delle condizioni di matrice A > B
, A < B
o A == B
risulta vera per tutti gli elementi, quindi viene eseguita la clausola else
:
if A > B 'greater' elseif A < B 'less' elseif A == B 'equal' else error('Unexpected situation') end
Diverse funzioni sono utili per ridurre i risultati dei confronti di matrici a condizioni scalari, da utilizzare con if
, incluso
isequal isempty all any
Controllo sui loop: for, while, continue, break
Questa sezione illustra le funzioni di MATLAB che offrono un controllo sui loop nei programmi.
for
Il loop for
ripete un gruppo di dichiarazioni per un numero fisso e predeterminato di volte. Le dichiarazioni sono delimitate da un end
corrispondente:
for n = 3:32 r(n) = rank(magic(n)); end r
Il punto e virgola che conclude la dichiarazione interna sopprime la ripetizione della stampa, mentre l'elemento r
dopo il loop visualizza il risultato finale.
È buona prassi far rientrare i loop per una maggior leggibilità, in particolare quando sono annidati:
for i = 1:m for j = 1:n H(i,j) = 1/(i+j); end end
while
Il loop while
ripete un gruppo di dichiarazioni per un numero indefinito di volte sotto il controllo di una condizione logica. Le dichiarazioni sono delimitate da un end
corrispondente.
Qui di seguito viene riportato un programma completo, che illustra l'uso di while
, if
, else
ed end
, che cerca lo zero di un polinomio con il metodo della bisezione di un intervallo:
a = 0; fa = -Inf; b = 3; fb = Inf; while b-a > eps*b x = (a+b)/2; fx = x^3-2*x-5; if sign(fx) == sign(fa) a = x; fa = fx; else b = x; fb = fx; end end x
Il risultato è la radice del polinomio x3 – 2x – 5, vale a dire
x = 2.09455148154233
Quanto riportato relativamente ai confronti tra matrici nella sezione sulla dichiarazione if
si applica anche alla dichiarazione while
.
continue
La dichiarazione continue
passa il controllo all'iterazione successiva del loop for
o del loop while
in cui appare, saltando le restanti dichiarazioni nel corpo del loop. Lo stesso vale per le dichiarazioni continue
nei loop annidati. Ciò significa che l'esecuzione continua all'inizio del loop in cui si trova la dichiarazione continue
.
L'esempio seguente illustra un loop continue
che conta le righe di codice nel file magic.m
, saltando tutte le righe vuote e i commenti. Una dichiarazione continue
consente di passare alla riga successiva in magic.m
senza incrementare il conteggio ogni volta che viene rilevata una riga vuota o una riga di commento:
fid = fopen('magic.m','r'); count = 0; while ~feof(fid) line = fgetl(fid); if isempty(line) || strncmp(line,'%',1) || ~ischar(line) continue end count = count + 1; end fprintf('%d lines\n',count); fclose(fid);
break
La dichiarazione break
consente di uscire anticipatamente da un loop for
o da un loop while
. Nei loop annidati, break
esce solo dal loop più interno.
Ecco un miglioramento dell'esempio della sezione precedente. Perché è una buona idea usare break
in questo modo?
a = 0; fa = -Inf; b = 3; fb = Inf; while b-a > eps*b x = (a+b)/2; fx = x^3-2*x-5; if fx == 0 break elseif sign(fx) == sign(fa) a = x; fa = fx; else b = x; fb = fx; end end x
Termine del programma: return
Questa sezione illustra la funzione MATLAB return
che consente di terminare il programma prima del completamento dell'esecuzione.
return
return
termina la sequenza corrente di comandi e restituisce il controllo alla funzione invocante o alla tastiera. return
è utilizzato anche per terminare la modalità keyboard
. Una funzione invocata solitamente trasferisce il controllo alla funzione che l'ha invocata quando raggiunge la fine della funzione. È possibile inserire una dichiarazione return
all'interno della funzione invocata per terminarla anticipatamente e trasferire il controllo alla funzione invocante.
Vettorializzazione
Un metodo per velocizzare l'esecuzione dei programmi di MATLAB consiste nel vettorializzare gli algoritmi utilizzati nella realizzazione del programma. Nei casi in cui altri programmi potrebbero utilizzare i loop for
o DO
, MATLAB è in grado di utilizzare operazioni su vettori o matrici. Un semplice esempio richiede la creazione di una tabella di logaritmi:
x = 0.01; y = log10(x); for k = 1:999 x(k+1) = x(k) + 0.01; y(k+1) = log10(x(k+1)); end
Una versione vettorializzata dello stesso codice è
x = .01:.01:10; y = log10(x);
In caso di codice più complesso, le opzioni di vettorializzazione non sono sempre così ovvie.
Pre-allocazione
Se non fosse possibile vettorializzare una parte di codice, velocizzare l'esecuzione dei loop for
pre-allocando qualsiasi vettore o array in cui vengono memorizzati i risultati dell'output. Ad esempio, questo codice utilizza la funzione zeros
per pre-allocare il vettore creato nel loop for
. Questo velocizza notevolmente l'esecuzione del loop for
:
r = zeros(32,1); for n = 1:32 r(n) = rank(magic(n)); end
Senza la preallocazione dell'esempio precedente, l'interprete di MATLAB aumenta il vettore r
un elemento alla volta per tutto il loop. La pre-allocazione del vettore elimina questa fase e consente di velocizzare l'esecuzione.