【Julia】SymPy.jlメモ（Julia v1.11.2、SymPy.jl v2.2.0、SymPy v1.13.3で動作確認済）

# 使う前に
　SymPy.jlはJuliaで記号計算をするための拡張機能です。これを使ってREPL(Juliaの黒い画面)上で記号計算をしても良いのですが見づらいです。見やすくするために、拡張機能IJulia.jlのJupyter NotebookやJupyter Labを立ち上げ、そこで記号計算をすると良いです。大抵はMathJaxによるきれいな数式が表示されるので見やすくなります。つまり、
```julia
using IJulia
notebook()
```
または、
```julia
using IJulia
jupyterlab()
```
を実行してNotebookを作り、その中でSymPy.jlを使うと良いです。SymPy.jlを使う前には都度、以下のコードを実行しておきます。
```julia
using SymPy
```

ただし、初回に限り以下のように拡張機能を追加しておく必要があります。
```julia
using Pkg
Pkg.add("IJulia")
Pkg.add("SymPy")
```

以降の説明のコードは全て`using SymPy`の後で実行するものとします。
　なお、SymPy.jlは内部的にPython上のSymPyを使用するものであり、内部のSymPyのバージョンは`sympy.__version__`を実行することで確認できます。また、内部のSymPyのバージョンアップは、Conda.jl経由でPythonを入れている場合（明示的にそうした覚えがない人はおそらくこの場合に該当）、`using Conda`の後に`Conda.update()`を実行することで行えます（`その後、Conda.list()`を実行してもSymPyのバージョンを確認できます）。

# 変数を作る

## 例1：xを作る
```julia
@syms x
#上記は下記の省略(マクロを使った記法)
x = Sym("x")
#下記でも同じ結果
x = symbols("x")
```
補足：`@syms`は以前は`@vars`でしたが廃止されました。

## 例2：xとyを一気に作る
```julia
@syms x y
#上記は下記の省略(マクロを使った記法)
x, y = Sym("x y") #"x y"の部分は"x,y"、"x, y"、"x,y,"等でも良い
#下記でも同じ結果
x, y = symbols("x y")
#上記は下記の省略(明らかなタプルの略記)
(x, y) = symbols("x y")
#ヒント：もっと理解するにはJuliaのタプル(tuple)を調べよう
```

## 例3：ギリシャ文字や下付文字

```julia
@syms x1 α beta R_max
[x1 α beta R_max]
```
出力（そのままの見た目）：$[x_1\ \alpha\ \beta\ R_{max}]$
　つまり、`@syms`で作った変数の見た目は以下のようになります。
・最後の数字は下付文字になる
・ギリシャ文字はそのままギリシャ文字になる
・ギリシャ文字の名前は対応するギリシャ文字になる
・ラテン文字(ローマ字)は斜体になる
・_に後続する部分は下付文字になる

## 例4：変数名と見た目を分ける、立体と斜体を指定
　例3の変数`R_max`の見た目は$R_{max}$でしたが、変数名を`Rmax`（`_`抜き）として見た目を$R_{\rm{max}}$（maxは斜体ではなく立体）としたい場合は以下のように書けます。
```julia
@syms Rmax=>"R_\\mathrm{max}"
#上記は下記の省略
Rmax = Sym("R_\\mathrm{max}")
#下記でも同じ結果
Rmax = symbols("R_\\mathrm{max}")
```
ここで、`\\mathrm{A}`はAだけを立体：romanにする指定です（逆にAだけを明示的に斜体：italicにする指定は`\\mathit{A}`です）。もっと複雑な見た目を表現したい場合は、TeX、LaTeX、MathJaxの数式の書き方を調べていろいろ真似して書いてみると良いでしょう（注：通常のTeX等で`\`と書くべき所はここでは`\\`に変える必要があります）。

## 例5：数の分類の仮定を加えて変数を作る
　数の分類の仮定（実数：real、複素数：complex、整数：integer、正の数：positive、負の数：negative等）を加えて変数を作ることもできます。
　例えば、ある解決したい二次方程式の問題があって、その二次方程式についての意味のある解が実数だと分かっているとします。このような場合、解かれることになる変数を作成する時に実数の仮定を付与しておくと良いです。その変数による二次方程式を作り、これをSymPyに解かせると、SymPyは判別式に応じた適切な結果を出してくれます。つまり、判別式が負なら解なしという結果を、判別式が非負なら実数解の結果を出してくれるということです。
　上記のように後々の処理によっては、数の分類の情報を付与して変数を作っておいた方が都合が良いということもあるので、この方法も覚えておきましょう。
 
### 例5-1：実数を仮定する

```julia
@syms x::real #注：realは小文字始まりであること(他の指定も同様)
#上記は下記の省略
x = symbols("x", real=true) #注：symbolsをSymに変えるとエラー
```
補足：`@syms x::real`は以前は`@syms x real=true`でしたが廃止されました。

### 例5-2：複素数を仮定する
```julia
@syms x::complex
#上記は下記の省略
x = symbols("x", complex=true)
```

### 例5-3：正［負］［非正］［非負］を仮定する
　下記は正（positive）の場合です。負、非正、非負を仮定した場合は、positiveをそれぞれ、negative、nonpositive、nonnegativeに置き換えましょう。
```julia
@syms x::(real, positive) #複数の仮定を付与する場合は丸括弧とカンマが使える
#上記は下記の省略
x = symbols("x", real=true, positive=true)
#下記でも同じ結果
@syms x::positive #positiveは実数で正のことなのでrealは省略可
#上記は下記の省略
x = symbols("x", positive=true)
```
補足：`@syms x::(real, positive)`は以前は`@syms x real=true positive=true`でしたが廃止されました。

### 例5-4：仮定の詳細を確認する
例5-3で作った変数`x`の仮定の詳細は、次のコードで確認できます。
```julia
x.assumptions0
```
出力：
```math
\begin{equation*}\begin{cases}\mathtt{\text{extended_nonnegative}} & \text{=>} &\text{True}\\\mathtt{\text{imaginary}} & \text{=>} &\text{False}\\\mathtt{\text{negative}} & \text{=>} &\text{False}\\\mathtt{\text{extended_nonzero}} & \text{=>} &\text{True}\\\mathtt{\text{extended_nonpositive}} & \text{=>} &\text{False}\\\mathtt{\text{nonzero}} & \text{=>} &\text{True}\\\mathtt{\text{extended_real}} & \text{=>} &\text{True}\\\mathtt{\text{complex}} & \text{=>} &\text{True}\\\mathtt{\text{extended_positive}} & \text{=>} &\text{True}\\\mathtt{\text{hermitian}} & \text{=>} &\text{True}\\\mathtt{\text{finite}} & \text{=>} &\text{True}\\\mathtt{\text{extended_negative}} & \text{=>} &\text{False}\\\mathtt{\text{zero}} & \text{=>} &\text{False}\\\mathtt{\text{real}} & \text{=>} &\text{True}\\\mathtt{\text{infinite}} & \text{=>} &\text{False}\\\mathtt{\text{nonnegative}} & \text{=>} &\text{True}\\\mathtt{\text{positive}} & \text{=>} &\text{True}\\\mathtt{\text{commutative}} & \text{=>} &\text{True}\\\mathtt{\text{nonpositive}} & \text{=>} &\text{False}\\\end{cases}\end{equation*}
```
また、例えば`x.is_negative`のような`x.is_何らかの仮定`で、`x`が`何らかの仮定`となっているかを確認できます。`何らかの仮定`が`x.assumptions0`の中にある仮定ならば真偽が返され、ない仮定ならば`None`が返されます。

### 例5-5：その他の仮定
　他にもいろいろな仮定を変数に付与できます。詳しくは、例えば、下記サイト中のassumptionsの項に記載の指定が使えます。

https://docs.sympy.org/dev/modules/core.html#module-sympy.core.assumptions

# 大小関係（等式と不等式）を作る
　`x`と`a`を使って説明します。ということで、
 ```julia
@syms x a
 ```
を実行した状態として以降の例を見てください。

## 例1：xがa未満（x<a）
```julia
ineq = x ≪ a #≪は\llを入力してタブを押すと出る文字
#上記は下記の省略
ineq = Lt(x, 0) #less thanに由来
```

## 例2：xがa以下（x≦a）
```julia
ineq = x ≦ a #≦は\leqqを入力してタブを押すと出る文字
#上記は下記の省略
ineq = Le(x, a) #less than or equal toに由来
```

## 例3：xがa丁度（x=a）
```julia
eq = x ~ a #注：~が等号の代わりだ
#上記は下記の代わりの構文
eq = x ⩵ a #注：⩵は\Equalを入力してタブを押すと出る文字
#上記は下記の省略
eq = Eq(x, a)
```

## 例4：xがa以上（x≧a）
```julia
ineq = x ≧ a #≧は\geqqを入力してタブを押すと出る文字
#上記は下記の省略
ineq = Ge(x, a) #grater than or equal toに由来
```

## 例5：xが0超（x>a）
```julia
ineq = x ≫ a #≫は\ggを入力してタブを押すと出る文字
#上記は下記の省略
ineq = Gt(x, 0) #grater thanに由来
```
余談：未満の対義語を調べたら面白い記事[https://kijiken.blog/words/「以上」「以下」「未満」「？」](https://kijiken.blog/words/%E3%80%8C%E4%BB%A5%E4%B8%8A%E3%80%8D%E3%80%8C%E4%BB%A5%E4%B8%8B%E3%80%8D%E3%80%8C%E6%9C%AA%E6%BA%80%E3%80%8D%E3%80%8C%EF%BC%9F%E3%80%8D/)を見つけました。

# 方程式を作る
　上記「大小関係（等式と不等式）を作る」の例3と同じやり方で作れます。
```julia
@syms x a b c
eq = a*x^2 + b*x ~ -c #注：~が等号の代わりだ
#上記は下記の代わりの構文
eq = a*x^2 + b*x ⩵ -c #注：⩵は\Equalを入力してタブを押すと出る文字
#上記は下記の省略
eq = Eq(a*x^2 + b*x , -c)
```
出力：$a x^{2} + b x = - c$

# 方程式を解く
```julia
@syms x a b c
eq = a*x^2 + b*x ⩵ -c
solve(eq, x) #方程式eqをxについて解く
```
出力：
```math
\left[\begin{smallmatrix}\frac{- b - \sqrt{- 4 a c + b^{2}}}{2 a}\\\frac{- b + \sqrt{- 4 a c + b^{2}}}{2 a}\end{smallmatrix}\right]
```
上記は以下に代えても同じです。
```julia
@syms x a b c
eq = a*x^2 + b*x + c
solve(eq, x)
```
つまり、`solve`に渡すのは、`~`や`⩵`で作られる方程式ではなく、方程式の片方の辺（左辺でも右辺でも）を他方の辺に全て移項したらできる空っぽでない方の辺でも良いということです。

# 方程式の左辺、右辺を取得する
```julia
@syms x
eq = x^2 + 10 ⩵ x

#eqの左辺を取得(直後の4行は全て同じ結果)
left_hand_side = lhs(eq)
left_hand_side = eq |> lhs
left_hand_side = eq.lhs()
left_hand_side = eq.lhs


#eqの右辺を取得(直後の4行は全て同じ結果)
right_hand_side = rhs(eq)
right_hand_side = eq |> rhs
right_hand_side = eq.rhs()
right_hand_side = eq.rhs
```

# 連立方程式を解く
```julia
@syms x y
eq1 = 3*x + 2*y ⩵ 11
eq2 = 2*x - 2*y ⩵ 4
sol = solve((eq1, eq2), (x, y)) #注：連立方程式と解きたい変数はタプルで与える
```
出力：
```math
\begin{equation*}\begin{cases}x & \text{=>} &3\\y & \text{=>} &1\\\end{cases}\end{equation*}
```
この解をそれぞれ`x_sol`と`y_sol`に格納したければ
```julia
x_sol = sol[x]
y_sol = sol[y]
#ヒント：もっと理解するにはJuliaの辞書(dictionary)を調べよう
```
とします。もしくは、次のように`solve`を使う段階で一気に格納することもできます。

```julia
x_sol, y_sol = solve((eq1, eq2), (x, y)) |> λ->(λ[x], λ[y]) #λは適当な文字列で可
#上記は下記の省略(明らかなタプルの略記)
(x_sol, y_sol) = solve((eq1, eq2), (x, y)) |> λ->(λ[x], λ[y])
#ヒント：もっと理解するにはJuliaのパイプ演算子(pipe operator)|>と無名関数(anonymous function)->を調べよう
```

# 微分する
```julia
@syms x
y = sin(x) + x^3 + x^2 + x + 1
yd = diff(y, x) #yをxで微分する
#上記は下記の省略
yd = diff(y, x=>1) #yをxで1階微分する
```
出力：$3 x^{2} + 2 x + \cos{\left(x \right)} + 1$
`n`階微分したい場合`diff(y, x=>n)`とすれば良いということです。

# 積分する
```julia
@syms x
y = sin(x) + x
integrate(y, x) #yをxで積分する
```
出力：$\frac{x^{2}}{2} - \cos{\left(x \right)}$
注：積分定数は付きません。

# 定積分する
```julia
@syms x
y = sin(x) + x
integrate(y, x=>(0, PI)) #yをxの0からπまでの範囲で積分する
```
出力：$2 + \frac{\pi^{2}}{2}$
注：円周率にはSymPyが提供する`PI`とJuliaが提供する`pi`(`π`でも全く同じ)があります。両者には違いがあります。前者`PI`を使えば、記号パイのままどこまでも記号計算されます。一方、後者`pi`（または`π`）を使うと、一部の例外を除いて基本的に数値に変換されます。

# 級数展開する
## 例1：好きな次数まで展開
```julia
@syms a0 a1 a2 a3
@syms Δx::nonnegative
f = a0 + a1*Δx + a2*Δx^2 + a3*Δx^3 + sin(Δx) + cos(Δx)
f_series = series(f, Δx, 0, 5) #fをΔxの0まわりにビッグオーの次数が5次となるようにテイラー展開(Δxの4次までの展開)
#下記でも同じ結果
f_series = f |> x->series(x, Δx, 0, 5)
#下記でも同じ結果
f_series = f.series(Δx, 0, 5) #簡単だけれどJuliaらしくない書き方かも
```
出力：$1 + Δx \left(a_{1} + 1\right) + Δx^{2} \left(a_{2} - \frac{1}{2}\right) + Δx^{3} \left(a_{3} - \frac{1}{6}\right) + \frac{Δx^{4}}{24} + a_{0} + O\left(Δx^{5}\right)$
## 例2：ビッグオーは不要として展開
前コードの`f_series`以降を次のように変えれば良いです（末尾に`.removeO()`を加えるだけ）。
```julia
f_series = series(f, Δx, 0, 5).removeO()
#下記でも同じ結果
f_series = f |> x->series(x, Δx, 0, 5).removeO()
#下記でも同じ結果
f_series = f.series(Δx, 0, 5).removeO()
#注：下記はエラー(removeOという関数は存在しない)
f_series = f |> x->series(x, Δx, 0, 5) |> removeO
```
出力：$a_{0} + \frac{Δx^{4}}{24} + Δx^{3} \left(a_{3} - \frac{1}{6}\right) + Δx^{2} \left(a_{2} - \frac{1}{2}\right) + Δx \left(a_{1} + 1\right) + 1$

# 極限をとる

## 例1：無限大の極限
```julia
@syms Δx a b
c = a/(1/Δx + b)
limit(c, Δx=>oo) #cについてΔxを∞に限りなく近づける操作を行う
```
出力：$\frac{a}{b}$
注：無限大にはSymPyが提供する`oo`とJuliaが提供する`Inf`があります。`oo`と`Inf`で挙動が変わることはないと思いますが、念のため、`oo`だけを使用しました。

## 例2：どちらから近付くのかを指定した極限
```julia
@syms x
limit(tan(x), x=>PI/2, dir="+") #"+"だと正から負に近づける指定("-"だとその逆)
```
出力：$-\infty$
注：`PI`を`pi`（`π`でも同じ）に変えると数値解になってしまいます。

# 代入する
```julia
@syms x y a b c
y_ = 3*a*x + 3*b
z = c*y
z_ = z(y=>y_) #zのyをy_に代えたものをz_に格納する
#上記は下記の略記
z_ = subs(z, y=>y_)
#下記でも同じ結果
z_ = z |> subs(y=>y_)
#上記は下記の省略
z_ = z |> λ->subs(λ, y=>y_)
#ヒント：y=>y_のようなペアをカンマで区切って複数書けば一度にいくつも代入可
```
出力：$c \left(3 a x + 3 b\right)$

# 展開する
　続きのコードとして説明します。
```julia
z_exp = expand(z_)
#下記でも同じ結果
z_exp = z_ |> expand
#上記は下記の省略
z_exp = z_ |> λ->expand(λ)
#下記でも同じ結果
z_exp = z_.expand() #簡単だけれどJuliaらしくない書き方かも
```
出力：$3 a c x + 3 b c$

# 括る
　続きのコードとして説明します。
```julia
z_fac = factor(z_exp, c) #z_expがcで括れるなら括る
#下記でも同じ結果
z_fac = z_exp |> λ->factor(λ, c)
#下記でも同じ結果
z_fac = z_exp.factor(c) #簡単だけれどJuliaらしくない書き方かも
```
出力：$c \left(3 a x + 3 b\right)$

# 簡略化する(いい感じに簡単な形にする)
続きコードの続きとして説明します。
```julia
z_sim = simplify(z_exp)
#下記でも同じ結果
z_sim = z_exp |> simplify
#上記は下記の省略
z_sim = z_exp |> λ->simplify(λ)
#下記でも同じ結果
z_sim = z_exp.simplify() #簡単だけれどJuliaらしくない書き方かも
```
出力：$3 c \left(a x + b\right)$

# 消せるものは消す
　続きのコードとして説明します。例えば、次の結果は明らかに0ですが、二つの式を減算記号でくっつけただけです。
```julia
z_sim - z_fac
```
出力：$3 c \left(a x + b\right) - c \left(3 a x + 3 b\right)$
　これをちゃんと0に整理する場合にも次のように`simplify`を使います。
```julia
simplify(z_sim - z_fac)
#下記でも同じ結果
z_sim - z_fac |> simplify
#下記でも同じ結果
(z_sim - z_fac).simplify() #簡単だけれどJuliaらしくない書き方かも
```
出力：$0$
　上記の出力は`simplify`ではなく`expand`、`factor`を使っても得られます。困ったらとりあえずこれらを使ってみましょう。

# 因数分解する
　先に`factor`は括りたい時に使えることを説明しましたが、`factor`の本質的な挙動は因数分解です。
```julia
@syms x
y = x/(x + 1) + 2/(x*(x + 1))
```
出力：$\frac{x}{x + 1} + \frac{2}{x \left(x + 1\right)}$
　上記の`y`を因数分解するには、次のようにします。
```julia
factor(y)
#下記でも同じ結果
factor(y, x)
```
出力：$\frac{x^{2} + 2}{x \left(x + 1\right)}$

# 部分分数分解する
　上記の`y`を部分分数分解するには、次のようにします。
```julia
apart(y)
#下記でも同じ結果
apart(y, x)
```
出力：$1 - \frac{3}{x + 1} + \frac{2}{x}$

# 通分して一つの分数にする
　上記の`y`を通分された分数にするには次のようにします。ただし、分母と分子は展開された形となります（因数分解されないということ）。
```julia
cancel(y)
```
出力：$\frac{x^{2} + 2}{x^{2} + x}$

# 分数の分母と分子を取得する
```julia
@syms a b c d
fract = (a + b)/(c + d) #分数

#分母を取得
denom = denominator(fract)
#下記でも同じ結果
denom = fract |> denominator

#分子を取得
numer = numerator(fract)
#下記でも同じ結果
numer = fract |> numerator
```

# 先程の二次方程式を行列で解く
```julia
A = Sym[3  2
        2 -2]
b = Sym[11
        4]
c = A\b #解のベクトル
#下記でも同じ結果
c = inv(A)*b #inv(A)はAの逆行列の計算
#もしSymをなくすとJuliaの標準の行列やベクトルとなり、cは数値解となる
#ただし、行列やベクトル中に@syms等で作った変数が一つでもあればSymは必要ない
```
出力：
```math
\left[\begin{smallmatrix}3\\1\end{smallmatrix}\right]
```
　先程と同様に`x_sol`と`y_sol`に格納するには次のようにします。
```julia
x_sol = c[1] #ベクトルcの1番目の成分を格納
y_sol = c[2] #ベクトルcの2番目の成分を格納
#下記でも同じ結果
x_sol, y_sol = c #ベクトルcの各成分を順々にタプルに格納
#上記は下記の省略(明らかなタプルの略記)
(x_sol, y_sol) = c
```

# 行列のエルミート転置と通常の転置
　Juliaでは行列についての以下の2種類の転置をとる操作が提供されています。これはSymPyの機能で作った行列にも適用できます。
 
行列`X`のエルミート転置：`X'`
行列`X`の転置：`transpose(X)`

　複素数の行列にこの2種類の転置を適用する例を以降に示します。
注：エルミート転置について、念のため説明しておきます（名前は仰々しいですが、以降の例を先に見てもらえば単純なことだと分かるかと思います）。エルミート転置とは、「転置をとる→複素共役をとる」の操作（これは「複素共役をとる→転置をとる」の操作でも同じ）でできる行列のことです。そのため、エルミート転置は共役転置等とも呼ばれます（「共役」の「役」の字は、元来「軛」（くびき）でしたが、常用漢字外ということで、ただ音が同じ「役」に書き換えられました。「共役」の字面からは特段の意味を察することはできません）。また、実数の複素共役をとる操作では元の実数が得られるだけなので、実数のエルミート転置はただの転置です。
## 操作1：複素数の行列を作る
```julia
a1, a2, b1, b2, c1, c2, d1, d2 = symbols("a1 a2 b1 b2 c1 c2 c3 c4", real=true)
X = [a1 + im*a2 b1 + im*b2
     c1 + im*c2 d1 + im*d2]
```
出力：
```math
\left[\begin{smallmatrix}a_{1} + i a_{2} & b_{1} + i b_{2}\\c_{1} + i c_{2} & c_{3} + i c_{4}\end{smallmatrix}\right]
```
## 操作2：エルミート転置をとる

```julia
X'
```
出力：
```math
\left[\begin{smallmatrix}a_{1} - i a_{2} & c_{1} - i c_{2}\\b_{1} - i b_{2} & c_{3} - i c_{4}\end{smallmatrix}\right]
```
## 操作3：通常の転置をとる
```julia
transpose(X)
```
出力：
```math
\left[\begin{smallmatrix}a_{1} + i a_{2} & c_{1} + i c_{2}\\b_{1} + i b_{2} & c_{3} + i c_{4}\end{smallmatrix}\right]
```

# 未知関数を作る、微分方程式を解く
　例として[https://www.jsme.or.jp/kaisi/1210-32/](https://www.jsme.or.jp/kaisi/1210-32/)の式(8)の微分方程式を解いて境界条件を適用して式(10)を求めるまでの流れを以下に示します。
```julia
#微分方程式を作る
@syms w() x EI Coef M0 q l #@syms w()で未知関数wが作れる
eq = EI*diff(w(x), x=>2) ~ 1//2*q*x^2 + (M0/l - 1//2*q*l)*x - M0
#ヒント：もっと理解するには次を実行してみよう：@macroexpand @syms w()
```
出力：$EI \frac{d^{2}}{d x^{2}} w{\left(x \right)} = - M_{0} + \frac{q x^{2}}{2} + x \left(\frac{M_{0}}{l} - \frac{l q}{2}\right)$
```julia
#微分方程式を解く
w_sol = dsolve(eq, w(x)) |> simplify #eqをw(x)について解いて簡略化する
```
出力：$w{\left(x \right)} = \frac{24 EI l \left(C_{1} + C_{2} x\right) + l x^{2} \left(- 12 M_{0} + q x^{2}\right) + 2 x^{3} \left(2 M_{0} - l^{2} q\right)}{24 EI l}$
```julia
#境界条件を適用して積分定数C1を解く
@syms C1 #これは何で必要？：ないとw_sol中のC1に言及できないから
C1_ = solve(0 ~ w_sol.rhs(x=>0), C1)[1] #[1]は何で必要？：解が1つであっても解がベクトルで作られるのでその第1成分を取得してスカラーにするため
```
出力：$0$
```julia
#境界条件を適用して積分定数C2を解く
@syms C2
C2_ = solve(0 ~ diff(w_sol.rhs, x)(x=>0), C2)[1]
```
出力：$0$
```julia
#解かれた積分定数を適用したw(x)を作る
w_ = w_sol(C1=>C1_, C2=>C2_)
```
出力：$w{\left(x \right)} = \frac{l x^{2} \left(- 12 M_{0} + q x^{2}\right) + 2 x^{3} \left(2 M_{0} - l^{2} q\right)}{24 EI l}$
```julia
#M0を求める
M0_ = solve(0 ~ w_.rhs(x=>l), M0)[1]
```
出力：$- \frac{l^{2} q}{8}$

# 区分的に（場合分けで）定義する
　例えば、ランプ関数（[https://ja.wikipedia.org/wiki/ランプ関数](https://ja.wikipedia.org/wiki/%E3%83%A9%E3%83%B3%E3%83%97%E9%96%A2%E6%95%B0)）は場合分けで次のように表せます。
```julia
@syms x::real
f = sympy.Piecewise((x, x ≧ 0), (0, x ≪ 0)) #最後の条件式x ≪ 0はtrueとしても良い
#ヒント：fは、subsで代入、diffで微分、integrateで積分する等の対象となりうる
```
出力：
```math
\begin{cases} x & \text{for}\: x \geq 0 \\0 & \text{otherwise} \end{cases}
```
これに対して操作を加えると次のようになります。
 ```julia
@syms a
g = f + a
 ```
 出力：
 ```math
a + \begin{cases} x & \text{for}\: x \geq 0 \\0 & \text{otherwise} \end{cases}
 ```
 全てを場合分けの波括弧の中に入れたい場合は次のようにします。
 ```julia
g_fold = sympy.piecewise_fold(g)
 ```
 出力：
 ```math
\begin{cases} a + x & \text{for}\: x \geq 0 \\a & \text{otherwise} \end{cases}
 ```
otherwiseがあることで推測がつきますが、SymPyでの通常の場合分けはif-elseif-else形式で書かれます。相互的に排他的な条件式で書かせることもでき、それは次のようにすれば行えます。

 ```julia
g_exclusive = sympy.piecewise_exclusive(g_fold)
 ```
 出力：
 ```math
\begin{cases} a + x & \text{for}\: x \geq 0 \\a & \text{for}\: x < 0 \end{cases}
 ```

# 区分的な表現に書き換える
　不連続な関数は場合分けで表すことができます。例えば、`max(x, 0)`を場合分けで表現させるには次のようにします。
```julia
@syms x
max(x, 0).rewrite("Piecewise")
```
出力：
```math
\begin{cases} 0 & \text{for}\: x \leq 0 \\x & \text{otherwise} \end{cases}
```

# 好きな関数を使った形に書き換る
　どんな書き換えができるのかは、とにかくコードと出力を見ていただければ理解が早いかと思います。
```julia
@syms x
#直後の3行は全て同じ結果
tan(x).rewrite("sin")
tan(x).rewrite(sin)
tan(x).rewrite(sin(x))
```
出力：$\frac{2 \sin^{2}{\left(x \right)}}{\sin{\left(2 x \right)}}$
`tan(x)`を`sin`関数を使った等価な表現に書き換えたということです。他にもいろいろな書き換えができそうです（いろいろ試してみると面白そうです）。

# 〈蛇足〉Julia自体のヒント（Julia自体をよく知らない人向け）
　行頭に`?`と打ち、続けざまに調べたいコードを打つと、Juliaがいろいろ教えてくれます。知っておきたいJuliaでの調べ方：[https://qiita.com/I_ppp/items/9b660fe123bd5c5af174](https://qiita.com/I_ppp/items/9b660fe123bd5c5af174)がとても勉強になります。

# Juliaのための他の記号計算
　拡張機能SymPy.jlは内部的にPython上のSymPyによって処理するもので、逆行列の記号計算等で速度がちょっと遅いと感じることや、一部の積分が苦手のようだと分かりました（Mathematicaで知られるWolfram社のオンラインサービスWolfram CloudのWolfram言語で試してできた一部の積分にエラーとなったものがあった）。現在は、他に純粋にJulia上で処理する類似の拡張機能Symbolics.jlというものが開発されており、先日、試用した感じだと、できないことがいろいろあって完成度がまだあまり高くはないと感じました。しかし、将来的にはこちらの方が高速に動作するJuliaのための良い記号計算の機能となるかも知れないので、ちょくちょく情報を収集していきたいです（Wolfram言語が個人的にとっつきにくく感じたのですがこちらにも慣れた方がいいかも知れないとも思いました）。