DvdZero: UNA ROUTINE PER
AZZERARE FUNZIONI TRAMITE METODO DICOTOMICO
Contenuto
Realizzazione di una routine in grado di azzerare funzioni non lineari
Testo del problema
Il seguente esempio descrive la realizzazione di una routine in
linguaggio Matlab dedicata all'azzaramento di funzioni non lineari in
una sola incognita tramite metodo dicotomico.
L'aspetto fondamentale di questo esempio è quello della realizzazione di
una function riutilizzabile, capace di risolvere un generico problema di
azzeramento di funzione.
Il codice script seguente determina la temperatura di ebollizione
dell'acqua a pressione ambiente utilizzando la function "DvdZero"
Inizializzazione dell'ambiente
clear all
clc
Costanti/variabili globali presenti nello script principale e nella
funzione da azzerare "fWater"
global A B C D E PRESSIONE
Inizializzazione coefficienti pressione di vapore acqua secondo banca dati DIPPR
A = 7.3649E+01;
B = -7.2582E+03;
C = -7.3037E+00;
D = 4.1653E-06;
E = 2.0000E+00;
PRESSIONE = 101325.;
a = 80. + 273.15;
b = 120. + 273.15;
epsi = 1.e-5;
iPrint = 1;
Chiamata alla routine "DvdZero"
Si noti la differenza rispetto al codice dell'esempio "Azzeramento" dove
la porzione di algoritmo dicotomico è disciolta all'interno dello script
stesso. In tale esempio il codice di azzeramento non è direttamente
riutilizzabile e neppure strutturato per un uso del tutto generale.
Il pregio della routine "DvdZero" è quello di semplificare l'attività
del programmatore e al contempo di fornire tutte le informazioni
desiderate dall'utente.
Dopo aver testato approfonditamente la routine "DvdZero" si è
certi della sua affidabilità e di aver congelato al suo interno un
codice corretto e ben strutturato, riutilizzabile tutte le volte che lo
si desidererà.
[x, fx, delta] = DvdZero(@fWater,a,b,epsi,iPrint);
disp(' ');
disp(['xSol = ',num2str(x),' K ovvero ',num2str(x-273.15),' ^C f(xSol) = ',num2str(fx)]);
disp(['Ampiezza finale dell''intervallo di incertezza = ',num2str(delta)]);
1) c = 373.15 f(c) = -64.437 delta = 20
2) c = 383.15 f(c) = 41798.7066 delta = 10
3) c = 378.15 f(c) = 19376.0447 delta = 5
4) c = 375.65 f(c) = 9303.1897 delta = 2.5
5) c = 374.4 f(c) = 4533.6657 delta = 1.25
6) c = 373.775 f(c) = 2213.4873 delta = 0.625
7) c = 373.4625 f(c) = 1069.2806 delta = 0.3125
8) c = 373.3062 f(c) = 501.1153 delta = 0.15625
9) c = 373.2281 f(c) = 218.0131 delta = 0.078125
10) c = 373.1891 f(c) = 76.7066 delta = 0.039063
11) c = 373.1695 f(c) = 6.1144 delta = 0.019531
12) c = 373.1598 f(c) = -29.1664 delta = 0.0097656
13) c = 373.1646 f(c) = -11.5272 delta = 0.0048828
14) c = 373.1671 f(c) = -2.7067 delta = 0.0024414
15) c = 373.1683 f(c) = 1.7038 delta = 0.0012207
16) c = 373.1677 f(c) = -0.50148 delta = 0.00061035
17) c = 373.168 f(c) = 0.60115 delta = 0.00030518
18) c = 373.1679 f(c) = 0.04983 delta = 0.00015259
19) c = 373.1678 f(c) = -0.22583 delta = 7.6294e-005
20) c = 373.1678 f(c) = -0.087998 delta = 3.8147e-005
21) c = 373.1678 f(c) = -0.019084 delta = 1.9073e-005
22) c = 373.1678 f(c) = 0.015373 delta = 9.5367e-006
xSol = 373.1678 K ovvero 100.0178 ^C f(xSol) = 0.015373
Ampiezza finale dell'intervallo di incertezza = 9.5367e-006
DvdZero: una routine di
azzeramento funzioni tramite metodo dicotomico
function [x, fx, delta] = DvdZero(FUN,a,b,epsi,iPrint)
nIter = ceil((log(b-a) - log(epsi)) / log(2.));
iConto = 0;
fa = feval(FUN,a);
fb = feval(FUN,b);
if sign(fa) * sign(fb) > 0
error('Estremi del metodo dicotomico NON consistenti. Impossibile continuare...');
end
for i = 1: nIter
c = a + 0.5 * (b-a);
fc = feval(FUN,c);
if sign(fa) * sign(fc) < 0.
b = c;
fb = fc;
else
a = c;
fa = fc;
end
if iPrint ~= 0
disp([num2str(i),') c = ',num2str(c),' f(c) = ',num2str(fc),' delta = ',num2str(b-a)]);
end
end
x = c;
fx = fc;
delta = b - a;
fWater: esempio di funzione
da azzerare
function f = fWater(T)
global A B C D E PRESSIONE
f = exp(A + B / T + C * log(T) + D * T ^ E) - PRESSIONE;