Derivación numérica

Aproximamos la derivada de $f(x) = e^x$ en $x=1$ por la diferencia:

$$f'(x) \approx \frac{f(x + \Delta x) - f(x)}{\Delta x}$$

Comparamos el error cuando $\Delta x$ decrece, entre la aproximación y la respuesta correcta $f'(1) = e$.

Usamos un gráfico de tipo loglog, en el que ambos ejes están en escala logarítmica.

Observamos que a menor $h$, menor error, hasta que $h$ es aproximadamente 1e-8: para un $h$ menor, el error aumenta.

In [5]:
f = @(x)(sin(x));
%Derivada de f
fp = @(x)(cos(x));

x0 = 1;
fp0 = fp(x0);

%Usamos valores de h de la forma 1/2^n
hs = 2.^(-[1:60]);
fd_2p_forward = (f(x0+hs) - f(x0))./hs;
errores_2p = abs(fd_2p_forward - fp0);

title('Error en la diferencia dividida como funcion de h')
loglog(hs, errores_2p, 'g.')
xlabel("h")
ylabel("error")
legend('error en la formula de 2 puntos')

Recordamos la expresión que derivamos para el error de truncamiento que comete la diferencia de dos puntos hacia delante:

$$ f'(x) = \frac{f(x + h) - f(x)}{h} - \frac{h}{2}f''(\xi) $$

para un punto $\xi\in (x, x + h)$.

Dibujamos los errores que comete y los comparamos con la cota del error, usando la aproximación $f''(\xi)\approx f''(x)$.

In [16]:
f = @(x)(sin(x));
%Derivada de f
fp = @(x)(cos(x));
%Segunda derivada de f
fp2 = @(x)(-sin(x));

x0 = 1;
fp0 = fp(x0);

%Usamos valores de h de la forma 1/2^n
hs = 2.^(-[1:60]);
fd_2p_forward = (f(x0+hs) - f(x0))./hs;
errores_2p = abs(fd_2p_forward - fp0);
cota_error_2p = abs(fp2(x0))*hs/2;

hold on;
set(gca, 'XScale', 'log', 'YScale', 'log');
title('Error en la diferencia dividida como funcion de h')
loglog(hs, errores_2p, 'g.')
loglog(hs, cota_error_2p, 'g-')
xlabel("h")
ylabel("error")
legends = cell(1,2);
legends{1} = 'error en la formula de 2 puntos';
legends{2} = 'cota del error en la formula de 2 puntos';
legend(legends)
hold off;

Recordamos que si incorporamos el error de redondeo, obtenemos una cota mejor

$$ \left|f'(x) - \frac{f(x + h) - f(x)}{h}\right| < \frac{\varepsilon}{h} + \frac{h}{2}M $$

donde $\varepsilon$ es una cota del error de redondeo al evaluar $f$, que estimamos como el epsilon de la máquina (aunque para algunas funciones puede ser demasiado optimista), y $M$ es una cota para $|f''(\xi)|$ cuando $\xi\in (x, x + h)$.

In [17]:
f = @(x)(sin(x));
%Derivada de f
fp = @(x)(cos(x));
%Segunda derivada de f
fp2 = @(x)(-sin(x));

x0 = 1;
fp0 = fp(x0);

%Usamos valores de h de la forma 1/2^n
hs = 2.^(-[1:60]);
fd_2p_forward = (f(x0+hs) - f(x0))./hs;
errores_2p = abs(fd_2p_forward - fp0);
M = 1;
% Si cambias x0, o f, es necesario cambiar la cota M
% la línea siguiente estima M como el máximo entre
% |fp2(x0)| y |fp2(x0+h)|
%M = np.maximum(np.abs(fp2(x0)), np.abs(fp2(x0+hs)))
cota_error_2p = eps./hs + M.*hs./2;

hold on;
set(gca, 'XScale', 'log', 'YScale', 'log');
title('Error en la diferencia dividida como funcion de h')
loglog(hs, errores_2p, 'g.')
loglog(hs, cota_error_2p, 'g-')
xlabel("h")
ylabel("error")
legends = cell(1,2);
legends{1} = 'error en la formula de 2 puntos';
legends{2} = 'cota del error en la formula de 2 puntos';
legend(legends)
hold off;

Ejercicios

  • Dibuja en la misma gráfica loglog los errores que cometen la aproximación a $f'$ de dos puntos hacia delante, y la aproximación centrada de tres puntos.
  • Compara el error que comete la aproximación centrada de tres puntos con la cota del error que vimos en clase: $$ \left|f'(x) - \frac{f(x + h) - f(x-h)}{2h}\right| < \frac{\varepsilon}{h} + \frac{h^2}{6}M $$ para una cota $M$ de $f^{(3}(\xi)$ con $\xi\in(x,x+h)$.
In [ ]:

In [ ]:

In [ ]:

Ahora hacemos otro tipo de gráfica: dejamos $h$ fijo (no demasiado pequeño) y cambiamos $x$.

Dibujamos los errores que comete y los comparamos con la cota del error: $$ f'(x) = \frac{f(x + h) - f(x)}{h} - \frac{h}{2}f''(\xi) $$ para un punto $\xi\in (x, x + h)$, usando la aproximación $f''(\xi)\approx f''(x)$.

In [21]:
f = @(x)(sin(x));
%Derivada de f
fp = @(x)(cos(x));
%Segunda derivada de f
fp2 = @(x)(-sin(x));

xs = linspace(0,2*pi,100);
fps = fp(xs);
h = 0.1;
fd_2p_forward = (f(xs + h) - f(xs))/h;
errores_2p = fps - fd_2p_forward;
cota_error_2p = - (h/2)*fp2(xs);

hold on;
title('Error en la diferencia dividida como funcion de x')
plot(xs, errores_2p, 'g.')
plot(xs, cota_error_2p, 'g-')
xlabel("x")
ylabel("error")
legends = cell(1,2);
legends{1} = 'error en la formula de 2 puntos';
legends{2} = 'cota del error en la formula de 2 puntos';
legend(legends)
hold off;

Ejercicio

  • Repite la gráfica anterior para otra función distinta
  • Repite la gráfica anterior para la diferencia centrada de tres puntos, con su estimación del error.
In [ ]:

In [ ]:

La fórmula de tres puntos siguiente aproxima la segunda derivada de una función:

$$ f''(x_0)\approx\frac{f(x_0-h)-2f(x_0)+f(x_0+h)}{h^2} $$

Ejercicio

  • Dibuja el error que comete esta expresión al aproximar $f''$ para $f(x)=\sin(x)$ con valores de $h$ de la forma $1/2^n$, al igual que hicimos antes con la primera derivada.
  • Compara la gráfica anterior con la cota de error
$$ \left|f''(x) - \frac{f(x + h) - 2f(x) +f(x-h)}{h^2}\right| < \frac{\varepsilon}{h^2} + \frac{h^2}{24}M $$

para una cota $M$ de $f^{(4}(\xi)$ con $\xi\in(x-h,x+h)$.

In [ ]:

In [ ]:

In [ ]:

In [ ]: