# Adjoint sensitivities

**URL:** <https://discourse.mc-stan.org/t/adjoint-sensitivities/935>\
**Category:** Algorithms\
**Created:** [June 16, 2017, 4:52pm UTC](https://discourse.mc-stan.org/t/adjoint-sensitivities/935 "2017-06-16T16:52:09Z")\
**Posts on this page:** 6\
**Page:** 2

<div class="post-metadata">

**Author:** ![submagr](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.mc-stan.org/submagr/32/5282_2.png) [@submagr](https://discourse.mc-stan.org/u/submagr)\
**Post date:** [July 20, 2019, 12:40am UTC](https://discourse.mc-stan.org/t/adjoint-sensitivities/935/21 "2019-07-20T00:40:12Z")

</div>

Dear @bbbales2 and Stan team,  
Why did you not pursue this further? It seems like you coded most of the part and it was ready for merging. I tried reading all the comments, but didn’t actually understand the reasons for not pursuing this further.

In our project, we wrote a wrapper around integrate\_ode\_rk45 in stan::math to integrate using adjoint method, and it seems to work correctly. I am a novice in stan::math, but I can try to conduct required experiments for merging this.

---

<div class="post-metadata">

**Author:** ![bbbales2](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.mc-stan.org/bbbales2/32/77_2.png) [@bbbales2](https://discourse.mc-stan.org/u/bbbales2)\
**Post date:** [July 20, 2019, 11:53am UTC](https://discourse.mc-stan.org/t/adjoint-sensitivities/935/22 "2019-07-20T11:53:58Z")

</div>

I lost interest in this approach because I felt like integrating the adjoint ODE accurately ended up being quite difficult. It just didn’t end up being as fast as I wanted.

It bothered me that the continuous adjoint ODE stuff gives you approximations to the true sensitivities, when in reality HMC wants gradients of whatever it is in the log density evaluation, which is an approximation itself.

The discrete adjoint ODE stuff (autodiffing through a solver, basically) gives you exact gradients of the approximation.

Chris Rackauckas wrote a paper on the continuous vs. discrete, fwd vs. reverse thing. He’s as deep into ODEs/autodiff and the types of problems we care about as anyone (he’s done tons for ODEs in Julia with DifferentialEquations.jl). It’s here: [https://arxiv.org/abs/1812.01892](https://arxiv.org/abs/1812.01892)

Chris also made some compelling arguments for handling things like PKPD dosing better at the solver level.

If/when I go back to this, I’d start by reading Chris’s paper, experimenting with the solvers on different problems and just stick to the discrete sensitivity stuff (be it adjoint or fwd).

If you wanted to work on this, feel free. I’m happy to share opinions. My buddy @arya probably would too if he has time. Arya contacted to Chris about this stuff, and Chris was super happy to share advice. I don’t think just adding continuous adjoint sensitivity stuff is the way to go though. Too many other questions.

---

<div class="post-metadata">

**Author:** ![wds15](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.mc-stan.org/wds15/32/908_2.png) [@wds15](https://discourse.mc-stan.org/u/wds15)\
**Post date:** [July 21, 2019, 4:48pm UTC](https://discourse.mc-stan.org/t/adjoint-sensitivities/935/23 "2019-07-21T16:48:25Z")

</div>

Hi @submagr!

Can you describe your application a little bit and what benefits of the Adjoint approach you are observing?

I wanted to evaluate this approach myself for a while (I still intend to), but I got side tracked by within chain parallelization which solves the speed problem for any hierarchical ode model.

@bbbales2 the profiler dump you show above makes perfect sense to me by now. We are wasting a huge amount of overhead with the nested vector stuff to get the jacobian of the ode system here. I coded up code generation for this and I am getting 2-3x speedup by doing this. One should probably reattempt all of this with code generation . I am still thinking that Adjoint must be much better for a range of interesting problems (many ode parameters for example).

…for now I am busy with the next gen parallelism using the tbb…

Best,  
Sebastian

---

<div class="post-metadata">

**Author:** ![submagr](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.mc-stan.org/submagr/32/5282_2.png) [@submagr](https://discourse.mc-stan.org/u/submagr)\
**Post date:** [July 22, 2019, 8:50pm UTC](https://discourse.mc-stan.org/t/adjoint-sensitivities/935/24 "2019-07-22T20:50:24Z")

</div>

Hi @wds15,

> [@wds15](#):
>
> Can you describe your application a little bit

Our aim is to integrate the dynamics of the system (first-order ODEs) forward in time and get the gradients of the integrated state with respect to the parameters. More specifically, these ODEs are related to Rigid Body Dynamics.

> [@wds15](#):
>
> what benefits of the Adjoint approach you are observing?

We are still in the process of merging the implementation of Adjoint Method integration. But we are motivated by [Neural Ordinary Differential Equation](https://arxiv.org/abs/1806.07366) paper, where authors reported several advantages (memory as well as time) of using the adjoint method. We have replicated [nueralODE’s implementation](https://github.com/rtqichen/torchdiffeq/blob/master/torchdiffeq/_impl/adjoint.py) in stan math.

[Here is a small implementation](https://github.com/submagr/Stan-Math-Adjoint-Method)

---

<div class="post-metadata">

**Author:** ![yizhang](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.mc-stan.org/yizhang/32/15673_2.png) [@yizhang](https://discourse.mc-stan.org/u/yizhang)\
**Post date:** [July 23, 2019, 12:13am UTC](https://discourse.mc-stan.org/t/adjoint-sensitivities/935/25 "2019-07-23T00:13:36Z")

</div>

> [@submagr](#):
>
> Our aim is to integrate the dynamics of the system (first-order ODEs) forward in time and get the gradients of the integrated state with respect to the parameters. More specifically, these ODEs are related to Rigid Body Dynamics.

Depends on the scenario, will Newmark or (even better)HHT give better accuracy and proper dissipation? In that case you’ll going to lose AD from Stan’s solvers. But since you’re already implementing your own integrator, maybe HHT-alpha + Complex step approximation gives a faster turn out(not necessarily faster solution speed). In terms of adjoint, what is your Lagrangian?

---

<div class="post-metadata">

**Author:** ![submagr](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.mc-stan.org/submagr/32/5282_2.png) [@submagr](https://discourse.mc-stan.org/u/submagr)\
**Post date:** [July 23, 2019, 5:14pm UTC](https://discourse.mc-stan.org/t/adjoint-sensitivities/935/26 "2019-07-23T17:14:09Z")

</div>

Hi @yizhang,

> [@yizhang](#):
>
> Depends on the scenario, will Newmark or (even better)HHT give better accuracy and proper dissipation?

The adjoint method treats the integration method being used as a BlackBox. We can use Newmark, HHT or any integrator. We concern ourselves with getting fast derivatives with respect to the integrated state, which is the main advantage of the Adjoint method.

> [@yizhang](#):
>
> In that case you’ll going to lose AD from Stan’s solvers

I am sorry but I didn’t understand this point. Which case are you talking about?

> [@yizhang](#):
>
> In terms of adjoint, what is your Lagrangian?

Not very sure, but have a look at page 3 on [this Stanford tutorial](https://cs.stanford.edu/~ambrad/adjoint_tutorial.pdf) which derives adjoint method for ODEs via Lagrangian. As mentioned, we have used the implementation and derivation from [NeuralODE paper](https://arxiv.org/pdf/1806.07366.pdf) (look Appendix B.1 and B.2).

[Previous page](https://discourse.mc-stan.org/t/adjoint-sensitivities/935.md?page=1)
