«Кто-то» ответил на ваш вопрос, но вы (и будущие читатели) могут найти эту дополнительную информацию полезной.
Для получения точной аппроксимации производной вам необходимо сделать h
довольно маленьким. Однако, если вы сделаете его слишком маленьким, вы фактически потеряете точность из-за ограниченной точности поплавков Python. Вы можете получить больше точности, используя модуль decimal
. Однако этот модуль поддерживает только простые арифметические операторы и функцию квадратного корня. Если вам нужны более удобные функции, такие как тригонометрические или экспоненциальные функции, вы можете использовать сторонний пакет произвольной точности математического пакета, такой как отличный mpmath
, хотя, если вы используете mpmath
, то вы, вероятно, используете его numerical derivative functions.
FWIW, вы можете сделать приближение производной более точным (для заданного h
), сделав x
серединой интервала. Вот краткий демо:
def dfa(f, x, h):
return (f(x + h) - f(x))/h
def dfb(f, x, h):
hh = 0.5 * h
return (f(x + hh) - f(x - hh))/h
# The function
def func(x): return x**3 + x*x + x + 1
# Its exact derivative
def dfunc(x): return 3*x*x + 2*x + 1
h = 0.001
for i in range(10):
x = 1 + 0.1 * i
print(x, dfunc(x), dfb(func, x, h), dfa(func, x, h))
выход
1.0 6.0 6.00000024999936 6.004000999999093
1.1 6.830000000000001 6.830000249999024 6.8343009999995985
1.2 7.719999999999999 7.72000024999997 7.724600999999609
1.3 8.67 8.670000249998644 8.674900999999124
1.4 9.68 9.680000249999487 9.685200999998145
1.5 10.75 10.750000249998948 10.755500999998446
1.6 11.880000000000003 11.880000249998801 11.885800999996476
1.7000000000000002 13.070000000000002 13.07000024999816 13.07610099999934
1.8 14.32 14.320000249997022 14.326400999998157
1.9 15.629999999999999 15.630000249997167 15.636700999996478
Вот результаты для экспоненциальной функции.
from math import exp
def dfa(f, x, h):
return (f(x + h) - f(x))/h
def dfb(f, x, h):
hh = 0.5 * h
return (f(x + hh) - f(x - hh))/h
func = dfunc = exp
h = 0.001
for i in range(10):
x = 1 + 0.1 * i
print(x, dfunc(x), dfb(func, x, h), dfa(func, x, h))
выход
1.0 2.718281828459045 2.718281941720413 2.7196414225332255
1.1 3.0041660239464334 3.0041661491195804 3.005668607777512
1.2 3.3201169227365472 3.320117061074157 3.3217775346887635
1.3 3.6692966676192444 3.669296820505874 3.6711319276547805
1.4 4.0551999668446745 4.0552001358102885 4.057228242863253
1.5 4.4816890703380645 4.481689257074706 4.483930662008362
1.6 4.953032424395115 4.953032630771403 4.955509766318755
1.7000000000000002 5.473947391727201 5.473947619807795 5.476685277975513
1.8 6.0496474644129465 6.049647716480422 6.0526732966712515
1.9 6.6858944422792685 6.685894720857455 6.689238504094419
Обратите внимание, что dfb
не является надежным: если вы пытаетесь найти производную в x
значение, которое находится рядом с полюсом или разрыва, то смещение интервала включить полюс или разрывы могут дать ошибочные результаты. Конечно, вы можете получить ту же проблему с dfa
, например, если f(x) = 1/x
и x
- отрицательное число, но x+h
положительно.
Очевидно, что 'f' должен быть функцией, с которой вы переходите в' difference_quotient' для ее вызова. Поэтому 'f (x + h)' и f (x) 'вызывают функцию, которую вы передали с разными аргументами. – khelwood
FWIW, Joel Grus является членом SO http: // stackoverflow.com/users/1076346/joel –