kaeken(嘉永島健司)のTech探究ブログ

主に情報科学/情報技術全般に関する知見をポストします。(最近は、特にData Science、機械学習、深層学習、統計学、Python、数学、ビッグデータ)

『Pythonからはじめる数学入門』7章(後半) 初等解析問題を解く / 高階微分および積分

f:id:kaeken:20171206212414p:plain

Pythonからはじめる数学入門』7章(後半) 初等解析問題を解く

の解説です。

7.5 高階微分と極大極小の計算

Derivativeクラスを使った微分オブジェクトのデフォルトは、 1階微分です。

高階微分をおこなうには、階数を第三引数に渡します。

ここでは、関数の1階微分と2階微分を使ってある区間の極大・極小を求める方法を示します。

定義域[-5,5]の関数 { \displaystyle
x^{5} - 30 x^{3} + 50 x
} を考えます。 f:id:kaeken:20171206212414p:plain

関数の極大値・極小値・最大値・最小値を求めるには、以下のように処理します。

#7.5 高階微分と極大極小の計算
from sympy import Symbol, solve, Derivative
x = Symbol('x')
f = x**5 - 30*x**3 + 50*x
d1 = Derivative(f, x).doit() #1階微分 階数を引数に指定するが、1階のときは省略
print('1階微分: {0}'.format(d1))
critical_points = solve(d1) #関数の臨界点
print('critical_points: {0}'.format(critical_points))
A = critical_points[2]
B = critical_points[0]
C = critical_points[1]
D = critical_points[3]

d2 = Derivative(f, x, 2).doit() #2階微分 階数を引数に指定
print('2階微分: {0}'.format(d2))

#2階微分の値が負なら極大点、正なら極小点、0なら未決
print('B: {0}'.format(d2.subs({x:B}).evalf()) )
print('C: {0}'.format(d2.subs({x:C}).evalf()) )
print('A: {0}'.format(d2.subs({x:A}).evalf()) )
print('D: {0}'.format(d2.subs({x:D}).evalf()) )
#AとCは負なので極大点、BとDは正なので極小点

x_min = -5 #端点最小値
x_max = 5 #端点最大値
print('x_min: {0}'.format(f.subs({x:x_min}).evalf()) )
print('x_max: {0}'.format(f.subs({x:x_max}).evalf()) )
#最大値を求めるためには、端点とA,Cで比較
print('A: {0}'.format(f.subs({x:A}).evalf()) )
print('C: {0}'.format(f.subs({x:C}).evalf()) )
#点Aが最大値

#最小値を求めるためには、端点とB,Dで比較
print('B: {0}'.format(f.subs({x:B}).evalf()) )
print('D: {0}'.format(f.subs({x:D}).evalf()) )
#点Dが最小値

結果

1階微分: 5*x**4 - 90*x**2 + 50
critical_points: [-sqrt(-sqrt(71) + 9), sqrt(-sqrt(71) + 9), -sqrt(sqrt(71) + 9), sqrt(sqrt(71) + 9)]
2階微分: 20*x*(x**2 - 9)
B: 127.661060789073
C: -127.661060789073
A: -703.493179468151
D: 703.493179468151
x_min: 375.000000000000
x_max: -375.000000000000
A: 705.959460380365
C: 25.0846626340294
B: -25.0846626340294
D: -705.959460380365

7.6 勾配上昇法を用いて最大値を求める

7.6.1 勾配上昇法のジェネリックなプログラム

7.6.2 初期値について一言

.6.3 ステップサイズとイプシロンの役割

7.7 関数の積分を求める

#7.7 関数の積分を求める

#Integralオブジェクトで不定積分、定積分を扱う
from sympy import Integral, Symbol
x = Symbol('x')
k = Symbol('k')
i1 = Integral(k*x, x).doit() #関数k*xと積分する変数xでIntegralオブジェクトを作り積分を評価
print('関数kxの不定積分: {0}'.format(i1))

i2 = Integral(k*x, (x,0,2)).doit() #定積分は、変数x、下限0、上限2、といったセットをタプルで渡す
print('関数kxの定積分(xが0から2をとる場合): {0}'.format(i2))

結果

関数kxの不定積分: k*x**2/2
関数kxの定積分(xが0から2をとる場合): 2*k

7.8 確率密度関数