Supponiamo di avere il nostro algoritmo per \(\zeta(s)\) in uno script:
Supponiamo di avere il nostro algoritmo per \(\zeta(s)\) in uno script:
s = 3;
z = 0;
old_z = -1;
n = 1;
for i = 1:10000
z = z + 1 ./ n.^s;
if abs(z - old_z) < 1e-6
break
end
old_z = z;
end
s = 3
s
, dobbiamo modificare lo scriptI file di script sono utili per:
Non sono adatti a definire un algoritmo riutilizzabile
Per tali casi possiamo definire una nuova funzione
Stiamo usando funzioni già dalla prima lezione!
Per definire una nuova funzione si usa la sintassi:
<fn>
è il nome della funzione<pXX>
sono nomi di variabili (si chiamano parametri formali)<res>
è il nome della variabile da restituireSi chiama interfaccia di una funzione l’insieme del suo nome, dei parametri e delle variabili di ritorno
Per definire una nuova funzione si usa la sintassi:
Usiamo come esempio la nostra Zeta di Riemann:
zeta
s
z
Cosa succede quando eseguiamo (e.g.) zeta(3)
+[INVIO]?
zeta
Cosa succede quando eseguiamo (e.g.) zeta(3)
+[INVIO]?
Cosa succede quando eseguiamo (e.g.) zeta(3)
+[INVIO]?
Cosa succede quando eseguiamo (e.g.) zeta(3)
+[INVIO]?
Cosa succede quando eseguiamo (e.g.) zeta(3)
+[INVIO]?
Cosa succede quando eseguiamo (e.g.) zeta(3)
+[INVIO]?
Cosa succede quando eseguiamo (e.g.) zeta(3)
+[INVIO]?
Cosa succede quando eseguiamo (e.g.) zeta(3)
+[INVIO]?
z
vale circa 1.2
)Cosa succede quando eseguiamo (e.g.) zeta(3)
+[INVIO]?
z
(variabile di ritorno) viene copiato nel chiamanteCosa succede quando eseguiamo (e.g.) zeta(3)
+[INVIO]?
Cosa succede quando eseguiamo (e.g.) zeta(3)
+[INVIO]?
ans
Qualche considerazione, usando la nostra zeta
come esempio:
Quando la funzione viene chiamata:
Il record di attivazione viene distrutto quando il corpo della funzione termina
Qualche considerazione, usando la nostra zeta
come esempio:
Le variabili definite all’interno della funzione (z
, old_z
…):
Qualche considerazione, usando la nostra zeta
come esempio:
I parametri formali (s
in questo caso) sono variabili locali:
I parametri attuali (3
in zeta(3)
) sono valori:
Qualche considerazione, usando la nostra zeta
come esempio:
Il passaggio di parametri è posizionale:
Qualche considerazione, usando la nostra zeta
come esempio:
Se alcuni parametri attuali vengono omessi nella chiamata:
s
non è disponibileNot enough input arguments
Qualche considerazione, usando la nostra zeta
come esempio:
La variabile di ritorno (in queso caso z
)
Qualche considerazione, usando la nostra zeta
come esempio:
Il corpo di una funzione può contenere una chiamata a funzione:****
Abbiamo visto che:
Questi spazi di memoria si chiamano ambienti. Vale la regola che:
Le variabili in un ambiente sono accessibili (visibili) solo per il codice “proprietario” dell’ambiente
In sintesi:
È possibile ispezionare l’ambiente corrente utilizzando i comandi:
È possibile eliminare una variabile utilizzando:
Come abbiamo visto, eliminiamo tutte le variabili con:
In Matlab, una funzione può avere più variabili di ritorno
<r1>
, <r2>
, etc. sono nomi di variabiliLa funzione può essere chiamata con:
<r1>
, <r2>
, etc. sono altri nomi di variabiliUn esempio: restituire la parte reale ed immaginaria
Possiamo chiamarla con:
R
ed imm
…Non c’entrano con R
ed I
nella funzione!
Se ci interessa solo la parte reale, va bene anche:
R
Quindi, ci possono essere molti modi di chiamare una funzione:
Controllate la documentazione (help
, doc
) delle funzioni che usiamo!
Consideriamo una funzione per trovare 0
in una matrice
function trovato = find_zero(A)
trovato = false;
[m, n] = size(A)
for i == 1:m
for j == 1:n
if A(i, j) == 0;
trovato = true;
break;
end
end
end
end
break
interrompe il ciclo su j
, ma non quello su i
!Consideriamo una funzione per trovare 0
in una matrice
function trovato = find_zero(A)
trovato = false;
[m, n] = size(A)
for i == 1:m
for j == 1:n
if A(i, j) == 0;
trovato = true;
return; % INTERROMPE LA FUNZIONE
end
end
end
end
return
interrompe immediatamente la funzioneIn Matlab \(>\) 2016b si può definire una funzione in un file di script
Un caso tipico:
In alternativa, una funzione può essere inserita in un file a parte
In particolare, in Matlab si chiama file di funzione
.m
…Per esempio, nel file zeta.m
possiamo inserire:
In Matlab 2016a, questa è l’unica alternativa possibile
Quando proviamo ad invocare (e.g.) zeta(3)
:
zeta.m
”La ricerca avviene all’interno di una serie di cartelle:
Attenzione ai nomi!
sum
in “sum.m
”sum
di MatlabMatlab pre-2016b non permette di definire funzioni in script
A però volte una funzione è utile solo per un determinato problema
In questo caso definire un file di funzione rende le cose più complicate
È possibile aggirare il problema?
Sì! Il modo più semplice consiste in:
Matlab permette di definire più funzioni in un unico file
Per esempio, nel file somma_mat.m
:
Matlab permette di definire più funzioni in un unico file
La funzione principale:
Le funzioni ausiliarie:
Supponiamo di avere uno script del genere:
Possiamo convertirlo in una funzione!
clear all
è inutile (il record di attivazione è inizialmente vuoto)
function my_test()
W = rand(1, 1000);
res = my_sum(W)
end
function s = my_sum(V)
s = 0;
for v in V
s = s + v;
end
end
Inseriamo tutto questo in un file di funzione my_test.m
Per eseguire lo “script”, dobbiamo chiamarlo come funzione
…Del resto, a questo punto è una funzione
Nota: se vogliamo chiamare una funzione senza parametri:
()
”…Problema: confrontare due orari
[hh, mm]
Vogliamo definire nello script es_timecmp.m
una funzione:
Tale che il risultato sia
-1
se il primo orario precede il secondo0
se sono uguali+1
se il secondo orario precede il primoNel file di funzione es_timecmp.m
:
function es_timecmp()
res1 = timecmp([15, 00], [15, 21])
res2 = timecmp([15, 00], [14, 59])
res3 = timecmp([15, 00], [15, 00])
end
function res = timecmp(t1, t2)
...
end
timecmp
…Vediamo una possibile implementazione di timecmp
:
Il calore (specifico) molare di un sostanza:
\[c_p^* = a + b\, T + c\, T^2 + d\, T^3\]
Avete visto/vedrete questi argomenti nel corso di Termodinamica
Matlab fornisce funzioni per operare su polinomi
Un polinomio viene rappresentato come un vettore di coefficienti:
\[\underline{c_n} x^n + \underline{c_{n-1}} x^{n-1} + \ldots + \underline{c_1} x + \underline{c_0} \ \longleftrightarrow \ p = (c_n, c_{n-1}, \ldots c_1, c_0)\]
length(p)-1
Quindi, per il calore molare:
[d, c, b, a]
(invertito!)Consideriamo il composto \(n\)-ottano
Vogliamo studiarne il calore molare in funzione della temperatura
Dobbiamo valutare un polinomio. In Matlab possiamo usare:
P
è il polinomio da valutareX
è il valore di \(x\) e può essere anche un vettoreY
è il vettore con la valutazione di ogni elemento di X
es_polyval.m
nello start-kitParte 1: calcolate il calore molare con polyval
di Matlab
plot
Parte 2: nello stesso file, definite una funzione:
p
…x
è uno scalare (per semplicità)my_polyval
e disegnatelaIl valore di \(c_p^*\) è necessario per calcolare la differenza di Entalpia
\[\Delta H = \int_{T_0}^{T_1} c_p^*(T) \, dT\]
Dal punto di vista matematico:
A partire da essa possiamo calcolare:
\[\Delta H = C_p^*(T_1) - C_p^*(T_0)\]
Matlab fornisce una funzione per integrare e derivare polinomi
Dato un polinomio:
\[c_n\, x^n + c_{n-1}\, x^{n-1} + \ldots + c_1\, x + c_0\]
Il suo integrale è un altro polinomio, ossia:
\[\frac{1}{n+1} c_n\, x^{n+1} + \frac{1}{n} c_{n}\, x^{n-1} + \ldots + \frac{1}{2} c_1\, x^2 + c_0\, x\]
Matlab fornisce una funzione per integrare e derivare polinomi
In termini della rappresentazione utilizzata da Matlab:
p
è il polinomio (vettore di coefficienti) da integrareP
è il polinomio (vettore di coefficienti) risultatoP
ha un grado in più (un elemento in più) di p
:\[(c_n, c_{n-1}, \ldots c_1, c_0) \longrightarrow \left(\frac{1}{n+1} c_n, \frac{1}{n} c_{n-1}, \ldots \frac{1}{2} c_1, c_0, 0\right)\]
Matlab fornisce una funzione per integrare e derivare polinomi
Per esempio:
Calcolate \(\Delta H\) per l’\(n\)-ottano tra 300K e 400K
Utilizzate come partenza il file es_polyint.m
Step 1: Calcolate il polinomio integrale \(C_p^*(T)\) con polyint
polyval
per calcolare \(C_p^*(T)\) a 300K e 400KStep 2: Definite la funzione
p
…P
polyint
Matlab fornisce la funzione:
0
Nel file di script es_find
, definite la funzione (ausiliaria):
Scrivere del codice di test nella funzione principale
rand
non genera mai 0
Matlab fornisce la funzione:
Che restituisce un vettore con il fattoriale di ogni numero in V
V
devono essere numeri interi\[n! = \left\{\begin{aligned} & 1 && \text{ se } n = 0\\ & \prod_{i = 1}^n i && \text{ se } n > 0 \end{aligned}\right.\]
Si definisca un file di funzione es_factorial
, contenente:
Una funzione ausiliaria:
factorial
Si verifichi il funzionamento:
my_factorial
e factorial
su un vettore scelto a manoAbbiamo visto che Matlab permette di accedere ad un vettore con:
V
è un vettoreI
è un vettore di valori logiciNel file di funzione es_index2.m
, definite la funzione (ausiliaria):
Che replichi la stessa funzionalità
In matematica, dato un polinomio:
\[c_n\, x^{n} + c_{n-1}\, x^{n-1} + \ldots + c_0\]
La sua derivata è un altro polinomio:
\[n\, c_n\, x^{n-1} + (n-1)c_{n-1}\, x^{n-2} + \ldots + c_1\]
In termini della rappresentazione utilizzata da Matlab:
\[(c_n, c_{n-1}, \ldots c_1, c_0) \longrightarrow (n c_n, (n-1) c_{n-1}, \ldots c_1)\]
Lo possiamo calcolare con la funzione predefinita:
In un file di funzione es_polyder.m
:
Definire una funzione (ausiliaria):
p
…dp
Quindi, nella funzione principale:
polyder
Matlab fornisce la funzione:
X
che restituisce gli elementi distinti del vettore X
Nel file di funzione es_unique.m
, definite una la funzione (ausiliaria):
Che replichi la stessa funzionalità