# Optimizing ODE parameters with constants

**URL:** https://discourse.julialang.org/t/optimizing-ode-parameters-with-constants/42171
**Category:** New to Julia
**Tags:** diffeq, optimization
**Created:** [June 27, 2020, 9:32pm UTC](https://discourse.julialang.org/t/optimizing-ode-parameters-with-constants/42171 "2020-06-27T21:32:17Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![vaglino](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vaglino/32/16669_2.png) [@vaglino](https://discourse.julialang.org/u/vaglino)
#### Post date: [June 27, 2020, 9:32pm UTC](https://discourse.julialang.org/t/optimizing-ode-parameters-with-constants/42171/1 "2020-06-27T21:32:17Z")

</div>

Hi, new to Julia here,  
I’m trying to optimize the parameters of an ode system, while keeping some parameter constant.  
Using the lotka-volterra as an example,

```julia
function f(du,u,p,t)
  du[1] = dx = p[1]*u[1] - u[1]*u[2]
  du[2] = dy = -a*u[2] + u[1]*u[2]
end

u0 = [1.0;1.0]
tspan = (0.0,10.0)
p = [1.5]
prob = ODEProblem(f,u0,tspan,p)

cost_function = build_loss_objective(prob,Tsit5(),L2Loss(t,data),
                                     maxiters=10000,verbose=false)
using Optim
result = optimize(cost_function, 0.0, 10.0)

```

say I wanted to programmatically pass a constant ‘a’ and then optimize p, then pass a different constant ‘a’ and optimize p again, and so forth for many values of a. I am confused on the syntax for doing this. I was thinking having a function g(a) that includes all the code above and returns the optimized p, but it doesn’t seem to be the best way to do this, especially if I want to try different odes.

Thanks

---

<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: [June 27, 2020, 9:45pm UTC](https://discourse.julialang.org/t/optimizing-ode-parameters-with-constants/42171/2 "2020-06-27T21:45:25Z")

</div>

> [@vaglino](#):
>
> say I wanted to programmatically pass a constant ‘a’ and then optimize p, then pass a different constant ‘a’ and optimize p again, and so forth for many values of a. I am confused on the syntax for doing this. I was thinking having a function g(a) that includes all the code above and returns the optimized p, but it doesn’t seem to be the best way to do this, especially if I want to try different odes.

Doing that in a loop would be fine, and throwing `@threads` over it would parallelize it.

---

<div class="post-metadata">

### Author: ![vaglino](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vaglino/32/16669_2.png) [@vaglino](https://discourse.julialang.org/u/vaglino)
#### Post date: [June 27, 2020, 10:09pm UTC](https://discourse.julialang.org/t/optimizing-ode-parameters-with-constants/42171/3 "2020-06-27T22:09:08Z")

</div>

Thanks for the quick response (and thanks for the diffeq package in general, as a matlab user it is very refreshing)

If I put both the model f(du,u,p,t) and the optimizer in the same function g(a), then I won’t be able to use f independently of the optimizer. I would instead need to use f (with any given constant a) for other purposes (say plotting for a given p) without running the optimization.  
What can I do instead?

---

<div class="post-metadata">

### Author: ![vaglino](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vaglino/32/16669_2.png) [@vaglino](https://discourse.julialang.org/u/vaglino)
#### Post date: [June 27, 2020, 10:13pm UTC](https://discourse.julialang.org/t/optimizing-ode-parameters-with-constants/42171/4 "2020-06-27T22:13:56Z")

</div>

To qualify a bit what I mean:  
I need to be able to do both:

plot f given a, and p

and optimize p given f, and a

---

<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: [June 27, 2020, 10:23pm UTC](https://discourse.julialang.org/t/optimizing-ode-parameters-with-constants/42171/5 "2020-06-27T22:23:34Z")

</div>

Closures are your friend here:

```julia
function my_dynamics(du,u,p,t,a)

end

f = (du,u,p,t) -> my_dynamics(du,u,p,t,a) # enclose a to now solve with, or enclose other values later

```

---

<div class="post-metadata">

### Author: ![vaglino](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vaglino/32/16669_2.png) [@vaglino](https://discourse.julialang.org/u/vaglino)
#### Post date: [June 28, 2020, 8:46am UTC](https://discourse.julialang.org/t/optimizing-ode-parameters-with-constants/42171/6 "2020-06-28T08:46:56Z")

</div>

I rewrote the code based on your suggestion to use closures. I was not familiar with the concept of closures since you mentioned it, so I am not sure that the way I applied is proper, logically and stylistically.  
The code seems to work fine, although it’s a little convoluted in my opinion (which may stem from me not using closures properly)

```julia
using DifferentialEquations, DiffEqParamEstim
using Optim, Plots

function my_dynamics(du,u,p,t,a)
    du[1] = dx = p[1]*u[1] - u[1]*u[2]
    du[2] = dy = -a*u[2] + u[1]*u[2]
end

f = (du,u,p,t) -> my_dynamics(du,u,p,t,a) # enclose a to now solve with, or enclose other values later

# generate data with a = 1
u0 = [1.0;1.0]
tspan = (0.0,10.0)
p = [1.5]

a = 1
prob = ODEProblem(f,u0,tspan,p)
sol = solve(prob,Tsit5())

t = collect(range(0,stop=10,length=200))
using RecursiveArrayTools # for VectorOfArray
randomized = VectorOfArray([(sol(t[i]) + .01randn(2)) for i in 1:length(t)])
data = convert(Array,randomized)
h = scatter(t,data')

# plot with different values of a
for i = range(1,stop=10)
    new_a = i
    f = (du,u,p,t) -> my_dynamics(du,u,p,t,new_a)
    prob = ODEProblem(f,u0,tspan,p)
    sol = solve(prob,Tsit5())
    plot!(sol)
end

display(h)

# optimize p with given a
function optimization(a)
    f = (du,u,p,t) -> my_dynamics(du,u,p,t,a)
    prob = ODEProblem(f,u0,tspan,p)
    cost_function = build_loss_objective(prob,Tsit5(),L2Loss(t,data),
                   maxiters=10000,verbose=false)

    result = optimize(cost_function, 0.0, 10.0)   
end 

# optimize for a=2
optimization(2)           

```

---

<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: [June 28, 2020, 10:25am UTC](https://discourse.julialang.org/t/optimizing-ode-parameters-with-constants/42171/7 "2020-06-28T10:25:32Z")

</div>

Yeah, in general we’re moving more towards the DiffEqFlux style because it’s a bit more flexible.

[https://diffeqflux.sciml.ai/dev/](https://diffeqflux.sciml.ai/dev/)

That then doesn’t have these issues, but it requires you write out a cost function in full.
