API reference
Index
ImplicitDifferentiation.ImplicitDifferentiation
ImplicitDifferentiation.AbstractLinearSolver
ImplicitDifferentiation.DirectLinearSolver
ImplicitDifferentiation.ImplicitFunction
ImplicitDifferentiation.ImplicitFunction
ImplicitDifferentiation.ImplicitFunction
ImplicitDifferentiation.IterativeLinearSolver
ChainRulesCore.rrule
Docstrings
ImplicitDifferentiation.ImplicitDifferentiation
— ModuleImplicitDifferentiation
A Julia package for automatic differentiation of implicit functions.
Its main export is the type ImplicitFunction
.
ImplicitDifferentiation.AbstractLinearSolver
— TypeAbstractLinearSolver
All linear solvers used within an ImplicitFunction
must satisfy this interface.
It can be useful to roll out your own solver if you need more fine-grained control on convergence / speed / behavior in case of singularity. Check out the source code of IterativeLinearSolver
and DirectLinearSolver
for implementation examples.
Required methods
presolve(linear_solver, A, y)
: Returns a matrix-like objectA
for which it is cheaper to solve several linear systems with different vectorsb
(a typical example would be to perform LU factorization).solve(linear_solver, A, b)
: Returns a vectorx
satisfyingAx = b
. If the linear system has not been solved to satisfaction, every element ofx
should be aNaN
of the appropriate floating point type.
ImplicitDifferentiation.DirectLinearSolver
— TypeDirectLinearSolver
An implementation of AbstractLinearSolver
using the built-in backslash operator.
Fields
verbose::Bool
: Whether to throw a warning when the solver fails (defaults totrue
)
ImplicitDifferentiation.ImplicitFunction
— TypeImplicitFunction{F,C,L,B}
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
.
Fields
forward::F
: a callable, does not need to be compatible with automatic differentiationconditions::C
: a callable, must be compatible with automatic differentiationlinear_solver::L
: a subtype ofAbstractLinearSolver
, defines how the linear system will be solvedconditions_backend::B
: eithernothing
or a subtype ofAbstractDifferentiation.AbstractBackend
, defines how the conditions will be differentiated within the implicit function theorem
There are two possible signatures for forward
and conditions
, which must be consistent with one another:
- Standard:
forward(x, args...; kwargs...) = y
andconditions(x, y, args...; kwargs...) = c
- Byproduct:
forward(x, args...; kwargs...) = (y, z)
andconditions(x, y, z, args...; kwargs...) = c
.
In both cases, x
, y
and c
must be arrays, with size(y) = size(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.
ImplicitDifferentiation.ImplicitFunction
— Method(implicit::ImplicitFunction)(x::AbstractArray, args...; kwargs...)
Return implicit.forward(x, args...; kwargs...)
, which can be either an array y
or a tuple (y, z)
.
This call is differentiable.
ImplicitDifferentiation.ImplicitFunction
— MethodImplicitFunction(
+ forward,
+ conditions;
+ linear_solver=IterativeLinearSolver(),
+ conditions_backend=nothing,
+)
Construct an ImplicitFunction
with default parameters.
ImplicitDifferentiation.IterativeLinearSolver
— TypeIterativeLinearSolver
An implementation of AbstractLinearSolver
using Krylov.gmres
.
Fields
verbose::Bool
: Whether to throw a warning when the solver fails (defaults totrue
)
ChainRulesCore.rrule
— Functionrrule(rc, implicit, x, args...; kwargs...)
Custom reverse rule for an ImplicitFunction
, to ensure compatibility with reverse mode autodiff.
This is only available if ChainRulesCore.jl is loaded (extension), except on Julia < 1.9 where it is always available.
We compute the vector-Jacobian product Jᵀv
by solving Aᵀu = v
and setting Jᵀv = -Bᵀu
. Positional and keyword arguments are passed to both implicit.forward
and implicit.conditions
.