DifferentialEquations.jl
DifferentialEquations.jl copied to clipboard
Callbacks and params passed by reference
For ODEProblem, parameters are passed by reference, so parameter updates via callbacks can cause upstream issues. This occurs for both VectorContinuousCallback and ContinuousCallback. As expected, the ODEProblem object is also modified. Is this a design choice or unexpected behavior? Thanks!
using OrdinaryDiffEq
using Plots; gr()
f(u,p,t) = p.*u
u0 = [10.0,]
params = [-1.0,]
tspan = (0.0,20.0)
function condition!(out, u, t, integrator)
out[1] = u[1] - 2.5
end
function condition(u,t,integrator)
return u[1] - 2.5
end
function affect!(integrator, event_index)
integrator.p[1] = integrator.p[1]*.5
end
prob = ODEProblem(f,u0,tspan,params)
Vcb = VectorContinuousCallback(condition!,affect!,1, save_positions=(true,true))
Ccb = ContinuousCallback(condition, i->affect!(i,0), save_positions=(true,true))
## Using VectorContinuousCallback
@show params # params = [-1.0]
sol = solve(prob,Tsit5(), callback=Vcb)
@show params # params = [-0.5]
sol2 = solve(prob,Tsit5(), callback=Vcb)
## Using ContinuousCallback
@show params # params = [-0.25]
sol3 = solve(prob,Tsit5(), callback=Ccb)
@show params # params = [-0.125]
sol4 = solve(prob,Tsit5(), callback=Ccb)
@show params # params = [-0.0625]
plot(sol)
plot!(sol2)
plot!(sol3)
plot!(sol4)

It's at least the current design that we don't make a copy unless we specifically need to. The initial condition and the parameters are thus just references. There is a common solve argument u0_alias for the initial condition part, but nothing on the parameters.
This is a bigger issue with some of the Verner methods since they can treat their interpolation lazily, so a change of p can change f calls, so post solve f calls can have an influence. It might be good to have a p_alias argument.