# Best method for (scalar) second derivative with ForwardDiff

**URL:** <https://discourse.julialang.org/t/best-method-for-scalar-second-derivative-with-forwarddiff/95039>\
**Category:** Performance\
**Tags:** forwarddiff\
**Created:** [February 22, 2023, 7:13pm UTC](https://discourse.julialang.org/t/best-method-for-scalar-second-derivative-with-forwarddiff/95039 "2023-02-22T19:13:00Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![fph](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fph/32/17159_2.png) [@fph](https://discourse.julialang.org/u/fph)\
**Post date:** [February 22, 2023, 7:13pm UTC](https://discourse.julialang.org/t/best-method-for-scalar-second-derivative-with-forwarddiff/95039/1 "2023-02-22T19:13:00Z")

</div>

What is the best/most efficient method to find the first two derivatives of a scalar function with ForwardDiff?

[This old post](https://discourse.julialang.org/t/how-to-find-second-and-third-derivative-using-forwarddiff/20964) suggests

```
ForwardDiff.derivative(x -> ForwardDiff.derivative(f, x), 1.0)

```

to compute the second derivative but that sounds inefficient, thinking about the algebraic structure of the computation. I’d like to get the first derivative as well using the `DiffResults` API, and this looks like a mess to do in this format with nested calls.

Alternatively, I can wrap everything in a vector and use

```
ForwardDiff.hessian(x -> f(x[1]), [x])

```

but I am not sure about the impact of extra vector allocations.

Is there a better builtin method already implemented in the package? The [source](https://github.com/JuliaDiff/DiffResults.jl/blob/master/src/DiffResults.jl) of `DiffResults` suggests that it supports higher derivatives natively, but I don’t see anything corresponding in ForwardDiff, so maybe the API is there but not the implementation.

Thanks in advance for any help!

---

<div class="post-metadata">

**Author:** ![mikmoore](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mikmoore/32/31109_2.png) [@mikmoore](https://discourse.julialang.org/u/mikmoore)\
**Post date:** [February 23, 2023, 4:10pm UTC](https://discourse.julialang.org/t/best-method-for-scalar-second-derivative-with-forwarddiff/95039/2 "2023-02-23T16:10:17Z")

</div>

I haven’t delved into this in a bit. I believe you’re looking to call [`ForwardDiff.hessian!`](https://juliadiff.org/ForwardDiff.jl/stable/user/api/#ForwardDiff.hessian!) with a [`DiffResults.HessianResult`](https://juliadiff.org/DiffResults.jl/stable/#DiffResults.HessianResult) object to compute multiple derivatives simultaneously.

If the scalar/vector distinction is causing issues, you can always use `SVector(x)` from the `StaticArrays` package to create a 1-element vector (or small-ish vectors, in general) with virtually no overhead. These play well with these autodiff packages.

```julia-repl
julia> using DiffResults, ForwardDiff, StaticArrays

julia> x = SVector(1.0)
1-element SVector{1, Float64} with indices SOneTo(1):
 1.0

julia> res = DiffResults.HessianResult(x)
ImmutableDiffResult(1.0, ([1.0], [0.0;;]))

julia> ForwardDiff.hessian!(res,z->sin(only(z)),x)
ImmutableDiffResult(0.8414709848078965, ([0.5403023058681398], [-0.8414709848078965;;]))

```

Note that I used `sin(only(z))` instead of `sin(z)` to extract the one element from the vector input.

---

<div class="post-metadata">

**Author:** ![fph](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fph/32/17159_2.png) [@fph](https://discourse.julialang.org/u/fph)\
**Post date:** [February 23, 2023, 4:51pm UTC](https://discourse.julialang.org/t/best-method-for-scalar-second-derivative-with-forwarddiff/95039/3 "2023-02-23T16:51:24Z")

</div>

Many thanks; this works and it seems like a good solution!

In the meantime I have also found an [open issue](https://github.com/JuliaDiff/ForwardDiff.jl/issues/187) on Github from 2017 for an API to compute higher scalar derivatives, so I assume there is still nothing implemented natively in ForwardDiff.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [February 23, 2023, 5:00pm UTC](https://discourse.julialang.org/t/best-method-for-scalar-second-derivative-with-forwarddiff/95039/4 "2023-02-23T17:00:02Z")

</div>

> [@fph](#):
>
> [This old post](https://discourse.julialang.org/t/how-to-find-second-and-third-derivative-using-forwarddiff/20964) suggests
> 
> ```julia
> ForwardDiff.derivative(x -> ForwardDiff.derivative(f, x), 1.0)
> 
> ```
> 
> to compute the second derivative but that sounds inefficient

What do you think `ForwardDiff.hessian` does? It works in exactly the same way, by [computing the Jacobian of the gradient](https://github.com/JuliaDiff/ForwardDiff.jl/blob/4b143a199f541e7c1248dc5bc29b397be938e81d/src/hessian.jl#L14-L19).

---

<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 23, 2023, 5:04pm UTC](https://discourse.julialang.org/t/best-method-for-scalar-second-derivative-with-forwarddiff/95039/5 "2023-02-23T17:04:23Z")

</div>

For higher order derivatives like this, you may want to try TaylorDiff.jl which has optimizations for this kind of case.

> **[GitHub - JuliaDiff/TaylorDiff.jl: Taylor-mode automatic differentiation for...](https://github.com/JuliaDiff/TaylorDiff.jl)**
>
> Taylor-mode automatic differentiation for higher-order derivatives - GitHub - JuliaDiff/TaylorDiff.jl: Taylor-mode automatic differentiation for higher-order derivatives

It’s built on the same underpinning as ForwardDiff.jl with optimizations for how it goes to higher order.
