# Fast f(x) ∂f∂x and ∂2f∂x2

**URL:** <https://discourse.julialang.org/t/fast-f-x-f-x-and-2f-x2/65569>\
**Category:** Performance\
**Tags:** autodiff\
**Created:** [July 30, 2021, 8:30pm UTC](https://discourse.julialang.org/t/fast-f-x-f-x-and-2f-x2/65569 "2021-07-30T20:30:51Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![longemen3000](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/longemen3000/32/7298_2.png) [@longemen3000](https://discourse.julialang.org/u/longemen3000)\
**Post date:** [July 30, 2021, 8:30pm UTC](https://discourse.julialang.org/t/fast-f-x-f-x-and-2f-x2/65569/1 "2021-07-30T20:30:51Z")

</div>

Hi, im trying to make a fast evaluation of the value, first and second derivative, in the least amount of forward passes as possible. i’m using at the moment this function:

```julia
using DiffResults, StaticArrays, ForwardDiff
function f∂f∂2f(f,x::T) where T
    _f(z) = f(only(z))
    x_vec = SVector(x)
    ∂result = DiffResults.HessianResult(x_vec)  
    _∂f = ForwardDiff.hessian!(∂result, _f,x_vec)
    fx = DiffResults.value(_∂f)
    ∂f∂x = only(DiffResults.gradient(_∂f))
    ∂²f∂²x = only(DiffResults.hessian(_∂f))
    return fx,∂f∂x,∂²f∂²x
end

```

but, even as everything seems defined statically, this function allocates:

```julia
julia> @btime f∂f∂2f(sin,$Ref(2.0)[])
  78.189 ns (1 allocation: 96 bytes)
(0.9092974268256817, -0.4161468365471424, -0.9092974268256817)

```

the same version, but only obtaining the first derivative, doesn’t allocate:

```julia
function f∂f(f,x::T) where T
    _f(z) = f(only(z))
    x_vec = SVector(x)
    ∂result = DiffResults.GradientResult(x_vec)  
    _∂f = ForwardDiff.gradient!(∂result, _f,x_vec)
    fx = DiffResults.value(_∂f)
    ∂f∂x = only(DiffResults.gradient(_∂f))
    return fx,∂f∂x
end

```

```julia
>julia @btime f∂f(sin,$Ref(2.0)[])
16.116 ns (0 allocations: 0 bytes)
(0.9092974268256817, -0.4161468365471424)

```

any idea on how to improve the situation here?

---

<div class="post-metadata">

**Author:** ![Skoffer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/skoffer/32/378_2.png) [@Skoffer](https://discourse.julialang.org/u/Skoffer)\
**Post date:** [July 30, 2021, 8:43pm UTC](https://discourse.julialang.org/t/fast-f-x-f-x-and-2f-x2/65569/2 "2021-07-30T20:43:07Z")

</div>

This is experimental now, but maybe you want to try another AD?

```julia
using Diffractor
using BenchmarkTools

function fdfd2f(f, x)
    let var"'" = Diffractor.PrimeDerivativeFwd
        fx = f(x)
        dfx = f'(x)
        d2fx = f''(x)
        return fx, dfx, d2fx
    end
end

julia> @btime fdfd2f(sin, $Ref(2.0)[])
  33.272 ns (0 allocations: 0 bytes)
(0.9092974268256817, -0.4161468365471424, -0.9092974268256817)

```

---

<div class="post-metadata">

**Author:** ![longemen3000](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/longemen3000/32/7298_2.png) [@longemen3000](https://discourse.julialang.org/u/longemen3000)\
**Post date:** [July 30, 2021, 8:45pm UTC](https://discourse.julialang.org/t/fast-f-x-f-x-and-2f-x2/65569/3 "2021-07-30T20:45:37Z")

</div>

> [@Skoffer](#):
>
> ```julia
> function fdfd2f(f, x)
> let var"'" = Diffractor.PrimeDerivativeFwd
> fx = f(x)
> dfx = f'(x)
> d2fx = f''(x)
> return fx, dfx, d2fx
> end
> end
> 
> ```

interesting, but i’m stuck with ForwardDiff for now, as i have to differenciate through functions with mutation, and i dont have the rrules defined for those

---

<div class="post-metadata">

**Author:** ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)\
**Post date:** [July 30, 2021, 8:48pm UTC](https://discourse.julialang.org/t/fast-f-x-f-x-and-2f-x2/65569/4 "2021-07-30T20:48:35Z")

</div>

I believe Difractor can deal with mutation.

---

<div class="post-metadata">

**Author:** ![oxinabox](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oxinabox/32/206603_2.png) [@oxinabox](https://discourse.julialang.org/u/oxinabox)\
**Post date:** [July 30, 2021, 8:55pm UTC](https://discourse.julialang.org/t/fast-f-x-f-x-and-2f-x2/65569/5 "2021-07-30T20:55:17Z")

</div>

not in reverse mode.  
but i think, yes, in forwards mode

---

<div class="post-metadata">

**Author:** ![longemen3000](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/longemen3000/32/7298_2.png) [@longemen3000](https://discourse.julialang.org/u/longemen3000)\
**Post date:** [July 30, 2021, 9:51pm UTC](https://discourse.julialang.org/t/fast-f-x-f-x-and-2f-x2/65569/6 "2021-07-30T21:51:55Z")

</div>

how can i ask difractor to do Forward over Forward in that case?
