振り子の運動について考えます。
振り子のHamiltonianは以下のように書けます。
振り子の正準運動方程式はHamiltonianから以下の通りに求められます。ここで、lは角運動量、θは角度、mは質量、gは重力加速度、Lは振り子の長さです。Euler法でMaximaに周期を計算させてみましょう。
以下の二階微分方程式に直してからスタートします。
/* 5.1.13m */ theta : %pi/2$ dtheta : 0$ dt : 0.02$ t : 0$ while theta > 0 do ( ddtheta : -sin(theta), dtheta : dtheta + ddtheta*dt, theta : theta + dtheta * dt, t : t + dt)$ period : 4 * t;
正確な周期は以下の積分で表されます。
/* 5.1.17m */ p : sqrt(8) * quad_qags(1 / sqrt(cos(theta)), theta, 0, %pi / 2)$ p[1], numer;
使用した機能
Euler法で求めた値が近かったことがわかりました。
次に数値積分をせずに計算してましょう。
sqrt(8)*integrate(1/sqrt(cos(theta)), theta, 0, %pi/2); %, numer;
使用した機能
βはベータ函数です。こちらの値がより精確な値となります。
θの初期条件をではなく、一般にとすると、周期は以下の積分で表されます。
これは、式変形により、第一種完全楕円関数K(k)で表すことができます。Maximaの楕円積分ライブラリでも、の値を確認しておきましょう。
4*elliptic_kc(sin(%pi/4)^2); %, numer;
使用した機能
を求めるのに、elliptic_kc(sin(%pi/4)^2)を使っていることに注意してください。Maximaの楕円積分ライブラリはAbramowitz&Stegunを参照して設計されているため、通常の楕円積分と定義が異なっています。
Hamiltonianまで戻って、Runge-Kutta法を使って、数値的に解いてみましょう。
/* 5.1.25m */ load(dynamics)$ h(v, x) := v ^ 2 / 2 - cos(x)$ dt : 0.02$ phaseplot : rk([diff(h(v, x), v), -diff(h(v, x), x)], [x, v], [float(%pi / 2), 0], [t, 0, 8, dt])$ plot2d([discrete, makelist([x[2], x[3]], x, phaseplot)])$
使用した機能
この計算結果からの符号が変わる時刻を内挿し、周期を計算してみましょう。
/* 5.1.27m */ j : 1$ while j <= length(phaseplot) do ( if phaseplot[j][2] < 0 then return(), j : j + 1)$ before : abs(phaseplot[j - 1][2])$ after : abs(phaseplot[j][2])$ period : 4 * (before*phaseplot[j][1] + after*phaseplot[j - 1][1]) / (after + before)$
Euler積分を使った値より精度の高い値が求められました。