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.DiffResult
— Type.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 Number
s or SArray
s, 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...)
.
DiffResults.JacobianResult
— Function.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.
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
.
DiffResults.GradientResult
— Function.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.
DiffResults.HessianResult
— Function.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.
Accessing data from a DiffResult
DiffResults.value
— Function.value(r::DiffResult)
Return the primal value stored in r
.
Note that this method returns a reference, not a copy.
DiffResults.derivative
— Function.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.
DiffResults.gradient
— Function.gradient(r::DiffResult)
Return the gradient stored in r
.
Equivalent to derivative(r, Val{1})
.
DiffResults.jacobian
— Function.jacobian(r::DiffResult)
Return the Jacobian stored in r
.
Equivalent to derivative(r, Val{1})
.
DiffResults.hessian
— Function.hessian(r::DiffResult)
Return the Hessian stored in r
.
Equivalent to derivative(r, Val{2})
.
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)
.
value!(f, r::DiffResult, x)
Equivalent to value!(r::DiffResult, map(f, x))
, but without the implied temporary allocation (when possible).
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})
.
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).
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.
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.
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.
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.
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.
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.