DifferentialEquations.jl
DifferentialEquations.jl copied to clipboard
Provide Callback Count to affect
A common application of callbacks is to take an effect after a certain number of occurrences, e.g. finding the third return to a Poincare section. Currently (at least to my knowledge), there are two main ways of doing this:
- Using the
userdatafield of theintegrator - Using a functor on a mutable struct
However, there are issues with this. The use of userdata is not-ergonomic as the fields must be built for each of the different events being included and quickly turns ugly to implement for any large number of callbacks. Second, the functor setup incurs an overhead and I'm seeing a 100% slowdown on average.
It would be beneficial to provide the number of times a particular affect! has been called in this integration so that logic that depends on this number can be easily performed.
Second, the functor setup incurs an overhead and I'm seeing a 100% slowdown on average.
That seems extreme. Is it strictly typed?
Do you have an example you can share that has this amount of slowdown?
Ahh, yes of course I've blundered. I've tried to nail down the types and now see that the relationship is somewhat flipped (see here). I am seeing that the functor method is ~40% faster than the userdata method (see attached script).
So is this (using functors) what is recommended for this use case? I have tried to search for other implementations online but have been unsuccessful finding any that match what I'm trying to do.
My only hesitation is that I don't like having these structs mutating within the integration as I can see myself creating bugs by accidentally reusing the structs for another integration without resetting the internal counter. That was the primary motivation for seeing if the integrator could provide that information to the function calls.
For userdata, why not pass a mutable struct for the mutable data? The dictionary will be slower.
True, thank you!