開発環境
- OS X El Capitan - Apple (OS)
- Emacs (Text Editor)
- Python 3.5 (プログラミング言語)
Pythonからはじめる数学入門 (Amit Saha (著)、黒川 利明 (翻訳)、オライリージャパン)の7章(初等解析問題を解く)、7.10(プログラミングチャレンジ)、問題7-2(勾配降下法を実装する)を取り組んでみる。
問題7-2(勾配降下法を実装する)
コード(Emacs)
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sympy
import matplotlib.pyplot as plt
def grad_descent(x0, f1x, x):
if not sympy.solve(f1x):
print('Cannot continue, solution for {0}=0 does not exist'.format(f1x))
return
epsilon = 1e-6
step_size = 1e-4
x_old = x0
x_new = x_old - step_size * f1x.subs({x: x_old}).evalf()
xs = []
while abs(x_old - x_new) > epsilon:
xs.append(x_new)
x_old = x_new
x_new = x_old - step_size * f1x.subs({x: x_old}).evalf()
return x_new, xs
def frange(start, stop, step):
numbers = [start]
while start < stop:
start += step
numbers.append(start)
return numbers
def draw(x, f, var, xs):
x0 = -abs(x) * 1.5
x1 = -x0
xs0 = frange(x0, x1, (x1 - x0) / 100)
ys0 = [f.subs({var: x}) for x in xs0]
plt.plot(xs0, ys0)
ys = [f.subs({var: x}) for x in xs]
plt.plot(xs, ys, marker='o')
if __name__ == '__main__':
f = input('Enter a function in one variable: ')
var = input('Enter the variable to differentiate with respect to: ')
var0 = float(input('Enter the initital value of variable: '))
try:
f = sympy.sympify(f)
except sympify.SympifyError as err:
print(err)
else:
var = sympy.Symbol(var)
d = sympy.Derivative(f, var).doit()
var_min, xs = grad_descent(var0, d, var)
if var_min:
plt.figure(figsize=(5, 5))
print('{0}: {1}'.format(var.name, var_min))
print('Minimum value: {0}'.format(f.subs({var: var_min})))
draw(var0, f, var, xs)
plt.savefig('sample2.png')
入出力結果(Terminal, IPython)
$ ./sample2.py Enter a function in one variable: 1/2*x**2 + 1 Enter the variable to differentiate with respect to: x Enter the initital value of variable: 1.001 x: 0.00999839378867327 Minimum value: 1.00004998393918 $
0 コメント:
コメントを投稿