# Chapter 5 Simplifications


```python
from sympy import *
x, y, z = symbols('x, y, z')
init_printing(use_unicode=True)
```

## 5.1 単純化

`sympy`のどんな数式も`simplify()`で簡単な形にできる！:


```python
simplify(sin(x)**2 + cos(x)**2)
```


```python
simplify((x**3 + x**2 - x - 1) / (x**2 + 2*x + 1))
```


```python
simplify(gamma(x) / gamma(x-2)) #ガンマ関数(特殊関数)
```

#### 注意点:その1


```python
simplify(x**2 + 2*x + 1)
```

---> **因数分解できない!!!** 因数分解は`factor()`関数を使う:


```python
factor(x**2 + 2*x + 1)
```

#### 注意点:その2

`simplify()`は遅い！

#### 解決策

- `simplify()`は「ある程度」簡単な形にまでしか変形できないので、確実に式を簡単にしたいなら、その用途に応じた適切な関数を使うべき! 

- インタラクティブシェルで`simplify`の挙動を見てから**個別の関数**(以下) を使って簡単にしよう.

## 5.2 多項式 / 有理式

### 5.2.1 `expand`関数

多項式を展開し、必要ならば項をキャンセルする.


```python
expand((x + 1)**2)
```


```python
expand((x + 2)*(x - 3))
```

「式を展開する」ことで「式が簡単になる」ことがある。


```python
expand((x + 1)*(x - 2) - (x - 1)*x) #式がキャンセルし合う
```

### 5.2.2 `factor`関数

数式を可能な限り因数分解する


```python
factor(x**3 - x**2 + x - 1)
```


```python
factor(x**2*z + 4*x*y*z + 4*y**2*z)
```


```python
factor_list(x**2*z + 4*x*y*z + 4*y**2*z) #(変数or定数, べき)
```

#### 三角関数程度の式なら、関数`factor`, `expand`で対応可能


```python
expand((cos(x) + sin(x))**2)
```


```python
factor(cos(x)**2 + 2*cos(x)*sin(x) + sin(x)**2)
```

### 5.2.3 `collect`関数

特定の変数でまとめたり、特定次の係数を取り出す.


```python
expr = x*y + x -3 + 2*x**2 - z*x**2 + x**3
```


```python
expr
```


```python
collected_expr = collect(expr, x) #xでまとめる.
```


```python
collected_expr
```

さらに以下のようにcoeffメソッドで特定次を取り出せる.


```python
collected_expr.coeff(x, 2) #xの2次だけ取り出す.
```

### 5.2.4 `cancel`関数

有理式を簡単にする


```python
cancel((x**2 + 2*x + 1) / (x**2 + x)) 
```


```python
expr = 1/x + (2*x/2 - 2) /(x - 4) 
```


```python
expr
```


```python
cancel(expr) #分母を通分する
```


```python
factor(expr) #factorも同じような操作をする.
```


```python
expr = (x*y**2 - 2*x*y*z + x*z**2 + y**2 - 2*y*z + z**2) / (x**2 - 1)
```


```python
expr
```


```python
cancel(expr)
```


```python
factor(expr) #factorも同じような変形をする.
```

**コメント**

式を単にキャンセルさせてシンプルにさせたいときは、`factor()`より`cancel()`のほうが効率的

### 5.2.5 `apart`関数

有理式(分数)を部分分数分解する


```python
x = symbols('x')
expr = (4*x**3 + 21*x**2 + 10*x + 12) / (x**4 + 5*x**3 + 5*x**2 + 4*x)
```


```python
expr
```


```python
apart(expr)
```

## 5.3 三角関数

**コメント**: 逆三角関数は頭に"a"を付ける: acos, asin, atan, etc...


```python
acos(x)
```


```python
cos(acos(x))
```


```python
asin(1)
```

### 5.3.1 `trigsimp`関数

三角関数の表式を、公式を用いて可能な限りシンプルな形にする.


```python
trigsimp(sin(x)**2 + cos(x)**2)
```


```python
trigsimp(sin(x)**4 - 2*cos(x)**2*sin(x)**2 + cos(x)**4)
```


```python
trigsimp(sin(x)*tan(x)/sec(x))
```


```python
trigsimp(cosh(x)**2-sinh(x)**2)
```

### 5.3.2 `expand_trig`関数

三角関数の式を展開する。 `trigsimp`と`expand_trig`は完全に逆の操作をする


```python
expand_trig(sin(x + y))
```


```python
expand_trig(tan(2*x))
```

## 5.4 べき乗


```python
x, y = symbols('x y', positive=True) #変数が正であると仮定
```


```python
a, b = symbols('a, b', real = True) #変数が実数であると仮定
```


```python
z, t, c = symbols('z t c')
```

**コメント**: `sqrt(x)`と`x**Rational(1,2)`, `x**0.5`, `x**(1/2)`は同じ


```python
sqrt(x)
```


```python
x**Rational(1,2)
```


```python
x**(0.5)
```


```python
x**(1/2)
```

### 5.4.1 `powsimp` 関数

冪が変数(`Sympy`シンボル)のときに限り、シンプルな形にする


```python
powsimp(x**a*x**b) #これ以上簡単にできない.
```


```python
powsimp(x**a*y**a)
```

変数の仮定にかかわらず実行させたいとき:


```python
powsimp(t**c*z**c)
```

を


```python
powsimp(t**c*z**c, force=True)
```

とする. `t` もしくは `z` が負になっても強制的にこの変形は行われる.


```python
(z*t)**2 #冪が整数、有理数, 2のとき.
```


```python
sqrt(x*y) #同じ
```

**注意** このような式に対しては`powsimp`は使えない:


```python
powsimp(z**2*t**2) #指数が整数
```


```python
sqrt(x*y)
```

--->冪が変数のときに`powsimp`で簡単にできる.

### 5.4.2 `expand_power_expr`関数, `expand_power_base`関数

べき乗を展開する. `powsimp`関数と逆の操作


```python
expand_power_exp(x**(a + b))
```


```python
expand_power_base((x*y)**a)
```

**注意** これも`powsimp()`と同様で、変形できないときは元の式を返す:


```python
expand_power_base((z*t)**c)
```

`t*z`が正という条件を`symbols`でつけていれば展開できるが、
今回のようにそうと限らないときは展開してくれない. 強制的に行うには


```python
expand_power_base((z*t)**c, force=True)
```

とする. また冪が数のときは


```python
x**2*x**3
```


```python
expand_power_exp(x**5)
```

のように変形できない。

### 5.4.3 `powdenest`関数

べき乗のべき乗を展開


```python
(x**a)**b #カッコを外して展開
```


```python
powdenest((x**a)**b)
```


```python
powdenest((z**a)**b)
```


```python
powdenest((z**a)**b, force=True)
```

## 5.5 指数関数、対数関数


```python
ln(x) #ln(x)とlog(x)は同じ.
```


```python
log(x)
```


```python
x, y = symbols('x y', positive=True)
```


```python
n = symbols('n', real=True)
```

### 5.5.1 `expand_log`関数

対数関数を展開する


```python
expand_log(log(x*y))
```


```python
expand_log(log(x/y))
```


```python
expand_log(log(x**2))
```


```python
expand_log(log(x**n))
```


```python
expand_log(log(z*t))
```

**注意** これまでと同様にして、正でない変数は展開できないので、そのときは`Force=True`オプションを付ける。


```python
expand_log(log(z**2))
```


```python
expand_log(log(z**2), force=True)
```

### 5.5.2 `logcombine`関数

対数関数をシンプルにする.


```python
logcombine(log(x) + log(y)) #対数関数を簡単にする
```


```python
logcombine(n*log(x))
```


```python
logcombine(n*log(z))
```


```python
logcombine(n*log(z), force=True)
```

## 5.6 特殊関数


```python
x, y, z = symbols('x y z')
```


```python
k, m, n = symbols('k m n')
```

### 5.6.1 階乗


```python
factorial(n)
```


```python
factorial(10)
```

### 5.6.2 組み合わせ (Combination)


```python
binomial(n, k) #nCk
```


```python
combsimp(factorial(n) / factorial(n - 3)) #シンプルにする
```


```python
combsimp(binomial(n + 1, k + 1) / binomial(n, k))
```

### 5.6.3 ガンマ関数


```python
gamma(z)
```


```python
combsimp(gamma(x)*gamma(1 - x)) #ガンマ関数にも使える
```

### 5.6.4 一般化された超幾何関数


```python
hyper([1, 2], [3], z)
```

### 5.6.5 関数を別の関数で書き換える


```python
tan(x).rewrite(sin) #tanをsinで書き換える
```


```python
factorial(x).rewrite(gamma) #階乗をガンマ関数で書き換える
```

### 5.6.6 特殊関数をいくつかの恒等式で書き換える


```python
expand_func(gamma(x + 3))
```

次は[Chapter6 Calculus](https://hiroyuki827.github.io/SymPy_tutorial/Chapter6_Calculus.html)へ!

3d192210ddfccc9d60e6751ab3a29291c138bf02
ipynb
Jupyter Notebook
Chapter5_Simplification.ipynb
hiroyuki827/SymPy_tutorial
8423ceab49482dc83c90c4cb1d388cad100ced84
BSD-3-Clause
2018-01-02T16:53:11.000Z
2021-05-05T13:48:49.000Z
Chapter5_Simplification.ipynb
hiroyuki827/SymPy_tutorial
8423ceab49482dc83c90c4cb1d388cad100ced84
BSD-3-Clause
2018-06-12T03:51:09.000Z
2018-06-13T08:15:45.000Z
Chapter5_Simplification.ipynb
hiroyuki827/SymPy_tutorial
8423ceab49482dc83c90c4cb1d388cad100ced84
BSD-3-Clause
Qwen/Qwen-72B
1. YES
2. YES