I just want to preface this with the fact that I have almost no programming experience, and know way less than either of those who have replied, so definitely listen to them first and foremost. I just want to add what I did, which is more like substituting a value for your parameters instead of redefining the equation to redefine a parameter-value. I am continuing with your example of the lorentz attractor:
@parameters t σ ρ β
@variables x(t) y(t) z(t)
@derivatives D'~t
eqs = [D(x) ~ σ*(y-x),
D(y) ~ x*(ρ-z)-y,
D(z) ~ x*y - β*z]
de = ODESystem(eqs, t, [x, y, z], [σ, ρ, β])
ode_f = ODEFunction(de)
u₀ = [x₀, y₀, z₀]
tspan = (your_custom_timespan)
p = [σ_val, ρ_val, β_val]
prob = ODEProblem(ode_f, u₀, tspan, p)
sol = solve(prob)
So when you define p with parameter values, you are substituting in your fixed constants. Another advantage, which is what I found useful about this way of defining things is that you can redefine parameters without redefining your original equations. So if you want to double the sigma value and run again, you can do
p = [2σ_val, ρ_val, β_val]
or, even more compact,
p[1] = 2σ_val
and then run
prob = ODEProblem(ode_f, u₀, tspan, p)
sol = solve(prob)
again to get the new solution, all while using what you have already defined.
\n
\n
So that brings me to why I was googling and stumbled upon this post, and this is more directed at the two gentlemen who already replied, @shashi and @ChrisRackauckas (Thank you so much for your work, you are amazing):
The problem is that I feel like I have defined what the parameters are 3 times:
The “@parameters” macro,
In the equations,
In the “de” definition
and their values a seperate time, when defining p
I do realize that this is to get a nice structure and not necessary, but I don’t want to abandon the nice structure at all. I am imagining something like the following:
eqs = [D(x) ~ σ*(y-x),
D(y) ~ x*(ρ-z)-y,
D(z) ~ x*y - β*z]
p = Dict(σ=>σ_val, ρ=>ρ_val, β=>β_val) # constructing a dictionary linking parameters and their values
# (maybe Pair is a better datatype with more natural syntax, I don't know)
de = ODESystem(eqs, t, [x, y, z], p) # this would read the dictionary keys
ode_f = ODEFunction(de)
u₀ = [x₀, y₀, z₀]
tspan = (your_custom_timespan)
prob = ODEProblem(ode_f, u₀, tspan, p) # This would index the dict keys to get values
sol = solve(prob)
From here a redefinition is just as easy, and so the value of the nice structure is conserved:
p[σ] = 2σ_val
prob = ODEProblem(ode_f, u₀, tspan, p)
sol = solve(prob)
Now I don’t that my suggestion is a perfect solution at all. Something maybe close to ideal would be to link parameters with values when they are declared in the macro (p=>p_val Pairs perhaps?), with the possibility of easy redefinition, and never having to pass them as arguments in “prob” and “de” definitions. I know you are doing a lot of amazing work and don’t want to waste your time on syntax-polishing if you have better things to do, so feel free to ignore this suggestion if it is hard to implement, unfeasible or plain stupid ^-^