数値微分

数値微分

SciPy 数値微分

 scipy.misc.derivative() は中心差分公式
 
\[f'(a)=\frac{f(a+h)-(a-h)}{2h}\]
を使って、受け取った関数の指定点における 微分係数 を計算します。

 scipy.misc.derivative(func, x0, dx=1.0, n=1, args=(), order=3)

 func には関数オブジェクト、x0 には微分係数を求める点 (中心差分公式のa) を渡します。dx は中心差分公式における h の値であり、デフォルトでは 1 に設定されていますが、より小さな値に設定しないと意味のある精度の値が得られません (具体的な値はサンプルコードを参照してください)。n は微分の階数であり、デフォルトでは 1 に設定されています。

 3次関数 $f(x)=x^3$ の 1 階微分係数を求めてみます。

# DERIVATIVE_01-1

from scipy.misc import derivative

# 3次関数を定義
f = lambda x : x**3

# x=1における1階微分係数
df_1 = derivative(f, 1, dx=1e-5)

print(df_1)
3.000000000097369

 
 n = 2 を指定すると 2 階微分係数を計算します。

# DERIVATIVE_01-2

# x=1における2階微分係数
df_2 = derivative(f, 1, dx=1e-5, n=2)

print(df_2)
6.000002716888274

 

SymPy 微分・偏微分

 引数に渡した関数 func を 変数 var で n階微分するときは次の構文を記述します。

 diff(func, var, n)

 引数 n を省略すると 1 階微分します。

# DERIVATIVE_02

import sympy

# 記号a, b, c, xを定義
sympy.var('a b c x')

# 関数f(x)を定義
f = a*x**2 + b*x + c

# f(x)をxで微分
dfdx1 = sympy.diff(f, x)

# f(x)をxで2階微分
dfdx2 = sympy.diff(f, x, 2)

# f(x)をxで3階微分
dfdx3 = sympy.diff(f, x, 3)

print("dfdx1 = {}".format(dfdx1))
print("dfdx2 = {}".format(dfdx2))
print("dfdx3 = {}".format(dfdx3))
dfdx1 = 2*a*x + b
dfdx2 = 2*a
dfdx3 = 0

 
 引数 var に複数の記号 x1, x2, ... を渡して導関数を得る構文もあります。

 diff(func, x1[, x2, ...])

 次のサンプルコードでは、$f(x)=\cos(xy)$ を $x$ と $y$ で 1 回ずつ偏微分しています。

# DERIVATIVE_03

import sympy

# 記号xを定義
sympy.var('x y')

# f(x)を定義
f = sympy.cos(x*y)

# f(x)をxとyで1回ずつ偏微分
df_dx_dy = sympy.diff(f, x, y)

print("df_dx_dy = {}".format(df_dx_dy))
df_dx_dy = -(x*y*cos(x*y) + sin(x*y))

 
 diff()関数の代わりに diff()メソッドを使って微分することもできます。

# DERIVATIVE_04

import sympy

# 記号xを定義
sympy.var('x')

# f(x) = xexp(x)
f = x * sympy.exp(x)

# f(x)をxで微分
df_dx = f.diff(x, 1)

print(df_dx)
x*exp(x) + exp(x)