どうも、木村(@kimu3_slime)です。
今回は、Julia(SymPy)で1変数関数を微分する方法を紹介します。数値微分ではなく、数式処理として記号的に微分できます。
準備
SymPyを使うので、持っていなければインストールしておきましょう。
1 2 | using Pkg Pkg.add("SymPy") |
準備として、以下のコードを実行しておきます。
1 | using SymPy |
1変数関数の微分
まず、\(x\)を数式処理用の変数、記号として用意しましょう。
1 | x=symbols("x") |
多項式
2次関数
\[ \begin{aligned}f(x)=3x^2+2x+1\end{aligned} \]
を微分してみます。「数式.diff(変数)」で微分できます。
1 2 | ex1 = 3*x^2+2*x+1 ex1.diff(x) |
\[ \begin{aligned}6 x + 2\end{aligned} \]
きちんと微分できていますね。「数式.diff(変数,微分回数)」で2階微分、3階微分を計算できます。
1 2 | ex1.diff(x,2) ex1.diff(x,3) |
\[ \begin{aligned}6\end{aligned} \]
\[ \begin{aligned}0\end{aligned} \]
平方根、べき乗関数
同じ方法で微分できるので、どんどん微分していきましょう。
\[ \begin{aligned}\sqrt{x}\end{aligned} \]
1 2 | ex2 = sqrt(x) ex2.diff(x) |
\[ \begin{aligned}\frac{1}{2\sqrt{x}}\end{aligned} \]
\[ \begin{aligned}x^{\frac{2}{3}}\end{aligned} \]
1 2 | ex3 = x^(2/3) ex3.diff(x) |
分数のべき乗をそのまま書くと、
\[ \begin{aligned}x^{0.666666666666667}\end{aligned} \]
\[ \begin{aligned}\frac{0.666666666666667}{x^{0.333333333333333}}\end{aligned} \]
と数値として扱われてしまい、微分の計算自体は正確であるものの、きれいではありません。分数を数式処理的に扱うために、「Rational(分子,分母)」を使いましょう。
1 2 | ex4 = x^(Rational(2,3)) ex4.diff(x) |
\[ \begin{aligned}x^{\frac{2}{3}}\end{aligned} \]
\[ \begin{aligned}\frac{2}{3 \sqrt[3]{x}}\end{aligned} \]
うまく計算できました。
負のべき乗、有理関数
負のべき乗も、\(x=0\)で定義されていないことを除いて、きちんと微分してくれます。
1 2 3 | ex5 = 1/x ex5.diff(x) ex5.diff(x,2) |
\[ \begin{aligned}\frac{1}{x}\end{aligned} \]
\[ \begin{aligned}- \frac{1}{x^{2}}\end{aligned} \]
\[ \begin{aligned}\frac{2}{x^{3}}\end{aligned} \]
有理関数(多項式の分数関数)も、問題なく微分できます。
1 2 | ex6 = (2x+1)/((x-2)*(x-1)*(x+1)) ex6.diff(x) |
\[ \begin{aligned}\frac{2 x + 1}{\left(x – 2\right) \left(x – 1\right) \left(x + 1\right)}\end{aligned} \]
\[ \begin{aligned}\frac{2}{\left(x – 2\right) \left(x – 1\right) \left(x + 1\right)} – \frac{2 x + 1}{\left(x – 2\right) \left(x – 1\right) \left(x + 1\right)^{2}}\\ – \frac{2 x + 1}{\left(x – 2\right) \left(x – 1\right)^{2} \left(x + 1\right)} – \frac{2 x + 1}{\left(x – 2\right)^{2} \left(x – 1\right) \left(x + 1\right)}\end{aligned} \]
「solve」によって微分が0となる点を求めると、
1 | solve(ex6.diff(x),x) |
\[ \begin{aligned}\left[ \begin{array}{r}\frac{1}{12} + \left(- \frac{1}{2} – \frac{\sqrt{3} i}{2}\right) \sqrt[3]{\frac{\sqrt{935}}{48} + \frac{1153}{1728}} + \frac{49}{144 \left(- \frac{1}{2} – \frac{\sqrt{3} i}{2}\right) \sqrt[3]{\frac{\sqrt{935}}{48} + \frac{1153}{1728}}}\\\frac{1}{12} + \frac{49}{144 \left(- \frac{1}{2} + \frac{\sqrt{3} i}{2}\right) \sqrt[3]{\frac{\sqrt{935}}{48} + \frac{1153}{1728}}} + \left(- \frac{1}{2} + \frac{\sqrt{3} i}{2}\right) \sqrt[3]{\frac{\sqrt{935}}{48} + \frac{1153}{1728}}\\\frac{1}{12} + \frac{49}{144 \sqrt[3]{\frac{\sqrt{935}}{48} + \frac{1153}{1728}}} + \sqrt[3]{\frac{\sqrt{935}}{48} + \frac{1153}{1728}}\end{array} \right]\end{aligned} \]
と、複雑ですが、2つの虚数解と1つの実数解が得られます。
関数のグラフを描く方法と合わせると、
1 2 3 4 | using Plots trim(f ) = x -> abs(f(x)) > 10 ? NaN : f(x) plot(trim(ex6),xlim=(-5,5),xticks=(-5:5),gridalpha=0.7) plot!([solve(ex6.diff(x),x)[3]], seriestype="vline") |
確かに微分が0となる点が求められていることがわかります。
絶対値
絶対値関数\(|x|\)は、そのまま計算すると少し複雑な形が出てきます。
1 2 | ex7 = abs(x) ex7.diff(x) |
\[ \begin{aligned}\frac{\left(\operatorname{re}{\left(x\right)} \frac{d}{d x} \operatorname{re}{\left(x\right)} + \operatorname{im}{\left(x\right)} \frac{d}{d x} \operatorname{im}{\left(x\right)}\right) \operatorname{sign}{\left(x \right)}}{x}\end{aligned} \]
これは変数\(x\)が、デフォルトでは複素数として扱われているからです。変数が実数であると宣言すれば、
1 2 3 | x=symbols("x", real = True) ex7 = abs(x) ex7.diff(x) |
\[ \begin{aligned}\operatorname{sign}{\left(x \right)}\end{aligned} \]
と符号関数が返ってきます。\(x\)が正なら\(1\)、負ならば\(-1\)を返します。
この式は、\(x=0\)では正しくない結果を返していることに注意しましょう。\(x=0\)で\(|x|\)は微分不可能です。SymPyは、\(x \neq 0\)で成り立つ微分を計算しています。
指数関数、対数関数
オイラー数\(e\)を底とする指数関数は「exp(x)」、(自然)対数関数は「log(x)」です。
1 2 3 4 | ex8 = exp(x) ex8.diff(x) ex9 = log(x) ex9.diff(x) |
\[ \begin{aligned}e^{x}\end{aligned} \]
\[ \begin{aligned}e^{x}\end{aligned} \]
\[ \begin{aligned}\log{\left(x \right)}\end{aligned} \]
\[ \begin{aligned}\frac{1}{x}\end{aligned} \]
底を変えても、きちんと微分は計算されます。
1 2 3 4 | ex10 = 10^x ex10.diff(x) ex11 = log(10,x) ex11.diff(x) |
\[ \begin{aligned}10^{x}\end{aligned} \]
\[ \begin{aligned}10^{x} \log{\left(10 \right)}\end{aligned} \]
\[ \begin{aligned}\frac{\log{\left(x \right)}}{\log{\left(10 \right)}}\end{aligned} \]
\[ \begin{aligned}\frac{1}{x \log{\left(10 \right)}}\end{aligned} \]
何も底が書かれていない\(\log\)は、ここでは\(\log_e\)であることに注意しましょう。
三角関数、逆三角関数
三角関数、逆三角関数の微分もきちんとできます。
1 2 3 4 5 6 | diff(sin(x)) diff(cos(x)) diff(tan(x)) diff(asin(x)) diff(acos(x)) diff(atan(x)) |
\[ \begin{aligned}\cos{\left(x \right)}\end{aligned} \]
\[ \begin{aligned}- \sin{\left(x \right)}\end{aligned} \]
\[ \begin{aligned}\tan^{2}{\left(x \right)} + 1\end{aligned} \]
\[ \begin{aligned}\frac{1}{\sqrt{1 – x^{2}}}\end{aligned} \]
\[ \begin{aligned}- \frac{1}{\sqrt{1 – x^{2}}}\end{aligned} \]
\[ \begin{aligned}\frac{1}{x^{2} + 1}\end{aligned} \]
双曲線関数、逆双曲線関数
双曲線関数、逆双曲線関数についても同様です。
1 2 3 4 5 6 | diff(sinh(x)) diff(cosh(x)) diff(tanh(x)) diff(asinh(x)) diff(acosh(x)) diff(atanh(x)) |
\[ \begin{aligned}\cosh{\left(x \right)}\end{aligned} \]
\[ \begin{aligned}\sinh{\left(x \right)}\end{aligned} \]
\[ \begin{aligned}1 – \tanh^{2}{\left(x \right)}\end{aligned} \]
\[ \begin{aligned}\frac{1}{\sqrt{x^{2} + 1}}\end{aligned} \]
\[ \begin{aligned}\frac{1}{\sqrt{x^{2} – 1}}\end{aligned} \]
\[ \begin{aligned}\frac{1}{1 – x^{2}}\end{aligned} \]
以上、Julia(SymPy)で1変数関数を微分する方法を紹介してきました。
数値計算ではなく記号的に微分してくれるので、関数電卓の代わりに気楽に使えて便利ですね。
木村すらいむ(@kimu3_slime)でした。ではでは。
コロナ社 (2020-03-26T00:00:01Z)
¥7,353 (コレクター商品)
こちらもおすすめ
.Julia(SymPy)で有理関数を部分分数分解、通分する方法
Julia(SymPy)で多項式の展開・因数分解、方程式を解く方法
Juliaで1変数関数のグラフを描く方法(多項式、指数対数、三角関数)