DifferentialEquations.jl icon indicating copy to clipboard operation
DifferentialEquations.jl copied to clipboard

Provide Callback Count to affect

Open rjpower4 opened this issue 6 years ago • 5 comments

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:

  1. Using the userdata field of the integrator
  2. 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.

rjpower4 avatar Jun 15 '19 07:06 rjpower4

Second, the functor setup incurs an overhead and I'm seeing a 100% slowdown on average.

That seems extreme. Is it strictly typed?

ChrisRackauckas avatar Jun 15 '19 07:06 ChrisRackauckas

Do you have an example you can share that has this amount of slowdown?

ChrisRackauckas avatar Jun 15 '19 16:06 ChrisRackauckas

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.

rjpower4 avatar Jun 15 '19 19:06 rjpower4

For userdata, why not pass a mutable struct for the mutable data? The dictionary will be slower.

ChrisRackauckas avatar Jun 15 '19 22:06 ChrisRackauckas

True, thank you!

rjpower4 avatar Jun 18 '19 21:06 rjpower4