Numeryczne obliczanie pochodnej funkcji w danym punkcie

Stronę tą wyświetlono już: 139 razy

Numeryczne obliczanie pochodnej funkcji f(x) w danym punkcie x sprowadza się do zastosowania ogólnej graficznej interpretacji przybliżonej wartości pochodnej, która pokazana została na poniższym rysunku. Widać tutaj dwa punkty P1 i P2, które są oddalone od siebie o wartość Δx, współrzędne y-kowe tych punktów są dane funkcją f(x) dla punktu pierwszego i f(x + Δx) dla punktu drugiego. Punty P1 i P2 wyznaczają pewną prostą, której kąt β przy bardzo małym Δx w przybliżeniu jest równy kątowi stycznej do punktu P1.

Obliczanie przybliżonej wartości pochodnej - graficzna interpretacja
Rys. 1
Obliczanie przybliżonej wartości pochodnej - graficzna interpretacja.

Wiedząc, że pochodna funkcji w danym jej punkcie jest równa tangensowi kąta nachylenia prostej stycznej do tej funkcji można obliczyć numerycznie pierwszą pochodną funkcji f(x) korzystając z następującego wzoru:

Wzór na pierwszą pochodną całki numerycznej w zadanym punkcie x [1]

Zapis wyrażenia w formacie TeX-a:

\frac{d\,f(x)}{d\,x}=\frac{f(x + \Delta x) - f(x)}{\Delta x}=\tan\, \beta

Korzystając z wzoru [1] można wyznaczyć wzór na przybliżoną wartość drugiej pochodnej funkcji:

Wzór na pierwszą pochodną całki numerycznej w zadanym punkcie x [2]

Zapis wyrażenia w formacie TeX-a:

\frac{d\,f(x)}{d^2\,x}=\frac{f(x + 2\cdot\Delta x) - 2 \cdot f(x + \Delta x) + f(x)}{{\Delta x}^2}

W językach programowania takich jak C++ do wykorzystania tego algorytmu konieczne jest zaimplementowanie algorytmu ONP, który powstał jako modyfikacja algorytmu notacji polskiej Jana Łukasiewicza. W przypadku języków skryptowych takich jak PHP czy Python można posłużyć się funkcją eval, której użycie ze względów bezpieczeństwa jest niekiedy niewskazane.

Oto przykład prostego programu napisanego w Pythonie obliczającego tą metodą pierwszą i drugą pochodną podanej na wejście funkcji:

Listing 1
  1. #!/usr/bin/env python
  2. from math import *
  3. def diff(function, x, dx):
  4. f_x1 = eval(function)
  5. x += dx
  6. f_x2 = eval(function)
  7. return (f_x2 - f_x1) / dx
  8. def diff2(function, x, dx):
  9. f_x1 = eval(function)
  10. x += dx
  11. f_x2 = eval(function)
  12. x += dx
  13. f_x3 = eval(function)
  14. return (f_x3 - 2 * f_x2 + f_x1) / (dx * dx)
  15. def main(args):
  16. function = input("Podaj funkcję f(x): ")
  17. x = float(input("Punkt dla pochodnej funkcji f(x): "))
  18. dx = float(input("Rozmiar elementarnego przesunięcia: "))
  19. print("Pochodna funkcji {function} w punkcie {x} dla dx = {dx} jest równa: {diff}".format(function = function, x = x, dx = dx, diff = diff(function, x, dx)))
  20. print("Druga pochodna funkcji {function} w punkcie {x} dla dx = {dx} jest równa: {diff2}".format(function = function, x = x, dx = dx, diff2 = diff2(function, x, dx)))
  21. return 0
  22. if __name__ == '__main__':
  23. import sys
  24. sys.exit(main(sys.argv))

Przykład obliczenia pierwszej i drugiej pochodnej funkcji f(x) = sin(x) dla x = 1 i Δx = 0.1:

Podaj funkcję f(x): sin(x)
Punkt dla pochodnej funkcji f(x): 1
Rozmiar elementarnego przesunięcia: 0.1
Pochodna funkcji sin(x) w punkcie 1.0 dla dx = 0.1 jest równa: 0.4973637525353891
Druga pochodna funkcji sin(x) w punkcie 1.0 dla dx = 0.1 jest równa: -0.8904649347747926
Aby kontynuować, naciśnij dowolny klawisz . . .

Pierwsza pochodna funkcji f(x) = sin(x) jest równa f'(x) = cos(x) a więc wartość tej funkcji dla x = 1 [rad] wynosi f'(1) = 0.540302305, natomiast druga pochodna to f''(x) = -sin(x), dla której wartość tej funkcji dla x = 1 [rad] wynosi f''(x) = -0.841470984. Różnice dla Δx = 0.1 są znaczące, więc warto zmniejszyć ten parametr do np. Δx = 0.00001 w wyniku czego otrzymany zostanie następujący rezultat:

Podaj funkcję f(x): sin(x)
Punkt dla pochodnej funkcji f(x): 1
Rozmiar elementarnego przesunięcia: 0.00001
Pochodna funkcji sin(x) w punkcie 1.0 dla dx = 1e-05 jest równa: 0.5402980985058647
Druga pochodna funkcji sin(x) w punkcie 1.0 dla dx = 1e-05 jest równa: -0.8414757779462433
Aby kontynuować, naciśnij dowolny klawisz . . .

Jak widać rozbieżności są znacznie mniejsze niż poprzednio.

Komentarze