# DifferentialEquations.jl VectorContinuousCallback vs CallbackSet

**URL:** <https://discourse.julialang.org/t/differentialequations-jl-vectorcontinuouscallback-vs-callbackset/88536>\
**Category:** Numerics\
**Tags:** diffeq\
**Created:** [October 10, 2022, 9:18pm UTC](https://discourse.julialang.org/t/differentialequations-jl-vectorcontinuouscallback-vs-callbackset/88536 "2022-10-10T21:18:25Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Max\_M](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/max_m/32/32051_2.png) [@Max\_M](https://discourse.julialang.org/u/Max_M)\
**Post date:** [October 10, 2022, 9:18pm UTC](https://discourse.julialang.org/t/differentialequations-jl-vectorcontinuouscallback-vs-callbackset/88536/1 "2022-10-10T21:18:25Z")

</div>

From the docs:

> The [`VectorContinuousCallback`] [https://diffeq.sciml.ai/stable/features/callback\_functions/#SciMLBase.VectorContinuousCallback](https://diffeq.sciml.ai/stable/features/callback_functions/#SciMLBase.VectorContinuousCallback)) works like a vector of `ContinuousCallbacks` and lets the user specify which callback is called when.
> 
> Multiple callbacks can be chained together to form a `CallbackSet` . A `CallbackSet` is constructed by passing the constructor `ContinuousCallback` , `DiscreteCallback` , `VectorContinuousCallback` or other `CallbackSet` instances

What exactly is the purpose of a VectorContinousCallback if you could should just use a CallbackSet of multiple ContinuousCallback? This seems to be like two options trying to achieve the same thing.

Additionally the VectorContinousCallback also requires some if else synthax sugaring in the affect function which does not look clean.

```julia
function condition(out,u,t,integrator) # Event when event_f(u,t) == 0
  out[1] = u[1]
  out[2] = (u[3] - 10.0)u[3]
end

function affect!(integrator, idx)
  if idx == 1
    integrator.u[2] = -0.9integrator.u[2]
  elseif idx == 2
    integrator.u[4] = -0.9integrator.u[4]
  end
end

cb = VectorContinuousCallback(condition,affect!,2)

```

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [October 11, 2022, 3:46am UTC](https://discourse.julialang.org/t/differentialequations-jl-vectorcontinuouscallback-vs-callbackset/88536/2 "2022-10-11T03:46:47Z")

</div>

> [@Max\_M](#):
>
> What exactly is the purpose of a VectorContinousCallback if you could should just use a CallbackSet of multiple ContinuousCallback? This seems to be like two options trying to achieve the same thing.

They have very different performance characteristics. VectofContinuousCallbacks will scale to thousands of callbacks, but CallbackSet will hit compile time issues at around 10 or so.

---

<div class="post-metadata">

**Author:** ![Max\_M](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/max_m/32/32051_2.png) [@Max\_M](https://discourse.julialang.org/u/Max_M)\
**Post date:** [October 11, 2022, 4:36pm UTC](https://discourse.julialang.org/t/differentialequations-jl-vectorcontinuouscallback-vs-callbackset/88536/3 "2022-10-11T16:36:07Z")

</div>

Alright that makes sense so far. But with that the question arises how the situation looks like for DiscreteCallbacks? A VectorDiscreteCallback doesn’t seem to exist, is there a reasoning behind that?

If possible I suggest to include your explanation somewhere in the docs because I think this is important to know when making design decisions as a user.

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [October 11, 2022, 4:46pm UTC](https://discourse.julialang.org/t/differentialequations-jl-vectorcontinuouscallback-vs-callbackset/88536/4 "2022-10-11T16:46:39Z")

</div>

> [@Max\_M](#):
>
> But with that the question arises how the situation looks like for DiscreteCallbacks? A VectorDiscreteCallback doesn’t seem to exist, is there a reasoning behind that?

DiscreteCallbacks run off of a true false. You can easily do a “VectorDiscreteCallback” by just doing `bool1 && bool2`. Implicit state in the condition is then all that’s needed to know which one fired. So no extra machinery on the backend is required to do it.

VectorContinuousCallbacks on the other hand cannot be made from ContinuousCallbacks because it requires the ability to run multiple rootfinding problems simultaneously. `root1 * root2` can work in a pinch, but there are many ways which this can fail (for example, `0 * NaN`). Also the problem of attribution, i.e. finding which callback fired first, can become an issue. Using a CallbackSet of ContinuousCallbacks stacks them and if two fire in the same interval, it takes the one that fires first. But that requires doubling the interpolation, i.e. doing two completely independent rootfinds. If you have `n` of them, first of all you have an `n` type tuple (so compile times die), and then you also have `n` rootfinding problems so your runtimes die. It’s just not a feasible approach to scale. But VectorContinuousCallbacks have quite a bit of overhead in the scalar case, and a more cumbersome API, so leaving ContinuousCallbacks alone was the solution in the end.

> [@Max\_M](#):
>
> If possible I suggest to include your explanation somewhere in the docs because I think this is important to know when making design decisions as a user

I thought it was, but it wasn’t. See if this quenches your thirst:

> <https://github.com/SciML/DiffEqDocs.jl/commit/40d84fa68311343f6b407496b6d2fafdfec3f588>

---

<div class="post-metadata">

**Author:** ![Max\_M](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/max_m/32/32051_2.png) [@Max\_M](https://discourse.julialang.org/u/Max_M)\
**Post date:** [October 11, 2022, 7:03pm UTC](https://discourse.julialang.org/t/differentialequations-jl-vectorcontinuouscallback-vs-callbackset/88536/5 "2022-10-11T19:03:01Z")

</div>

Thanks a lot!  
The updated docs look good to me.

---

<div class="post-metadata">

**Author:** ![shoumikdc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/shoumikdc/32/50602_2.png) [@shoumikdc](https://discourse.julialang.org/u/shoumikdc)\
**Post date:** [July 14, 2023, 3:56pm UTC](https://discourse.julialang.org/t/differentialequations-jl-vectorcontinuouscallback-vs-callbackset/88536/6 "2023-07-14T15:56:21Z")

</div>

@ChrisRackauckas I just wanted to briefly follow up on the question posed in this thread, specifically about the idea of a `VectorDiscreteCallback`. Could you elaborate on how this would work?

> [@ChrisRackauckas](#):
>
> You can easily do a “VectorDiscreteCallback” by just doing `bool1 && bool2`. Implicit state in the condition is then all that’s needed to know which one fired.

* * *

I’m asking this question in the context of using `DiscreteCallbacks` when I have high dimensional state vectors, and I want to check a condition on each component. As a thought-example, suppose I have a 10-dimensional vector `u` where the first five entries `u[1:5]` represent velocities and the last five `u[6:10]` are the corresponding positions. Suppose, after each integration step, I want to kick the velocity if its corresponding position is below zero. E.g. if the condition `u[6] <= 0`, then I do the action `u[1] += 10`; if `u[7] <= 0`, then I do `u[2] += 10`, and so on for each component.

In this case, it seems like I would have to write five separate `DiscreteCallback`s and `affect` functions for each of the components I am separately checking. Or is there a better solution that I’m not aware of for this to have just a single callback that affects all of the components in a single step?

If I do have to write separate discrete callbacks for each component of the state vector, is the best practice then to wrap all of those in a `CallbackSet`?

---

<div class="post-metadata">

**Author:** ![shoumikdc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/shoumikdc/32/50602_2.png) [@shoumikdc](https://discourse.julialang.org/u/shoumikdc)\
**Post date:** [July 14, 2023, 4:13pm UTC](https://discourse.julialang.org/t/differentialequations-jl-vectorcontinuouscallback-vs-callbackset/88536/7 "2023-07-14T16:13:12Z")

</div>

Also — you mentioned some performance limits of `CallbackSets` above:

> [@ChrisRackauckas](#):
>
> They have very different performance characteristics. VectofContinuousCallbacks will scale to thousands of callbacks, but CallbackSet will hit compile time issues at around 10 or so.

Is that statement about compile time issues true for a `CallbackSet` of `DiscreteCallback`s as well?

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [July 14, 2023, 6:48pm UTC](https://discourse.julialang.org/t/differentialequations-jl-vectorcontinuouscallback-vs-callbackset/88536/8 "2023-07-14T18:48:35Z")

</div>

> [@shoumikdc](#):
>
> If I do have to write separate discrete callbacks for each component of the state vector, is the best practice then to wrap all of those in a `CallbackSet`?

No, just make one DiscreteCallback as described above.
