物理学の具体的な計算にPython(SymPy)を使って、物理学もPython(SymPy)も同時に学んでしまいましょう。今回はPythonの数式処理ライブラリであるSymPyを使って微分方程式を解きたいと思います。
一般に、未知関数とその導関数を含んだ方程式を微分方程式といいます。一変数関数の場合を常微分方程式、多変数関数の場合を偏微分方程式と呼びます。今回は力学で現れる具体的な常微分方程式をいくつか解いてみます。
Python(SymPy)のごく基本的な使い方については以下の記事を参照してください:
不定積分
まず微分方程式を解くにあたって関数の積分を復習しておきましょう。
import sympy as sp sp.init_printing() sp.var('a, x') sp.integrate(sp.exp(-a*x), x)
などとします(ただし積分定数は省かれてしまいます)。
少しの間、この不定積分を出力する関数を I と定義してこれを用います:
def I(f): return sp.integrate(f, x)
上の例では
I(sp.exp(-a*x))
より
です(ただし積分定数は省かれています)。他にも
sp.var('n')
I(x**n)
が求まりますし、また
I(sp.cos(n*x))
が求まります。さてウォーミングアップは軽く済ませて、早速、微分方程式を解いていきましょう。
微分方程式
1階線型常微分方程式
簡単な例として次の1階線型常微分方程式
を考えましょう。ここで は の関数、 は定数とします。
この微分方程式は変数分離法によって解くことができます:
より
両辺の指数関数をとって
と解くことができます。
2階線型常微分方程式:自由落下
で記述されます。
ここで は鉛直方向の座標(上を正の方向にとりました)、
また、 は質点の質量、 は重力加速度です。
import sympy as sp sp.init_printing() sp.var('g, t') x = sp.Function('x')(t) eq1 = sp.Eq( sp.diff(x,t,2), -g ) sp.dsolve(eq1)
とすることで
がわかります。ここで は初速度、 は初期位置に相当する積分定数です。
さて、初期条件 を課すと
sp.var('v') sp.dsolve(eq1, ics={x.subs(t,0):0, sp.diff(x,t,1).subs(t,0):v})
によって
が出力されます。
1次元調和振動子
水平右向きを 軸の正方向にとります。運動方程式は
です。この状況設定をPythonに入力して解を求めるには
import sympy as sp sp.init_printing() sp.var('m,k, t') x = sp.Function('x')(t) F = -k*x eq2 = sp.Eq( m*sp.diff(x,t,2), F ) sp.dsolve(eq2)
として、一般解が
とわかります。ここで は積分定数です。
いまバネ定数 、質量 はともに正の値なので
としてEulerの公式 を使うと、一般解が
で与えられることがわかります。あるいはより具体的に
という場合を考えると
import sympy as sp sp.init_printing() sp.var('t') x = sp.Function('x')(t) eq3 = sp.Eq( sp.diff(x,t,2), -x) sp.dsolve(eq3)
より、その一般解として
が出力されます。
裳華房の『解析学概論』(矢野・石原)は、常微分方程式(だけでなく、ベクトル解析、複素解析、フーリエ解析)に関してよくまとめられた解説と例題、さまざまな練習問題が載っており、効率よく応用数学が学べる理工系学部生におすすめのテキストです:
テキストに載っている問題を、手計算で解けるようになることはもとより、Pythonを利用して解いてみるのも、Pythonを有効に活用するための練習として有用です。
Airy(エアリー)方程式
もう少し複雑な微分方程式としてAiry方程式
を考えてみます:Pythonに
import sympy as sp sp.init_printing() sp.var('x') y = sp.Function('y')(x) eq4 = sp.Eq( sp.diff(y,x,2), x*y) sp.dsolve(eq4)
と入力するとその結果として
が出力されるだけです。本来であれば
が出力されるべきですが、特殊関数をともなう計算にはSymPyでは限界があるようです。
(追記)SymPyのバージョンが古かったようです。最新版のSymPyにアップデートしたら正しく
と出力されました。