# Type Stabled Jacobian of a Hessian

**URL:** <https://discourse.julialang.org/t/type-stabled-jacobian-of-a-hessian/134148>\
**Category:** Performance\
**Tags:** forwarddiff, type-stability, autodiff\
**Created:** [November 26, 2025, 6:03pm UTC](https://discourse.julialang.org/t/type-stabled-jacobian-of-a-hessian/134148 "2025-11-26T18:03:25Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![JPCAM](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jpcam/32/219554_2.png) [@JPCAM](https://discourse.julialang.org/u/JPCAM)\
**Post date:** [November 26, 2025, 6:03pm UTC](https://discourse.julialang.org/t/type-stabled-jacobian-of-a-hessian/134148/1 "2025-11-26T18:03:25Z")

</div>

I’ve run into a type-stability issue when trying to compute third-order derivatives with ForwardDiff.

I have a potential function that takes a vector as input. Computing the Hessian with `ForwardDiff.hessian` works well and is entirely type-stable for my use case. However, I also need the _Jacobian of the Hessian_ (i.e. a third-order derivative tensor). Ideally, I would like to construct both a `HessianConfig` and a `JacobianConfig` for the Hessian, so that I can reuse them and keep the cost per evaluation low — this part of the code runs very frequently.

Unfortunately, it seems that nested ForwardDiff calls of this sort are not supported, or at least I haven’t been able to make them type-stable.

Right now my workaround is to cache Hessian configs keyed by input dual types, which avoids repeated allocations, but the resulting Jacobian-of-Hessian function is still type-unstable.

Has anyone found an alternative approach for computing third derivatives efficiently, or a way to make this pattern type-stable? Or is there something fundamental I’m misunderstanding about how ForwardDiff handles nested AD?

Any suggestions or pointers would be appreciated!

---

<div class="post-metadata">

**Author:** ![gdalle](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gdalle/32/27854_2.png) [@gdalle](https://discourse.julialang.org/u/gdalle)\
**Post date:** [November 26, 2025, 6:46pm UTC](https://discourse.julialang.org/t/type-stabled-jacobian-of-a-hessian/134148/2 "2025-11-26T18:46:55Z")

</div>

I have a few ideas but before answering: how big is your problem in terms of input dimension? And how complicated is your function?  
This is meant to figure out whether ForwardDiff is the right framework at all

---

<div class="post-metadata">

**Author:** ![JPCAM](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jpcam/32/219554_2.png) [@JPCAM](https://discourse.julialang.org/u/JPCAM)\
**Post date:** [November 27, 2025, 1:29pm UTC](https://discourse.julialang.org/t/type-stabled-jacobian-of-a-hessian/134148/3 "2025-11-27T13:29:48Z")

</div>

The input dimension can be quite large (depends on user), and this code needs to be general so a user can use whatever potential function they desire.

---

<div class="post-metadata">

**Author:** ![JPCAM](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jpcam/32/219554_2.png) [@JPCAM](https://discourse.julialang.org/u/JPCAM)\
**Post date:** [November 28, 2025, 11:41am UTC](https://discourse.julialang.org/t/type-stabled-jacobian-of-a-hessian/134148/4 "2025-11-28T11:41:28Z")

</div>

Solved: Looking at the ForwardDiff source code, this can be done in a similar way to hessian computation by setting up the configs carefully.

```julia
function gen_∂G∂θ_fwd(Vfunc, x; f=identity)
    chunk = ForwardDiff.Chunk(x)
    tag = ForwardDiff.Tag(Vfunc, eltype(x))
    jac_cfg = ForwardDiff.JacobianConfig(Vfunc, x, chunk, tag)
    hess_cfg = ForwardDiff.HessianConfig(Vfunc, jac_cfg.duals, chunk, tag)

    d = length(x)
    out = zeros(eltype(x), d^2, d)

    function ∂G∂θ_fwd(y)
        hess = z -> ForwardDiff.hessian(Vfunc, z, hess_cfg, Val{false}())
        ForwardDiff.jacobian!(out, hess, y, jac_cfg, Val{false}())
        return out
    end
    
    return ∂G∂θ_fwd
end

```
