# Using ForwardDiff to differentiate an ODE with respect to some of its parameters

**URL:** <https://discourse.julialang.org/t/using-forwarddiff-to-differentiate-an-ode-with-respect-to-some-of-its-parameters/37353>\
**Category:** Modelling & Simulations\
**Created:** [April 10, 2020, 4:21pm UTC](https://discourse.julialang.org/t/using-forwarddiff-to-differentiate-an-ode-with-respect-to-some-of-its-parameters/37353 "2020-04-10T16:21:41Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![peterj](https://avatars.discourse-cdn.com/v4/letter/p/22d042/32.png) [@peterj](https://discourse.julialang.org/u/peterj)\
**Post date:** [April 10, 2020, 4:21pm UTC](https://discourse.julialang.org/t/using-forwarddiff-to-differentiate-an-ode-with-respect-to-some-of-its-parameters/37353/1 "2020-04-10T16:21:41Z")

</div>

So far, I have this

```julia

using DifferentialEquations

using LabelledArrays

const n = 10

struct params

    p_to_optimize_array::AbstractArray{<:Real,1}

    p_constant_array::AbstractArray{<:Real,1}

end

function f1(du,u,p,t)

    du.x .= -1 .*u.x * p.p_constant_array.d

    du.y .= -1 .* u.y .* p.p_to_optimize_array.a * p.p_constant_array.e

end

function objective(p)

    p_to_optimize_array = @LArray (p) (:a,:b,:c)

    u_0 = @LArray eltype(p) (2*n) (x = (1:n),y = (n+1:2*n))

    u_0 .= 1000.0

    p_constant_array = @LArray [1.0,2.0] (:d,:e)

    param_struct = params(p_to_optimize_array,p_constant_array)

    prob1 = ODEProblem(f1,u_0,(0,100.0),param_struct)

    sol = sum(solve(prob1, Rodas5()).u)
    return sum(sol)

end

using ForwardDiff

ForwardDiff.gradient(objective,[1.0,2.0,3.0])

```

the error I get is `ForwardDiff.DualMismatchError`, which I figure is because `u_0` and `p` are both `Dual`. However, if I don’t set the type of `u_0` to be `eltype(p)`, but rather `Float64` or something, then the ODE solver won’t accept the dual numbers as its state. I know `DiffEqParamEstim.jl` implements this sort of thing, but I want to understand how to use it myself.

---

<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:** [April 10, 2020, 5:35pm UTC](https://discourse.julialang.org/t/using-forwarddiff-to-differentiate-an-ode-with-respect-to-some-of-its-parameters/37353/2 "2020-04-10T17:35:07Z")

</div>

> [@peterj](#):
>
> sol = solve(prob1, Rodas5())

Does `sol = solve(prob1, Rodas5(autodiff=false))` work?

---

<div class="post-metadata">

**Author:** ![peterj](https://avatars.discourse-cdn.com/v4/letter/p/22d042/32.png) [@peterj](https://discourse.julialang.org/u/peterj)\
**Post date:** [April 10, 2020, 6:09pm UTC](https://discourse.julialang.org/t/using-forwarddiff-to-differentiate-an-ode-with-respect-to-some-of-its-parameters/37353/3 "2020-04-10T18:09:20Z")

</div>

No, that gives a different error `MethodError: no method matching extract_gradient!....`. Using a non-stiff solver like `Tsit5()` gives the same error.

---

<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:** [April 10, 2020, 6:12pm UTC](https://discourse.julialang.org/t/using-forwarddiff-to-differentiate-an-ode-with-respect-to-some-of-its-parameters/37353/4 "2020-04-10T18:12:34Z")

</div>

Your output isn’t a scalar, but you’re asking for the gradient. Did you mean to end with `sum(sol)` or something like that?

---

<div class="post-metadata">

**Author:** ![peterj](https://avatars.discourse-cdn.com/v4/letter/p/22d042/32.png) [@peterj](https://discourse.julialang.org/u/peterj)\
**Post date:** [April 10, 2020, 6:32pm UTC](https://discourse.julialang.org/t/using-forwarddiff-to-differentiate-an-ode-with-respect-to-some-of-its-parameters/37353/5 "2020-04-10T18:32:08Z")

</div>

That’s embarassing, yeah I had a loss function there in the larger project that this example is being used to prototype for.

Yeah the error goes away with autodiff = false or a non-stiff solver.

---

<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:** [April 10, 2020, 6:38pm UTC](https://discourse.julialang.org/t/using-forwarddiff-to-differentiate-an-ode-with-respect-to-some-of-its-parameters/37353/6 "2020-04-10T18:38:35Z")

</div>

Yes nesting autodiff here gets a little bit tricky, but that gets you working for now.
