# Is there a way to change a single parameter in am ODEproblem and rerun it?

**URL:** <https://discourse.julialang.org/t/is-there-a-way-to-change-a-single-parameter-in-am-odeproblem-and-rerun-it/86775>\
**Category:** Modelling & Simulations\
**Created:** [September 4, 2022, 11:01pm UTC](https://discourse.julialang.org/t/is-there-a-way-to-change-a-single-parameter-in-am-odeproblem-and-rerun-it/86775 "2022-09-04T23:01:45Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![TS-CUBED](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ts-cubed/32/25292_2.png) [@TS-CUBED](https://discourse.julialang.org/u/TS-CUBED)\
**Post date:** [September 4, 2022, 11:01pm UTC](https://discourse.julialang.org/t/is-there-a-way-to-change-a-single-parameter-in-am-odeproblem-and-rerun-it/86775/1 "2022-09-04T23:01:45Z")

</div>

I do define a model with a set of parameters that comes from the default settings for the components.

I then want to change a parameter and rerun the problem.

I could of course set up a parameter input map

```julia
p = [
p1 => 1
p2 => 2
p3 => 3
.
.
.
p156 => 156
]

```

and then use `varmap_to_vars` and `remake` to get the new model. And that is usually how I do it.

But in some cases I want to avoid setting up the whole parameter map, only to change one parameter, and in those cases, I’d like to have something like the CellMLToolkit method:

```julia
p = list_params(ml)
update_list!(p, :stimulus_protocol₊IstimPeriod, 250.0)
prob = ODEProblem(ml, (0, 10000.0); p=p)

```

Is such a thing possible for an MTK model?

---

<div class="post-metadata">

**Author:** ![SteffenPL](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/steffenpl/32/206270_2.png) [@SteffenPL](https://discourse.julialang.org/u/SteffenPL)\
**Post date:** [September 5, 2022, 7:13am UTC](https://discourse.julialang.org/t/is-there-a-way-to-change-a-single-parameter-in-am-odeproblem-and-rerun-it/86775/2 "2022-09-05T07:13:23Z")

</div>

What exactly is the problem with `varmap_to_vars`? It is runtime concerns or  
is the code not nice enough for you? Using the `defaults` keyword, is seems pretty close to your suggested variant and you could simply define a function `update_params!` if you need it often.

```julia
using ModelingToolkit: varmap_to_vars

p_new = varmap_to_vars([p156 => 157.0], parameters(sys), defaults=Dict(p))
prob_new = remark(prob, p = p_new)

```

---

<div class="post-metadata">

**Author:** ![TS-CUBED](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ts-cubed/32/25292_2.png) [@TS-CUBED](https://discourse.julialang.org/u/TS-CUBED)\
**Post date:** [September 5, 2022, 8:35am UTC](https://discourse.julialang.org/t/is-there-a-way-to-change-a-single-parameter-in-am-odeproblem-and-rerun-it/86775/3 "2022-09-05T08:35:21Z")

</div>

I did not know that keyword (I looked for the documentation on `varmap_to_vars` and could not find that in what I found). In the cases were I have the parameter map `p` as described. That will be really helpful. Thanks a lot.

However, in this case `p` does not exist yet. So nothing to put into `defaults` (if I understand your example correctly).

So I guess the question is can I get `p` (the input map) from `parameters(sys)` and `prob.p`, which contain the two vectors that could create that?

This:

```julia
prob.p[156] = 157

```

does work, but requires me to now the order of the parameter vector (which I don’t do all the time, since the equations change between variation of models. Most of the time the parameter list stays in the same order, but not when I replace a simple model for a more complex one.

Something like:

```julia
prob.p[:p156] = 157

```

or (in my case):

```julia
prob.p[:AV.c1] = 0.75

```

where `AV` is the component, and `c1` is the parameter to be changed, would be what I’m after.

Edit:  
I just realised that my (seemingly obvious) idea to switch from a parameter file, which has all parameters as global parameters that are then used in the creation of the model (so no globals within the model functions themselves) to a parameter map of the model parameters, wouldn’t be practical, since I use the different parameters (with the same valuse, so only defined once) in different models.

So I’d need separate maps for different models, since MTK/DifferentialEquations doesn’t like unused parameters in the maps.

My models have between 80 and several hundred parameters. But

- most of them will stay at their sane defaults, which are set in the functions that create the equations
- others will be set once at the `@named` component creation (from those global parameter variables) and then stay the same
- a varying subset will be defined as the optimisation/tuning parameters.

I want to avoid having to create `p` with all of these hundreds of lines (error prone) and have a `p` that only contains the last set.

So I was wondering if there is a function like that already (like the `default` parameter I didn’t know about) or if I need to hack one together myself.

If there isn’t I’d put a feature request on github, and possibly have a go myself to implement it properly.

---

<div class="post-metadata">

**Author:** ![TS-CUBED](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ts-cubed/32/25292_2.png) [@TS-CUBED](https://discourse.julialang.org/u/TS-CUBED)\
**Post date:** [September 5, 2022, 8:39am UTC](https://discourse.julialang.org/t/is-there-a-way-to-change-a-single-parameter-in-am-odeproblem-and-rerun-it/86775/4 "2022-09-05T08:39:34Z")

</div>

> [@SteffenPL](#):
>
> you could simply define a function `update_params!` if you need it often.

I already have a `reparameterise(prob, sys, p)` which takes the whole parameter map `p`, will add the `default` option to that, so it deals with partial maps as well.

That’s very helpful.

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [September 5, 2022, 4:00pm UTC](https://discourse.julialang.org/t/is-there-a-way-to-change-a-single-parameter-in-am-odeproblem-and-rerun-it/86775/5 "2022-09-05T16:00:40Z")

</div>

Note that `sys` now exists in the `ODEFunction`, so in theory we can setup `remake` to use it correctly. Just no one has done it.

---

<div class="post-metadata">

**Author:** ![TS-CUBED](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ts-cubed/32/25292_2.png) [@TS-CUBED](https://discourse.julialang.org/u/TS-CUBED)\
**Post date:** [September 5, 2022, 5:00pm UTC](https://discourse.julialang.org/t/is-there-a-way-to-change-a-single-parameter-in-am-odeproblem-and-rerun-it/86775/6 "2022-09-05T17:00:51Z")

</div>

> [@ChrisRackauckas](#):
>
> Note that `sys` now exists in the `ODEFunction`

Interesting. How do I get that? I only have `ODESystem` and `ODEProblem` in my case?

> so in theory we can setup `remake` to use it correctly. Just no one has done it.

Would that mean one could use

```julia
remake(prob, p = [p156 => 157])

```

in order to change only the value of `p156` and leave the others as they are?

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [September 5, 2022, 6:31pm UTC](https://discourse.julialang.org/t/is-there-a-way-to-change-a-single-parameter-in-am-odeproblem-and-rerun-it/86775/8 "2022-09-05T18:31:18Z")

</div>

> [@TS-CUBED](#):
>
> Would that mean one could use
> 
> ```julia
> remake(prob, p = [p156 => 157])
> 
> ```
> 
> in order to change only the value of `p156` and leave the others as they are?

yes, if someone improves the `remake` dispatch. It’s in `prob.f.sys`.

---

<div class="post-metadata">

**Author:** ![TS-CUBED](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ts-cubed/32/25292_2.png) [@TS-CUBED](https://discourse.julialang.org/u/TS-CUBED)\
**Post date:** [September 5, 2022, 7:05pm UTC](https://discourse.julialang.org/t/is-there-a-way-to-change-a-single-parameter-in-am-odeproblem-and-rerun-it/86775/9 "2022-09-05T19:05:31Z")

</div>

Thanks.

I’ll put that on github as a suggestion, then. Not a high priority, but I guess it would be a neat feature. Teaching is looming, so I don’t think I can dive that deep into the code (and I’m a high-level user, so the internals are all black magic to me).

---

<div class="post-metadata">

**Author:** ![TS-CUBED](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ts-cubed/32/25292_2.png) [@TS-CUBED](https://discourse.julialang.org/u/TS-CUBED)\
**Post date:** [December 20, 2022, 4:01pm UTC](https://discourse.julialang.org/t/is-there-a-way-to-change-a-single-parameter-in-am-odeproblem-and-rerun-it/86775/10 "2022-12-20T16:01:10Z")

</div>

I have played around with this a bit and found that:

```julia
Dict(parameters(prob.f.sys)[n] => prob.p[n] for n in 1:length(prob.p))

```

allows me to create a dict of all the parameters that are in the current problem.

So a simple function like:

```julia
function update_params(prob, pmap)
    pdict=Dict(parameters(prob.f.sys)[n] => prob.p[n] for n in 1:length(prob.p))

    remake(prob; p = varmap_to_vars(pmap, parameters(prob.f.sys), defaults=pdict))
end

```

does work, and allows me to do things like:

```julia
new_prob = update_params(prob, [p156 => 157])

```

where that vector of parameters can contain as many as we need. We can also pass a Dict instead of the vector parameter map.

Btw, at the moment we can use vectors or Dicts as parameter maps. Will MTK keep both, or/and is there a preference? The `defaults` parameter only takes a Dict.

Btw2, is there a way to make that a mutating function?

```julia
function update_params!(prob, pmap)
    pdict=Dict(parameters(prob.f.sys)[n] => prob.p[n] for n in 1:length(prob.p))

    prob = remake(prob; p = varmap_to_vars(pmap, parameters(prob.f.sys), defaults=pdict))
end

```

doesn’t seem to work.

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [December 20, 2022, 6:17pm UTC](https://discourse.julialang.org/t/is-there-a-way-to-change-a-single-parameter-in-am-odeproblem-and-rerun-it/86775/11 "2022-12-20T18:17:11Z")

</div>

> [@TS-CUBED](#):
>
> `new_prob = update_params(prob, [p156 => 157])`

Why not just do `new_prob = remake(prob, [p156 => 157])` on the latest version? This works now.

---

<div class="post-metadata">

**Author:** ![TS-CUBED](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ts-cubed/32/25292_2.png) [@TS-CUBED](https://discourse.julialang.org/u/TS-CUBED)\
**Post date:** [December 20, 2022, 7:10pm UTC](https://discourse.julialang.org/t/is-there-a-way-to-change-a-single-parameter-in-am-odeproblem-and-rerun-it/86775/12 "2022-12-20T19:10:23Z")

</div>

Great. When was that introduced? Will update and test.

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [December 20, 2022, 8:01pm UTC](https://discourse.julialang.org/t/is-there-a-way-to-change-a-single-parameter-in-am-odeproblem-and-rerun-it/86775/13 "2022-12-20T20:01:07Z")

</div>

Maybe a month or two ago?

---

<div class="post-metadata">

**Author:** ![TS-CUBED](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ts-cubed/32/25292_2.png) [@TS-CUBED](https://discourse.julialang.org/u/TS-CUBED)\
**Post date:** [December 20, 2022, 9:48pm UTC](https://discourse.julialang.org/t/is-there-a-way-to-change-a-single-parameter-in-am-odeproblem-and-rerun-it/86775/14 "2022-12-20T21:48:45Z")

</div>

Indeed, it does work. I really need to try to keep up with your release notes 🙂

---

<div class="post-metadata">

**Author:** ![TS-CUBED](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ts-cubed/32/25292_2.png) [@TS-CUBED](https://discourse.julialang.org/u/TS-CUBED)\
**Post date:** [December 20, 2022, 9:50pm UTC](https://discourse.julialang.org/t/is-there-a-way-to-change-a-single-parameter-in-am-odeproblem-and-rerun-it/86775/15 "2022-12-20T21:50:38Z")

</div>

Ok, I had Chris’s post set as the solution, but there’s a typo in that.

It needs to be `p = [<parameter map>]`, so:

```julia
new_prob = remake(prob, p = [p156 => 157])

```

Edit: according to the changelogs, I guess this was brought in in v8.29

---

<div class="post-metadata">

**Author:** ![johannesnauta](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/johannesnauta/32/47434_2.png) [@johannesnauta](https://discourse.julialang.org/u/johannesnauta)\
**Post date:** [February 26, 2024, 11:57am UTC](https://discourse.julialang.org/t/is-there-a-way-to-change-a-single-parameter-in-am-odeproblem-and-rerun-it/86775/16 "2024-02-26T11:57:08Z")

</div>

I might be (very) late to the party, but if I try to use this syntax I get missing from variable map errors, while the above syntax does work. In other words, I need a function like this to update only part of the parameters:

```julia
function update_params(prob, pmap)
    params = ModelingToolkit.parameters(prob.f.sys)
    pdict = Dict(
        params[n] => prob.p[n] for n in 1:length(prob.p)
    )
    p = ModelingToolkit.varmap_to_vars(
        pmap, params, defaults=pdict
    )
    updated_prob = remake(prob; p=p)
    return updated_prob
end

```

as just calling `remake(prob, p=pmap)` does not work when `pmap` does not contain all parameters.

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [February 28, 2024, 8:30pm UTC](https://discourse.julialang.org/t/is-there-a-way-to-change-a-single-parameter-in-am-odeproblem-and-rerun-it/86775/17 "2024-02-28T20:30:57Z")

</div>

What version are you using? Can you make an MWE for MTK v9?
