How to change the value of a parameter with DifferentialEquations?

Hello,
I have a series of differential equations, and I can change the value of the integrator with a back call like this:

condition(u, t, integrator) = t==1000             # time of alteration
affect!(integrator) = integrator.u[4] += 500     # alter 4th value of the integrator
cb = DiscreteCallback(condition,affect!)
prob = ODEProblem(myFun!, u0, tspan, parms)
soln = solve(prob, AutoVern7(Rodas5()), callback=cb)

Is it possible to change the value of a parameter at a given time, let’s say t=1000? That is, instead of changing the whole integrator, I simply change the value of one parameter.
Thanks

Sure, that’s possible. I can’t give you a precise line of code, because I don’t know what’s inside your parameter construct p; is it a NamedTuple, just a regular vector or a custom struct. Since it’s a basic question, I am assuming that you are using a regular array or just a number as your parameter

Assuming it is just one parameter, then you could change its value like this:

function affect!(integrator)
    integrator.u[4] += 500.0
    integrator.p = 10.0 #obviously, 10.0 is just an example
end

If it’s a vector of parameters instead, it would look like this:

function affect!(integrator)
    integrator.u[4] += 500.0
    integrator.p[1] = 10.0 #again, just an example, obviously you have to get the index and the value right yourself
end

I have kept the change of state value (integrator.u[4] += 500.0) line in there, but it can of course be removed if your problem doesn’t require this.

Hope it helps!

1 Like

Thank you,
I have a vector of parameters, so I used:

function myFun!(du, u, p, t)
    μ, ν, κ, φ, ψ, ω, β, Β, η, Η, ϛ = p
    ...
    println(ϛ)
end

parms = [mu, nu, kappa, phi, psi, omega, beta, Beta, eta, Eta, upstigma]
tspan = (0.0, tmax)
u0 = [c_s0, c_i0, c_v0, o_s0, o_i0, o_v0]
condition(u, t, integrator) = t==t_in               # time of alteration
affect!(integrator) = integrator.p[11] = 0.0    # new value
cb = DiscreteCallback(condition,affect!)
prob = ODEProblem(myFun!, u0, tspan, parms)
soln = solve(prob, AutoVern7(Rodas5()), callback=cb, tstops=[1000])

but the value does not change. I introduced a prinln statement in myFun, and p[11] is always 1…
I even used integrator.p[11] == 0.0 but did not change either.
If I change the sequence of the arguments in the function (since p comes before t), I get an error:

julia> prob = ODEProblem(myFun!, u0, parms, tspan)
ERROR: The length of tspan must be two (and preferably, tspan should be a tuple, i.e. (0.0,1.0)). If you are trying to include other values for saving reasons, note see the [common solver arguments page](https://docs.juliadiffeq.org/latest/basics/common_solver_opts/) for information on the saving command saveat.

What am I getting wrong?

prob = ODEProblem(multiInfect!, u0, tspan, parms)

@Luigi_Marongiu
Your post has internal inconsistencies (myFun! vs multiInfect!, changing p[11], but printing p[12]). Makes it a little hard to fully resolve this :slight_smile:

If you need further help, consider posting a minimum workable example of your problem, but since a very similar example is found in the DiffEq Docs ( Event Handling and Callback Functions · DifferentialEquations.jl (sciml.ai)), it might be just a matter of adapting one of those examples to your case of changing integrator.p[11].

Hi, I am already using prob = ODEProblem(myFun!, u0, tspan, parms) but the p[11] does not change. prob = ODEProblem(myFun!, u0, parms, tspan) gives the error even if the function is: function myFun!(du, u, p, t).

PS: sorry for the incosistencies, it was due to typos in copy and pasting but changing the original name of the function.

Well ODEProblem(myFun!, u0, parms, tspan) is always wrong, so it’s definitely not the solution. Do not start randomly changing arguments, try and figure out what’s going on and fix things in a targeted direction.

Is t_in == 1000? I would recommend just using PresetTimeCallback because you seem to be just randomly trying things which does not include having the tstops at the correct time. See this example:

https://diffeq.sciml.ai/stable/features/callback_functions/#PresetTimeCallback

Now just change it to integrator.p and you’re done.

1 Like

Thank you, the error was indeed tstops. I used soln = solve(prob, AutoVern7(Rodas5()), callback=cb, tstops=[t_in]) and it worked.

1 Like