<jupyter_start><jupyter_text>Chapter 5 Simplifications<jupyter_code>from sympy import *
x, y, z = symbols('x, y, z')
init_printing(use_unicode=True)<jupyter_output><empty_output><jupyter_text>5.1 単純化 `sympy`のどんな数式も`simplify()`で簡単な形にできる！:<jupyter_code>simplify(sin(x)**2 + cos(x)**2)
simplify((x**3 + x**2 - x - 1) / (x**2 + 2*x + 1))
simplify(gamma(x) / gamma(x-2)) #ガンマ関数(特殊関数)<jupyter_output><empty_output><jupyter_text>注意点:その1<jupyter_code>simplify(x**2 + 2*x + 1)<jupyter_output><empty_output><jupyter_text>---> **因数分解できない!!!** 因数分解は`factor()`関数を使う:<jupyter_code>factor(x**2 + 2*x + 1)<jupyter_output><empty_output><jupyter_text>注意点:その2 `simplify()`は遅い！  解決策- `simplify()`は「ある程度」簡単な形にまでしか変形できないので、確実に式を簡単にしたいなら、その用途に応じた適切な関数を使うべき! - インタラクティブシェルで`simplify`の挙動を見てから**個別の関数**(以下) を使って簡単にしよう.  5.2 多項式 / 有理式  5.2.1 `expand`関数 多項式を展開し、必要ならば項をキャンセルする.<jupyter_code>expand((x + 1)**2)
expand((x + 2)*(x - 3))<jupyter_output><empty_output><jupyter_text>「式を展開する」ことで「式が簡単になる」ことがある。<jupyter_code>expand((x + 1)*(x - 2) - (x - 1)*x) #式がキャンセルし合う<jupyter_output><empty_output><jupyter_text>5.2.2 `factor`関数 数式を可能な限り因数分解する<jupyter_code>factor(x**3 - x**2 + x - 1)
factor(x**2*z + 4*x*y*z + 4*y**2*z)
factor_list(x**2*z + 4*x*y*z + 4*y**2*z) #(変数or定数, べき)<jupyter_output><empty_output><jupyter_text>三角関数程度の式なら、関数`factor`, `expand`で対応可能<jupyter_code>expand((cos(x) + sin(x))**2)
factor(cos(x)**2 + 2*cos(x)*sin(x) + sin(x)**2)<jupyter_output><empty_output><jupyter_text>5.2.3 `collect`関数 特定の変数でまとめたり、特定次の係数を取り出す.<jupyter_code>expr = x*y + x -3 + 2*x**2 - z*x**2 + x**3
expr
collected_expr = collect(expr, x) #xでまとめる.
collected_expr<jupyter_output><empty_output><jupyter_text>さらに以下のようにcoeffメソッドで特定次を取り出せる.<jupyter_code>collected_expr.coeff(x, 2) #xの2次だけ取り出す.<jupyter_output><empty_output><jupyter_text>5.2.4 `cancel`関数 有理式を簡単にする<jupyter_code>cancel((x**2 + 2*x + 1) / (x**2 + x)) 
expr = 1/x + (2*x/2 - 2) /(x - 4) 
expr
cancel(expr) #分母を通分する
factor(expr) #factorも同じような操作をする.
expr = (x*y**2 - 2*x*y*z + x*z**2 + y**2 - 2*y*z + z**2) / (x**2 - 1)
expr
cancel(expr)
factor(expr) #factorも同じような変形をする.<jupyter_output><empty_output><jupyter_text>**コメント**式を単にキャンセルさせてシンプルにさせたいときは、`factor()`より`cancel()`のほうが効率的  5.2.5 `apart`関数 有理式(分数)を部分分数分解する<jupyter_code>x = symbols('x')
expr = (4*x**3 + 21*x**2 + 10*x + 12) / (x**4 + 5*x**3 + 5*x**2 + 4*x)
expr
apart(expr)<jupyter_output><empty_output><jupyter_text>5.3 三角関数 **コメント**: 逆三角関数は頭に"a"を付ける: acos, asin, atan, etc...<jupyter_code>acos(x)
cos(acos(x))
asin(1)<jupyter_output><empty_output><jupyter_text>5.3.1 `trigsimp`関数 三角関数の表式を、公式を用いて可能な限りシンプルな形にする.<jupyter_code>trigsimp(sin(x)**2 + cos(x)**2)
trigsimp(sin(x)**4 - 2*cos(x)**2*sin(x)**2 + cos(x)**4)
trigsimp(sin(x)*tan(x)/sec(x))
trigsimp(cosh(x)**2-sinh(x)**2)<jupyter_output><empty_output><jupyter_text>5.3.2 `expand_trig`関数 三角関数の式を展開する。 `trigsimp`と`expand_trig`は完全に逆の操作をする<jupyter_code>expand_trig(sin(x + y))
expand_trig(tan(2*x))<jupyter_output><empty_output><jupyter_text>5.4 べき乗<jupyter_code>x, y = symbols('x y', positive=True) #変数が正であると仮定
a, b = symbols('a, b', real = True) #変数が実数であると仮定
z, t, c = symbols('z t c')<jupyter_output><empty_output><jupyter_text>**コメント**: `sqrt(x)`と`x**Rational(1,2)`, `x**0.5`, `x**(1/2)`は同じ<jupyter_code>sqrt(x)
x**Rational(1,2)
x**(0.5)
x**(1/2)<jupyter_output><empty_output><jupyter_text>5.4.1 `powsimp` 関数 冪が変数(`Sympy`シンボル)のときに限り、シンプルな形にする<jupyter_code>powsimp(x**a*x**b) #これ以上簡単にできない.
powsimp(x**a*y**a)<jupyter_output><empty_output><jupyter_text>変数の仮定にかかわらず実行させたいとき:<jupyter_code>powsimp(t**c*z**c)<jupyter_output><empty_output><jupyter_text>を<jupyter_code>powsimp(t**c*z**c, force=True)<jupyter_output><empty_output><jupyter_text>とする. `t` もしくは `z` が負になっても強制的にこの変形は行われる.<jupyter_code>(z*t)**2 #冪が整数、有理数, 2のとき.
sqrt(x*y) #同じ<jupyter_output><empty_output><jupyter_text>**注意** このような式に対しては`powsimp`は使えない:<jupyter_code>powsimp(z**2*t**2) #指数が整数
sqrt(x*y)<jupyter_output><empty_output><jupyter_text>--->冪が変数のときに`powsimp`で簡単にできる.  5.4.2 `expand_power_expr`関数, `expand_power_base`関数 べき乗を展開する. `powsimp`関数と逆の操作<jupyter_code>expand_power_exp(x**(a + b))
expand_power_base((x*y)**a)<jupyter_output><empty_output><jupyter_text>**注意** これも`powsimp()`と同様で、変形できないときは元の式を返す:<jupyter_code>expand_power_base((z*t)**c)<jupyter_output><empty_output><jupyter_text>`t*z`が正という条件を`symbols`でつけていれば展開できるが、今回のようにそうと限らないときは展開してくれない. 強制的に行うには<jupyter_code>expand_power_base((z*t)**c, force=True)<jupyter_output><empty_output><jupyter_text>とする. また冪が数のときは<jupyter_code>x**2*x**3
expand_power_exp(x**5)<jupyter_output><empty_output><jupyter_text>のように変形できない。  5.4.3 `powdenest`関数 べき乗のべき乗を展開<jupyter_code>(x**a)**b #カッコを外して展開
powdenest((x**a)**b)
powdenest((z**a)**b)
powdenest((z**a)**b, force=True)<jupyter_output><empty_output><jupyter_text>5.5 指数関数、対数関数<jupyter_code>ln(x) #ln(x)とlog(x)は同じ.
log(x)
x, y = symbols('x y', positive=True)
n = symbols('n', real=True)<jupyter_output><empty_output><jupyter_text>5.5.1 `expand_log`関数 対数関数を展開する<jupyter_code>expand_log(log(x*y))
expand_log(log(x/y))
expand_log(log(x**2))
expand_log(log(x**n))
expand_log(log(z*t))<jupyter_output><empty_output><jupyter_text>**注意** これまでと同様にして、正でない変数は展開できないので、そのときは`Force=True`オプションを付ける。<jupyter_code>expand_log(log(z**2))
expand_log(log(z**2), force=True)<jupyter_output><empty_output><jupyter_text>5.5.2 `logcombine`関数 対数関数をシンプルにする.<jupyter_code>logcombine(log(x) + log(y)) #対数関数を簡単にする
logcombine(n*log(x))
logcombine(n*log(z))
logcombine(n*log(z), force=True)<jupyter_output><empty_output><jupyter_text>5.6 特殊関数<jupyter_code>x, y, z = symbols('x y z')
k, m, n = symbols('k m n')<jupyter_output><empty_output><jupyter_text>5.6.1 階乗<jupyter_code>factorial(n)
factorial(10)<jupyter_output><empty_output><jupyter_text>5.6.2 組み合わせ (Combination)<jupyter_code>binomial(n, k) #nCk
combsimp(factorial(n) / factorial(n - 3)) #シンプルにする
combsimp(binomial(n + 1, k + 1) / binomial(n, k))<jupyter_output><empty_output><jupyter_text>5.6.3 ガンマ関数<jupyter_code>gamma(z)
combsimp(gamma(x)*gamma(1 - x)) #ガンマ関数にも使える<jupyter_output><empty_output><jupyter_text>5.6.4 一般化された超幾何関数<jupyter_code>hyper([1, 2], [3], z)<jupyter_output><empty_output><jupyter_text>5.6.5 関数を別の関数で書き換える<jupyter_code>tan(x).rewrite(sin) #tanをsinで書き換える
factorial(x).rewrite(gamma) #階乗をガンマ関数で書き換える<jupyter_output><empty_output><jupyter_text>5.6.6 特殊関数をいくつかの恒等式で書き換える<jupyter_code>expand_func(gamma(x + 3))<jupyter_output><empty_output>