DiffResults

Many differentiation techniques can calculate primal values and multiple orders of derivatives simultaneously. In other words, there are techniques for computing f(x), ∇f(x) and H(f(x)) in one fell swoop!

For this purpose, DiffResults provides the DiffResult type, which can be passed to in-place differentiation methods instead of an output buffer. The method then loads all computed results into the given DiffResult, which the user can then query afterwards.

Here's an example of DiffResult in action using ForwardDiff:

julia> using ForwardDiff, DiffResults

julia> f(x) = sum(sin, x) + prod(tan, x) * sum(sqrt, x);

julia> x = rand(4);

# construct a `DiffResult` with storage for a Hessian, gradient,
# and primal value based on the type and shape of `x`.
julia> result = DiffResults.HessianResult(x)

# Instead of passing an output buffer to `hessian!`, we pass `result`.
# Note that we re-alias to `result` - this is important! See `hessian!`
# docs for why we do this.
julia> result = ForwardDiff.hessian!(result, f, x);

# ...and now we can get all the computed data from `result`
julia> DiffResults.value(result) == f(x)
true

julia> DiffResults.gradient(result) == ForwardDiff.gradient(f, x)
true

julia> DiffResults.hessian(result) == ForwardDiff.hessian(f, x)
true

The rest of this document describes the API for constructing, accessing, and mutating DiffResult instances. For details on how to use a DiffResult with a specific package's methods, please consult that package's documentation.

Constructing a DiffResult

DiffResults.DiffResultType
DiffResult(value::Union{Number,AbstractArray}, derivs::Tuple{Vararg{Number}})
DiffResult(value::Union{Number,AbstractArray}, derivs::Tuple{Vararg{AbstractArray}})

Return r::DiffResult, with output value storage provided by value and output derivative storage provided by derivs.

In reality, DiffResult is an abstract supertype of two concrete types, MutableDiffResult and ImmutableDiffResult. If all value/derivs are all Numbers or StaticArrays, then r will be immutable (i.e. r::ImmutableDiffResult). Otherwise, r will be mutable (i.e. r::MutableDiffResult).

Note that derivs can be provide in splatted form, i.e. DiffResult(value, derivs...).

source
DiffResults.JacobianResultFunction
JacobianResult(x::AbstractArray)

Construct a DiffResult that can be used for Jacobian calculations where x is the input to the target function. This method assumes that the target function's output dimension equals its input dimension.

Note that JacobianResult allocates its own storage; x is only used for type and shape information. If you want to allocate storage yourself, use the DiffResult constructor instead.

source
JacobianResult(y::AbstractArray, x::AbstractArray)

Construct a DiffResult that can be used for Jacobian calculations where x is the input to the target function, and y is the output (e.g. when taking the Jacobian of f!(y, x)).

Like the single argument version, y and x are only used for type and shape information and are not stored in the returned DiffResult.

source
DiffResults.GradientResultFunction
GradientResult(x::AbstractArray)

Construct a DiffResult that can be used for gradient calculations where x is the input to the target function.

Note that GradientResult allocates its own storage; x is only used for type and shape information. If you want to allocate storage yourself, use the DiffResult constructor instead.

source
DiffResults.HessianResultFunction
HessianResult(x::AbstractArray)

Construct a DiffResult that can be used for Hessian calculations where x is the input to the target function.

Note that HessianResult allocates its own storage; x is only used for type and shape information. If you want to allocate storage yourself, use the DiffResult constructor instead.

source

Accessing data from a DiffResult

DiffResults.valueFunction
value(r::DiffResult)

Return the primal value stored in r.

Note that this method returns a reference, not a copy.

source
DiffResults.derivativeFunction
derivative(r::DiffResult, ::Type{Val{i}} = Val{1})

Return the ith derivative stored in r, defaulting to the first derivative.

Note that this method returns a reference, not a copy.

source
DiffResults.gradientFunction
gradient(r::DiffResult)

Return the gradient stored in r.

Equivalent to derivative(r, Val{1}).

source
DiffResults.jacobianFunction
jacobian(r::DiffResult)

Return the Jacobian stored in r.

Equivalent to derivative(r, Val{1}).

source
DiffResults.hessianFunction
hessian(r::DiffResult)

Return the Hessian stored in r.

Equivalent to derivative(r, Val{2}).

source

Mutating a DiffResult

DiffResults.value!Function
value!(r::DiffResult, x)

Return s::DiffResult with the same data as r, except for value(s) == x.

This function may or may not mutate r. If r::ImmutableDiffResult, a totally new instance will be created and returned, whereas if r::MutableDiffResult, then r will be mutated in-place and returned. Thus, this function should be called as r = value!(r, x).

source
value!(f, r::DiffResult, x)

Equivalent to value!(r::DiffResult, map(f, x)), but without the implied temporary allocation (when possible).

source
DiffResults.derivative!Function
derivative!(r::DiffResult, x, ::Type{Val{i}} = Val{1})

Return s::DiffResult with the same data as r, except derivative(s, Val{i}) == x.

This function may or may not mutate r. If r::ImmutableDiffResult, a totally new instance will be created and returned, whereas if r::MutableDiffResult, then r will be mutated in-place and returned. Thus, this function should be called as r = derivative!(r, x, Val{i}).

source
derivative!(f, r::DiffResult, x, ::Type{Val{i}} = Val{1})

Equivalent to derivative!(r::DiffResult, map(f, x), Val{i}), but without the implied temporary allocation (when possible).

source
DiffResults.gradient!Function
gradient!(r::DiffResult, x)

Return s::DiffResult with the same data as r, except gradient(s) == x.

Equivalent to derivative!(r, x, Val{1}); see derivative! docs for aliasing behavior.

source
gradient!(f, r::DiffResult, x)

Equivalent to gradient!(r::DiffResult, map(f, x)), but without the implied temporary allocation (when possible).

Equivalent to derivative!(f, r, x, Val{1}); see derivative! docs for aliasing behavior.

source
DiffResults.jacobian!Function
jacobian!(r::DiffResult, x)

Return s::DiffResult with the same data as r, except jacobian(s) == x.

Equivalent to derivative!(r, x, Val{1}); see derivative! docs for aliasing behavior.

source
jacobian!(f, r::DiffResult, x)

Equivalent to jacobian!(r::DiffResult, map(f, x)), but without the implied temporary allocation (when possible).

Equivalent to derivative!(f, r, x, Val{1}); see derivative! docs for aliasing behavior.

source
DiffResults.hessian!Function
hessian!(r::DiffResult, x)

Return s::DiffResult with the same data as r, except hessian(s) == x.

Equivalent to derivative!(r, x, Val{2}); see derivative! docs for aliasing behavior.

source
hessian!(f, r::DiffResult, x)

Equivalent to hessian!(r::DiffResult, map(f, x)), but without the implied temporary allocation (when possible).

Equivalent to derivative!(f, r, x, Val{2}); see derivative! docs for aliasing behavior.

source