headmyshoulder / odeint-v2

odeint - solving ordinary differential equations in c++ v2
http://headmyshoulder.github.com/odeint-v2/
Other
344 stars 101 forks source link

Different absolute tolerance values for each state vector element #198

Closed CarterA closed 7 years ago

CarterA commented 7 years ago

Matlab’s ODE solvers allow you to specify a vector of relative tolerance values, and after a lot of digging it doesn’t seem to be possible to do that with odeint. Is this a feature that could be added? I think it could be expressed by allowing the use of the state type for the relative tolerance argument.

The desire for this feature comes from simulating systems where the order of magnitude of the state vector elements is very different.

headmyshoulder commented 7 years ago

Yes, unfortunately this is not easy doable right now. But maybe you could rescale individual components of your ODE such that the tolerances have different magnitudes compared to the unscaled ODE. But I think this is difficult for the relative error.

What kind of solver are you using? Have you tried Rosenbrock?

CarterA commented 7 years ago

Rescaling the state vector components can certainly essentially the same result, and is what I will go with for the time being. I have avoided the Rosenbrock solver due to its requirement that I use uBLAS vector types; if you think it might perform better, I can give it a shot.

Edit: currently I am using the runge_kutta_dopri5 stepper with dense output.

headmyshoulder commented 7 years ago

I just wonder wether your ODE is stiff, i.e. your ODE has different time scales. In this case you might want to try the Rosenbrock method since it allows for much better performance for stiff system then any of the Runge-Kutta methods.

CarterA commented 7 years ago

Sadly, calculating the Jacobian for the system is not straightforward, so I don’t think Rosenbrock or any other implicit methods are a good choice.

Rescaling the state vector parameters to be of similar order reduced the average run time by about 25% (not bad!). I’ll stick with that for now.

mariomulansky commented 7 years ago

Another possibility is to write your own ErrorChecker, that supports specifying a vector of tolerances. This should not be too difficult. The default error checker is implemented there: https://github.com/headmyshoulder/odeint-v2/blob/master/include/boost/numeric/odeint/stepper/controlled_runge_kutta.hpp#L56 If the state type is fixed for you (which I guess it is), then you dont need to base the computations on an algebra but just implement everything inside you error checker.

headmyshoulder commented 7 years ago

Yeah, very good idea. This should work.

On 03.01.2017 07:53, Mario Mulansky wrote:

Another possibility is to write your own ErrorChecker, that supports specifying a vector of tolerances. This should not be too difficult. The default error checker is implemented there: https://github.com/headmyshoulder/odeint-v2/blob/master/include/boost/numeric/odeint/stepper/controlled_runge_kutta.hpp#L56 If the state type is fixed for you (which I guess it is), then you dont need to base the computations on an algebra but just implement everything inside you error checker.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/headmyshoulder/odeint-v2/issues/198#issuecomment-270146260, or mute the thread https://github.com/notifications/unsubscribe-auth/AAzSlMtyfSji7Fckd_N4r3F0px1m-_s3ks5rOm8IgaJpZM4LYgmX.