私は Haskell を初めて使用し、演習として、Joel Franklin の著書Computational Methods in Physicsから (Mathematica で記述された) コードの一部を実装しようとしました。最初の引数としてラムダ式 (加速度) を受け取る次のコードを作成しました。一般に、加速度は x'' = f(x',x,t) の形式ですが、常に 3 つの変数すべてであるとは限りません。
-- Implementation 2.1: The Verlet Method
verlet _ _ _ _ 0 = []
verlet ac x0 v0 dt n = take n $ zip [0,dt..] $ verlet' ac x0 v0 0 dt
where verlet' ac x0 v0 t0 dt =
let
xt = x0 + dt*v0 + 0.5*(dt^2)*(ac x0 v0 t0)
vt = v0 + dt*(ac x0 v0 t0)
in
xt:(verlet' ac xt vt (t0+dt) dt)
ghci では、次のコマンドでこのコードを実行します (加速関数 a = -(2pi) 2 x は本の練習問題から来ています)。
verlet (\x v t -> -(2*pi)^2*x) 1 0 0.01 1000
私の問題は、これが実際には Verlet 法ではないことです。ここでは x n+1 = x n + dt*v n +1/2*a(x n ,v n ,n) ですが、Verlet 法はウィキペディアで説明されています。 x n+1 = 2*x n - x n-1 +a(x n ,v n ,n) になります。Verlet 積分法をより忠実に表現するには、この関数をどのように書き直せばよいでしょうか?
接線的に、これをよりエレガントかつ簡潔に書く方法はありますか? これを容易にする線形代数ライブラリはありますか? アドバイスありがとうございます。