# DifferentialEquations: Change parameter in ODE after some time

Hello everyone,

I hope that this question belongs here, since my problem is mostly about the DifferentialEquations package.

I have the following dynamical system:

``````using DifferentialEquations
function some_dynamics(u,p,t)
du = zeros(length(u))
for i in 1:length(u)
for j in 1:length(u)
du[i] += p[i,j]*u[j]*u[i]
end
end
return du
end
``````

with some initial conditions:

``````p = rand(4,4)
u0 = zeros(length(p[1,:])) .+ 0.1
tspan = (0.,1.)
``````

I can solve the ODE using:

``````prob = ODEProblem(some_dynamics,u0,tspan,p)
sol = solve(prob)
``````

Is it possible to change the parameter p at some point before `tspan[end]?`
In pseudo code, I would like to be able to plug in something like
`if t == 0.5 -> p = ones(4,4)`

Hi,

you can use callbacks for this. That would entail adding something like

``````condition(u, t, integrator) = t - 0.5
affect!(integrator) = (integrator.p .= ones(4, 4))
callback = ContinuousCallback(condition, affect!)

...

solve(prob; callback = callback)
``````

Happy coding!

3 Likes

You may want to try the new `PresetTimeCallback`, now added by popular request! Just add the time that you want the callback to deploy at and then the `affect!` on the integrator goes as expected. Use a vector of times if you want multiple call times.

``````using OrdinaryDiffEq, DiffEqCallbacks, Test

function some_dynamics(u,p,t)
du = zeros(length(u))
for i in 1:length(u)
for j in 1:length(u)
du[i] += p[i,j]*u[j]*u[i]
end
end
return du
end

p = rand(4,4)
startp = copy(p)

u0 = zeros(length(p[1,:])) .+ 0.1
tspan = (0.,1.)
prob = ODEProblem(some_dynamics,u0,tspan,p)
cb = PresetTimeCallback(0.5,integrator -> integrator.p .= rand(4,4))
sol = solve(prob,Tsit5(),callback = cb)

prob = ODEProblem(some_dynamics,u0,tspan,p)
cb = PresetTimeCallback([0.3,0.6],integrator -> integrator.p .= rand(4,4))
sol = solve(prob,Tsit5(),callback = cb)
``````
4 Likes

That is exactly what I needed. Thank you so much!