使用 Python 求函数的差商

Finding the Difference Quotient of a function Using Python

我正在阅读 Joel Grus 的 Data Science From Scratch,并且坚持理解简单差商函数如何使用 python。
这是代码:

f 是单变量函数的函数,依赖于 x,因为 h 接近 0。

def difference_quotient(f, x, h):
    return (f(x + h) - f(x)) / h

我知道这只是求极限的方程式,在本例中是求导数,但我不明白脚本是如何工作的。您会在函数中放入哪些参数,以允许 f(something) 的 return 语句而不是 f*(something)。到目前为止,我不断收到诸如 'float'/'dict' object is not callable.

之类的错误

f 是您试图找到 x 处的 derivative/difference 商的函数。

试试这个代码:(python 3)

def difference_quotient(f, x, h):
    return (f(x + h) - f(x)) / h

def func(x):
    # this is f of x, the function you are taking the derivative of
    return x * x

print(difference_quotient(func, 2, 0.001))

"Someone" 已回答您的问题,但您(和未来的读者)可能会发现此补充信息很有用。

要获得导数的准确近似值,您需要使 h 相当小。但是,如果你让它太小,那么由于 Python 浮点数的精度有限,你实际上会失去准确性。您可以使用 decimal 模块获得更高的精度。但是,该模块仅支持简单的算术运算符和平方根函数。如果您需要更高级的函数,如三角函数或指数函数,那么您可以使用第三方包 arbitrary-precision 数学包,例如优秀的 mpmath, although if you do use mpmath then you'd probably use its numerical derivative functions.

FWIW,您可以通过使 x 位于区间的中间来使导数近似更准确(对于给定的 h)。这是一个简短的演示:

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/xx 是负数,但 x+h 是正数。