つれづれなる備忘録

日々の発見をあるがままに綴る

SymPyの使い方12 ~ 式の操作

 今回はSymPyで扱われている式を基本要素に分解して表示する方法や式の評価を停止する方法について紹介する。

1. 式を基本要素に分解

srepr()を用いるとSymPyで表される式を、基本要素に分解して表示する。 例えばx+y+2を以下のように基本要素に分解すると

srepr(x+y+2)
>Add(Symbol('x'), Symbol('y'), Integer(2))

Symbolで宣言したx,yおよびSymPyのInteger型の2が加算演算であるAddにより加算されている式であることがわかる。

x**2では

srepr(x**2)
Pow(Symbol('x'), Integer(2))

Symbolのxがべき乗演算のPowによりInteger型の2乗される式になっている。

x/3+1/2では

srepr(x/3+1/2)
Add(Mul(Rational(1, 3), Symbol('x')), Float('0.5', precision=53))

x/3有理数であるRational(1,3)とSymbol xの乗算Mulで表されている。また1/2はFloat型の0.5として表現されている。

2. 式ツリーへの分解

式を関数としてとらえ、引数の表示を用いることで、式を基本要素のツリー構造に分解することができる。 式の引数を表示するには.argsを用いと、引数をタプルで返す。

expr=3*x*y**2
expr.args
>(3, x, y**2)

3*x*y**2の引数は3,x,y**2であることをあらわしている。タプルの引数に対して再度引数を表示させるには

expr.args[0].args
>()
expr.args[1].args
>()
expr.args[2].args
>(y, 2)

3は基本要素Integer(3),xは基本要素Symbol('x')なので、これ以上の引数がないため空のタプル()で返される。一方でy**2は引数としてyと2に分解できるため(y,2)が返される。 タプルが空になるため繰り返し.argsを適用して表示する関数を以下のように作成する。

def pre(expr):
    print(expr)
    for arg in expr.args:
        pre(arg)

3*x*y**2に対して上の関数を適用すると式をツリー状に基本要素まで分解して表示する。

pre(3*x*y**2)
>3*x*y**2
3
x
y**2
y
2

3. 式の評価の停止

 式の演算の実行を一時的に停止させるには、Addやsympify (文字列の数式から数式を生成)でevaluate=Falseとする。例えばAddでは

expr=Add(x,x)
expr
>2*x
expr=Add(x,x,evaluate=False)
expr
>x+x

またsympifyを用いる場合は

sympify("x*1/x")
>1
sympify("x*1/x",evaluate=False)
>x/x

evaluate=Falseは一時的な評価の停止で、例えば再度演算を実行すると評価の停止が解けてしまう。

expr=Add(x,x,evaluate=False)
expr
>x+x
expr+x
>3*x

そこで演算の評価をしない文字を指定するUnevaluatedExpr()を用いる。UnevaluatedExpr()で指定された文字のみ評価されない。

expr = x + UnevaluatedExpr(x)
expr
>x+x
expr+x
>2*x+x

評価の停止を解くには、.doit()とすると評価が実行される。

expr.doit()
>2*x