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 xIndeed, 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 matrixIn the case where
x.setDerivative(Eigen::Vector3d{1, 1, 1}); // set the tangent vectorIn 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)^TMore complex functions can be formed by defining a variable as the expression of other variables.
AutoDiff::Vector2d y = phi(x); // expression variableThe 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)_pReverse 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