Add the Störmer-Verlet method + symplectic test changes#303
Add the Störmer-Verlet method + symplectic test changes#303packquickly wants to merge 1 commit intopatrick-kidger:mainfrom
Conversation
|
|
||
| yhalf_1 = (y0_1 ** ω + term_1.vf_prod(t0, y0_2, args, control1_half_1) ** ω).ω | ||
| y1_2 = (y0_2 ** ω + term_2.vf_prod(midpoint, yhalf_1, args, control2) ** ω).ω | ||
| y1_1 = (yhalf_1 ** ω + term_1.vf_prod(t1, y1_2, args, control1_half_2 ** ω)).ω |
There was a problem hiding this comment.
Isn't this just semi-implicit Euler written in kick-drift-kick form? (I.e. offset by half a step.) Justification: it looks to me like y1_2 on this step is y0_2 on the next step, so the term_1.vf_prod(...) evaluations happen at the same point twice. (Which also means that this is increasing runtime/compiletime.)
There was a problem hiding this comment.
This is pretty subtle actually. long story short: the half step difference has an impact, and they are indeed different (you can check numerically, Störmer-Verlet is order 2, symplectic Euler is order 1.)
Störmer-Verlet is the composition of the symplectic euler method and it's adjoint (reverse method,) ie. it is both variants of symplectic Euler stacked with step-size
The implementation in non kick-drift-kick form, ie.
is distinct from symplectic Euler primarily because of the initialization. Looking at the second-order diffeq case (
and for Störmer-Verlet it's:
This is pretty much the only difference for these two though, and the non kick-drift-kick (often called the leapfrog-Verlet implementation, ugh) is definitely the better one when we don't care about knowing step, hence the more expensive kick-drift-kick implementation.
If you see a way to switch to the leapfrog-Verlet implementation though by all means I'll do that instead.
There was a problem hiding this comment.
Also, you might find it interesting that Hairer wrote a long article about Störmer-Verlet as a precursor to "Geometric Numerical Integration," where he used the method to demonstrate a bunch of the ideas later expanded on in the book
There was a problem hiding this comment.
I was just about to open a PR with a very similar implementation that I'm using in a project, and then stumbled on this! What's left here to resolve the discussion?
Changes:
all_symplectic_solverstotest/helpers.test_semi_implicit_eulerto a parameterised testtest_symplectic_solverswhich includes Störmer-Verlettest_symplectic_ode_ordersimilar totest_ode_orderusing a simple harmonic oscillator as the base problem instead of the linear equation intest_ode_order.Störmer-Verlet is implemented in the general partitioned form updating
pandqwith generic vector fieldsf(p)andg(q)rather than the more common version which assumesg(q) = q. This is consistent with the Diffrax implementation ofSemiImplicitEuler.