では私の答えにMSEの質問 2D、ハミルトニアンの物理シミュレーションに関しては、私はより高次の使用を示唆しているシンプレクティック積分器を。
次に、さまざまな時間ステップがさまざまな次数のメソッドのグローバル精度に及ぼす影響を示すのは良い考えだと思い、その効果のためにPython / Pylabスクリプトを作成して実行しました。比較のために私が選んだもの:
- (leap2)Wikipediaの2次例 Iは、名前の下にそれを知っているが、私は、よく知っていると馬跳び、
- (ruth3)ルースの3次シンプレクティック積分器、
- (ruth4)Ruthの4次シンプレクティック積分器。
奇妙なことに、どのタイムステップを選択しても、テストでは、Ruthの3次法の方がRuthの4次法よりも1桁精度が高いようです。
したがって、私の質問は次のとおりです。詳細は以下。
これらの方法は、分離可能なハミルトニアン、つまりとして記述できる
システムでその強さを展開します。
ここで、はすべての位置座標を含み、
は共役運動量を含み、
は運動論を表しますエネルギーとポテンシャルエネルギー。
この設定では、力と運動量を、それらが適用される質量によって正規化できます。したがって、力は加速度に変わり、モーメンタは速度に変わります。
シンプレクティックインテグレーターには、特別な(与えられた定数)係数が付属しており、これにおよびラベルを付けます。これらの係数を使用すると、システムを時間 から時間に進化させるための1つのステップは次の形式になります。
以下のために:
- すべての位置のベクトルを指定して、すべての加速度のベクトルを計算します
- すべての速度のベクトルを
- すべての位置のベクトルを
知恵は今係数にあります。これらは、
テストでは、1D初期値問題
これは分離可能なハミルトニアンを持っています。ここで、は識別されます。
上記のメソッドとIVPを で統合しました。ステップサイズはで、整数はから間で選択されています。撮影leap2考慮の速さを、私は三倍そのメソッドのために。次に、結果の曲線を位相空間にプロットし 、曲線が理想的に再び到達するはずのズームインしました。N(1、0)T=2π
以下は、とプロットとズームです。
以下のために、leap2ステップサイズで より近い家に到着する起こるruth4 ステップサイズで。、ruth4オーバー勝利leap2。ただし、ruth4と同じステップサイズのruth3は、これまでにテストしたすべての設定で、他の両方よりもはるかに家に近づいています。2 π
Python / Pylabスクリプトは次のとおりです。
import numpy as np
import matplotlib.pyplot as plt
def symplectic_integrate_step(qvt0, accel, dt, coeffs):
q,v,t = qvt0
for ai,bi in coeffs.T:
v += bi * accel(q,v,t) * dt
q += ai * v * dt
t += ai * dt
return q,v,t
def symplectic_integrate(qvt0, accel, t, coeffs):
q = np.empty_like(t)
v = np.empty_like(t)
qvt = qvt0
q[0] = qvt[0]
v[0] = qvt[1]
for i in xrange(1, len(t)):
qvt = symplectic_integrate_step(qvt, accel, t[i]-t[i-1], coeffs)
q[i] = qvt[0]
v[i] = qvt[1]
return q,v
c = np.math.pow(2.0, 1.0/3.0)
ruth4 = np.array([[0.5, 0.5*(1.0-c), 0.5*(1.0-c), 0.5],
[0.0, 1.0, -c, 1.0]]) / (2.0 - c)
ruth3 = np.array([[2.0/3.0, -2.0/3.0, 1.0], [7.0/24.0, 0.75, -1.0/24.0]])
leap2 = np.array([[0.5, 0.5], [0.0, 1.0]])
accel = lambda q,v,t: -q
qvt0 = (1.0, 0.0, 0.0)
tmax = 2.0 * np.math.pi
N = 36
fig, ax = plt.subplots(1, figsize=(6, 6))
ax.axis([-1.3, 1.3, -1.3, 1.3])
ax.set_aspect('equal')
ax.set_title(r"Phase plot $(y(t),y'(t))$")
ax.grid(True)
t = np.linspace(0.0, tmax, 3*N+1)
q,v = symplectic_integrate(qvt0, accel, t, leap2)
ax.plot(q, v, label='leap2 (%d steps)' % (3*N), color='black')
t = np.linspace(0.0, tmax, N+1)
q,v = symplectic_integrate(qvt0, accel, t, ruth3)
ax.plot(q, v, label='ruth3 (%d steps)' % N, color='red')
q,v = symplectic_integrate(qvt0, accel, t, ruth4)
ax.plot(q, v, label='ruth4 (%d steps)' % N, color='blue')
ax.legend(loc='center')
fig.show()
私はすでに単純なエラーをチェックしました:
- ウィキペディアのタイプミスはありません。私は(特に、参照をチェックしている1、 2、 3)。
- 係数列は正しいです。ウィキペディアの順序と比較すると、オペレーターアプリケーションの順序付けは右から左に機能することに注意してください。私の番号付けはCandy / Rozmusに同意します。それでも別の注文をしようとすると、結果はさらに悪くなります。
私の疑い:
- ステップサイズの順序が間違っている:たぶん、Ruthの3次スキームは、どういうわけかはるかに小さい暗黙の定数を持っています。ステップサイズを本当に小さくすると、4次メソッドが勝つでしょうか?しかし、私はも試してみましたが、3次法の方が優れています。
- 間違ったテスト:私のテストで何か特別なことをすると、ルースの3次メソッドは高次メソッドのように動作しますか?