読者です 読者をやめる 読者になる 読者になる

Bag of ML Words

ML = Machine Learning, Music Love, and Miscellaneous things in daily Livings

Python: SymPyことはじめ

都合によりSymbolic Mathが必要になったため、まずはPythonで触り始める。

そのメモ。

http://d.hatena.ne.jp/torilon/20100314/1268573285

がいい感じですね。以下はこれの写経です。

 

from sympy import *

 良くない書き方だけど、とりあえず全部インポート。

 

方程式の変数の定義と簡単な式

# x, yを数学的なの話での変数として定義
>>> x = Symbol('x')
>>> y = Symbol('y')
# x1, x2なんかも定義できちゃう
>>> vars = [Symbol('x' + str(i)) for i in range(3)]
vars

[x0, x1, x2]

# y = 2x + 1という等式をaという変数に代入 >>> a = Eq(y, 2*x + 1) >>> a y == 1 + 2*x

# これはアカン
>>> b = Eq(y, x0**3 + x1**2 + x2 + x)
'x0' is not found

# これはOK
>>> b = Eq(y, vars[0]**3 + vars[1]**2 + vars[2] + x)
>>> b
y == x + x0**3 + x1**2 + x2

 

ほむ、こうしてみるとa = Symbol(b)は、数式中でのbという文字をプログラム上の変数aと結びつけるという機能のようだ。

 

代入したり、解いてみたり

# xを求める式に変換(結果がリストになっているのに注意)
>>> solve(a, x)
[(-1/2) + (1/2)*y]

# これはアカン
>>> solve(b, x1)
'x1' is undefined

# こっちはOK. 結果は式で帰ってくるから見にくくなる。
# 2次式なので答えは二つ、リストになってます
>>> c = solve(b, vars[1])
>>> c
[-sqrt(-x - x0**3 - x2 + y), sqrt(-x - x0**3 - x2 + y)]
>>> type(c)
<type 'list'>

# xを2としてyを求める >>> a.subs(x, 2) y == 5
# y = x + 5の式と組み合わせて解を求める >>> solve( (a, Eq(y, x + 5) ), x, y) {y: 9, x: 4}

 

解いた結果がリストになって帰ってくるのは納得できますね。

だって「式」なんだから、Matlab的にはcell配列、Python的にはリストで返すしかないよねっていう。

最後のはちょっとややこしいですが、連立1次方程式ですね。y = x + 5とy = 2x + 1を解いた。

パタレコ的には典型的なAx = bのsolverを使うところですが、まあ、こういうこともできると。

subsで2つ以上の値を代入するにはどうすればいいんだろう?x[0] = 2, x[1] = 3を代入とか。

 

オシゴトではこれが見つからなくて変なことしてるコードが対象でしたが、当然のようにありました。SymPy Documentationに*1

>>> b.subs( [ ( vars[0], 2 ), ( vars[1], 3 ), ( vars[2], -1 ) ] )

y == x + 16

 はい、あってますね。2^3 + 3^2 -1 = 8 + 9 - 1 = 16.

*1:結論:ちゃんとDocumentationよめってことですね