Càlcul dels zeros d'una funció:
En aquesta pràctica veurem com es poden calcular numèricament els zeros d'una funció.
Teorema de Bolzano: Canvis de signe
Donada una funció f(x), per calcular els seus zeros haurem de fer:
- Triar el rang del domini en el que estudiem la funció: [xmin,xmax]
- Avaluar la funció en un conjunt de punts d'aquest domini
- Determinar els canvis de signe de la funció (per Bolzano sabem que allà hi haurà els zeros)
- Calcular els zeros
% funció f(x) definida com a inline
%rang de valors que estudiem
%-------------------------------------------------------------
% pintem la funció per tenir una idea dels zeros
%-------------------------------------------------------------
semieix_y=1.1*max(abs(y)); %ajustem els eixos als valors de la funció
axis([xmin xmax -semieix_y semieix_y]);
line([xmin xmax],[0 0],'Color','k','LineWidth',2)
line([0 0],[-semieix_y semieix_y],'Color','k','LineWidth',2)
Determinació de l'interval de canvi de signe
%-------------------------------------------------------------
% Determinem els possibles zeros de la funció.
%-------------------------------------------------------------
% Fem un estudi del numero de zeros a partir dels canvis de signe de la
disp(['zero ', num2str(nzeros)]);
disp(['interval [' num2str(x(j)) ',' num2str(x(j+1)) ']']);
intervals=[intervals; x(j), x(j+1)]; %guardem els intervals en una matriu
Mètode de la Bisecció
Es basa en dividir succesivament la meitat l'interval inicial [a,b],
en el que hi ha un canvi de signe i anar descartant la meitat que ja no conté el canvi de signe (trobareu el codi al final del guió). Iteracions de la bisecció
Càlcul del zero a cada interval
Ara per cada interval cridarem una funció que calculi el zero fins a una determinada tolerància d'error
. Aquest criteri és suficient si la funció és prou vertical però en general és més precís utilitzar que
que sempre donarà un valor més proper al zero real. tol = 1.e-8; % demanem 10^(-8) de precisió en el càlcul
numZeros = size(intervals,1); %cada fila és un interval [xa, xb] de canvi de signe
z(i) = biseccio(f, xa, xb, tol); %s'ha de triar el mètode a utilitzar
%z(i) = secant(f, xa, xb, tol);
%z(i) = newton(f,df,x0,tol);
end
iter = 1 x= -3.1250000000000000e+00 f(x)= -1.659189e-02
iter = 2 x= -3.1625000000000001e+00 f(x)= 2.090582e-02
iter = 3 x= -3.1437499999999998e+00 f(x)= 2.157345e-03
iter = 4 x= -3.1343749999999999e+00 f(x)= -7.217591e-03
iter = 5 x= -3.1390624999999996e+00 f(x)= -2.530151e-03
iter = 6 x= -3.1414062499999997e+00 f(x)= -1.864036e-04
iter = 7 x= -3.1425781250000000e+00 f(x)= 9.854713e-04
iter = 8 x= -3.1419921874999996e+00 f(x)= 3.995339e-04
iter = 9 x= -3.1416992187499995e+00 f(x)= 1.065652e-04
iter = 10 x= -3.1415527343749998e+00 f(x)= -3.991921e-05
iter = 11 x= -3.1416259765624996e+00 f(x)= 3.332297e-05
iter = 12 x= -3.1415893554687497e+00 f(x)= -3.298121e-06
iter = 13 x= -3.1416076660156245e+00 f(x)= 1.501243e-05
iter = 14 x= -3.1415985107421873e+00 f(x)= 5.857152e-06
iter = 15 x= -3.1415939331054688e+00 f(x)= 1.279516e-06
iter = 16 x= -3.1415916442871090e+00 f(x)= -1.009303e-06
iter = 17 x= -3.1415927886962889e+00 f(x)= 1.351065e-07
iter = 18 x= -3.1415922164916990e+00 f(x)= -4.370981e-07
iter = 19 x= -3.1415925025939941e+00 f(x)= -1.509958e-07
iter = 20 x= -3.1415926456451415e+00 f(x)= -7.944652e-09
--------------------------------
iter = 1 x= 2.5000000000000355e-02 f(x)= 2.499740e-02
iter = 2 x= -1.2499999999999734e-02 f(x)= -1.249967e-02
iter = 3 x= 6.2500000000003109e-03 f(x)= 6.249959e-03
iter = 4 x= -3.1249999999997113e-03 f(x)= -3.124995e-03
iter = 5 x= 1.5625000000002998e-03 f(x)= 1.562499e-03
iter = 6 x= -7.8124999999970579e-04 f(x)= -7.812499e-04
iter = 7 x= 3.9062500000029698e-04 f(x)= 3.906250e-04
iter = 8 x= -1.9531249999970440e-04 f(x)= -1.953125e-04
iter = 9 x= 9.7656250000296291e-05 f(x)= 9.765625e-05
iter = 10 x= -4.8828124999704056e-05 f(x)= -4.882812e-05
iter = 11 x= 2.4414062500296117e-05 f(x)= 2.441406e-05
iter = 12 x= -1.2207031249703969e-05 f(x)= -1.220703e-05
iter = 13 x= 6.1035156252960739e-06 f(x)= 6.103516e-06
iter = 14 x= -3.0517578122039478e-06 f(x)= -3.051758e-06
iter = 15 x= 1.5258789065460631e-06 f(x)= 1.525879e-06
iter = 16 x= -7.6293945282894233e-07 f(x)= -7.629395e-07
iter = 17 x= 3.8146972685856038e-07 f(x)= 3.814697e-07
iter = 18 x= -1.9073486298519098e-07 f(x)= -1.907349e-07
iter = 19 x= 9.5367431936684699e-08 f(x)= 9.536743e-08
iter = 20 x= -4.7683715524253140e-08 f(x)= -4.768372e-08
iter = 21 x= 2.3841858206215780e-08 f(x)= 2.384186e-08
iter = 22 x= -1.1920928659018680e-08 f(x)= -1.192093e-08
iter = 23 x= 5.9604647735985499e-09 f(x)= 5.960465e-09
--------------------------------
iter = 1 x= 3.1750000000000007e+00 f(x)= -3.340113e-02
iter = 2 x= 3.1375000000000006e+00 f(x)= 4.092642e-03
iter = 3 x= 3.1562500000000009e+00 f(x)= -1.465682e-02
iter = 4 x= 3.1468750000000005e+00 f(x)= -5.282322e-03
iter = 5 x= 3.1421875000000004e+00 f(x)= -5.948464e-04
iter = 6 x= 3.1398437500000007e+00 f(x)= 1.748903e-03
iter = 7 x= 3.1410156250000005e+00 f(x)= 5.770286e-04
iter = 8 x= 3.1416015625000004e+00 f(x)= -8.908910e-06
iter = 9 x= 3.1413085937500007e+00 f(x)= 2.840598e-04
iter = 10 x= 3.1414550781250004e+00 f(x)= 1.375755e-04
iter = 11 x= 3.1415283203125002e+00 f(x)= 6.433328e-05
iter = 12 x= 3.1415649414062505e+00 f(x)= 2.771218e-05
iter = 13 x= 3.1415832519531257e+00 f(x)= 9.401637e-06
iter = 14 x= 3.1415924072265629e+00 f(x)= 2.463632e-07
iter = 15 x= 3.1415969848632814e+00 f(x)= -4.331273e-06
iter = 16 x= 3.1415946960449221e+00 f(x)= -2.042455e-06
iter = 17 x= 3.1415935516357427e+00 f(x)= -8.980459e-07
iter = 18 x= 3.1415929794311528e+00 f(x)= -3.258414e-07
iter = 19 x= 3.1415926933288576e+00 f(x)= -3.973906e-08
iter = 20 x= 3.1415925502777102e+00 f(x)= 1.033121e-07
iter = 21 x= 3.1415926218032837e+00 f(x)= 3.178651e-08
iter = 22 x= 3.1415926575660706e+00 f(x)= -3.976277e-09
--------------------------------
z
-3.141592645645142e+00 5.960464773598550e-09 3.141592657566071e+00
Exercici 1:
Canvieu el criteri de detecció del zero de bisecció per la condició
. Hint: En aquest cas només cal fer
i només calen un parell més d'iteracions. Agafeu la funció
en
que és una funció molt plana (tota ella està per sota de
) i mireu la diferència entre els dos criteris (el segon sempre és més precís!!) Exercici 2: Mètode de la secant (regula falsi)
Implementeu el mètode de la secant creant una funció de Matlab
function zero = secant(f, xa, xb, tol)
i substituiu en el programa anterior la crida a biseccio per la crida a secant.
Mètode de la secant:
Anàlogament al que es fa en el mètode de bisecció, es pot fer el mateix però triant com a punt intermedi c, el punt de tall de l'eix x (y=0) amb la recta que uneix els dos punts (a,f(a)) i (b,fb)).
Podeu comprovar que la fórmula és:
A partir d'aquí es procedeix exactament igual que a bisecció, es descarta el subinterval que no conté el zero.
(source https://planetcalc.com/3712/)
Solució: Pel primer dels zeros només calen dues iteracions i donen:
iter = 1 x= -3.1415994094031583e+00 f(x)= 6.755813e-06
iter = 2 x= -3.1415926532799121e+00 f(x)= -3.098811e-10
Exercici 3: Mètode de Newton
Implementeu el mètode de Newton creant una funció de Matlab
function zero = newton(f, df, x0, tol)
i substituiu en el programa anterior la crida a biseccio per la crida a newton.
Mètode de Newton:
Anàlogament al que es fa en el mètode de secant, es pot fer el mateix però triant com a punt intermedi c, el punt de tall de l'eix x (y=0) amb la recta tangent en un punt inicial
de l'interval [a,b]. Per exemple el punt mig de [a,b],
. Això requereix, entre d'altres coses, el càlcul de la derivada de la funció f(x) i definir-la també com una funció inline.
La fórmula matemàtica del mètode en aquest cas és:
A partir d'aquí es procedeix exactament igual que a bisecció, es descarta el subinterval que no conté el zero.