今回はSymPyを用いて数式を簡素化するための方法を中心に紹介したい。簡素化は一般的な数式処理ソフトと同様だが、どのようにすれば簡単になるかは事前に判断して、どのようなコマンドを用いるか決める必要があり扱いが比較的難しい。
1. 一般的な簡素化
どうやって簡素化するかわからないときはsimplify
をまず試してみる。
simplify(cos(x)**2+sin(x)**2) >1
これ以上簡素化できない場合は以下のように入力した式がそのまま出力される。
simplify(cos(x)**2) >cos(x)**2
以下は分子は(x-1)*(x+1)**2
を展開したもの、分母は(x+1)**2
であるが
simplify((x**3 + x**2 - x - 1)/(x**2 + 2*x + 1)) >x-1
分母分子の共通項が消去されて簡素化された。
特殊関数の計算も有効でガンマ関数の場合は
simplify(gamma(x)/gamma(x - 2)) >(x-2)*(x-1)
このようにsimplify
は強力なコマンドだが、最も簡単な表現になるわけではない。例えば
simplify(x**2+2*x+1) >x**2 + 2*x + 1
この場合はsimplify
よりも因数分解を行うfactor
を指定すると簡単になる。
factor(x**2+2*x+1) >(x + 1)**2
ただし、以下の例だとsimplify
でも因数分解される。
simplify(x**2+2*x) >x*(x + 2)
2. 式の整理
式の簡素化よりも式を具体的に整理するコマンドとして展開expand
,因数分解 factor
,べき乗ごとに整理するcollect
, 有理表現cancel
がある。
式の展開:expand
前回も紹介したように、式を展開して多項式を表示するコマンド。3角関数の展開にも有効で
expand((cos(x) + sin(x))**2) >sin(x)**2 + 2*sin(x)*cos(x) + cos(x)**2
ただし、cos(x)**2+sin(x)**2
の部分は1に置き換えてくれないので、さらにsimplify
と組み合わせると
f=expand((cos(x) + sin(x))**2) simplify(f) >sin(2*x) + 1
簡素化された表現になる。
因数分解:factor
factor
も以前に紹介したが、多項式を因数分解するのに用いる。
factor(x**2*z + 4*x*y*z + 4*y**2*z) >z*(x + 2*y)**2
factor_list
を用いると因数成分のみを表示する。
factor_list(x**2*z + 4*x*y*z + 4*y**2*z) >(1, [(z, 1), (x + 2*y, 2)])
1以外は(要素,次数)のリストが出力される。
べき乗ごとに整理:collect
collect
を用いると指定した変数のべき乗で整理される。例えば、
expr = x*y + x - 3 + 2*x**2 - z*x**2 + x**3 expr >x**3 - x**2*z + 2*x**2 + x*y + x - 3 collect(expr,x) >x**3 + x**2*(-z + 2) + x*(y + 1) - 3
さらに.coeff(x,2)
とするとxの2乗にかかる係数を出力する。
collect(expr,y).coeff(x,2) >-z + 2
有理表現:cancel
cancel
を用いるとq/pにように有理表現で式を表示する。例えば、
cancel((x**2 + 2*x + 1)/(x**2 + x)) >(x + 1)/x
有理表現にしつつ、共通因子の(x+1)を打ち消している。
cancel(1/x + (3*x/2 - 2)/(x - 4)) >(3*x**2 - 2*x - 8)/(2*x**2 - 8*x)
べき乗としては増えてしまうが有理表現でまとめている。
3. まとめ
SymPyを用いて式を簡素化する方法について今回は紹介した。汎用的にはsimplify
だが、必ずしも簡素化できるわけではなく状況に応じてexpand
,factor
,cancel
などを使い分ける必要がある。