You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
If I have a function f(x::Real)::Real I have two options for computing f(x), f'(x), f''(x):
using ForwardDiff, DiffResults, StaticArrays, BenchmarkTools
functioncomputehessian(f, x::AbstractArray)
result = DiffResults.HessianResult(x)
result = ForwardDiff.hessian!(result, f, x)
return DiffResults.value(result), DiffResults.gradient(result), DiffResults.hessian(result)
endcomputehessian(f, x::T) where T <:Number=map(first, computehessian(f ∘ first, SVector{1, T}(x)))
functioncomputehessian2(f, x)
df(x) = ForwardDiff.derivative(f, x)
d2f(x) = ForwardDiff.derivative(df, x)
return (f(x), df(x), d2f(x))
end
x =rand()
w =rand()
s1 =rand()
s2 =rand()
f(w, s1, s2, x) =log(w * s1 *exp(-0.5* x * s1 ^2) + (1-w) * s2 *exp(-0.5* x * s2 ^2))
expandfunc(args, v) = args[1](args[2:end]..., v)
fixallbutlast(func, args...) = Base.Fix1(expandfunc, (func, args...))
g =fixallbutlast(f, w, s1, s2)
@btimecomputehessian($g, $x)
@btimecomputehessian2($g, $x)
69.075 ns (1 allocation:64 bytes)
83.289 ns (0 allocations:0 bytes)
The first approach, using the hessian! function, is faster because the value, 1st and 2nd derivatives can all be computed with a single call to f (using a DiffResult structure), whereas the second approach requires 4 calls of f to perform the same calculation. If f is slow, then the second approach is much worse. However, the first approach doesn't support scalar x::T (where T <: Number), requiring a wrapper to get around this. Furthermore, it causes an allocation, making the calculation slower than necessary.
Is it possible to implement the functionality of hessian! with a DiffResult input, but for scalar x? If so, is it possible to avoid the allocation (assuming f doesn't allocate)?
The text was updated successfully, but these errors were encountered:
If I have a function
f(x::Real)::Real
I have two options for computingf(x), f'(x), f''(x)
:The first approach, using the
hessian!
function, is faster because the value, 1st and 2nd derivatives can all be computed with a single call tof
(using aDiffResult
structure), whereas the second approach requires 4 calls off
to perform the same calculation. Iff
is slow, then the second approach is much worse. However, the first approach doesn't support scalarx::T
(whereT <: Number
), requiring a wrapper to get around this. Furthermore, it causes an allocation, making the calculation slower than necessary.Is it possible to implement the functionality of
hessian!
with aDiffResult
input, but for scalarx
? If so, is it possible to avoid the allocation (assumingf
doesn't allocate)?The text was updated successfully, but these errors were encountered: