Automatic differentiation¶
Any expression can be differentiated with respect to its variables:
wave::RotationMd R = wave::RotationMd::Random();
wave::Translationd p1 = wave::Translationd::Random();
wave::Translationd p2 = R * p1;
Eigen::Matrix3d J_p2_wrt_R = (R * p1).jacobian(R);
Above, J_p2_wrt_R
is the 3x3 Jacobian of p2 = R * p1
with respect to small changes in R
. wave_geometry computes local Jacobians, which are independent of the choice of parametrization for R
(e.g., rotation matrix or quaternion), and are useful for on-manifold optimization.
It is possible (and more efficient) to combine evaluation and multiple Jacobian calculations:
auto [p2, J_p2_wrt_R, J_p2_wrt_p1] = (R * p1).evalWithJacobians(R, p1);
We can also get all Jacobians at once by providing no arguments:
auto [p2, J_p2_wrt_R, J_p2_wrt_p1] = (R * p1).evalWithJacobians();
Currently, the call .evalWithJacobians(R, p1)
uses forward-mode automatic differentiation while .evalWithJacobians()
uses reverse mode; however, future versions of wave_geometry may simply choose the fastest mode for the arguments given.
wave_geometry’s expression template-based autodiff algorithm produces efficient code which runs nearly as fast as (or in some cases, just as fast as) hand-optimized code for manually-derived derivatives.