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

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