Pythonで数式処理だけで二次方程式の解を求める

二次方程式の解の公式ってまだ覚えてますか?自分は忘れました。 今回はPythonの数式処理パッケージであるSympyを使用して、プログラムによる数式処理だけで解の公式を導きます。
2022.04.30

Sympy

Sympyは何らかのシンボルに対して数学的な演算を行うPythonのパッケージです。 分類としては数式処理システム(Formula Manipulation System, Computer algebra system)の一つです。 できることは幅広く、単純な式変換から始まり、微積分や方程式を解いたりすることもできます。 公式サイトのドキュメントが結構充実しているので、読んでみると面白いです。

インストール

インストール

pip3 install sympy

使ってみる

今回はJupyerLab上で実行します。 JupyerLabで実行すると、数式が綺麗に表示されて見やすいのでおすすめです。

2次方程式を解く

まずはシンボルの定義から始めます。

シンボルの定義

from sympy import Symbol, symbols, solve, simplify
x = Symbol('x')
a, b, c = symbols('a b c')
y = a * x ** 2 + x * b + c

今回は3つの方法でシンボルの定義を行なっています。

  1. Symbolを使用して一つだけ定義する
  2. symbolsを使用してまとめて定義する
  3. 数式を記述して定義する

3つめで定義したyは二次関数です。 以下のような式になります。

早速このyが0になるようなxを探してみます。

solve関数を使用すればこれを解くことができます。

2次方程式を解く

solved = solve(y, x)
solved
-> [(-b - sqrt(-4*a*c + b**2))/(2*a), (-b + sqrt(-4*a*c + b**2))/(2*a)]

それっぽい値が出ていますね、今回はリストで2つの解が帰ってきたので、一つ目を表示してみます。

何だかこんな形だった気がします。

不安なので代入して0になるか確認してみます。

代入するにはsubsメソッドを使用します。ここではxを先ほどの解の一つ目solved[0]に置き換えています。

代入

subs = y.subs(x, solved[0])

代入後の式は以下のようになります。

わかりずらいので、式を単純化します。

式を単純化するにはsimplify関数を使います。

単純化

simplify(subs)

無事0になりましたね。

微積分

せっかくなので、先ほどの二次方程式を使用して微積分も行ってみます。

微分

まずは微分です。

微分をするにはdiff関数を使用します。

せっかくなので、頂点についても解いて見ましょう。

頂点は傾きが0になる点、つまりはdy_dxが0になる点です。

微分

dy_dx = diff(y, x)
solved = solve(dy_dx, x)

微分した後は以下のようになります。

これが0になるようなxは以下のようになります。

積分

積分ではintegrate関数を使用します。

積分

integrate(y, x)

結果を表示すると以下のようになっています。

式の展開と因数分解

簡単な式の展開と因数分解をしてみます。

式の展開

展開にはexpand関数を使用します。

展開

from sympy import expand, factor
expand((2*x+1)*(3*x+2))

これを表示すると以下のようになります。

因数分解

先ほどの式を逆に因数分解します。 因数分解にはfactorを使用します。

展開

from sympy import expand, factor
expand((2*x+1)*(3*x+2))

これを表示すると以下のようになります。

LaTexの数式として表示する

ドキュメントに使う場合、LaTexの数式として表示できると便利です。

これにはlatex関数を利用します。

LaTex

from sympy import latex
latex(y)
-> 'a x^{2} + b x + c'

さいごに

Sympyの簡単な使い方について説明しました。 まだまだ、触れていない素晴らしい機能がありますが、それを書くにはこの余白は狭すぎます... 個人的には不動小数点の丸め込み誤差などの問題から、どうしても数式処理をしたい局面などあったりすると思います。 そういった時に便利なんじゃないでしょうか。 あとは、そもそも数式についての理解を深めるために、いろいろいじったりするのに手軽で間違いがなく、いいと思います。