17. SciPy求函数的导数

在SciPy里提供了很多的方法函数可以实现对某函数进行求导和求积分的操作。

SciPy的求导相对简单也容易理解。已知函数$f(x)$求其在$x_0$的导数即$f'(x_0)$。

方法一,使用scipy.misc模块下的derivative方法函数。

import numpy as np

from scipy.misc import derivative

def f(x):

return x**5

for x in range(1, 4):

print derivative(f, x, dx=1e-6)

程序的执行结果:

4.999999999866223

80.00000000230045

405.00000005749826

这里的$f(x)= x^5$那么$f'(x) = 5 x^4$,当$x= 1$时$f'(x = 1) = 5$,当$x = 2$时$f'(x = 2) = 5\times 2 ^ 4 = 80$ 。

derivative方法函数还可以指定导数的阶数,下面求一下二阶导数。

import numpy as np

from scipy.misc import derivative

def f(x):

return x**5

for x in range(1, 4):

print derivative(f, x, dx=1e-6, n = 2)

程序的执行结果:

19.999335520992645

160.02132952053216

540.0124791776761

这里的$f(x)= x^5$那么$f''(x) = 20 x^3$,当$x= 1$时$f''(x = 1) = 20$,当$x = 2$时$f''(x = 2) = 20\times 2 ^ 3 = 160$ 。

方法二,使用sympy模块里的diff和symbols函数。diff函数可以得到$f(x)$的导数表达式$f'(x)$,而sympy的symbols函数给出数学表达式里数学符号描述符。

from sympy import diff, symbols

t = symbols('x', real=True)

for i in range(1, 4):

print diff(t**5, t, i)

print diff(t**5, t, i).subs(t, i),i

程序的执行结果:

5*x**4

5 1

20*x**3

160 2

60*x**2

540 3

程序里python变量t代表数学公式里的$x$,那么diff(t ** 5, t, i)里的$t ** 5 $的意思是$f(x) = x ^ 5$这样的一个函数,t, 1两个参数的意思是对$x$求i阶导数。

当$i = 1$时,即对$f(x) = x ^ 5$一阶求导,得导数表达式$f'(x) = 5 x^4$,而diff(t**5, t, i).subs(t, i)则是求$f'(x)$当$x = i$的导数的值,即$f'(1) = 5$。

当$i = 2$时,即对$f(x) = x ^ 5$二阶求导,得导数表达式$f''(x) = 20 x^3$,而diff(t**5, t, i).subs(t, i)则是求$f'(x)$当$x = i$的导数的值,即$f'(2) = 160$。

当$i = 3$时,即对$f(x) = x ^ 5$三阶求导,得导数表达式$f^{(3)}(x) = 60 x^2$,而diff(t**5, t, i).subs(t, i)则是求$f'(x)$当$x = 3$的导数的值,即$f'(3) = 540$。

方式三,使用numpy模块里的函数也可实现求函数的导数。

import numpy as np

p = np.poly1d([1,2,0,3,0,5])

print p

for i in range(1, 4):

print np.polyder(p,i)

print np.polyder(p,i)(1.0)

for i in range(1, 4):

print p.deriv(i)

print p.deriv(i)(1.0)

程序执行结果:

5 4 2

1 x + 2 x + 3 x + 5

4 3

5 x + 8 x + 6 x

19.0

3 2

20 x + 24 x + 6

50.0

2

60 x + 48 x

108.0

4 3

5 x + 8 x + 6 x

19.0

3 2

20 x + 24 x + 6

50.0

2

60 x + 48 x

108.0

用NumPy的poly1d构造$f(x)$,函数的形参是多项式的系数,最左侧的是最高次数的系数,因此p变量代表的方程为$f(x) = x^5 + 2x^4 + 3 x^2 + 5$。而NumPy的polyder和deriv函数的作用差不多都是对p所代表的多项式求导得到$f(x)$的导数的表达式。

下面仅分析一下如下代码:

for i in range(1, 4):

print np.polyder(p,i)

print np.polyder(p,i)(1.0)

其结果为:

4 3

5 x + 8 x + 6 x

19.0

3 2

20 x + 24 x + 6

50.0

2

60 x + 48 x

108.0

为了便于阅读,程序加上一些输出提示:

for i in range(1, 4):

print "f(x)'s %d-th derivative is" %(i)

print np.polyder(p,i)

print "f(x)'s %d-th value when i =" % (i), i

print np.polyder(p,i)(i)

结果为:

f(x)'s 1-th derivative is

4 3

5 x + 8 x + 6 x

f(x)'s 1-th value when i = 1

19

f(x)'s 2-th derivative is

3 2

20 x + 24 x + 6

f(x)'s 2-th value when i = 2

262

f(x)'s 3-th derivative is

2

60 x + 48 x

f(x)'s 3-th value when i = 3

684

方程为$f(x) = x^5 + 2x^4 + 3 x^2 + 5$其一阶导数的表达式为$f'(x) = 5 x^4 + 8 x^3 + 6x$由语句np.polyder(p,i)其$i = 1$时得到,而$f'(1) = 5 + 8 + 6 = 19$由语句np.polyder(p,i)(i)其$i = 1$时得到。

同理当$i = 3$时,语句np.polyder(p,i)计算p所代表的表达式$f(x) = x^5 + 2x^4 + 3 x^2 + 5$,求其三阶导数的表达式为$f^{(3)}(x) = 60 x^2 + 48 x $,而语句np.polyder(p,i)(i)则是计算p所代表的函数的导数在$x = 3$的导数值,即$f^{(3)}(x) = 60 \times 3^2 + 48\times 3 = 540 + 144 = 684$。

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐