「Maxima でケプラー方程式の近似解と数値解」の gnuplot 版。
ベッセル関数によるケプラー方程式のフーリエ級数解
ケプラー方程式
$$u – e \sin u = \omega t$$
のフーリエ級数解は,ベッセル関数 $J_n(x)$ を使って以下のように書ける。
$$u = \omega t+ \sum_{n=1}^{\infty} \frac{2}{n} J_n(n e) \sin(n\, \omega t)$$
現実世界では無限大まで足し算はできないので,以下のように $N$ までの和をとることにする。
$$u(N, e, \omega t) = \omega t+ \sum_{n=1}^{N} \frac{2}{n} J_n(n e) \sin(n\, \omega t)$$
これを gnuplot の関数として定義する。
# 最近の gnuplot にはベッセル関数 Jn(x) もある
help besjn
以下のようにして,三項演算子を使って再帰的に定義します。
\begin{eqnarray}
u(0, e, \omega t) &=& \omega t \\
u(N, e, \omega t) &=& \omega t+ \sum_{n=1}^{N} \frac{2}{n} J_n(n e) \sin(n\, \omega t) \\
&=& u(N-1, e, \omega t) + \frac{2}{N} J_N(N e) \sin(N\, \omega t)
\end{eqnarray}
# 三項演算子を使った再帰定義による sum2 の定義例
# i**2 を i=1 から N まで足す例
# sum2(N) = (N==1 ? 1**2 : sum2(N-1) + N**2)
Ubes(N, e, omegat) = (N == 0 ? \
omegat \
: Ubes(N-1, e, omegat) + 2./N * besjn(N, N*e)*sin(N*omegat))
# たとえば N=10, e=0.5, omegat = 1.0 の値
print Ubes(10, 0.5, 1)
逐次近似法によるケプラー方程式の近似解
離心率 $e$ は $0 \leq e < 1$ であることから,ケプラー方程式
$$u – e \sin u = \omega t$$
を以下のように逐次近似的に解いてみます。
\begin{eqnarray}
u &=& \omega t + e \sin u \\
u_0 &=& \omega t\\
u_1 &=& \omega t + e \sin u_0 = \omega t + e \sin \omega t\\
u_2 &=& \omega t + e \sin u_1 =\omega t + e \sin\left(\omega t + e \sin \omega t\right) \\
u_3 &=& \omega t + e \sin u_2 =\omega t + e \sin\left\{\omega t + e \sin\left(\omega t + e \sin \omega t\right)\right\} \\
&\vdots&\\
u_{n} &=& \omega t + e \sin u_{n-1} = \dots\\
\end{eqnarray}
$n$ が大きくなると,入れ子になっている項がどんどん増殖していきますが,$u_3$ のあたりまでは,近似的に $u$ は $t$ の陽関数としてあらわされているなぁ… という見た目がします。
上の式にそって,以下のように関数 $u(N, e, \omega t)$ を三項演算子を使って再帰的に定義します。
\begin{eqnarray}
N = 0 \ \ &\Rightarrow \ \ u_0 =& \omega t\\
N > 0 \ \ &\Rightarrow \ \ u_{N} =& \omega t + e \sin u_{N-1} \\
\end{eqnarray}
# gnuplot の三項演算子を使った関数の定義例
# N==0 なら f(N)=A, そうでないなら f(N)=B
# f(N) = (N==0 ? A : B)
Uite(N, e, omegat) = (N == 0 ? \
omegat \
: omegat + e*sin(Uite(N-1, e, omegat)))
# たとえば N=10, e=0.5, omegat = 1.0 の値
print Uite(10, 0.5, 1)
方程式の数値解法によるケプラー方程式の数値解
$\omega t$ を与えたときに,ケプラー方程式を数値的に解いて $u(\omega t)$ を求める。ケプラー方程式は超越方程式であるので,ニュートン法を使って数値に解く。
f(e, omt, u) = u - e*sin(u) - omt
# 再帰定義による解
# x には探索の初期値を入れる
# h は解の収束条件である微小量と数値微分をするときに使う微小量を兼ねる。
newton_f(e, omt, x, h) = \
(abs(f(e, omt, x)) > h ? \
newton_f(e,omt,x-f(e,omt,x)*2.*h/(f(e,omt,x+h)-f(e,omt,x-h)),h) \
: x)
Unum(e, omegat) = newton_f(e, omegat, omegat, 1E-15)
# たとえば e=0.5, omegat = 1.0 の値
print Unum(0.5, 1)
数値解と近似解との比較
# 数値解 Unum と逐次近似解 Uite, フーリエ級数解 Ubes の差
e = 0.5
N = 10
print "omega t Unum Uite-Unum Ubes-Unum"
do for [i=1: 9] {
omti = pi/10*i
print sprintf("%7.5f %18.15f %18.15f %18.15f", \
omti, \
Unum(e, omti), \
Uite(N, e, omti)-Unum(e, omti), \
Ubes(N, e, omti)-Unum(e, omti))
}
数値解との差の二乗平均平方根
- 参考:二乗平均平方根
いわゆる RMS (root mean square)
$$RMS \equiv \sqrt{\frac{1}{n} \sum_{i=1}^n \left( U(\omega t_i)- U_{\rm num}(\omega t_i)\right)^2}$$
# RMSite
tmpsum = 0
do for [i=1: 9] {
omti = pi/10*i
tmpsum = tmpsum + (Uite(N, e, omti)-Unum(e, omti))**2
}
print sprintf("Uite: %18.15e", sqrt(1./9 * tmpsum))
# RMSbes
tmpsum = 0
do for [i=1: 9] {
omti = pi/10*i
tmpsum = tmpsum + (Ubes(N, e, omti)-Unum(e, omti))**2
}
print sprintf("Ubes: %18.15e", sqrt(1./9 * tmpsum))
グラフ
$a = 5, \ e = 0.6$ の場合の楕円のグラフを描く。
\begin{eqnarray}
x(a, e, \omega t) &=& a (\cos u(\omega t) -e ) \\
y(a, e, \omega t) &=& a \sqrt{1 – e^2} \sin u(\omega t) \\
\end{eqnarray}
x(a, e, omegat) = a*(cos(Uite(10, e, omegat)) - e)
y(a, e, omegat) = a*sqrt(1-e**2)*sin(Uite(10, e, omegat))
%gnuplot inline svg size 600,480 fixed enhanced font 'Noto Sans CJK JP,14'
set parametric
set xrange [-9:3]
set yrange [-6:6]
set size square
set zeroaxis
plot [t=0:2*pi] x(5, 0.6, t), y(5, 0.6, t) lc "blue" notitle
set term svg font 'Noto Sans CJK JP,14'
set output "gn-fig1.svg"
replot
%gnuplot inline svg size 600,480 fixed enhanced font 'Noto Sans CJK JP,14'
array X[36]
array Y[36]
do for [i=1: 36] {
omegati = pi/18 * i
X[i] = x(5, 0.6, omegati)
Y[i] = y(5, 0.6, omegati)
}
plot Y using (X[$1]):2 pt 7 ps 0.8 lc "blue" notitle
set term svg font 'Noto Sans CJK JP,14'
set output "gn-fig2.svg"
replot