API reference
Public
ImplicitDifferentiation.ImplicitDifferentiation
— ModuleImplicitDifferentiation
A Julia package for automatic differentiation of implicit functions.
Its main export is the type ImplicitFunction
.
ImplicitDifferentiation.ImplicitFunction
— TypeImplicitFunction{lazy}
Wrapper for an implicit function defined by a forward mapping y
and a set of conditions c
.
An ImplicitFunction
object behaves like a function, and every call is differentiable with respect to the first argument x
. When a derivative is queried, the Jacobian of y
is computed using the implicit function theorem:
∂/∂y c(x, y(x)) * ∂/∂x y(x) = -∂/∂x c(x, y(x))
This requires solving a linear system A * J = -B
where A = ∂c/∂y
, B = ∂c/∂x
and J = ∂y/∂x
.
Type parameters
lazy::Bool
: whether to representA
andB
with aLinearOperator
from LinearOperators.jl (lazy = true
) or a dense Jacobian matrix (lazy = false
)
Usually, dense Jacobians are more efficient in small dimension, while lazy operators become necessary in high dimension. The value of lazy
must be chosen together with the linear_solver
, see below.
Fields
forward
: a callable computingy(x)
, does not need to be compatible with automatic differentiationconditions
: a callable computingc(x, y)
, must be compatible with automatic differentiationlinear_solver
: a callable to solve the linear systemconditions_x_backend
: defines how the conditions will be differentiated with respect to the first argumentx
conditions_y_backend
: defines how the conditions will be differentiated with respect to the second argumenty
Function signatures
There are two possible signatures for forward
and conditions
, which must be consistent with one another:
standard | byproduct |
---|---|
forward(x, args...; kwargs...) = y | conditions(x, y, args...; kwargs...) = c |
forward(x, args...; kwargs...) = (y, z) | conditions(x, y, z, args...; kwargs...) = c |
In both cases, x
, y
and c
must be AbstractVector
s, with length(y) = length(c)
. In the second case, the byproduct z
can be an arbitrary object generated by forward
. The positional arguments args...
and keyword arguments kwargs...
must be the same for both forward
and conditions
.
The byproduct z
and the other positional arguments args...
beyond x
are considered constant for differentiation purposes.
Linear solver
The provided linear_solver
objects needs to be callable, with two methods:
(A, b::AbstractVector) -> s::AbstractVector
such thatA * s = b
(A, B::AbstractVector) -> S::AbstractMatrix
such thatA * S = B
It can be either a direct solver (like \
) or an iterative one (like KrylovLinearSolver
). Typically, direct solvers work best with dense Jacobians (lazy = false
) while iterative solvers work best with operators (lazy = true
).
Condition backends
The provided conditions_x_backend
and conditions_y_backend
can be either:
- an object subtyping
AbstractADType
from ADTypes.jl; nothing
, in which case the outer backend (the one differentiating through theImplicitFunction
) is used.
ImplicitDifferentiation.ImplicitFunction
— Method(implicit::ImplicitFunction)(x::AbstractVector, args...; kwargs...)
Return implicit.forward(x, args...; kwargs...)
, which can be either an AbstractVector
y
or a tuple (y, z)
.
This call makes y
differentiable with respect to x
.
ImplicitDifferentiation.ImplicitFunction
— MethodImplicitFunction(
forward, conditions;
linear_solver=KrylovLinearSolver(),
conditions_x_backend=nothing,
conditions_x_backend=nothing,
)
Constructor for an ImplicitFunction
which picks the lazy
parameter automatically based on the linear_solver
, using the following heuristic: lazy = linear_solver != \
.
ImplicitDifferentiation.ImplicitFunction
— MethodImplicitFunction{lazy}(
forward, conditions;
linear_solver=lazy ? KrylovLinearSolver() : \,
conditions_x_backend=nothing,
conditions_x_backend=nothing,
)
Constructor for an ImplicitFunction
which picks the linear_solver
automatically based on the lazy
parameter.
Internals
ImplicitDifferentiation.KrylovLinearSolver
— TypeKrylovLinearSolver
Callable object that can solve linear systems As = b
and AS = b
in the same way as the built-in \
. Uses an iterative solver from Krylov.jl under the hood.
Note
This name is not exported, and thus not part of the public API, but it is used in the ImplicitFunction
constructors.
ImplicitDifferentiation.KrylovLinearSolver
— Method(::KrylovLinearSolver)(A, B::AbstractMatrix)
Solve a linear system with multiple right-hand sides.
ImplicitDifferentiation.KrylovLinearSolver
— Method(::KylovLinearSolver)(A, b::AbstractVector)
Solve a linear system with a single right-hand side.