Adding Symplectic Integrators - #1411
Conversation
|
@JacobHass8 : I think a good test is to identify the conserved quantity you wish to be conserved, and show that quantity is much better preserved with a symplectic integrator than with (say) RK4. I would also recommend an API for event detection and return a solution skeleton that can be interpolated as a Hermite spline, i.e., return ${t_k, y_k, dot{y}k}{k=0}^{n-1}$ rather than the typical solution skeleton {t_k, y_k, }_{k=0}^{n-1}. |
I've tried this on a harmonic oscillator and the energy fluctuations seem to be of order 1e-11 (for the 6th order method). I haven't checked RK4 (or any other method though!).
I'm not sure I totally understand what you mean. Are you saying return a third object that could be used to interpolate between different |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## develop #1411 +/- ##
===========================================
+ Coverage 95.39% 95.41% +0.01%
===========================================
Files 829 831 +2
Lines 69186 69422 +236
===========================================
+ Hits 66003 66241 +238
+ Misses 3183 3181 -2
... and 1 file with indirect coverage changes Continue to review full report in Codecov by Harness.
🚀 New features to boost your workflow:
|
Exactly. Say you have an However, you have to compute Note that this is still inferior to the "natural interpolant", but given there seems to be no hope to get every ODE stepper's interpolant into the standard graphics packages, I think this is a reasonable compromise. |
|
@NAThompson I created a .qbk file to add documentation for the functions I added. I couldn't figure out how to build the documentation though. I kept getting errors when trying to follow the boost math guide. I wanted to include an equation so I created a .svg and .png using latex. However, I noticed that all other equations have a .mml file. Do you know how to convert these? |
I just use this website and drop pngs in it. I also experienced errors while building the docs-I think @mborland may have to help based on your particular error. |
What are the errors you are getting? Unfortunately there is a rather long toolchain required for building the docs, we did have it all documented on the old wiki, but I have a hunch that's bitten the dust :(
Don't worry about .mml, these are all a "historical artefact": when we started there was no easy way to convert LaTex to SVG or something web friendly (other than blocky pngs) but MML was the new kid on the block and there was a nice GUI editor and some scripts to convert the mml to SVG so that was what we used. Nowadays those tools are all unmaintained, and LaTex is so much better... please just make sure that the original LaTex is archived somewhere (a comment in the docs next to the link including the SVG would be good) that way if someone later spots an error it's so much easier/quicker to fix! |
Actually, no errors. I found the .xml file but don't know how to convert this to html. I just ran
Sounds good! I added the latex command. |
|
@jzmaddock or @NAThompson do you think Kahan summation might help the accuracy of these algorithms? Essentially, the algorithm is just summing together a bunch of small steps so I thought it might help. Edit: I implemented kahan summation, but it didn't do anything. I could have done it wrong, but I don't think that's the case. I'm only testing against the simple harmonic oscillator example. Thus, the error term just oscillates from a small negative to a small positive value. |
|
@NAThompson, @jzmaddock, @mborland if all the tests come back passing, I think this PR is ready for review. There are only two small issues that I can think of . First, if the timestep, |
|
@NAThompson, @jzmaddock or @mborland gentle ping to see if anyone would be interested in reviewing. I can also make plots of more systems with my algorithm vs scipy if that would be helpful. |
mborland
left a comment
There was a problem hiding this comment.
Your accuracy is clearly good based on the plots in the main thread. I think reducing re-allocation or heavy objects will help significantly with performance.
| Func dHdp, | ||
| Func dHdq) | ||
| { | ||
| RandomAccessContainer p = p0; |
There was a problem hiding this comment.
This is a copy of a copy, but p0 is never used. Same for q0.
There was a problem hiding this comment.
I think p0 is just copied once now when integrate_hamiltonian_imp is called. Should I pass everything by reference when I can? Most function signatures have the parameters const RealType dt, Func dHdp, Func dHdq. The timestep dt is easy to pass by reference. Should I also pass the functions dHdp/dq?
There was a problem hiding this comment.
Yes, to the extent possible either pass by reference either const or non-const to the extent you can when moving containers around. Like the in-place add I mentioned I think there are other calculations you can do in-place since you're not mutating the users data.
| RealType b1 = static_cast<RealType>(0.0829844064174052); | ||
| RealType b2 = static_cast<RealType>(0.396309801498368); | ||
| RealType b3 = static_cast<RealType>(-0.0390563049223486); | ||
| RealType b4 = 1. - 2. * (b1 + b2 + b3); | ||
|
|
||
| RealType a1 = static_cast<RealType>(0.245298957184271); | ||
| RealType a2 = static_cast<RealType>(0.604872665711080); | ||
| RealType a3 = 0.5 - (a1 + a2); |
There was a problem hiding this comment.
Can these be competed to higher precision like you did above?
There was a problem hiding this comment.
I'll have to reread the paper to see how they did it. Even for the above (simpler) case it was quite complicated. I'll get a better idea and then report how difficult it would be.
There was a problem hiding this comment.
Was the answer here that these are overly complicated to calculate?
|
The one other change now is to mark your public APIs with |
|
@mborland I think this is ready to merge if you don't have any further comments. Thanks for the help! The drone failure looks spurious. Here's the error message |
mborland
left a comment
There was a problem hiding this comment.
Looks much better. Comments are much smaller in size and scope this go around.
| RealType b1 = static_cast<RealType>(0.0829844064174052); | ||
| RealType b2 = static_cast<RealType>(0.396309801498368); | ||
| RealType b3 = static_cast<RealType>(-0.0390563049223486); | ||
| RealType b4 = 1. - 2. * (b1 + b2 + b3); | ||
|
|
||
| RealType a1 = static_cast<RealType>(0.245298957184271); | ||
| RealType a2 = static_cast<RealType>(0.604872665711080); | ||
| RealType a3 = 0.5 - (a1 + a2); |
There was a problem hiding this comment.
Was the answer here that these are overly complicated to calculate?
| typedef void (*stepperType)(RandomAccessContainer&, RandomAccessContainer&, RealType, Func, Func); | ||
|
|
||
| stepperType stepper; | ||
| switch (method) { |
There was a problem hiding this comment.
Adding a default: BOOST_MATH_UNREACHABLE; will help make sure you don't ever miss a method, for example if you add additional options.
| std::vector<RandomAccessContainer> p(steps); | ||
| std::vector<RandomAccessContainer> q(steps); |
There was a problem hiding this comment.
We should probably have some kind of assertion that both p0 and q0 have at least steps amount of elements inside of them otherwise we will end up with a SEGFAULT in the stepper below.
All the tests are passing now. I think this is ready for another look! Thanks for all your help with this. |


Adds symplectic solvers for ODE systems with a conserved quantity (i.e. energy). This was a requested scipy feature (see #303 and scipy/scipy#12690). I'd ultimately like to merge this into scipy using cython. I'm still working on this and have a couple of features I'd like to add:
Does this seem like a good plan? I'd appreciate any input.