Funzioni definite dall'utente in MATLAB

In questa lezione vediamo come creare funzioni definite dall'utente in MATLAB.

A differenza di uno script, una funzione è un blocco di codice che può essere riutilizzato in più punti del programma. Inoltre, una funzione può avere degli argomenti e può restituire un valore.

Definire una funzione

In MATLAB ci sono differenti modi per organizzare script e funzioni. Per il momento, però, ogniqualvolta creeremo uno script o una funzione la creeremo in un file separato.

Anche le funzioni come gli script vanno create in un file con estensione .m, ossia un M-file. Analogamente agli script, per creare una funzione possiamo usare il menu New e poi Function. In alternativa possiamo usare il comando edit seguito dal nome della funzione che vogliamo creare.

edit mia_funzione

A questo punto si avvia l'editor di MATLAB e possiamo scrivere il codice della nostra funzione.

In generale, la struttura di una funzione in MATLAB è composta dai seguenti elementi:

  1. L'intestazione della funzione, con il nome della funzione, gli eventuali argomenti e il valore di ritorno;
  2. Una o più righe di commento che descrivono la funzione;
  3. Il corpo della funzione, ossia il codice che esegue le operazioni necessarie per ottenere il risultato;
  4. L'istruzione end che indica la fine della funzione.

Per cui, in generale l'aspetto di una funzione è il seguente:

function argomento_output = nome_funzione(argomento1, argomento2, ...)
% Descrizione della funzione

% Corpo della funzione

end

Proviamo a chiarire con un esempio. Supponiamo di voler creare una funzione che calcoli il volume di una sfera prendendo in input il raggio. Il codice della funzione sarà il seguente:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
function volume = volume_sfera(r)
% Calcola il volume di una sfera
% Input:
%   r: raggio della sfera
% Output:
%   volume: volume della sfera

    volume = (4/3) * pi * r^3;

end

Proviamo ad esaminare questa funzione riga per riga.

La prima riga è l'intestazione della funzione. Qui abbiamo definito che la funzione prende in input un argomento r e restituisce un valore volume. In questo caso, il nome della funzione è volume_sfera. Bisogna notare che il nome della funzione è uguale al nome del file in cui è contenuta, ossia volume_sfera.m. Questo non è un requisito obbligatorio, ma è una buona pratica di programmazione.

Consiglio

Nome della funzione e nome del file

Anche se non è obbligatorio, è sempre una buona pratica assegnare al file contenente la funzione lo stesso nome della funzione stessa. Per cui, se creiamo una funzione di nome mia_funzione, il file contenente la funzione dovrà chiamarsi mia_funzione.m.

Le righe dalla 2 alla 6 sono commenti che descrivono la funzione. Analogamente al caso degli script questi commenti sono utilizzati dalla funzione help per generare la documentazione della funzione. Infatti, se eseguiamo il comando help volume_sfera otteniamo la seguente documentazione:

>> help volume_sfera
  Calcola il volume di una sfera
  Input:
    r: raggio della sfera
  Output:
    volume: volume della sfera

La riga 8 rappresenta il vero e proprio corpo della funzione. Qui viene effettivamente calcolato il volume della sfera. Per restituire il risultato all'esterno della funzione, basta assegnare il valore all'argomento di output volume che abbiamo definito nell'intestazione. Assegnare un valore all'argomento di output è l'unico modo per restituire un valore dalla funzione.

Infine, la riga 10 è l'istruzione end che indica la fine della funzione.

Definizione

Definire una funzione

Per definire una funzione in MATLAB è necessario creare un file con estensione .m contenente il codice della funzione. La sintassi di una funzione in MATLAB è la seguente:

function argomento_output = nome_funzione(argomento1, argomento2, ...)
% Descrizione della funzione

% Corpo della funzione

end

In questo caso ci siamo concentrati sul definire una funzione che restituisce un unico valore. Vedremo successivamente come definire funzioni che restituiscono risultati multipli.

Invocare una funzione

Una volta definita una funzione, possiamo invocarla dal prompt di MATLAB nello stesso modo con cui invochiamo una funzione incorporata.

In altre parole, possiamo invocare la nostra funzione scrivendo il nome stesso seguito dalla lista degli argomenti tra parentesi tonde. Per cui, tornando all'esempio del volume della sfera, possiamo invocare la funzione volume_sfera scrivendo:

>> volume_sfera(4)

ans =

  268.0826

A questo punto possiamo utilizzare la nostra funzione come se fosse una funzione qualunque, usandola in espressioni complesse, assegnandola ad una variabile oppure usandola come argomento di altre funzioni.

>> volume = volume_sfera(4)

volume =

  268.0826

>> volume_sfera(4) + 10

ans =

  278.0826

>> sqrt(volume_sfera(4))

ans =

    16.3791
Definizione

Invocare una funzione

Per invocare una funzione in MATLAB è sufficiente scrivere il nome della funzione seguito dalla lista degli argomenti tra parentesi tonde.

La sintassi per invocare una funzione è la seguente:

nome_funzione(argomento1, argomento2, ...)

Generalizzare una funzione per i vettori

Nell'esempio precedente abbiamo definito una funzione che calcola il volume di una sfera supponendo che in ingresso venga fornito il raggio come un singolo argomento scalare.

Ci domandiamo cosa accade se proviamo ad invocare la funzione volume_sfera passandole un vettore di raggi, ossia un insieme di raggi.

>> volume_sfera([1 2 3])
Error using  ^ 
Incorrect dimensions for raising a matrix to a power. Check that the matrix is square and the power is a
scalar. To operate on each element of the matrix individually, use POWER (.^) for elementwise power.

Error in volume_sfera (line 8)
    volume = (4/3) * pi * r^3;

Abbiamo ottenuto un errore. Questo accade perché la funzione volume_sfera è stata definita usando l'operatore di elevamento a potenza per scalari ^.

Volendo, invece, lavorare con vettori o matrici possiamo modificare la funzione usando l'operatore di elevamento a potenza elemento per elemento: .^.

function volume = volume_sfera(r)
% Calcola il volume di una sfera
% Input:
%   r: raggio della sfera
%      può essere uno scalare o un vettore
% Output:
%   volume: volume della sfera

    volume = (4/3) * pi * r.^3;

end

A questo punto possiamo invocare la funzione volume_sfera passandole un vettore di raggi. MATLAB applicherà la funzione ai singoli elementi del vettore, ottimizzando l'esecuzione della funzione.

>> volume_sfera([1 2 3])

ans =

    4.1888   33.5103  113.0973

In questo modo, con una singola esecuzione, abbiamo potuto calcolare il volume di una sfera per tre raggi diversi.

In generale è sempre buona norma in MATLAB definire le funzioni in modo che possano essere invocate con argomenti scalari, vettori o matrici. Questo soprattutto in ottica del fatto che spesso le funzioni vengono invocate su insiemi di dati sotto forma di vettori o matrici.

Funzioni con più argomenti di input

Una funzione MATLAB può richiedere in ingresso più di un argomento. Per esempio, possiamo definire una funzione che calcola l'area di un poligono regolare. Tale funzione avrà due argomenti di input: il numero di lati del poligono e la lunghezza del lato.

La formula per calcolare l'area di un poligono regolare è la seguente:

A = \frac{n \cdot l^2}{4 \cdot \tan{\left(\frac{\pi}{n}\right)}}

Dove n è il numero di lati del poligono e l è la lunghezza del lato.

Per cui, possiamo definire la funzione area_poligono_regolare come segue:

function area = area_poligono_regolare(n_lati, lunghezza_lato)
% Calcola l'area di un poligono regolare
% Input:
%   n_lati: numero di lati del poligono
%   lunghezza_lato: lunghezza del lato del poligono
% Output:
%   area: area del poligono

    area = (n_lati * lunghezza_lato^2) / (4 * tan(pi/n_lati));

end

Come si può notare, per specificare più argomenti di input è sufficiente separare gli argomenti con una virgola.

A questo punto possiamo invocare la funzione area_poligono_regolare passandole due argomenti.

>> area_poligono_regolare(5, 2)

ans =

    6.8819

Il passo successivo è quello di generalizzare la funzione per lavorare con vettori di numeri di lati e vettori di lunghezze dei lati.

function aree = area_poligono_regolare(n_lati, lunghezza_lato)
% Calcola l'area di un poligono regolare
% Input:
%   n_lati: numero di lati del poligono
%           può essere uno scalare o un vettore
%   lunghezza_lato: lunghezza del lato del poligono
%                   può essere uno scalare o un vettore
% Output:
%   area: area del poligono

    aree = (n_lati .* lunghezza_lato.^2) ./ (4 * tan(pi./n_lati));

end

A questo punto possiamo calcolare l'area di un pentagono, di un esagono e di un decagono, tutti con un lato di lunghezza 2 con un'unica invocazione della funzione:

>> area_poligono_regolare([5 6 10], 2)

ans =

    6.8819   10.3923   30.7768

Oppure possiamo calcolare l'area di un pentagono, di un esagono e di un decagono, tutti con un lato di lunghezza diversa, con un'unica invocazione della funzione:

>> area_poligono_regolare([5 6 10], [2 3 4])

ans =

    6.8819   23.3827  123.1073

Funzioni con più argomenti di output

Una funzione MATLAB può restituire più di un argomento. Per esempio, possiamo definire una funzione che calcola l'area e il perimetro di un poligono regolare.

Per poter definire una funzione di questo tipo dobbiamo modificare l'intestazione della funzione usando una sintassi leggermente differente:

function [area, perimetro] = area_perimetro_poligono_regolare(n_lati, lunghezza_lato)
% Calcola l'area e il perimetro di un poligono regolare
% Input:
%   n_lati: numero di lati del poligono
%           può essere uno scalare o un vettore
%   lunghezza_lato: lunghezza del lato del poligono
%                   può essere uno scalare o un vettore
% Output:
%   area: area del poligono
%   perimetro: perimetro del poligono

    area = (n_lati .* lunghezza_lato.^2) ./ (4 * tan(pi./n_lati));
    perimetro = n_lati * lunghezza_lato;

end

Come si può notare, per specificare più argomenti di output è sufficiente separare gli argomenti con una virgola e racchiuderli tra parentesi quadre.

Definizione

Funzioni con più argomenti di output

In MATLAB è possibile specificare più argomenti di output per una funzione. La sintassi è la seguente:

function [output1, output2, ..., outputN] = nome_funzione(input1, input2, ..., inputN)
    % corpo della funzione
end

Invocare una funzione con più argomenti di output

Una volta definita una funzione con più argomenti di output, bisogna prestare attenzione al modo in cui essa viene invocata.

Riprendiamo l'esempio della funzione area_perimetro_poligono_regolare che calcola l'area e il perimetro di un poligono regolare.

Se proviamo ad invocarla normalmente, come abbiamo fatto per le funzioni con un solo argomento di output, otteniamo un risultato a prima vista inaspettato:

>> area_perimetro_poligono_regolare(5, 2)

ans =

    6.8819

In questo caso MATLAB ci restituisce solo l'area del poligono, ignorando il perimetro.

In altre parole, quando si invoca una funzione con più argomenti di output, MATLAB restituisce solo il primo argomento di output.

Per ottenere tutti gli argomenti di output è necessario modificare il modo in cui viene invocata la funzione. In particolare, bisogna specificare esplicitamente un vettore che contiene tutti gli argomenti di output. Per esempio:

>> [area, perimetro] = area_perimetro_poligono_regolare(5, 2)

area =

    6.8819


perimetro =

    10

Solo in questo modo MATLAB ci restituisce sia l'area che il perimetro del poligono.

Definizione

Invocare una funzione con più argomenti di output

Per poter ottenere tutti gli argomenti di output di una funzione, è necessario specificare un vettore con un identificatore per ogni argomento di output.

La sintassi di invocazione è la seguente:

[output1, output2, ..., outputN] = nome_funzione(input1, input2, ..., inputN)

In Sintesi

In questa lezione abbiamo visto come definire e invocare funzioni in MATLAB.

In particolare, abbiamo visto come:

  • definire una funzione con un solo argomento di input e un solo argomento di output
  • definire una funzione con più argomenti di input e un solo argomento di output
  • definire una funzione con più argomenti di input e più argomenti di output

Inoltre abbiamo visto come invocare tali funzioni.