Sei sulla pagina 1di 61

Matlab per

lIngegnere
Chimico

Matlab per lIngegnere Chimico


Sommario
Struttura di Matlab ............................................................................................................................................ 3
Alcuni comandi base.......................................................................................................................................... 3
% e %%........................................................................................................................................................... 3
clc ................................................................................................................................................................... 3
clear all .......................................................................................................................................................... 3
close all .......................................................................................................................................................... 4
help ................................................................................................................................................................ 4
Definizione di nuove variabili ............................................................................................................................ 4
Definizione di variabile .................................................................................................................................. 4
Definizione di un vettore ............................................................................................................................... 4
linspace e logspace .................................................................................................................................... 5
Definizione di una matrice............................................................................................................................. 5
Operazioni tra scalari......................................................................................................................................... 7
Operazioni con i vettori e con le matrici ........................................................................................................... 8
Selezione di elementi .................................................................................................................................... 8
Determinazione delle dimensioni.................................................................................................................. 9
Ricerca di massimi e minimi ........................................................................................................................ 10
Somma degli elementi ................................................................................................................................. 11
Trasposizione ............................................................................................................................................... 11
Determinante di una matrice ...................................................................................................................... 12
Inversione di una matrice ............................................................................................................................ 12
Operazioni tra matrici/vettori e scalari ....................................................................................................... 12
Operazioni tra matrici e vettori ................................................................................................................... 13
Somma e sottrazione ............................................................................................................................... 13
Prodotto tra vettori e matrici .................................................................................................................. 14
Divisione tra matrici................................................................................................................................. 15
Operazioni elemento per elemento ............................................................................................................ 16
Cicli for, if, while .............................................................................................................................................. 17
Ciclo for........................................................................................................................................................ 17
Ciclo if .......................................................................................................................................................... 21
Ciclo while.................................................................................................................................................... 24
Function ........................................................................................................................................................... 26
1

Rappresentazione di grafici ............................................................................................................................. 29


Rappresentazione di grafici 1D .................................................................................................................... 29
Rappresentazione di grafici 2D .................................................................................................................... 36
Rappresentazione e salvataggio dei risultati ................................................................................................... 39
fprintf ........................................................................................................................................................... 40
Integrazione ..................................................................................................................................................... 41
Integrazione numerica................................................................................................................................. 41
Integrazione simbolica................................................................................................................................. 43
Risoluzione di equazioni e sistemi ................................................................................................................... 44
Comando fzero ............................................................................................................................................ 44
Comando fsolve ........................................................................................................................................... 47
Risoluzione di equazioni differenziali .............................................................................................................. 56
Sistemi di equazioni differenziali di primo ordine ....................................................................................... 56
Problemi differenziali di ordine superiore................................................................................................... 59

Struttura di Matlab
Quando aprirai il programma noterai quattro aree principali: Current Folder, Command Window, Workspace
e Command History. La loro funzione risulta essere la seguente:

Command Window: in questa finestra possibile inserire i comandi che vuoi che Matlab esegua.
Utilizzare direttamente la Command Window per programmare risulta essere sconveniente. La via
pi agevole aprire un nuovo script (pulsante solitamente in alto a sinistra), che consente di scrivere
righe di comando e di salvarle successivamente a computer. Quando si vogliono eseguire quelle
specifiche righe di comando, basta aprire lo script con Matlab ed eseguirlo.
Current Folder: il percorso utilizzato da Matlab per risalire ai programmi che gli chiedi di eseguire.
Se chiedi a Matlab di eseguire un programma che non nella sua attuale folder, Matlab ti chieder
di cambiare folder, in modo tale da poter risalire alle righe di codice in questione. Da questo derivano
delle importanti implicazioni: se una risoluzione distribuita in pi script o function (vediamo dopo
di cosa si tratta), importante che siano tutte nella medesima cartella, affinch Matlab possa
eseguire la risoluzione.
Workspace: lo spazio in cui possono essere ricercate le varie variabili definite durante la
programmazione. Quando Matlab esegue il programma, definisce le variabili e queste possono
essere ricercate allinterno della Workspace.
Command History: contiene la cronologia dei comandi eseguiti nella Command Window.

Ora che abbiamo visto la struttura del programma, ti consiglio di aprire un nuovo script, in modo tale da fare
pratica con i seguenti comandi che vedremo.

Alcuni comandi base


Le possibilit offerte da Matlab sono moltissime. Prima di approfondire quelle applicazioni che rivestono
maggiore importanza nellambito dellIngegneria Chimica, risulta essere utile affrontare i comandi basi del
programma. Vediamoli insieme.

% e %%
In Matlab, tutto ci che risulta essere preceduto dal simbolo di percentuale non viene letto come riga di
comando (e appare colorato di verde). Dunque, se vogliamo inserire allinterno dello script dei commenti o
delle indicazioni utili (ad esempio procedure risolutive o unit di misura), bene farle precedere dal %. Se si
affiancano due simboli di percentuale (%%) si ottiene una suddivisione del programma stesso, e risulta essere
utile per avere una distinzione formale tra i diversi step risolutivi (definizione variabili, calcoli preliminari,
algoritmi di risoluzione, etc etc). Per commentare unintera porzione di testo basta selezionarla e premere
ctrl+r, mentre per de-commentarla basta eseguire la medesima operazione premendo per ctrl+t.

clc
Prima di eseguire un nuovo programma, risulta essere opportuno cancellare tutto quello che attualmente
presente sulla Command Window. Il comando clc, scritto tipicamente allinizio dello script, permette
proprio di fare questo.

clear all
La funzione precedentemente descritta (clc) permette di pulire la Command Window, ma non ha alcuna
influenza sulle variabili gi salvate allinterno del Workspace. Prima di eseguire dei nuovi comandi vale la
pena cancellare tutte le variabili attualmente presenti nel Workspace, e il comando clear all ha proprio
questa funzione.

close all
I precedenti script potrebbero aver generato dei grafici. A volte risulta essere scomodo chiuderli
manualmente, e si pu quindi utilizzare il comando close all per chiudere tutti i grafici attualmente aperti in
Matlab.
Riassumendo, risulta quindi utile iniziare i propri algoritmi con questi tre comandi:
%% Esempio di algoritmo in Matlab
clc
clear all
close all

% serve a pulire la command window


% serve a pulire il workspace
% serve a chiudere i grafici aperti

help
Se hai dei dubbi su come operi una certa funzione di Matlab, della quale ti ricordi il nome ma di cui non ricordi
la struttura e gli effetti, puoi ricercarla nella Command Window utilizzando il comando help. Ammettiamo ad
esempio che io non ricordi come utilizzare il comando plot. Basta che io scriva sulla Command Window:
help plot

In questo modo Matlab mi mostra la struttura e leffetto della funzione.


Ora che abbiamo ripulito Matlab dai risultati di algoritmi precedenti, siamo pronti ad eseguire nuovi
programmi. Uno step fondamentale risulta essere la definizione di nuove variabili.

Definizione di nuove variabili


Definizione di variabile
Se vogliamo definire una nuova variabile, in Matlab la procedura risulta essere alquanto semplice. Basta
decidere un nome per la nuova variabile, scrivere = e affiancarla al suo valore numerico. Di fianco alla nuova
variabile risulta essere sempre opportuno scrivere le unit di misura della medesima. Se ad esempio
volessimo definire in Matlab la costante universale dei gas (R), ci basterebbe scrivere:
R=8.314;

% J/(mol K)

Nota che dopo la scrittura del valore numerico della variabile compare un ;
Mettere il ; dopo la definizione di una variabile permette di non farne comparire il valore sulla Command
Window. Infatti, senza il ;, Matlab farebbe comparire sulla Command Window tutte le variabili definite, e
questo rende difficile la visualizzazione di risultati che sono invece di interesse. Per questo motivo, dopo aver
definito una nuova variabile, un nuovo vettore o una nuova matrice risulta essere sempre opportuno inserire
il ;

Definizione di un vettore
Per alcune quantit risulta essere pi comoda una definizione vettoriale. Si pensi ad esempio alla
composizione di una corrente in ingresso ad unapparecchiatura chimica, contenente cinque diversi
composti. Se volessimo esprimere la composizione di tale corrente mediante delle frazioni molari,
risulterebbe opportuno creare un singolo vettore che contiene tutte le informazioni di nostro interesse.
Immaginando, ad esempio, che tutti i composti siano caratterizzati dalla medesima frazione molare,
risulterebbe opportuno definire il vettore delle frazioni molari come segue:
x=[0.2 0.2 0.2 0.2 0.2];

x=[0.2,0.2,0.2,0.2,0.2];

Le diciture ora espresse permettono di generare dei vettori riga, specificandone i singoli elementi. I singoli
elementi possono essere separati da uno spazio (come nel primo caso) oppure da una virgola (come nel
secondo caso).
Se volessimo invece generare un vettore colonna, basta sostituire le , con dei ;
x=[0.2;0.2;0.2;0.2;0.2];

Questi comandi risultano essere comodi ed opportuni quando bisogna creare vettori aventi un numero
limitato di elementi. Immaginiamo ora di voler definire un nuovo vettore, che abbia come valori estremi 0 e
100 e i cui elementi siano distanziati di 1e-3 (10^-3, in linguaggio Matlab). Se dovessimo inserire a mano tutti
i valori non finiremmo pi. Per creare un vettore come questo, basta utilizzare il seguente comando:
s=0:1e-3:100;

Tra i due : riportata la spaziatura desiderata, mentre nelle zone esterne sono riportati gli estremi del
vettore. Nel caso in cui il valore della spaziatura venisse omesso, Matlab lo porrebbe automaticamente
uguale ad 1. Se volessimo trasformare il vettore ora introdotto in un vettore colonna, basterebbe trasporlo
nel seguente modo, utilizzando :
s=s';

Altri comandi utili per la definizione di un vettore risultano essere i seguenti:

linspace e logspace
Immaginiamo di voler generare un nuovo vettore riga avente estremi 0 e 100, come nel caso precedente.
Questa volta per, invece che voler specificare la spaziatura dei singoli elementi, vogliamo definire il numero
di elementi contenuti dal vettore (e lasciare a Matlab la determinazione della spaziatura). Ammettiamo nel
nostro caso di voler ottenere un vettore contenente 1000 elementi. Questo pu essere fatto con il comando
linspace, cos definito:
y=linspace(0,100,1000);

I primi due input del comando linspace corrispondono agli estremi del vettore desdierato, mentre il terzo
input corrisponde al numero totale di elementi che si desiderano nel vettore.
Funziona in modo analogo il comando logspace, con la differenza che crea una spaziatura logaritmica invece
che lineare.
y=logspace(a,b,n);

Il comando scritto genera un vettore di n elementi, logaritmicamente distanziati tra 10 e 10 .

Definizione di una matrice


Per alcune applicazioni risulta essere opportuno definire delle matrici. Si pensi ad esempio alla
determinazione di un equilibrio chimico che coinvolge pi di una reazione chimica. In questo caso risulta utile
definire una matrice di coefficienti stechiometrici, mettendo ad esempio nelle righe le varie specie chimiche
e nelle colonne le reazioni chimiche nelle quali prendono parte. Vediamo il tutto mediante un esempio:
1 : + 22 3

2 : 2 + 2 + 2
Coefficienti stechiometrici

2
2
2
3

1
-1
0
-2
0
+1

2
+1
-1
-1
+1
0

In Matlab possibile creare una matrice come quella descritta in modo del tutto analogo a come sono stati
definiti i vettori. In particolar modo, si definiscono le varie righe separando gli elementi mediante delle virgole
o degli spazi, e le varie colonne distinguendo le righe con dei ;
nu=[-1 +1;0 -1;-2 -1;0 +1;+1 0];

Un altro possibile metodo per creare delle matrici definendo prima i vettori che le compongono, e poi
unendo i due vettori per creare la matrice di interesse. Costruiamo ora la matrice precedentemente descritta,
ma unendo i vettori colonna che la caratterizzano.
nuR1=[-1;0;-2;0;+1];
nuR2=[+1;-1;-1;+1;0];
nu=[nuR1 nuR2];

Lo stesso pu essere fatto definendo prima i vettori riga e unendoli in colonne:


nuCO=[-1 +1];
nuCO2=[0 -1];
nuH2=[-2 -1];
nuH2O=[0 +1];
nuCH3OH=[+1 0];
nu=[nuCO;nuCO2;nuH2;nuH2O;nuCH3OH];

Vi sono altri comandi, che permettono di definire delle matrici o dei vettori speciali. Essi sono riassunti nella
seguente tabella:
Linea di comando:

Descrizione:
Crea una matrice identit n x n
Crea una matrice n x n avente tutti gli elementi
uguali a 1
Crea una matrice m x n avente tutti gli elementi
uguali a 1
Crea una matrice n x n avente tutti gli elementi
uguali a 0
Crea una matrice m x n avente tutti gli elementi
uguali a 0

eye(n)
ones(n)
ones(m,n)
zeros(n)
zeros(m,n)

Ora che abbiamo imparato a definire delle variabili scalari, dei vettori e delle matrici, possiamo vedere come
effettuare operazioni tra questi elementi.

Operazioni tra scalari


Come primo argomento, affrontiamo il pi semplice, ossia le operazioni tra scalari. Le operazioni principali
tra scalari, in Matlab, si fanno utilizzando i seguenti simboli:
a=5;
b=6;
c=a+b;
c=a-b;
c=a*b;
c=a/b;
c=a^b;

%
%
%
%
%

somma tra due scalari


differenza tra due scalari
prodotto tra due scalari
divisione tra due scalari
elevamento a potenza tra due scalari

Possono ovviamente essere applicate ad uno scalare unampia serie di funzioni matematiche (esponenziali,
logaritmiche, goniometriche, etc etc). In seguito presente lelenco di questi comandi:
Funzione
ceil(x)
fix(x)
floor(x)
round(x)
sign(x)
exp(x)
sqrt(x)
log(x)
log10(x)
abs(x)
angle(x)
conj(x)
imag(x)
real(x)
cos(x)
cot(x)
csc(x)
sin(x)
sec(x)
tan(x)
acos(x)
acot(x)
acsc(x)
asin(x)
asec(x)
atan(x)
cosh(x)
coth(x)
csch(x)
sinh(x)
sech(x)
tanh(x)
acosh(x)

Scopo
Arrotonda per eccesso allintero pi vicino
Arrotonda al numero intero pi vicino verso 0
Arrotonda per difetto allintero pi vicino
Arrotonda al numero intero pi vicino
Determina il segno della quantit x
Calcola il numero di Nepero elevato alla x
Calcola la radice quadrata di x
Calcola il logaritmo naturale di x
Calcola il logaritmo in base 10 di x
Calcola il valore assoluto di x
Calcola langolo di un numero complesso x
Calcola il complesso coniugato di un numero complesso x
Determina la parte immaginaria di un numero complesso x
Determina la parte reale di un numero complesso x
Calcola il coseno di x
Calcola la cotangente di x
Calcola la cosecante di x
Calcola il seno di x
Calcola la secante di x
Calcola la tangente di x
Calcola larcocoseno di x
Calcola larcocotangente di x
Calcola larcocosecante di x
Calcola larcoseno di x
Calcola larcosecante di x
Calcola larcotangente di x
Calcola il coseno iperbolico di x
Calcola la cotangente iperbolica di x
Calcola la cosecante iperbolica di x
Calcola il seno iperbolico di x
Calcola la secante iperbolica di x
Calcola la tangente iperbolica di x
Calcola larcocoseno iperbolico di x
7

acoth(x)
acsch(x)
asinh(x)
asech(x)
atanh(x)

Calcola larcocotangente iperbolica di x


Calcola larcocosecante iperbolica di x
Calcola larcoseno iperbolico di x
Calcola larcosecante iperbolica di x
Calcola larcotangente iperbolica di x

Operazioni con i vettori e con le matrici


Prima di vedere come operare matematicamente con dei vettori, vediamo alcuni comandi di Matlab utili, che
permettono di determinarne alcune caratteristiche importanti.

Selezione di elementi
Ad esempio, alcuni elementi di un vettore potrebbero non interessarci, e potremmo dunque essere
interessati a considerare una sola porzione del vettore stesso. Ammettiamo di considerare un vettore avente
8 elementi, ma che ci interessino solamente gli elementi che vanno dal terzo al quinto. Tali elementi possono
essere selezionati con il seguente comando:
v=[1 2 3 4 5 6 7 8];
v(3:5)
ans =
3

In particolar modo, se fossimo interessati al valore di uno specifico elemento del vettore, basterebbe mettere
tra parentesi la posizione corrispondente a quellelemento, e Matlab ce ne restituisce il valore:
v=[10 20 30 40 50 60 70 80];
v(5)
ans =
50

Con le matrici ci si pu comportare in modo del tutto analogo. Consideriamo una matrice 3 x 3, e ammettiamo
di voler considerare solamente i primi due elementi della seconda riga. possibile fare questo utilizzando il
seguente comando:
A=[1 2 3;4 5 6;7 8 9];
A(2,1:2)
ans =
4

Il primo elemento presente tra parentesi corrisponde alla riga nella quale vogliamo considerare gli elementi.
Il secondo elemento (dopo la virgola) corrisponde alla selezione degli elementi che vogliamo prendere in
quella riga. Pu essere effettuata unoperazione analoga per selezionare gli elementi appartenenti ad una
determinata colonna:
A(1:2,2)
ans =

2
5

Come possiamo operare se vogliamo considerare tutti gli elementi di una riga o di una colonna? In questo
caso, invece che imporre una selezione di elementi, basta specificare la riga o la colonna che si vogliono
considerare, e utilizzare il simbolo : (che consente di prendere tutti gli elementi in quella riga o in quella
colonna)
A(:,2)
ans =
2
5
8
A(1,:)
ans =
1

Se volessimo invece considerare uno specifico valore allinterno della matrice, basta specificarne la posizione
(riga, colonna). Ad esempio, se nella matrice A volessimo selezionare lelemento 6, basterebbe specificare
che si trova nella seconda riga e nella terza colonna:
A(2,3)
ans =
6

Determinazione delle dimensioni


Nella sezione precedente abbiamo visto come selezionare degli specifici elementi di un vettore o di una
matrice. In alcuni contesti risulta essere utile anche saper determinare le dimensioni di specifici vettori o di
specifiche matrice. Per determinare il numero di elementi contenuti in un determinato vettore, possibile
utilizzare il comando length:
v=1:1e-3:10;
length(v)
ans =
9001

possibile effettuare una procedura analoga nel caso delle matrici, utilizzando per questa volta il comando
size. Tale comando restituisce come output due diversi valori: il primo corrisponde al numero delle righe di
della matrice, mentre il secondo corrisponde al numero delle sue colonne:
A=[1 2 3;4 5 6;7 8 9];
size(A)
ans =
3

Ricerca di massimi e minimi


Ammettiamo di voler ricercare gli elementi massimi e gli elementi minimi presenti in un determinato vettore,
oppure in una determinata matrice. possibile fare questo utilizzando i comandi max e min. Se applichiamo
questi operatori ad un vettore, ci restituiscono immediatamente lelemento pi grande (e pi piccolo) del
vettore stesso:
v=[-9 -5 -8 1 -6 7 7 2 6];
min(v)
ans =
-9
max(v)
ans =
7

Applicando i comandi min e max ad una matrice otteniamo invece dei vettori riga che contengono, per ogni
posizione, rispettivamente gli elementi minimi e massimi delle colonne associate a quella posizione. Ad
esempio, se ho una matice 3 x 3, ottengo nelle terze posizioni del vettore riga rispettivamente lelemento pi
grande e lelemento pi piccolo della terza colonna:
A=[-9 -5 -8; 1 -6 7; 7 2 6];
min(A)
ans =
-9

-6

-8

max(A)
ans =
7

Per trovare gli elementi massimi e minimi di tutta la matrice, basta applicare due volte i comandi max e min,
e utilizzare cos in modo congiunto le due regole che abbiamo visto ora:
min(min(A))
ans =
-9
max(max(A))
ans =
7

Un altro comando utile, nel caso delle matrici, la determinazione del suo rango. Basta utilizzare il comando
rank.
10

rank(A)
ans =
3

Somma degli elementi


Se si desidera sommare tutti gli elementi che compaiono in un determinato vettore o in una determinata
matrice, basta utilizzare il comando sum, al quale viene dato come input il nome del vettore o della matrice.
Nel caso di vettori, il comando offre come dato di output un numero, corrispondente alla somma di tutti gli
elementi del vettore:
v=[-9 -5 -8 1 -6 7 7 2 6];
sum(v)
ans =
-5

Se applichiamo invece il comando ad una matrice, otteniamo come output un vettore riga, in cui ciascun
elemento corrisponde alla somma degli elementi della matrice presenti nella medesima colonna:
A=[-9 -5 -8; 1 -6 7; 7 2 6];
sum(A)
ans =
-1

-9

Anche in questo caso, come con i comandi min e max, se si vuole determinare la somma degli elementi di
tutta la matrice bisogna applicare il comando sum due volte:
sum(sum(A))
ans =
-5

Trasposizione
Una matrice o un vettore possono essere trasposti utilizzando
A=[1 2 3; 4 5 6; 7 8 9];
A'
ans =
1
2
3

4
5
6

7
8
9

v=[1 2 3];
v'

11

ans =
1
2
3

Determinante di una matrice


In Matlab il determinante di una matrice pu essere calcolato utilizzando il comando det.
A=[3 0 4;4 2 6;8 1 0];
det(A)
ans =
-66

Inversione di una matrice


In Matlab una matrice pu semplicemente essere invertita utilizzando il comando inv.
A=[3 0 4;4 2 6;8 1 0];
inv(A)
ans =
0.0909
-0.7273
0.1818

-0.0606
0.4848
0.0455

0.1212
0.0303
-0.0909

A livello teorico, loperazione effettuata per calcolare linversa di una matrice quadrata la seguente:
11
21
= [
1

12
22

1
11
1
2

21

] = det()[

1

12
22

1
2
] , = (1)+

Nella precedente formula, la grandezza corrisponde al minore complementare dellelemento (i,j). In altri
termini, corrisponde al determinante della matrice che si otterrebbe eliminando dalla matrice di partenza la
i-esima riga e la j-esima colonna.

Operazioni tra matrici/vettori e scalari


Le operazioni che abbiamo precedentemente visto per gli scalari possono essere utilizzate anche se si vuole
fare unoperazione tra un vettore/matrice ed uno scalare (tranne che per lelevamento a potenza, che
funziona diversamente). In particolar modo, vigono le seguenti equivalenze:
11
: = [

21

12
22 ]; :

+
+ = [ 11
21 +

12 +
]
22 +


= [ 11
21

12
]
22


= [ 11
21

12
]
22

12

/
/ = [ 11
21 /

12 /
]
22 /

Complessivamente, effettuare unoperazione tra una matrice ed uno scalare corrisponde ad effettuare tale
procedura matematica tra i diversi elementi della matrice e lo scalare stesso. Dunque, se si parte con una
matrice avente dimensioni n x m, si ottiene infine una matrice avente sempre dimensioni n x m. Le stesse
considerazioni valgono utilizzando le funzioni matematiche goniometriche, esponenziali e logaritmiche: esse
vengono applicate indipendentemente a ciascun elemento della matrice, ottenendo cos sempre una matrice
n x m.

Operazioni tra matrici e vettori


Come visto nel corso di Algebra Lineare, le operazioni tra matrici e vettori seguono delle regole diverse
rispetto alle operazioni tra scalari. Analizziamo dunque il funzionamento di ciascuna operazione:

Somma e sottrazione
Due matrici o due vettori possono essere sommati o sottratti se e solo se hanno le stesse dimensioni (le
dimensioni sono riportate sotto i vettori e le matrici):

=
(1, ) (1, ) (1, )

=
(, 1) (, 1) (, 1)

=
(, ) (, ) (, )
Se le dimensioni delle matrici o dei vettori non fossero le medesime, Matlab restituirebbe un messaggio di
errore. La somma di due matrici o di due vettori consente di sommare gli elementi che occupano le medesime
posizioni, in modo tale di ottenere come risultato una matrice o un vettore avente le stesse dimensioni degli
elementi di partenza.
A=[1 2 3;4 5 6;7 8 9];
B=[10 11 12;13 14 15;16 17 18];
A+B
ans =
11
17
23

13
19
25

15
21
27

-9
-9
-9

-9
-9
-9

A-B
ans =
-9
-9
-9

Quando si effettua la somma o la sottrazione di due vettori, importante controllare non solo che abbiano
le medesime dimensioni, ma anche che siano entrambi dei vettori riga o dei vettori colonna. Se si effettuasse

13

la somma tra un vettore riga ed un vettore colonna, anche se con un medesimo numero di elementi, Matlab
restituirebbe un messaggio di errore:
a=[1 2 3];
b=[1;2;3];
a+b
??? Error using ==> plus
Matrix dimensions must agree.

Prodotto tra vettori e matrici


In algebra lineare, il prodotto matriciale definito nel seguente modo:

=
, =
(, ) (, ) (, )
=1

Dalla precedente formula, notiamo subito come il numero delle colonne della prima matrice debba essere
uguale al numero di righe della seconda. Il risultato una matrice che ha il numero di righe della prima
matrice e il numero di colonne della seconda. Questo molto importante. Infatti, se in Matlab effettuiamo
un prodotto matriciale fra due matrici che non rispettano le condizioni ora esposte, esce un messaggio di
errore. Dalla precedente espressione, notiamo subito che se moltiplichiamo per se stesso un vettore riga o
un vettore colonna uscir un messaggio di errore. Se moltiplichiamo un vettore riga per un vettore colonna
(delle medesime dimensioni), otterremo come risultato del prodotto uno scalare. Se moltiplichiamo un
vettore colonna per un vettore riga, otteniamo come risultato delloperazione una matrice n x n, dove n il
numero di elementi presenti in ciascun vettore.
A=[1 2;3 4;5 6;7 8];
B=[1 2 3 4;5 6 7 8];
A*B
ans =
11
23
35
47

14
30
46
62

17
37
57
77

20
44
68
92

Come esempio del prodotto tra un vettore riga e un vettore colonna, effettuiamo la determinazione del peso
molecolare medio di una corrente gassosa. Consideriamo una corrente gassosa avente la seguente
composizione:
Composto
2
2

Peso molecolare (g/mol)


2
18
28
44

=
=1

14

Frazione molare
0.2
0.4
0.15
0.25

= [1

2

]; = [ ] = =
=1

PM=[2 18 28 44]; %g/mol


x=[0.2;0.4;0.15;0.25];
PMmix=PM*x
PMmix =
22.8000

Se moltiplicassimo invece il vettore frazioni molari per il vettore masse molecolari, otterremmo una matrice
n x n contenente il prodotto di ciascun elemento di x per ciascun elemento di PM:
x*PM
ans =
0.4000
0.8000
0.3000
0.5000

3.6000
7.2000
2.7000
4.5000

5.6000
11.2000
4.2000
7.0000

8.8000
17.6000
6.6000
11.0000

Divisione tra matrici


La trattazione sulla divisione tra matrici risulta essere utile nel caso si volessero effettuare delle risoluzioni
di sistemi lineari. Immaginiamo di avere un sistema lineare strutturato come segue:
11
21
= [
1

12
22

1
1
1
2
2

]; = [ ]; = [ ] =

Se conosciamo la matrice dei coefficienti e il vettore dei termini noti , possibile calcolare il vettore
delle incognite utilizzando due diversi metodi.
Il primo metodo quello di riduzione di Gauss. Per utilizzare questo metodo, basta utilizzare la divisione a
sinistra, nel seguente modo:
A=[0 4 6;5 1 9;7 10 5];
b=[2;5;3];
x=A\b
x =
0.2927
-0.1073
0.4049

Un altro metodo per risolvere il sistema lineare consiste nellutilizzo della matrice inversa:
[1 ] = [1 ]

15

1 ]
= [
x=inv(A)*b
x =
0.2927
-0.1073
0.4049

Operazioni elemento per elemento


Nella trattazione delle operazioni tra vettori e matrici, abbiamo visto come la somma e la sottrazione si
applichino elemento per elemento. In altri termini, lelemento che occuper la posizione (i,j) nella nuova
matrice corrisponde alla somma o alla sottrazione degli elementi che occupano le medesime posizioni nelle
matrici di partenza. Abbiamo visto, invece, che il prodotto e la divisione tra matrici seguono delle regole
diverse, definite dalla teoria dellalgebra lineare.
La domanda che ci poniamo : esiste un modo per effettuare una procedura simile a quella di somma e
sottrazione, ma utilizzando prodotto, divisione ed elevamento a potenza? La risposta fortunatamente s:
basta utilizzare le operazioni elemento per elemento. Queste possono essere fatte anteponendo un punto
alloperatore che vuole essere utilizzato (prodotto, divisione o elevamento a potenza).
11
21
= [
1

12
22

1
11
2

21

]; = [

1

11 11

. = [ 21 21

1 1

12 12
22 22

2 2

12
22

1
2
]

1 1
2 1
]

11 /11

/
./ = [ 21 21

1 /1

12 /12
22 /22

2 /2

1 /1
2 /1
]

11 ^11

^
. ^ = [ 21 21

1 ^1

12 ^12
22 ^22

2 ^2

1 ^1
2 ^1
]

Come possiamo vedere nelle precedenti espressioni, per effettuare delle operazioni elemento per elemento
le matrici o i vettori di partenza devono avere esattamente le stesse dimensioni. Ad esempio, non risulta
possibile effettuare unoperazione elemento per elemento che coinvolge un vettore riga e un vettore
colonna.
Per vedere un esempio con i vettori, consideriamo lo stesso esempio di prima, ossia quello del calcolo del
peso molecolare medio di una corrente gassosa. Stavolta, invece che definire il vettore dei pesi molecolari
come un vettore riga, e il vettore delle frazioni molari come un vettore colonna, decidiamo di definire
entrambi i vettori come vettori riga, e di utilizzare il prodotto elemento per elemento e il comando sum per
effettuare il calcolo del peso molecolare medio:
PM=[2 18 28 44]; % g/mol
x=[0.2 0.4 0.15 0.25];

16

PMmix=sum(PM.*x)

PMmix =

22.8000

Cicli for, if, while


Nellambito della creazione di programmi, i cicli for, if e while assumono una grandissima importanza, per
effettuare le operazioni pi disparate. Analizziamo nel dettaglio cosa permette di fare ciascuno di questi cicli,
e come possono essere utilizzati nei tipici problemi dellIngegneria Chimica.

Ciclo for

Consideriamo un vettore, avente lunghezza n. Un ciclo for ci consente di effettuare delle operazioni su tale
vettore, facendo variare lindice dopo ogni operazione in modo tale che questultima venga ripetuta per
ciascun elemento del vettore stesso. I cicli for risultano essere dunque di estrema utilit quando vogliono
essere effettuate delle medesime operazioni per i diversi elementi che caratterizzano dei vettori. Si pensi ad
esempio alla determinazione di un equilibrio termodinamico. Se siamo interessati a valutare le composizioni
allequilibrio a diverse T, basta creare un vettore di T desiderate e far variare la temperatura stessa mediante
un ciclo for, ripetendo ad ogni step le medesime operazioni di determinazione dellequilibrio termodinamico.
Vediamo un esempio applicato alle matrici. Ammettiamo di voler calcolare il prodotto tra due diverse matrici
A e B, senza per ricorrere a *. In altri termini, vogliamo creare noi un algoritmo che permetta di calcolare il
prodotto tra due matrici. Questo pu essere fatto nel seguente modo:

=
, =
(, ) (, ) (, )
=1

Come puoi notare, loperazione da fare risulta essere la medesima per ciascun elemento (i,j) della matrice.
Scrivere dunque la stessa operazione per ciascun elemento della matrice risulterebbe essere poco pratico.
Meglio inserire il comando allinterno di due cicli for diversi: il primo che faccia variare le i (fino al numero
totale di righe), il secondo che faccia variare le j (fino al numero totale di colonne.

A=[1 2 3 4;5 6 7 8];


B=[5 9 6;4 7 2;11 24 5;4 7 6];

% Creazione di una matrice 2x4


% Creazione di una matrice 4x3

% La matrice risultante dall'operazione di prodotto matriciale avr 2 righe


% e 3 colonne. Come prima cosa, utilizziamo gli appositi comandi di Matlab

17

% per determinare le dimensioni delle due matrici.


a=size(A);
b=size(B);
%
%
%
%

Le dimensioni di nostro interesse (quelle da inserire all'interno del


ciclo for) sono solamente il numero di righe di A e il numero di colonne
di B. Selezioniamo dunque il primo elemento di a e il secondo elemento di
b.

N=a(1);
M=b(2);
%
%
%
%

Creiamo una matrice C, risultato dell'operazione di prodotto vettoriale,


che abbia il numero di righe e il numero di colonne desiderato, e
composta da soli zeri. Nel successivo passaggio, andremo a sostituire gli
zeri con gli elementi di nostro interesse:

C=zeros(N,M);
% Implementiamo due cicli for, che permettano di calcolare ciascun elemento
% della nuova matrice.
for i=1:N
for j=1:M
C(i,j)=sum(A(i,:).*B(:,j)');
%
%
%
%
%
%

Con questa scrittura abbiamo effettuato il prodotto elemento per elemento


della i-esima riga di A con la j-esima colonna di B. La j-esima colonna
di B stata trasposta per ottenere un vettore riga, e per poter cos
effettuare l'operazione di prodotto elemento per elemento. Il risultato
del prodotto un nuovo vettore, i cui elementi sono stati sommati con il
comando sum.
end

end
C
C =
62
158

123
311

49
125

Da questo algoritmo possiamo notare la struttura del ciclo for. In ciascun ciclo, si specificano gli estremi tra
cui varia la variabile (nel caso di i, tra 1 e N, mentre nel caso di j tra 1 e M). Ciascun ciclo for viene quindi
concluso mediante un end. Nel nostro specifico caso, prima viene fissato un valore di i, poi con il ciclo for
interno si fa la stessa operazione per tutte le colonne (j viene fatto variare). Dunque, cambiando valore di i,
si cambia riga, e viene nuovamente effettuata la medesima operazione per tutte le colonne. In questo modo,
variano i e j, riusciamo ad effettuare la medesima operazione a tutti gli elementi della matrice di nostro
interesse.
Un altro utilizzo dei cicli for quello mirato alla risoluzione di equazioni differenziali. Matlab contiene
numerose funzioni che permettono di risolvere sistemi di equazioni differenziali (e le vedremo pi avanti in

18

questa guida). Ammettiamo di voler risolvere una semplice equazione differenziale a livello numerico
(discretizzandola). Prendiamo una reazione chimica caratterizzata da una cinetica del primo ordine:
= , = 0.010 = 2

Lespressione che permette di valutare le concentrazione di A nel tempo ricavabile risolvendo il seguente
problema di Cauchy (ammettendo di lavorare in un reattore batch):

=
{
( = 0) = 0

= ; ( + 1) = () ()

Lequazione differenziale, accompagnata dalla sua condizione al contorno, potrebbe essere tranquillamente
integrata matematicamente, per giungere in questo modo ad una soluzione analitica (esatta). Ammettiamo
per di voler procedere in via numerica, e di voler determinare landamento di nel tempo mediante una
procedura di discretizzazione. Come prima cosa, effettuiamo una discretizzazione dellintervallo temporale
nel quale vogliamo stimare i valori di concentrazione. Ciascun elemento dellintervallo temporale distante
dal precedente di una grandezza pari a .
= [0

A questo vettore di tempi sar associato un vettore ci concentrazioni, ciascuna della quale valutata nel
relativo istante temporale:
= [0

() (2) ( )]

Possiamo impostare un ciclo for che funziona nel seguente modo:

%% Risoluzione di un'equazione differenziale con un ciclo for


clc
clear all

19

close all
% Dati:
k=0.01;
CA0=2;

% Hz
% mol/m^3

% Risoluzione:
% Generiamo il vettore temporale, che nel nostro caso ha una spaziatura di
% 0.01 s e un valore massimo di 1000 s.
dt=1e-3;
t=0:dt:6e2;
%
%
%
%

Generiamo dei corrispondenti vettori riga di concentrazioni di A e di


variazioni infinitesime di concentrazioni di A, aventi la medesima
lunghezza di t ma costituiti solamente da 0. I vari elementi di questi
vettori saranno poi modificati lungo il ciclo for:

CA=zeros(1,length(t));
DCA=zeros(1,length(t));
% Impostiamo lo step (1) dell'equazione differenziale:
CA(1)=CA0;
DCA(1)=-k*CA(1)*dt;
%
%
%
%
%

Impostiamo i successivi step dell'equazione differenziale, mediante un


ciclo for. All'i-esimo step, determiniamo la concentrazione di A come
somma della concentrazione di A allo step precedente e la variazione di
concentrazione di A dello step precedente. Dunque, per il nuovo step,
determiniamo la nuova variazione di concentrazione di A.

for i=2:length(t)
CA(i)=CA(i-1)+DCA(i-1);
DCA(i)=-k*CA(i)*dt;
end
% Questi comandi servono a generare il grafico: vedremo pi avanti nella
% guida il loro funzionamento
figure('Name','Andamento della concentrazione di A','NumberTitle','off')
plot(t,CA)
grid on
legend('C_{A}')
xlabel('t [s]')
ylabel('Concentrazione di A [mol/m_{3}]')
title('Andamento della concentrazione di A')

20

Proseguiamo ora con la nostra trattazione, e analizziamo il ciclo if.

Ciclo if
Prima di effettuare la trattazione del ciclo if, introduciamo una serie di connettivi logici che risulteranno
essere funzionali nella nostra analisi.

Connettivo logico

Significato del connettivo logico


Minore
Maggiore
Minore o uguale
Maggiore o uguale
Uguale
Diverso. Il primo simbolo la tilde (pu essere
scritta con alt + 126 sul tastierino numerico)
Not
And
Or

<
>
<=
>=
==
~=
~
&
|

Il ciclo if permette di eseguire delle istruzioni diverse in funzione della casistica esaminata. In particolar
modo, se determinate condizioni di nostro interesse sono verificate, diciamo al programma di proseguire in
un determinato modo. Se tali condizioni non dovessero invece essere verificate, diciamo al programma di
proseguire in modo diverso.

21

Vediamone un esempio applicativo, prendendo in esame la struttura precedentemente creata per effettuare
il prodotto matriciale. Come abbiamo visto precedentemente, dal punto di vista teorico possibile effettuare
il prodotto tra due matrici o tra due vettori se e solo se il numero di colonne della prima matrice uguale al
numero di righe della seconda. Nel programma creato in precedenza, possiamo implementare un ciclo if,
che ci restituisca un messaggio di errore nel caso in cui le dimensioni delle due matrici non siano compatibili.
Per il messaggio di errore utilizzeremo il comando disp, che permette di visualizzare sulla Command Window
la stringa che viene racchiusa tra parentesi tonde e tra virgolette .
Come nel caso del ciclo for, il ciclo if va chiuso mediante un end.
A=[1 2 3 4;5 6 7 8];
B=[5 9 6;4 7 2;11 24 5;4 7 6];
a=size(A);
b=size(B);
%
%
%
%
%
%
%

Prima di procedere con le operazioni gi precedentemente descritte,


vediamo innanzitutto se possibile effettuare l'operazione di prodotto
tra la matrice A e la matrice B. Sappiamo che possibile fare tale
operazione se il numero di colonne di A uguale al numero di colonne
di B. Se tale condizione verificata, possiamo procedere con
l'algoritmo, altrimenti facciamo uscire un messaggio di errore che ci
avvisi del fatto che c' qualcosa che non va.

if a(2)==b(1)
N=a(1);
M=b(2);
C=zeros(N,M);
for i=1:N
for j=1:M
C(i,j)=sum(A(i,:).*B(:,j)');

22

end
end
else
disp('Non possibile effettuare l''operazione')
end
C
C =

62

123

49

158

311

125

Nel caso appena visto le due matrici sono adatte per loperazione di prodotto matriciale, e dunque
loperazione viene effettuata. Vediamo ora un caso in cui le due matrici non sono tra di loro compatibili.
A=[1 2 3 4 5;6 7 8 9 10];
B=[5 9 6;4 7 2;11 24 5;4 7 6];
a=size(A);
b=size(B);
if a(2)==b(1)
N=a(1);
M=b(2);
C=zeros(N,M);
for i=1:N
for j=1:M
C(i,j)=sum(A(i,:).*B(:,j)');
end
end
else
disp('Non possibile effettuare l''operazione')
end
Non possibile effettuare l'operazione

Se volessimo essere ancora pi precisi, potremmo avvalerci della struttura if-elseif. In particolar modo,
immaginiamo che oltre a voler sapere che loperazione non pu essere effettuata, vogliamo anche sapere se
il numero delle colonne di A maggiore del numero delle righe di B, o viceversa. Questo pu essere effettuato
mediante il seguente algoritmo.
A=[1 2 3 4 5;6 7 8 9 10];
B=[5 9 6;4 7 2;11 24 5;4 7 6];

23

a=size(A);
b=size(B);
if a(2)==b(1)
N=a(1);
M=b(2);
C=zeros(N,M);
for i=1:N
for j=1:M
C(i,j)=sum(A(i,:).*B(:,j)');
end
end
elseif a(2)>b(1)
disp('Non possibile effettuare l''operazione: il numero di colonne di A
maggiore del numero di righe di B')
elseif a(2)<b(1)
disp('Non possibile effettuare l''operazione: il numero di colonne di A
minore del numero di righe di B')
end
Non possibile effettuare l'operazione: il numero di colonne di A maggiore del
numero di righe di B

Proseguiamo ora con lanalisi del ciclo while.

Ciclo while
Il ciclo while permette di continuare a fare una determinata operazione fino a quando un certo criterio, da
noi deciso, viene soddisfatto. Come esempio, consideriamo nuovamente la cinetica del primo ordine
precedentemente analizzata.
= , = 0.010 = 2

Il sistema differenziale risulta essere il medesimo di quello analizzato nel caso del ciclo for. In questo caso,
immaginiamo di voler svolgere il medesimo processo di integrazione, ma di volerlo svolgere solamente fino
a quando la conversione del reagente A raggiunge il valore 0.99.
=

0
= 0.99
0

In questo caso risulta essere molto utile al nostro scopo un ciclo while. Fino a quando la conversione
inferiore al valore 0.99, proseguiamo con lintegrazione numerica. Quando raggiungiamo il valore 0.99, ci
fermiamo.
%% Risoluzione di un'equazione differenziale con un ciclo while
clc
clear all
close all

24

% Dati:
k=0.01;
CA0=2;

% Hz
% mol/m^3

% Risoluzione:
dt=1e-3;
t(1)=0;
CA(1)=CA0;
DCA(1)=-k*CA(1)*dt;
conv(1)=(CA0-CA(1))/CA0;
t(2)=dt;
CA(2)=CA(1)+DCA(1);
DCA(2)=-k*CA(2)*dt;
conv(2)=(CA0-CA(2))/CA0;
i=2;
while conv(i)<0.99
%
%
%
%
%

Il ciclo while, come prima cosa, confronta il valore della


conversione con il limite imposto. Se il valore della conversione
inferiore rispetto a 0.99, prosegue eseguendo le successive linee di
comando. Se il valore della conversione maggiore o uguale a 0.99,
si ferma.

% All'interno del ciclo while, bisogna continuare ad aggiornare la


% grandezza i, in modo tale che possano aggiungersi elementi ai vettori
% di partenza.
i=i+1;
% Vengono calcolate le grandezze di interesse all'i-esimo step.
t(i)=t(i-1)+dt;
CA(i)=CA(i-1)+DCA(i-1);
DCA(i)=-k*CA(i)*dt;
conv(i)=(CA0-CA(i))/CA0;
end
figure('Name','Andamento della conversione di A','NumberTitle','off')
plot(t,conv)
grid on
legend('X_{A}')
xlabel('t [s]')
ylabel('X_{A}')
title('Andamento della conversione di A')

25

Ora che abbiamo esaminato il funzionamento dei pi importanti cicli di programmazione, proseguiamo la
nostra trattazione con un elemento fondamentale: le function.

Function
Spesso, nelle scienze, vi sono una serie di calcoli che vengono ripetuti frequentemente. Ripetere ogni volta,
allinterno dello script, le strutture di calcolo necessarie risulterebbe palloso e ingombrante. Sarebbe bello
poter scrivere i comandi necessari in una funzione esterna, e richiamarla nel nostro script quando necessario.
Questo proprio lobiettivo delle function: creare delle strutture esterne che possono essere richiamate ed
eseguire allinterno degli script.
Ti faccio subito un esempio. Prima ti ho mostrato come creare un programma che effettua il prodotto tra
due diverse matrici, e abbiamo applicato tale programma a due specifiche matrici A e B. Se questa operazione
dovesse essere effettuata frequentemente, risulterebbe assai comodo definire una function con quella
sequenza di comandi, in modo tale da poterla richiamare e da poterla applicare a due qualsiasi matrici.
La struttura di una function la seguente:
[1 , , ] = . (1 , , )
Una function un programma che, avendo a disposizione una serie di dati di input, fornisce una serie di dati
di output, effettuando delle operazioni.
Consideriamo lesempio del prodotto tra le due matrici A e B. Se vogliamo definire una function che ne faccia
il prodotto, gli input saranno proprio le matrici A e B, mentre loutput sar la matrice C, risultato del prodotto
tra A e B. Volendo, potremmo definire una serie di output maggiore, come ad esempio le dimensioni della
matrice ottenuta con loperazione di prodotto matriciale. Vediamo unapplicazione.

26

function C=prodmat(A,B)
a=size(A);
b=size(B);
if a(2)==b(1)
N=a(1);
M=b(2);
C=zeros(N,M);
for i=1:N
for j=1:M
C(i,j)=sum(A(i,:).*B(:,j)');
end
end
elseif a(2)>b(1)
C='Non possibile effettuare l''operazione: il numero di colonne di A
maggiore del numero di righe di B';

elseif a(2)<b(1)
C='Non possibile effettuare l''operazione: il numero di colonne di A
maggiore del numero di righe di B';
end
end

Ora che abbiamo creato la function prodmat e labbiamo salvata (attenzione: le function vanno salvate
esattamente con il nome che stato dato loro), possiamo applicarla a due generiche matrici, a nostro
piacimento.
A=[1 2 3;4 5 6;7 8 9];
B=[3 4;5 6];
C=prodmat(A,B)
C =
Non possibile effettuare l'operazione: il numero di colonne di A maggiore del
numero di righe di B
A=[1 2 3;4 5 6;7 8 9];
B=[3 4 5;5 6 7;9 4 3];
C=prodmat(A,B)
C =

27

40

28

28

91

70

73

142

112

118

Immaginiamo ora di voler creare unaltra applicazione, utile per gli scopi dellingegneria chimica.
Consideriamo nuovamente la corrente gassosa di uno degli esempi precedenti.
Composto
2
2

Peso molecolare (g/mol)


2
18
28
44

Frazione molare
0.2
0.4
0.15
0.25

Spesso, nellIngegneria Chimica, risulta essere assai utile passare da composizioni molari a composizioni
massive, e viceversa. Creiamo dunque una function che permette di effettuare entrambi questi processi.
Questa function avr tre dati di input e uno di output:
[] = (, , )

y = Corrisponde al risultato desiderato. Nel caso di conversione da composizioni molari a massive,


sar un vettore di composizioni massive. Viceversa, sar un vettore di composizioni molari.
x = il vettore di partenza, di composizioni massive o molari.
PM = il vettore delle masse molecolari delle diverse specie.
n = un parametro che ci permette di indentificare loperazione che vogliamo effettuare. Se poniamo
n=1, vuol dire che vogliamo convertire una composizione molare in una composizione massiva. Se
poniamo n=2, vuol dire che vogliamo convertire una composizione massiva in molare.

function y=convcomp(x,PM,n)
% Per n=1 convertiamo una composizione molare in una composizione massiva
if n==1
y=PM.*x/sum(PM.*x);
% Per n=2 convertiamo una composizione massiva in una composizione molare
elseif n==2
y=(x./PM)/sum(x./PM);
end
x=[0.2 0.4 0.15 0.25];
PM=[2 18 28 44];
om=convcomp(x,PM,1)

om =

28

0.0175

0.3158

0.1842

0.4825

Come si pu notare, non necessario chiamare la variabile di output con il medesimo nome che le stato
assegnato nella function. Mentre nel caso della function abbiamo chiamato la variabile di output y, in questo
caso labbiamo chiamata om. Nel caso in cui vi fossero pi variabili di output, esse possono essere chiamate
in modo diverso, tenendo conto del fatto che Matlab le restituisce con lordine in cui sono state inserite negli
output della function. Immaginiamo ora di avere un sistema analogo al precedente, ma in cui il vettore di
composizione iniziale non corrisponde alle frazioni molari ma alle frazioni massive:
Composto
2
2

Peso molecolare (g/mol)


2
18
28
44

Frazione massiva
0.2
0.4
0.15
0.25

Per calcolare le frazioni molari basta operare come segue:


om=[0.2 0.4 0.15 0.25];
PM=[2 18 28 44];
x=convcomp(om,PM,2)

x =

0.7504

0.1668

0.0402

0.0426

Rappresentazione di grafici
Nei precedenti argomenti, in particolar modo nella trattazione della risoluzione di equazioni differenziali
mediante cicli for e cicli while, abbiamo rappresentato dei grafici. La rappresentazione di grafici un
argomento molto importante, dal momento che consente di visualizzare a livello visivo informazioni su
quanto stato fatto con i precedenti step risolutivi. Vediamo ora insieme come rappresentare un grafico
monodimensionale, mediante un algoritmo commentato.

Rappresentazione di grafici 1D
%% Rappresentazione di un grafico
clc
clear all
close all
% Come prima cosa, definiamo un vettore di x (variabile indipendente) e un
% vettore di y (variabile dipendente). Immaginiamo ad esempio di voler
% rappresentare la funzione seno.
x=0:pi*1e-2:6*pi; % La grandezza pi, in Matlab, corrisponde a pi greco
y=sin(x);
% Questo primo comando permette di aprire una nuova figura, con il nome che
% desideriamo darle e senza contrassegnarla con un numero. Volendo, se non

29

% si volesse dare uno specifico nome alla figura, basterebbe scrivere figure(1):
figure('Name','Grafico della funzione sen(x)','NumberTitle','off')
% Il comando plot permette di effettuare dei grafici monodimensionali,
% specificando coma dati di input prima il vettore di variabile
% indipendenti e poi il vettore di variabili dipendenti.
plot(x,y)
% Il comando grid permette di inserire all'interno del grafico una griglia,
% in modo tale da vedere meglio i valori dei vari punti.
grid on
% Il comando legend pone una legenda all'interno del grafico, che permette di
% visualizzare il significato di ciascuna curva.
legend('sen(x)')
% Il comando axis permette di effettuare una scelta sui valori limite degli
% assi cartesiani. Ha struttura axis([xmin xmax ymin ymax)]. Il comando pu
% anche essere omesso, e Matlab si regola da solo.
axis([0 6*pi -1.5 1.5])

% I comandi label permettono di denominare gli assi x e y


xlabel('x')
ylabel('y')
% Il comando title fa apparire sopra il grafico stesso il titolo scelto
title('Grafico della funzione sen(x)')

Vediamo ora maggiormente nel dettaglio le caratteristiche dei comandi precedentemente elencati. Partiamo
dal comando plot. Nel programma precedente, abbiamo inserito allinterno di plot solamente il vettore delle
ascisse e il vettore delle ordinate. In realt, si possono specificare anche delle informazioni in merito alla linea
con cui vogliamo che plot crei il grafico.
30

Colore

Significato
Blu
Verde
Rosso
Cyan
Magenta
Giallo
Nero
Bianco

b
g
r
c
m
y
k
w

Simbolo
.

X
+
*
s
d
v
^
<
>
p
h

Significato
Punto
Cerchio
X
Pi
Stella
Quadrato
Diamante
Triangolo (in gi)
Triangolo (in su)
Triangolo (a
sinistra)
Trangolo (a destra)
Pentagono
Esagono

Linea
:
-.
-(none)

Significato
Continua
A puntini
Tratto-punto
Tratteggiata
Nessuna

Ad esempio, se nel programma precedente avessimo utilizzato il seguente comando per plot e se avessimo
utilizzato una spaziatura sulle x di pi*1e-1, avremmo ottenuto il seguente risultato.
plot(x,y,'rd-.')

Allinterno del comando plot, in realt, possono essere inseriti pi comandi ancora, presenti nella seguente
tabella:
Comando

Effetto
Il presente comando regola lo spessore della linea
(n) con la quale viene disegnata la funzione.
Questo comando regola il colore del contorno del
simbolo scelto per rappresentare il grafico. Al

LineWidth,n
'MarkerEdgeColor','color',

31

posto di color si inserisce la lettera corrispondente


ad uno dei colori visti in precedenza.
Questo comando regola il colore dello sfondo del
simbolo scelto per rappresentare il grafico. Al
posto di color si inserisce la lettera corrispondente
ad uno dei colori visti in precedenza.
Il presente comando permette di creare il colore
con il quale viene creata la linea, usando la
notazione RGB (frazione di ciascun colore utilizzato
nella miscela)

'MarkerFaceColor','color'

'Color',[.6 0 0]

%% Rappresentazione di un grafico
clc
clear all
close all
x=0:pi*1e-1:6*pi;
y=sin(x);
figure('Name','Grafico della funzione sen(x)','NumberTitle','off')
% I tre punti servono per andare a capo
plot(x,y,'s-','Color',[.2 .6 .2],'LineWidth',2,...
'MarkerEdgeColor','r','MarkerFaceColor','b')
grid on
legend('sen(x)')
axis([0 6*pi -1.5 1.5])
xlabel('x')
ylabel('y')
title('Grafico della funzione sen(x)')

32

Se volessimo inserire allinterno di una medesima figura pi grafici, basta inserire i nuovi dati allinterno del
medesimo comando plot, a fianco dei dati precedenti. In questo caso, risulta essere opportuno aggiornare
anche il comando legend, in modo tale che fornisca delle indicazioni su entrambi i grafici. In alternativa, si
pu utilizzare un altro comando plot, specificando per prima il comando hold on. Rappresentiamo, ad
esempio, anche la funzione coseno allinterno del medesimo grafico.
%% Rappresentazione di seno e coseno sullo stesso grafico
clc
clear all
close all
x=0:pi*1e-1:6*pi;
y1=sin(x);
y2=cos(x);
figure('Name','Grafico delle funzioni sen(x) e cos(x)','NumberTitle','off')
plot(x,y1,'r-',x,y2,'b--')
grid on
legend('sen(x)','cos(x)')
axis([0 6*pi -1.5 1.5])
xlabel('x')
ylabel('sen(x),cos(x)')
title('Grafico delle funzioni sen(x) e cos(x)')
% In questo algoritmo stato aggiunto anche il comando gtext, che permette
% di inserire all'interno del grafico una stringa, specificando con il
% mouse dove posizionarla.
gtext('sen(x),cos(x)')

33

Se volessimo invece rappresentare le funzioni in due grafici distinti? In questo caso potremmo avvalerci del
comando subplot(m,n,p). Allinterno della precedente espressione, m corrisponde al numero di righe di
grafici che vogliamo creare, mentre n al numero delle colonne di grafici che vogliamo creare. In altri termini,
come se il comando subplot dividesse la figura in una matrice m x n, e raffigurasse in ogni posizione diversa
un diverso grafico. Ammettiamo, ad esempio, di voler rappresentare le funzioni seno e coseno tra di loro
affiancate, invece che sul medesimo grafico.
%% Rappresentazione di seno e coseno su grafici distinti
clc
clear all
close all
x=0:pi*1e-1:6*pi;
y1=sin(x);
y2=cos(x);
figure('Name','Grafico delle funzioni sen(x) e cos(x)','NumberTitle','off')
subplot(1,2,1)
plot(x,y1,'r-')
grid on
legend('sen(x)')
axis([0 6*pi -1.5 1.5])
xlabel('x')
ylabel('sen(x)')
title('Grafico della funzione sen(x)')
subplot(1,2,2)
plot(x,y2,'b--')
grid on
legend('cos(x)')
axis([0 6*pi -1.5 1.5])
xlabel('x')
ylabel('cos(x)')
title('Grafico della funzione cos(x)')

34

Oltre al comando plot, possono esserne utilizzati degli altri per creare dei grafici aventi delle caratteristiche
diverse.
Comando

Scopo
Crea un diagramma logaritmico di y in funzione di x
Crea un diagramma semilogaritmico di y in
funzione di x, con lasse x in scala logaritmica
Crea un diagramma semilogaritmico di y in
funzione di x, con lasse y in scala logaritmica
Crea un diagramma a gradini di y in funzione di x
Crea un diagramma a steli di y in funzione di x
Crea un diagramma a barre di y in funzione di x
Crea un diagramma polare di coordinate teta e r,
utilizzando la tipologia di linea specificata in tipo

loglog(x,y)
semilogx(x,y)
semilogy(x,y)
stairs(x,y)
stem(x,y)
bar(x,y)
polar(teta,r,tipo)

Se vogliamo rappresentare una linea non in un piano, ma in uno spazio, possiamo utilizzare il comando
plot3. Il suo funzionamento risulta essere del tutto analogo rispetto a quello del comando plot. Vediamo
un esempio di rappresentazione di una curva nello spazio, le cui coordinate sono funzione di un parametro.
() = sin() exp(0.02 ), () = cos() exp(0.02 ), () = 2 t
clc
clear all
close all
t=0:pi*1e-1:12*pi;
x=sin(t).*exp(-0.02*t);
y=cos(t).*exp(-0.02*t);
z=2*t;
figure('Name','Grafico della funzione','NumberTitle','off')
plot3(x,y,z)
grid on
xlabel('x')
ylabel('y')
zlabel('z')

35

Passiamo ora allanalisi della rappresentazione di superfici.

Rappresentazione di grafici 2D
Consideriamo la seguente funzione di due variabili:
= ( 3)2 + 3 2 + 3
Rappresentiamo questa superficie in uno spazio tridimensionale. I vari comandi utilizzati sono commentati
allinterno dellalgoritmo stesso.
%% Rappresentazione di una superficie in 3D
clc
clear all
close all
% Come prima cosa, definiamo i vettore x e y, che andranno a costituire le
% ampiezze dei due assi di variabili indipendenti, con i quali valori
% vogliamo effettuare una stima della funzione in due variabili.
x=-3:1e-2:3;
y=-4:1e-2:4;
% Utilizziamo i due vettori ora creati per creare un piano (rettangolare o
% quadrato) che utilizzeremo come base per la rappresentazione della nostra
% funzione.
[X,Y]=meshgrid(x,y);
% Definiamo la funzione Z:
Z=(X-3).^3+3*X.*2.*Y+Y.^3;
figure('Name','Rappresentazione di una superficie','NumberTitle','off')
mesh(X,Y,Z)
xlabel('x')
ylabel('y')
zlabel('z')
title('Rappresentazione di una superficie')

Possono essere utilizzati anche altri comandi per generare una superficie (meshc,meshz,surf,surfc).
Essi forniscono i seguenti risultati.
Nel caso di meshc, possono anche essere visualizzate le curve di livello sul piano (x,y).
36

Con il comando meshz, vengono visualizzate delle linee di riferimento verticali sotto la superficie.

37

Nel caso del comando surf, vengono utilizzati dei pannelli colorati, invece che delle semplici linee:

Nel caso in cui si utilizzi il comando surfc, si ottengono i medesimi effetti del comando surf ma si visualizzano
anche le curve di livello sul piano (x,y):

38

Nel caso in cui non si volessero visualizzare le superfici, ma solamente le linee di livello in un piano (x,y), si
pu utilizzare il comando contour(X,Y,Z,n). Il valore n allinterno del comando corrisponde al numero di
curve di livello che si vogliono disegnare.

Rappresentazione e salvataggio dei risultati


Nella precedente sezione abbiamo visto come sia possibile rappresentare a livello grafico i risultati ottenuti
con i calcoli. Ammettiamo ora di voler visualizzare i risultati ottenuti sulla Command Window, oppure di
volersi salvare in un file a parte, per poterli consultare in altri momenti.
Per quanto riguarda la visualizzazione di grandezze sulla Command Window, essa pu essere effettuata in
due diverse vie. La prima via consiste nel non mettere il ; dopo le grandezze che intendiamo visualizzare. In
questo modo Matlab permette di visualizzare la grandezza stessa.
X=[0 1 2 3]

X =

Se si volessero visualizzare i risultati ottenuti in modo pi fine, si potrebbe utilizzare il comando disp. Il
comando disp permette di visualizzare sulla Command Window le stringe che sono poste come argomento
del comando disp stesso. Come possibile notare nel seguente comando, le stringhe vengono inserite tra .
disp('Oggi una bella giornata!')
Oggi una bella giornata!

39

Il comando disp permette d visualizzare delle stringhe, mentre noi siamo interessati a visualizzare dei numeri.
Per poter utilizzare il comando disp, risulta dunque essere necessario convertire i numeri in stringhe, e
questo pu essere effettuato con il comando num2str. Ammettiamo ad esempio di aver ottenuto come
risultato di unoperazione una temperatura di 346,2 [K].
T=346.2;
disp(['La temperatura del sistema di ',num2str(T),' [K]'])
La temperatura del sistema di 346.2 [K]

fprintf
Ammettiamo ora di voler salvare i risultati su un file di testo (.txt) esterno. Come prima cosa, creiamo un file
di testo in cui effettuare il salvataggio. Nel nostro caso chiamiamolo dati.txt. Il salvataggio possibile grazie
alla funzione fprintf, e il suo funzionamento pu essere compreso dal seguente algoritmo commentato.
%% Salvataggio di dati su file mediante fprintf
clc
clear all
close all
% Come prima cosa, generiamo un vettore di ascisse
x = 0:.1:2;
%
%
%
A

Costruiamo una matrice che ha come prima riga il vettore delle ascisse, e
come seconda e terza riga le funzioni seno e exp calcolate per ciascun
elemento del vettore delle ascisse
= [x; sin(x); exp(x)];

% Apriamo il file 'dati.txt' con permesso di scrittura (wt)


fileID = fopen('dati.txt','wt');
% Generiamo una prima riga all'interno del file dati.txt. Tale riga
% composta da 3 stringe (s), di cui la prima lunga 6 elementi, la seconda
% 12 elementi e l'ultima 12 elementi. Nella prima stringa scriviamo x,
% nella seconda sin(x) e nell'ultima exp(x). Dopo aver fatto questa
% operazione, andiamo a capo (\n).
fprintf(fileID,'%6s %12s %12s\n','x','sin(x)','exp(x)');
% Scriviamo la prima colonna della matrice A. Rappresentiamo il primo
% numero come floating-point number, con 6 cifre totali di cui 2 decimali
% (6.2f). Il secondo e il terzo numero presenti nella colonna li
% rappresentiamo entrambi come floating-point numbers, con 12 cifre totali
% di cui 8 dopo la virgola (12.8f). Dopo aver fatto questo, andiamo a capo
% (\n). fprintf continua a fare la medesima cosa con le altre colonne, fino
% a quando tutta la matrice viene rappresentata.
fprintf(fileID,'%6.2f %12.8f %12.8f\n',A);
% Chiudiamo il file precedentemente aperto:
fclose(fileID);
% Rappresentiamo sulla Command Window il contenuto del file, con il comando
% type
type('dati.txt')

40

Il risultato che otteniamo sulla Command Window, applicando questo algoritmo, :


x

sin(x)

exp(x)

0.00

0.00000000

1.00000000

0.10

0.09983342

1.10517092

0.20

0.19866933

1.22140276

0.30

0.29552021

1.34985881

0.40

0.38941834

1.49182470

0.50

0.47942554

1.64872127

0.60

0.56464247

1.82211880

0.70

0.64421769

2.01375271

0.80

0.71735609

2.22554093

0.90

0.78332691

2.45960311

1.00

0.84147098

2.71828183

1.10

0.89120736

3.00416602

1.20

0.93203909

3.32011692

1.30

0.96355819

3.66929667

1.40

0.98544973

4.05519997

1.50

0.99749499

4.48168907

1.60

0.99957360

4.95303242

1.70

0.99166481

5.47394739

1.80

0.97384763

6.04964746

1.90

0.94630009

6.68589444

2.00

0.90929743

7.38905610

Integrazione
Integrazione numerica
Molte volte, nellambito dellIngegneria Chimica, capita di dover effettuare dei processi di integrazione.
Alcuni integrali possono essere risolti analiticamente e dunque essere determinati in modo esatto. Vi sono
per un buon numero di casistiche in cui non risulta conveniente (o non risulta possibile) calcolare un
integrale a livello analitico. In questi casi, viene in nostro aiuto il calcolo numerico, che ci consente una
determinazione non esatta degli integrali ma vicina al valore reale.
Una prima funzione che consente il calcolo numerico degli integrali trapz. Questo comando, una volta
definito un vettore di ascisse e un vettore di ordinate calcolate in corrispondenza di quelle ascisse, permette
di calcolare lintegrale definito della funzione = (), tra gli estremi definiti dal vettore delle ascisse,
mediante il metodo dei trapezi. Immaginiamo ad esempio di voler calcolare il seguente integrale definito.

41

2
0

possibile calcolare questo integrale, su Matlab, nel seguente modo:


%% Integrazione numerica: funzione trapz
clc
clear all
close all
% Definisco il vettore delle ascisse:
x=0:1e-3:6;
% Definisco il vettore delle ordinate:
y=x.^2.*sin(x);
% Effettuo il calcolo dell'integrale definito della funzione:
I=trapz(x,y);
I =

-37.9988

Unalternativa luso delle funzioni quad o quadl. Queste funzioni hanno la seguente sintassi:
= ( , , , )
Nella precedente formula:

funzione corrisponde alla funzione che desideriamo integrare. Se vi sono operazioni come

prodotto, divisioni oppure elevamenti a potenza, in questo contesto bisogna utilizzare loperatore
preceduto dal punto.
a e b corrispondono agli estremi di integrazione.
tol un parametro che pu essere omesso, e che fornisce informazioni sulla tolleranza assoluta di
errore. Il valore di default 1e-6.

Vediamo un esempio delluso di queste funzioni per il calcolo dellintegrale visto in precedenza. La funzione
quad utilizza il metodo di Simpson, mentre la funzione quadl (che ha la stessa sintassi) utilizza il metodo di
quadratura di Lobatto.
%% Integrazione numerica: funzioni quad e quadl
clc
clear all
close all
% Effettuo il calcolo dell'integrale definito della funzione con quad:
I1=quad('x.^2.*sin(x)',0,6);
% Effettuo il calcolo dell'integrale definito della funzione con quadl:
I2=quadl('x.^2.*sin(x)',0,6);
I1 =

42

-37.9988
I2 =

-37.9988

Integrazione simbolica
Unalternativa allutilizzo dellintegrazione numerica lintegrazione simbolica. Matlab in grado di
effettuare dei calcoli analitici di integrali definiti e indefiniti, restituendone cos lespressione finale. Per
utilizzare questa potente funzione, bisogna operare in ambiente simbolico, mediante lausilio del comando
syms. Ammettiamo ad esempio di voler determinare lintegrale indefinito della precedente funzione.
Possiamo farlo utilizzando il comando int.
%% Integrazione simbolica
clc
clear all
close all
syms x
y=int(x^2*sin(x));
y =
2*cos(x) - x^2*cos(x) + 2*x*sin(x)

Per effettuare unintegrazione definita, risulta essere sufficiente specificare allinterno del commando int
gli estremi di integrazione. In questo modo otteniamo una nuova variabile simbolica, che pu essere tradotta
a quantitativo numerico mediante il comando eval.
%% Integrazione simbolica definita
clc
clear all
close all
syms x
y=int(x^2*sin(x),0,6)
I=eval(y)
y =

12*sin(6) - 34*cos(6) - 2

I =

-37.9988

43

Risulta essere assai comodo tenere a mente questi comandi, dal momento che sono di ampio utilizzo
nellambito dellIngegneria Chimica. Per vedere un esempio di utilizzo di questo comando, si consideri un
sistema termodinamico che raggiunge lequilibrio in un contesto adiabatico (capitolo sullequilibrio chimico
del libro di Termodinamica dellIngegneria Chimica, di Rota Renato).

Risoluzione di equazioni e sistemi


Nei problemi affrontati risulta fondamentale saper risolvere le equazioni (o i sistemi di equazioni) che
emergono dai modelli che si deciso di utilizzare per la risoluzione del problema stesso. Quando le equazioni
(o i sistemi di equazioni) sono semplici, si pu tranquillamente ricorrere allazzeramento analitico. anche
vero che spesso, nei problemi tipici dellIngegneria Chimica, emergono delle equazioni che non possono
essere risolte a livello analitico, e bisogna dunque affidarsi a metodi numerici.

Comando fzero
Il comando fzero risulta essere molto comodo per la risoluzione di unequazione in una singola incognita, che
vogliamo risolvere a livello numerico. Consideriamo ad esempio la seguente equazione:
+ sin = 2
Questa equazione non pu essere risolta a livello analitico, e dunque per risolverla possono essere utilizzati
degli strumenti numerici. Vediamo, ad esempio, come poter utilizzare il comando fzero.
%% Azzeramento di un'equazione in una variabile
clc
clear all
close all
% Scelgo un valore di primo tentativo da immettere nell'algoritmo di
% azzeramento.
X0=0.2;
% Struttura dellalgoritmo fzero
X=fzero('expsin',X0)

%% Funzione ausiliaria all'azzeramento di una funzione in una variabile


function F=expsin(x)
F=exp(x)+sin(x)-2;

----------------------------------------------------------------------------------------------------------------------------------------------X =
0.4487

Come possiamo notare nel precedente algoritmo, nel comando fzero bisogna inserire prima il nome della
funzione da azzerare (che viene definita in una function a parte), poi fornire un valore di primo tentativo, dal
quale il comando partir per effettuare lazzeramento numerico. Allinterno della function definiamo la
funzione che vogliamo azzerare. Dal momento che vogliamo azzerare la funzione F, tutti i termini della
funzione di partenza sono stati portati da un medesimo lato delluguale:
= + sin 2 = 0
Vediamo ora un esempio applicativo di questo comando in una tipica applicazione dellIngegneria Chimica.
Ammettiamo di voler costruire il diagramma delle T di bolla e rugiada e il diagramma y-x di una miscela
44

binaria, dove x corrisponde alla frazione molare in fase liquida del composto pi leggero, y alla sua frazione
molare in fase vapore e T alla temperatura del sistema. In particolar modo, ammettiamo di considerare un
sistema binario benzene-toluene, caratterizzato dai seguenti dati:
= 1
Benzene
Toluene

A
15.9008
16.0137

B
2788.51
3096.52

ln () =

C
-52.36
-53.67

[]
353.3
383.8

, ()[][]
+

Immaginiamo di poter utilizzare il modello di gas perfetto. In questo caso, la relazione di equilibrio
termodinamico tra specie espressa dalla legge di Raoult:
() =
() =
Imponendo che la sommatoria delle frazioni molari in fase vapore delle due specie debba essere 1, otteniamo
che:
() + () = ( + ) =
Per trovare le T di bolla a diverse composizioni, lequazione che vogliamo azzerare :
= () + () = 0
Tale equazione contiene la sola incognita T. Facendo variare la composizione del sistema, possiamo calcolare
la T di bolla a diverse condizioni. Per ciascuna condizione si pu determinare la corrispondente frazione
molare in fase vapore utilizzando lequilibrio tra fasi:
=

()
=

Con queste informazioni possiamo costruire il diagramma delle T di bolla e delle T di rugiada (per la curva di
rugiada basta rappresentare T in funzione di y, invece che di x), e il diagramma y/x. Lalgoritmo di calcolo il
seguente:
%% Creazione di un diagramma di T bolla e di T rugiada
clc
clear all
close all
global A B C P xb xt i
%% Dati: Si riferiscono alle specie S=[benzene toluene]
P=1; %[atm]
A=[15.9008 16.0137]; % Parametri della Antoine
B=[2788.51 3096.52];
C=[-52.36 -53.67];
Tebn=[353.3 383.8]; %[K]

45

%% Risoluzione:
xb=0:0.001:1;
xt=1-xb;
% Creiamo dei vettori, aventi la medesima lunghezza di xb, costituiti
inizialmente da soli 0, ma che conterranno poi I valori di T0 (temperature di
primo tentativo) e di T
T0=zeros(1,length(xb));
T=zeros(1,length(xb));
for i=1:length(xb)
T0(i)=Tebn(2)+xb(i).*(Tebn(1)-Tebn(2)); % Valore lineare di primo tentativo
T(i)=fzero('fTbollrug',T0(i));
end
Pev=exp(A(1)-B(1)./(T+C(1)))/760;
k=Pev./P;
yb=k.*xb;
% Creazione dei diagrammi
figure('Name','Diagramma Tbolla-Trugiada e diagramma y/x','NumberTitle','off')
subplot(1,2,1)
plot(xb,T,'b-','LineWidth',2)
% Il comando hold on permette di sovrascrivere sul medesimo grafico
hold on
plot(yb,T,'k-','LineWidth',2)
grid on
xlabel('Frazione molare di benzene')
ylabel('T [K]')
legend('Curva bolla','Curva rugiada')
subplot(1,2,2)
plot(xb,xb,'b-','LineWidth',2)
hold on
plot(xb,yb,'k-','LineWidth',2)
grid on
xlabel('Frazione molare di benzene (fase L)')
ylabel('Frazione molare di benzene (fase V)')
legend('Bisettrice','Curva y/x')

----------------------------------------------------------------------------------------------------------------------------------------------%% Funzione ausiliaria per la creazione di un diagramma di T bolla e di T


rugiada
function F=fTbollrug(T)
global A B C P xb xt i
F=(exp(A(1)-B(1)./(T+C(1)))*xb(i))+(exp(A(2)-B(2)./(T+C(2)))*xt(i))-P*760;

46

Nel precedente algoritmo tutti I comandi sono gi stati spiegati nelle sezioni precedenti, tranne uno. Mi
riferisco al comando global.
Il comando global serve a fare in modo che la function attinga ai dati gi presenti allinterno dello script
principale, senza doverli riscrivere allinterno della function stessa. Tale comando va inserito sia allinterno
dello script principale che allinterno della function, in entrambi i casi allinizio dellalgoritmo stesso e con le
variabili nel medesimo ordine. Nel caso dello script il comando global viene inserito dopo i comandi clc,
clear all e close all, mentre nel caso della function dopo la definizione iniziale dei dati di input e
output della medesima. I dati condivisi mediante il comando global appaiono nello script e nella function
di colore azzurro.
Nel nostro caso, abbiamo fatto in modo che la function potesse risalire direttamente dallo script principale
ai valori dei parametri delle leggi di Antoine (A,B,C), al valore della pressione (P), ai valori di frazioni molari
di benzene e toluene e al valore dellindice i. Risulta molto importante, nel nostro caso, trasferire alla function
informazioni sul valore dellindice i, che cambia ad ogni passaggio del ciclo for. Infatti, in questo modo, la
function sa in qualsiasi contesto quali elementi dei vettore xb e xt deve considerare. Lutilizzo del comando
global rende la procedura risolutiva e gli algoritmi pi snelli, in quanto permette di non dover riportare ogni
volta i dati anche allinterno delle function.

Comando fsolve
Mentre il comando fzero consente di effettuare azzeramenti di una funzione in una variabile, il comando
fsolve consente la risoluzione di sistemi di N equazioni linearmente indipendenti in N incognite. Il comando
fsolve pu essere utilizzato anche per unequazione in una singola incognita, al posto del comando fzero.
Il funzionamento del comando risulta essere molto simile a quello di fzero, con la differenza che in questo
caso dovremo fornire non un singolo valore di primo tentativo ma un vettore N-dimensionale di valori di
primo tentativo. Inoltre, non dovremo scrivere una sola funzione F, ma tante funzioni F quante sono le

47

incognite. Avremo dunque un vettore F di equazioni allinterno della function, e dobbiamo sempre stare
attenti al fatto che tale vettore sia strutturato come vettore colonna. Se cos non fosse, fsolve restituirebbe
un errore.
Vediamo ora un algoritmo commentato, allinterno del quale viene utilizzato il comando fsolve e in cui
vengono usati molti altri comandi gi descritti in precedenza. Consideriamo la reazione di sintesi del
metanolo, e determiniamo la conversione di monossido di carbonio in diverse condizioni di P e T (prima
esercitazione di Chimica Industriale Organica). Nel farlo, utilizziamo lequazione di stato PR. Le reazioni che
avvengono nel sistema sono le seguenti:
1

+ 22 3
2

2 + 2 + 2 0
IN
1
0.01
2
0
0
3.01

2
2
2 0
3
TOT

,1 =

3
2 2

,2 =

2
2 2

OUT
1 1 + 2
0.01 2
2 21 2
2
1
3.01 21

Tenendo conto che lo stato di riferimento corrisponde a gas ideale 1 [bar], possiamo riformulare
matematicamente le precedenti espressioni come segue:
,1 = (

(3.01 21 )2 1 3
2
)
(1 1 + 2 ) (2 21 2 )2 2 2

(1) = ,1 (
) (1 1 + 2 ) (2 21 2 )2 2 2 (3.01 21 )2 1 3 = 0

,2 =

2 (1 1 + 2 )2
2 2 (0.01 2 )(2 21 2 )

(2) = ,2 2 2 (0.01 2 )(2 21 2 ) 2 (1 1 + 2 )2


Abbiamo ottenuto in questo modo un sistema di due equazioni in due incognite, che pu essere azzerato
numericamente mediante il comando fsolve. Possiamo notare che le grandezze inizialmente a
denominatore sono state portate a numeratore e moltiplicate per le costanti di equilibrio. Questo stato
fatto per motivi di stabilit dellalgoritmo risolutivo. La presenza di grandezze a denominatore pu condurre
a condizioni di divergenza.
%% Studio dell'equilibrio termodinamico della reazione di sintesi del metanolo
clc
clear all

48

close all
%% Dati:
% Considero il vettore delle specie S=[CO CO2 H2 H2O CH3OH]
% Condividiamo con le function i dati utili allo sviluppo di calcoli
global Keq1 Keq2 i P j phi
% Forniamo i dati sul punto critico dei vari elementi, pi il fattore
% acentrico di Pitzer.
Tc=[132.92 304.19 33.18 647.13 512.58]; % [K]
Pc=[34.99 73.82 13.13 220.55 80.96]*1e5; % [Pa]
om=[0.066 0.228 -0.220 0.345 0.566]; % [ad]
% Forniamo i dati utili al calcolo del DG di formazione dei composti, in
% funzione della temperatura
AdG=[-109.885 -393.360 0 -241.74 -201.86]*1e3; % [J/mol]
BdG=[-9.2218e-2 -3.8212e-3 0 4.1740e-2 1.2542e-1]*1e3; % [J/(mol K)]
CdG=[1.4547e-6 1.3322e-6 0 7.4281e-6 2.0345e-5]*1e3; % [J/(mol K^2)]
R=8.314; % [J/(mol K)]
% Creiamo dei vettori di pressione e di temperatura ai quali valutare
% l'equilibrio termodinamico.
T=400:50:700; % [K]
P=50e5:50e5:300e5; % [Pa]
% Creiamo i vettori che saranno di supporto ai seguenti calcoli. I loro
% elementi verranno modificati man mano che i calcoli proseguiranno.
Keq1=zeros(length(T),1);
Keq2=zeros(length(T),1);
Z=zeros(length(Tc),1);
A=zeros(length(Tc),1);
B=zeros(length(Tc),1);
phi=zeros(length(Tc),1);
phiCO=zeros(length(T),length(P));
phiCO2=zeros(length(T),length(P));
phiH2=zeros(length(T),length(P));
phiH2O=zeros(length(T),length(P));
phiCH3OH=zeros(length(T),length(P));
lam1=zeros(length(T),length(P));
lam2=zeros(length(T),length(P));
%Come ciclo pi esterno poniamo un ciclo for sull temperatura, e per ogni
%temperatura calcoliamo i DG di formazione dei composti e le costanti di
%equilibrio delle due reazioni che caratterizzano il sistema.
for i=1:length(T)
DG0=AdG+BdG*T(i)+CdG*T(i)^2; % [J/mol]
DGR1=DG0(5)-DG0(1); % [J/mol]
DGR2=DG0(1)+DG0(4)-DG0(2); % [J/mol]
Keq1(i)=exp(-DGR1/(R*T(i)));

49

Keq2(i)=exp(-DGR2/(R*T(i)));
%All'interno del ciclo for sulla temperatura, apriamo un nuovo ciclo
%for sulla pressione.
for j=1:length(P)
%Ad ogni pressione e ad ogni temperatura, calcoliamo le grandezze
%che ci permettono di determinare il coefficiente di fugacit di
%ciascun composto. Questo fatto mediante una function esterna,
%che si chiama Eos_v (pu essere trovata sul libro di Termodinamica
%dell'Ingegneria Chimica). Notiamo che i valori dei parametri Z, A
%e B dei composti vengono aggiornati ad ogni ciclo, dal momento che
%sono di nostro interesse solamente per l'azzeramento del sistema
%di equazioni.
for k=1:length(Tc);
[Z(k),A(k),B(k)]=Eos_v(T(i),P(j),Tc(k),Pc(k),om(k),4);
phi(k)=exp(Z(k)-1-log(Z(k)-B(k))+(A(k)/(2*sqrt(2)*B(k)))*...
log((Z(k)+B(k)*(1-sqrt(2)))/(Z(k)+B(k)*(1+sqrt(2)))));
end
%
%
%
%
%
%
%

Si ricercano i valori di lambda1 e lambda2 che permettono di


azzerare il sistema, mediante la funzione fsolve. Possiamo notare
che come dato di input al comando bisogna fornire il nome
della funzione ausiliaria e il vettore di valori di primo
tentativo. Come output della funzione, otteniamo i valori di
lambda1 e lambda 2 che azzerano il sistema, scritti all'interno
di un vettore X.

X=fsolve('EqMetanolo',[0.1 1e-4]);
% Salviamo i valori di lambda1 e lambda2 alla i-esima temperatura e
% j-esima pressione
lam1(i,j)=X(1);
lam2(i,j)=X(2);
% Salviamo i valori dei coefficienti di fugacit dei composti
phiCO(i,j)=phi(1);
phiCO2(i,j)=phi(2);
phiH2(i,j)=phi(3);
phiH2O(i,j)=phi(4);
phiCH3OH(i,j)=phi(5);

end
end
% Cancelliamo nuovamente la Command Window, dal momento che fsolve scrive
% dei messaggi in merito ai suoi processi di azzeramento.
clc
% Calcoliamo le matrici di moli e di frazioni molari finali per ciascun
% composto.
nout=3.01-2*lam1;
noutCO=1-lam1+lam2;

50

noutCO2=0.01-lam2;
noutCH3OH=lam1;
noutH2=2-2*lam1-lam2;
noutH2O=lam2;
convCO=lam1-lam2;
xoutCO=noutCO./nout;
xoutCO2=noutCO2./nout;
xoutH2=noutH2./nout;
xoutH2O=noutH2O./nout;
xoutCH3OH=noutCH3OH./nout;
% Creiamo delle matrici di ausilio per la funzione fprint
A1=[(P./1e5)',xoutCO(1,:)',xoutCO2(1,:)',xoutH2(1,:)',xoutH2O(1,:)',...
xoutCH3OH(1,:)',noutCO(1,:)',noutCO2(1,:)',noutH2(1,:)',...
noutH2O(1,:)',noutCH3OH(1,:)'];
A2=[(P./1e5)',xoutCO(2,:)',xoutCO2(2,:)',xoutH2(2,:)',xoutH2O(2,:)',...
xoutCH3OH(2,:)',noutCO(2,:)',noutCO2(2,:)',noutH2(2,:)',...
noutH2O(2,:)',noutCH3OH(2,:)'];
A3=[(P./1e5)',xoutCO(3,:)',xoutCO2(3,:)',xoutH2(3,:)',xoutH2O(3,:)',...
xoutCH3OH(3,:)',noutCO(3,:)',noutCO2(3,:)',noutH2(3,:)',...
noutH2O(3,:)',noutCH3OH(3,:)'];
A4=[(P./1e5)',xoutCO(4,:)',xoutCO2(4,:)',xoutH2(4,:)',xoutH2O(4,:)',...
xoutCH3OH(4,:)',noutCO(4,:)',noutCO2(4,:)',noutH2(4,:)',...
noutH2O(4,:)',noutCH3OH(4,:)'];
A5=[(P./1e5)',xoutCO(5,:)',xoutCO2(5,:)',xoutH2(5,:)',xoutH2O(5,:)',...
xoutCH3OH(5,:)',noutCO(5,:)',noutCO2(5,:)',noutH2(5,:)',...
noutH2O(5,:)',noutCH3OH(5,:)'];
A6=[(P./1e5)',xoutCO(6,:)',xoutCO2(6,:)',xoutH2(6,:)',xoutH2O(6,:)',...
xoutCH3OH(6,:)',noutCO(6,:)',noutCO2(6,:)',noutH2(6,:)',...
noutH2O(6,:)',noutCH3OH(6,:)'];
A7=[(P./1e5)',xoutCO(7,:)',xoutCO2(7,:)',xoutH2(7,:)',xoutH2O(7,:)',...
xoutCH3OH(7,:)',noutCO(7,:)',noutCO2(7,:)',noutH2(7,:)',...
noutH2O(7,:)',noutCH3OH(7,:)'];
% Salviamo i dati su un file esterno. Per farlo, necessario salvare un
% file in formato di testo con il nome EqMetanolo.txt
fileID = fopen('EqMetanolo.txt','wt');
fprintf(fileID,'T=400 [K]\n\n');
fprintf(fileID,'%8s %11s %11s %11s %11s %11s %11s %11s %11s %11s %11s\n',...
'P [bar]','xCO','xCO2','xH2','xH2O','xCH3OH',...
'nCO','nCO2','nH2','nH2O','nCH3OH');
fprintf(fileID,'%8.2f %10.9f %10.9f %10.9f %10.9f %10.9f %10.9f %10.9f %10.9f
%10.9f %10.9f\n',A1');
fprintf(fileID,'\n');
fprintf(fileID,'T=450 [K]\n\n');
fprintf(fileID,'%8s %11s %11s %11s %11s %11s %11s %11s %11s %11s %11s\n',...
'P [bar]','xCO','xCO2','xH2','xH2O','xCH3OH',...
'nCO','nCO2','nH2','nH2O','nCH3OH');
fprintf(fileID,'%8.2f %10.9f %10.9f %10.9f %10.9f %10.9f %10.9f %10.9f %10.9f
%10.9f %10.9f\n',A2');
fprintf(fileID,'\n');
fprintf(fileID,'T=500 [K]\n\n');
fprintf(fileID,'%8s %11s %11s %11s %11s %11s %11s %11s %11s %11s %11s\n',...
'P [bar]','xCO','xCO2','xH2','xH2O','xCH3OH',...
'nCO','nCO2','nH2','nH2O','nCH3OH');
fprintf(fileID,'%8.2f %10.9f %10.9f %10.9f %10.9f %10.9f %10.9f %10.9f %10.9f
%10.9f %10.9f\n',A3');

51

fprintf(fileID,'\n');
fprintf(fileID,'T=550 [K]\n\n');
fprintf(fileID,'%8s %11s %11s %11s %11s %11s %11s %11s %11s %11s %11s\n',...
'P [bar]','xCO','xCO2','xH2','xH2O','xCH3OH',...
'nCO','nCO2','nH2','nH2O','nCH3OH');
fprintf(fileID,'%8.2f %10.9f %10.9f %10.9f %10.9f %10.9f %10.9f %10.9f %10.9f
%10.9f %10.9f\n',A4');
fprintf(fileID,'\n');
fprintf(fileID,'T=600 [K]\n\n');
fprintf(fileID,'%8s %11s %11s %11s %11s %11s %11s %11s %11s %11s %11s\n',...
'P [bar]','xCO','xCO2','xH2','xH2O','xCH3OH',...
'nCO','nCO2','nH2','nH2O','nCH3OH');
fprintf(fileID,'%8.2f %10.9f %10.9f %10.9f %10.9f %10.9f %10.9f %10.9f %10.9f
%10.9f %10.9f\n',A5');
fprintf(fileID,'\n');
fprintf(fileID,'T=650 [K]\n\n');
fprintf(fileID,'%8s %11s %11s %11s %11s %11s %11s %11s %11s %11s %11s\n',...
'P [bar]','xCO','xCO2','xH2','xH2O','xCH3OH',...
'nCO','nCO2','nH2','nH2O','nCH3OH');
fprintf(fileID,'%8.2f %10.9f %10.9f %10.9f %10.9f %10.9f %10.9f %10.9f %10.9f
%10.9f %10.9f\n',A6');
fprintf(fileID,'\n');
fprintf(fileID,'T=700 [K]\n\n');
fprintf(fileID,'%8s %11s %11s %11s %11s %11s %11s %11s %11s %11s %11s\n',...
'P [bar]','xCO','xCO2','xH2','xH2O','xCH3OH',...
'nCO','nCO2','nH2','nH2O','nCH3OH');
fprintf(fileID,'%8.2f %10.9f %10.9f %10.9f %10.9f %10.9f %10.9f %10.9f %10.9f
%10.9f %10.9f\n',A7');
fclose(fileID);
type('Es1CIO2.txt')
% Creiamo una superficie di conversioni di CO per vari valori di pressione
% e di temperatura.
[X,Y]=meshgrid(P*1e-5,T);
meshc(X,Y,convCO)
xlabel('Pressione [bar]')
ylabel('Temperatura [K]')
zlabel('Conversione CO')
% Effettuiamo una medesima rappresentazione in un grafico bidimensionale,
% modificando come parametro la pressione.
figure('Name','Andamento della conversione di CO','NumberTitle','off')
plot(T,convCO(:,1),T,convCO(:,2),T,convCO(:,3),T,convCO(:,4),T,convCO(:,5),T,con
vCO(:,6))
grid on
legend('50 [bar]','100 [bar]','150 [bar]','200 [bar]','250 [bar]','300 [bar]')
xlabel('T [K]')
ylabel('Conversione di CO [adl]')
title('Andamento della conversione di CO')

----------------------------------------------------------------------------------------------------------------------------------------------function F=EqMetanolo(X)
% Definiamo le function da azzerare. F corrisponde al vettore colonna delle
% equazioni da azzerare, mentre X corrisponde alle variabili di azzeramento
% del sistema.
global Keq1 Keq2 i P j phi

52

% Forniamo una nuova denominazione alle due variabili di azzeramento,


% affinch sia chiaro il loro senso fisico nel problema
lam1=X(1);
lam2=X(2);
F(1)=Keq1(i)*(P(j)*1e-5)^2*(1-lam1+lam2)...
*(2-2*lam1-lam2)^2*phi(1)*phi(3)^2-(3.01-2*lam1)^2*lam1*phi(5);
F(2)=Keq2(i)*(0.01-lam2)*(2-2*lam1-lam2)*phi(2)...
*phi(3)-(1-lam1+lam2)*lam2*phi(1)*phi(4);
% Il vettore F generato risulta essere un vettore riga. Trasponiamolo, per
% farlo diventare un vettore colonna:
F=F';

---------------------------------------------------------------------------------------------------------------------------------------------function [Z,A,B,alT,k]=Eos_v(T,P,Tc,Pc,om,tipo)
% Questa funzione permette di effettuare il calcolo dei parametri utili
% alla stima del coefficiente di fugacit, e permette di scegliere tra pi
% funzioni di stato.
%% 1) Dati:
R=8.314;
RT=R*T;
RTc=R*Tc;
TR=T/Tc;
%% 2) Calcolo dei parametri dell'equazione nella forma
Z^3+alfa*Z^2+beta*Z+gamma=0
if tipo==1 %VdW
a=27*RTc^2/(64*Pc);
b=RTc/(8*Pc);
A=a*P/(RT)^2;
B=b*P/(RT);
alfa=-1-B;
beta=A;
gamma=-(A*B);
end
if tipo==2 %RK
a=0.42748*RTc^2/(Pc*sqrt(TR));
b=0.08664*RTc/Pc;
A=a*P/(RT)^2;
B=b*P/(RT);
alfa=-1;
beta=A-B-B^2;
gamma=-(A*B);
end
if tipo==3 %RKS
k=0.48+1.574*om-0.176*om^2;
alT=(1+k*(1-sqrt(T/Tc)))^2;
a=0.42748*alT*RTc^2/Pc;

53

b=0.08664*RTc/Pc;
A=a*P/(RT)^2;
B=b*P/(RT);
alfa=-1;
beta=A-B-B^2;
gamma=-(A*B);
end
if tipo==4 %PR
k=0.37464+1.54226*om-0.26992*om^2;
alT=(1+k*(1-sqrt(T/Tc)))^2;
a=0.45724*alT*RTc^2/Pc;
b=0.07780*RTc/Pc;
A=a*P/(RT)^2;
B=b*P/(RT);
alfa=-1+B;
beta=A-2*B-3*B^2;
gamma=-(A*B)+B^2+B^3;
end
%% 3) Risoluzione analitica della cubica:
p=beta-alfa^2/3;
q=2*alfa^3/27-alfa*beta/3+gamma;
q2=q/2;
a3=alfa/3;
D=q^2/4+p^3/27;
if D>0
if (q2+sqrt(D))>0 && (-q2+sqrt(D))>0
Z1=(-q2+sqrt(D))^(1/3)+(-(q2+sqrt(D))^(1/3))-a3;
elseif (q2+sqrt(D))>0 && (-q2+sqrt(D))<0
Z1=(-(+q2-sqrt(D)))^(1/3)+(-(q2+sqrt(D))^(1/3))-a3;
elseif (q2+sqrt(D))<0 && (-q2+sqrt(D))>0
Z1=(-q2+sqrt(D))^(1/3)+((-q2-sqrt(D))^(1/3))-a3;
else
Z1=(-(+q2-sqrt(D)))^(1/3)+((-q2-sqrt(D))^(1/3))-a3;
end
Z=[Z1 Z1 Z1];
elseif D==0
Z1=-2*(q2)^(1/3)-a3;
Z2=(q2)^(1/3)-a3;
Z=[Z1 Z2 Z2];
else
r=sqrt(-p^3/27);
teta=acos(-q2*sqrt(-27/p^3));
Z1=2*r^(1/3)*cos(teta/3)-a3;
Z2=2*r^(1/3)*cos((2*pi+teta)/3)-a3;
Z3=2*r^(1/3)*cos((4*pi+teta)/3)-a3;
Z=[Z1 Z2 Z3];
end
% Ordiniamo in senso crescente gli elementi di Z
Z=sort(Z);
% Scegliamo il valore di Z corrispondente alla fase gas
Z=Z(3);

54

55

Risoluzione di equazioni differenziali


Sistemi di equazioni differenziali di primo ordine
Nellambito dellIngegneria Chimica, risulta essere di fondamentale importanza la capacit di risolvere
problemi di Cauchy, composti da un sistema di equazioni differenziali con le relative condizioni iniziali. Molte
equazioni differenziali (soprattutto quando le espressioni cinetiche sono complesse) non possono essere
risolte per via analitica. Risulta dunque opportuno imparare a risolverle mediante metodi numerici.
Abbiamo visto in questa guida come risolvere delle equazioni differenziali mediante i cicli for e while.
Adesso approfondiamo lutilizzo di un potente strumento matematico di Matlab, che consente la risoluzione
di equazioni differenziali: le funzioni ode.
Consideriamo il seguente problema, caratterizzato da due reazioni chimiche in serie, e vediamo un algoritmo
che ne consente la risoluzione:
1

, 1 = 0.7[]2 = 0.4[]

= 1

= 1 2

= 2

( = 0) = 5 [ 3 ]

{ ( = 0) = ( = 0) = 0
%% Risoluzione di un sistema di equazioni differenziali
clc
clear all
close all
global k1 k2
%% Dati:
k1=0.7;
k2=0.4;
CA0=5;

% Hz
% Hz
% mol/m^3

%% Risoluzione:
% Costruiamo il vettore di condizioni iniziali
C0=[CA0 0 0];
% Nel risolvere le equazioni differenziali, risulta essere utile
% specificare le seguenti opzioni, per migliorare le performance del
% risolutore numerico:
options=odeset('RelTol',1E-8,'AbsTol',1E-12);
% tSpan il vettore che caratterizza i tempi di derivazione.

56

tSpan=0:1e-4:5;
%
%
%
%
%
%
%

La funzione ode strutturata nel seguente modo. Come dati di output,


fornisce il vettore delle variabili indipendenti (nel nostro caso il
tempo di integrazione) e la matrice delle variabili dipendenti, in cui
ciascuna colonna rappresenta l'evoluzione temporale delle variabili. Come
dati di input la funzione necessit la funzione ausiliaria in cui
definito il sistema, l'intervallo temporale (tSpan), il vettore di condizioni
iniziali e (facoltativo) le options con i parametri di risoluzione.

[t,C] = ode45('fEqDiff',tSpan,C0,options);
% Definiamo i vettori delle concentrazioni di ciascuna specie:
CA=C(:,1);
CB=C(:,2);
CC=C(:,3);
% possibile trovare l'istante temporale corrispondente alla massima
% concentrazione di B nel seguente modo:
CBmax=max(CB);
% Il seguente comando permette di trovare l'indice vettoriale
% corrispondente alla concentrazione massima di B.
i=find(CB==CBmax);
tmax=t(i);
% Rappresentiamo a livello grafico l'andamento delle concentrazioni delle
% specie
figure('Name','Andamento delle concentrazioni di A,B e C','NumberTitle','off')
plot(t,CA,t,CB,t,CC)
grid on
legend('C_{A}','C_{B}','C_{C}')
xlabel('t [s]')
ylabel('Concentrazione [mol/m^{3}]')
title('Andamento delle concentrazioni di A,B e C')
gtext('C_{A}')
gtext('C_{B}')
gtext('C_{C}')

----------------------------------------------------------------------------------------------------------------------------------------------function dcdt=fEqDiff(t,C)
%
%
%
%
%

Nel definire la funzione, prima dell'uguale si mette il nome delle varie


equazioni che costituiranno il sistema differenziale. Tra parentesi viene
messa la variabile indipendente (nel nostro caso il tempo) e le variabili
dipendenti (nel nostro caso C, che rappresenta le concentrazioni. C(1)
rappresenta la concentrazione di A, C(2) quella di B e C(3) quella di C.

global k1 k2
% Scriviamo per prima l'equazione differenziale che governa la
% concentrazione della specie A, poi quelle delle specie B e C. Infinte,

57

% trasponiamo il vettore, per trasformarlo in un vettore colonna


dcdt(1)=-k1*C(1);
dcdt(2)=k1*C(1)-k2*C(2);
dcdt(3)=k2*C(2);
dcdt=dcdt';

Allinterno del programma stato utilizzato il comando ode45. Matlab in realt dispone di pi funzioni utili
alla risoluzione di equazioni differenziali, che usano metodi diversi e che risultano essere appropriate a diversi
contesti. In particolar modo, alcune ode risultano essere particolarmente adatte alla risoluzione di problemi
stiff, caratterizzati da ordini di grandezza molto diversi. Nella seguente tabella (presa da Matlab 6 per
lIngegneria e la Scienza) sono riassunti i vari comandi, con specificate le loro caratteristiche:
Funzione

Descrizione
Risolutore di ordine basso. Non complessa.
Risolutore di ordine medio. Non complessa.
Risolutore di ordine variabile. Non complessa.
Risolutore di ordine basso. Complessa.
Risolutore basato sul metodo dei trapezi.
Moderatamente complessa.
Risolutore di ordine basso. Complessa.
Risolutore di ordine variabile. Complessa.

ode23
ode45
ode113
ode23s
ode23t
ode23tb
ode15s

58

Abbiamo visto come risolvere, mediante le ode, sistemi di equazioni differenziali. Ora analizziamo come poter
risolvere delle equazioni differenziali di grado superiore al primo.

Problemi differenziali di ordine superiore


Consideriamo la seguente equazione differenziale, corredata dalle relative condizioni iniziali:
4 2 + 6 = 2 + 3
{
(0) = 0
(0) = 4
Per poterla risolvere numericamente, iniziamo ad esplicitare la derivata di ordine massimo:
2 + 3 1 3
=
+
4
2
2

Usiamo ora la seguente nomenclatura:


1 = ;2 =
Lequazione differenziale pu quindi essere riscritta mediante il seguente sistema di equazioni differenziali:
1 = 2
{ 2 + 3 1
3
2 =
+ 2 1
4
2
2
In questo modo abbiamo ricondotto lequazione differenziale iniziale di secondo grado in un sistema di due
equazioni differenziali di primo grado, che possiamo risolvere con le metodologie viste in precedenza.
%% Risoluzione di un'equazione differenziale di secondo ordine
clc
clear all
close all
%% Risoluzione:
% Consideriamo il vettore di condizioni iniziali:
y0=[0 4];
options=odeset('RelTol',1E-8,'AbsTol',1E-12);
tSpan=0:1e-3:15;
[t,X] = ode15s('fEqDiff2',tSpan,y0,options);
Y=X(:,1);
Yprimo=X(:,2);
% Se si vuole scrivere ' all'interno di una stringa, va messo due volte
% (altrimenti viene interpretato come simbolo di fine stringa)
figure('Name','Andamento di y e y'' in funzione di t','NumberTitle','off')
plot(t,Y,'b-',t,Yprimo,'k-')
grid on
legend('y(t)','y''(t)')
xlabel('t')
ylabel('y,y''')
title('Andamento di y e y'' in funzione di t')

59

----------------------------------------------------------------------------------------------------------------------------------------------function dxdt=fEqDiff2(t,X)
dxdt(1)=X(2);
dxdt(2)=(t^2+3*t)/4+0.5*X(2)-1.5*X(1);
dxdt=dxdt';

60

Potrebbero piacerti anche