Tip
For more detailed mathematical background on differentiation, see Automatic differentiation and differential geometry.
The Variable
class in AutoDiff uses mathematical function notation for the getters of value and derivative.
Real x; // create a variable
x(); // get the value of x
d(x); // get the derivative of x
Indeed, depending on the current evaluation mode (forward or reverse), a variable in AutoDiff can be interpreted precisely as a particular mathematical function.
Forward mode is used when you call evaluate
or pushTangent
on a Function
object.
In this context, a literal variable
AutoDiff::Vector3d x;
is a smooth function
on a smooth manifold
By setting the value of the variable
x = Eigen::Vector3d{1, 2, 3};
we are setting
x(); // returns x(p) = (1, 2, 3)
Because
x.setDerivative(Eigen::Matrix3d::Identity()); // set the Jacobian matrix
In the case where
x.setDerivative(Eigen::Vector3d{1, 1, 1}); // set the tangent vector
In differential geometry, the derivative (also called differential) is sometimes written as d
operator returns the differential of a variable evaluated at
d(x); // returns d(x)_p = (1, 1, 1)^T
More complex functions can be formed by defining a variable as the expression of other variables.
AutoDiff::Vector2d y = phi(x); // expression variable
The expression variable y
represents the composition of two functions,
Like before, the variable y
can be evaluated as function, where
y(); // returns y(p) = ϕ(x(p)) = ϕ((1, 2, 3))
Automatic differentiation builds on the chain rule, which states that the differential of a composite is the composite of the differentials,
In AutoDiff, calling pushTangent
on a Function
instance applies the chain rule and computes the differential of the variable y
by composing the derivatives from right to left.
AutoDiff::Function f(from(x), to(y))
f.pushTangent(); // applies the chain rule
d(x); // returns d(x)_p
d(y); // returns d(y)_p = d(ϕ)_{x(p)} ∘ d(x)_p
Reverse mode is used when you call pullGradient
on a Function
object.
In reverse mode, the same variables are interpreted as different mathematical functions.
The output variable y
is now the function
mapping the value
In the case where
y.setDerivative(Eigen::RowVector2d{1, 1}); // set the cotangent vector
d(y); // returns d(ŷ) = (1, 1)
The variable x
is now associated with the composition
with
Reverse-mode automatic differentiation uses again the chain rule to compute the gradient of
When calling pullGradient
on a Function
instance, the chain rule is applied and the gradients are computed by composing the derivatives from left to right, i.e., in the reverse order of evaluation.
f.pullGradient(y); // applies the chain rule
d(x); // returns d(x^)_{x(p)}
Tip
The discussion above also extends to binary expressions. In this case, the domain is the Cartesian product of the domains of the two inputs.
The derivative