81 using Result =
decltype(std::apply(f, x));
82 using Scalar = ::smooth::Scalar<Result>;
86 Result fval = std::apply(f, x);
88 static constexpr Eigen::Index Nx = wrt_Dof<decltype(x)>();
89 static constexpr Eigen::Index Ny = Dof<Result>;
90 const Eigen::Index nx = std::apply([](
auto &&... args) {
return (
dof(args) + ...); }, x);
91 const Eigen::Index ny = dof<Result>(fval);
93 static_assert(Nx > 0,
"Ceres autodiff does not support dynamic sizes");
95 Eigen::Matrix<Scalar, Nx, 1> a = Eigen::Matrix<Scalar, Nx, 1>::Zero(nx);
96 Eigen::Matrix<Scalar, Ny, 1> b(ny);
97 Eigen::Matrix<
Scalar, Ny, Nx, (Nx == 1) ? Eigen::ColMajor : Eigen::RowMajor> jac(ny, nx);
100 const auto f_deriv = [&]<
typename T>(
const T * in, T * out) {
101 Eigen::Map<const Eigen::Matrix<T, Nx, 1>> mi(in, nx);
102 Eigen::Map<Eigen::Matrix<T, Ny, 1>> mo(out, ny);
103 mo = rminus<CastT<T, Result>>(std::apply(f, wrt_rplus(wrt_cast<T>(x), mi)), cast<T, Result>(fval));
106 const Scalar * a_ptr[1] = {a.data()};
107 Scalar * jac_ptr[1] = {jac.data()};
109 ceres::internal::AutoDifferentiate<Dof<Result>, ceres::internal::StaticParameterDims<Nx>>(
110 f_deriv, a_ptr,
static_cast<int>(b.size()), b.data(), jac_ptr);
112 return std::make_pair(std::move(fval), Eigen::Matrix<Scalar, Ny, Nx>(jac));
ceres::AutoDiffManifold< CeresParamFunctor< G >, G::RepSize, G::Dof > CeresLocalParameterization
Parameterization for on-manifold optimization with Ceres.