2016年4月7日木曜日

開発環境

Doing Math with Python: Use Programming to Explore Algebra, Statistics, Calculus, and More! (Amit Saha (著)、No Starch Press)のChapter 7.(Solving Calculus Problems)、Programming Challenges #2: Implement the Gradient Descent, (No. 4930)を取り組んでみる。

Programming Challenges #2: Implement the Gradient Descent, (No. 4930)

コード(Emacs)

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import sympy
import matplotlib.pyplot as plt

def grad_descent(x0, flx, x):
    epsilon = 1e-6
    step_size = 1e-4
    x_old = x0
    x_new = x_old - step_size * flx.subs({x:x_old}).evalf()

    xs = [x_new]
    while abs(x_old - x_new) > epsilon:
        x_old = x_new
        x_new = x_old - step_size * flx.subs({x:x_old}).evalf()
        xs.append(x_new)
    return x_new, xs

def draw_graph(f, xs, var):
    ns = []
    n = -1
    while n <= 1:
        ns.append(n)
        n += 0.01
    ms = [f.subs({var:n}) for n in ns]
    plt.plot(ns, ms)
    
    ys = [f.subs({var:x}) for x in xs]
    plt.plot(xs, ys, 'r.')
    plt.savefig('grad_descent.svg')
    plt.show()

if __name__ == '__main__':
    f = input('Enter a single-variable function: ')
    try:
        f = sympy.sympify(f)
    except sympy.SympifyError as err:
        print('Invalid function entered: {0}'.format(err))
    else:
        var = input('Enter the variable: ')
        var0 = input('enter the initial value: ')

        var = sympy.Symbol(var)
        var0 = float(var0)
    
        d = sympy.Derivative(f, var).doit()
        var_min, xs = grad_descent(var0, d, var)

        print('{0}: {1}'.format(var.name, var_min))
        print('Minimum value: {0}'.format(f.subs({var:var_min})))
        draw_graph(f, xs, var)

入出力結果(Terminal, IPython)

$ ./sample2.py
Enter a single-variable function: 25*25*sin(2*theta)/9.8
Enter the variable: theta
enter the initial value: 0.001
theta: -0.785360851298204
Minimum value: -63.7755100265060
$

0 コメント:

コメントを投稿