11. Derivate di funzioni#
11.1. Differenze finite#
Il calcolo della derivata di una funzione \(f(x)\) derivabile in un punto \(x_0\) può essere svolto utilizzando l’espansione locale in serie di Taylor di una funzione.
11.1.1. Derivata prima#
Usando le espansioni
si possono ricavare:
gli schemi del primo ordine
\[\begin{split}\begin{aligned} f'(x) & = \frac{f(x+h) - f(x)}{h} + O(h) \\ f'(x) & = \frac{f(x) - f(x-h)}{h} + O(h) \\ \end{aligned}\end{split}\]lo schema centrato del secondo ordine
\[f'(x) = \dfrac{f(x+h) - f(x-h)}{2 h} + O(h^2) \]lo schema non centrato del secondo ordine:
\[f'(x) = \frac{-3 \, f(x) + 4 \, f(x+h) - f(x+2h)}{2 \, h} + O(h^2) \ .\]Dimostrazione
Usando le espansioni in serie,
\[\begin{split}\begin{aligned} f(x + h) & = f(x) + f'(x) \, h + f''(x) \frac{h^2}{2} + f'''(x) \frac{h^3}{3!} + o(h^3) \\ f(x + 2h) & = f(x) + f'(x) \, 2 h + 2 f''(x) \, h^2 + f'''(x) \frac{4}{3} h^3 + o(h^3) \\ \end{aligned}\end{split}\]si cerca una coppia di coefficienti della combinazione lineare \(a_1 f(x+h) + a_2 f(x+2h)\) che annullano il termine di secondo grado.
In particolare è facile dimostrare che una di queste scelte è \(\alpha_1 = 4\), \(\alpha_2 = -1\), e la combinazione lineare per questi valori diventa,
\[4 f(x+h) - f(x+2h) = 3 f(x) + 2 \, h f'(x) + O(h^3) \ .\]A questo punto è semplice isolare \(f'(x)\) per trovare lo schema numerico desiderato,
\[f'(x) = \frac{-3 \, f(x) + 4 \, f(x+h) - f(x+2h)}{2 \, h} + O(h^2) \ .\]…
schemi di ordine superiore…
11.1.2. Derivata seconda#
Usando le stesse espansioni in serie, si può ottenere uno schema del secondo ordine per la derivata seconda
Dimostrazione
Usando le espansioni in serie
si può notare che nella somma che compare al numeratore dello schema numerico si annullano sia il termine di primo grado sia il termine di terzo grado,
e quindi lo schema numerico proposto è del secondo ordine,
""" Numerical schemes for derivatives """
df_first_order_left = lambda f, x, h: (f(x) - f(x-h)) / h
df_first_order_right = lambda f, x, h: (f(x+h) - f(x)) / h
df_second_order_center = lambda f, x, h: (f(x+h) - f(x-h)) / ( 2. * h )
df_second_order_left = lambda f, x, h: ( 3*f(x) - 4*f(x-h) + f(x-2*h)) / ( 2. * h )
df_second_order_right = lambda f, x, h: (- 3*f(x) + 4*f(x+h) - f(x+2*h)) / ( 2. * h )
df_fun_dict = {
'1_left' : df_first_order_left,
'1_right' : df_first_order_right,
'2_center': df_second_order_center,
'2_left' : df_second_order_left,
'2_right' : df_second_order_right
}
""" Example """
import numpy as np
f = lambda x: 2. * np.exp(- x**2)
x, h = 1., .01
for df_label, df_fun in df_fun_dict.items():
print(f"Scheme: {df_label.ljust(10)}, value: {df_fun(f,x,h)}" )
Scheme: 1_left , value: -1.4788256893130014
Scheme: 1_right , value: -1.4641117378933477
Scheme: 2_center , value: -1.4714687136031745
Scheme: 2_left , value: -1.4716195509633268
Scheme: 2_right , value: -1.4716121945026028