37concept HasResetJacobian =
requires(S
const & space, Eigen::MatrixXd &
block) {
38 space.resetJacobian(
block.col(0),
block.col(0),
block.middleRows(0, 0));
45concept DeclaresIdentityReset =
requires {
requires bool(S::identityReset); };
52template <
typename Blocks>
53struct AllIdentityReset;
56template <
typename... Blocks>
57struct AllIdentityReset<std::tuple<Blocks...>> : std::bool_constant<(identityResetOf<Blocks>() && ...)>
68 if constexpr (DeclaresIdentityReset<S>)
72 else if constexpr (HasResetJacobian<S>)
76 else if constexpr (IsComposite<S>)
78 return AllIdentityReset<CompositeBlocks<S>>::value;
80 else if constexpr (IsRepeated<S>)
82 return identityResetOf<RepeatedBlock<S>>();
111template <
typename Block,
typename X,
typename D,
typename Moved,
typename Out>
115 Eigen::MatrixBase<X>
const & x,
116 Eigen::MatrixBase<D>
const & d,
117 [[maybe_unused]] Eigen::MatrixBase<Moved>
const & moved,
118 Eigen::MatrixBase<Out>
const & out
121 if constexpr (HasResetJacobian<Block>)
123 block.resetJacobian(x, d, out);
127 using Scalar =
typename Out::Scalar;
132 using Dual = Eigen::AutoDiffScalar<Eigen::Matrix<Scalar, K, 1, Eigen::ColMajor, KMax, 1>>;
133 using DualValue = Eigen::Matrix<Dual, V, 1, Eigen::ColMajor, VMax, 1>;
134 using DualDifference = Eigen::Matrix<Dual, K, 1, Eigen::ColMajor, KMax, 1>;
136 auto step = DualDifference{};
138 for (Eigen::Index i = 0; i < k; ++i)
140 step(i) = Dual{Scalar(d(i)), int(k), int(i)};
142 DualValue
const start = x.template cast<Dual>();
143 DualValue
const end = moved.template cast<Dual>();
144 DualValue perturbed = DualValue::Zero(start.size());
145 plusInto(
block, start, step, perturbed);
146 DualDifference error = DualDifference::Zero(k);
147 minusInto(
block, perturbed, end, error);
149 for (Eigen::Index r = 0; r < k; ++r)
154 error(r).derivatives().size() == k &&
"each coordinate of the difference must depend on the step"
156 o.row(r) = error(r).derivatives().transpose();
167template <
typename S,
typename F>
169forEachResetBlock(S
const & space, F && f, Eigen::Index valueOffset = 0, Eigen::Index differenceOffset = 0)
173 else if constexpr (IsComposite<S> && !HasResetJacobian<S>)
175 [&]<std::size_t... I>(std::index_sequence<I...>) {
176 ((forEachResetBlock(space.template
block<I>(), f, valueOffset, differenceOffset),
180 }(std::make_index_sequence<std::tuple_size_v<CompositeBlocks<S>>>{});
182 else if constexpr (IsRepeated<S> && !HasResetJacobian<S>)
184 auto const &
block = space.block();
187 for (Eigen::Index k = 0; k < space.count(); ++k)
189 forEachResetBlock(
block, f, valueOffset + k * values, differenceOffset + k * differences);
194 f(space, valueOffset, differenceOffset);
203template <
typename Cov,
typename G>
205congruence(Eigen::MatrixBase<Cov>
const & cov, Eigen::Index offset, G
const & g)
207 using Scalar =
typename Cov::Scalar;
208 constexpr int K = G::RowsAtCompileTime;
209 constexpr int KMax = G::MaxRowsAtCompileTime;
210 constexpr int N = Cov::ColsAtCompileTime;
211 constexpr int NMax = Cov::MaxColsAtCompileTime;
213 Eigen::Index
const k = g.rows();
214 auto strip = MatrixOf<Scalar, K, N, KMax, NMax>{};
215 strip.resize(k, p.cols());
216 strip.noalias() = multiply(g, middleRowsOf<K>(p, offset, k));
217 middleRowsOf<K>(p, offset, k) = strip;
218 middleColsOf<K>(p, offset, k) = strip.transpose();
219 auto diagonal = MatrixOf<Scalar, K, K, KMax, KMax>{};
220 diagonal.resize(k, k);
221 diagonal.noalias() = multiply(middleColsOf<K>(strip, offset, k), g.transpose());
222 blockOf<K, K>(p, offset, offset, k, k) = Scalar(0.5) * (diagonal + diagonal.transpose());
231template <
bool Inverse = false,
typename S,
typename X,
typename D,
typename Moved,
typename Cov>
235 Eigen::MatrixBase<X>
const & x,
236 Eigen::MatrixBase<D>
const & d,
237 Eigen::MatrixBase<Moved>
const & moved,
238 Eigen::MatrixBase<Cov>
const & cov
246 && cov.cols() ==
differenceDimension(space) &&
"the value, step, and covariance must fit the space"
248 forEachResetBlock(space, [&](
auto const &
block, Eigen::Index values, Eigen::Index differences) {
249 using Block = std::remove_cvref_t<
decltype(
block)>;
250 using Scalar =
typename Cov::Scalar;
256 MatrixOf<Scalar, K, K, KMax, KMax> g = MatrixOf<Scalar, K, K, KMax, KMax>::Zero(k, k);
259 middleRowsOf<V>(x, values, v),
260 middleRowsOf<K>(d, differences, k),
261 middleRowsOf<V>(moved, values, v),
264 if constexpr (Inverse)
266 using Matrix = MatrixOf<Scalar, K, K, KMax, KMax>;
267 g = inverseFrom<Matrix>(Eigen::PartialPivLU<Matrix>{g});
269 congruence(cov, differences, g);
280template <
typename S,
typename X,
typename D,
typename Moved,
typename F>
282forEachInverseResetJacobian(
284 Eigen::MatrixBase<X>
const & x,
285 Eigen::MatrixBase<D>
const & d,
286 Eigen::MatrixBase<Moved>
const & moved,
296 forEachResetBlock(space, [&](
auto const &
block, Eigen::Index values, Eigen::Index differences) {
297 using Block = std::remove_cvref_t<
decltype(
block)>;
298 using Scalar =
typename X::Scalar;
304 MatrixOf<Scalar, K, K, KMax, KMax> g = MatrixOf<Scalar, K, K, KMax, KMax>::Zero(k, k);
307 middleRowsOf<V>(x, values, v),
308 middleRowsOf<K>(d, differences, k),
309 middleRowsOf<V>(moved, values, v),
312 using Matrix = MatrixOf<Scalar, K, K, KMax, KMax>;
313 g = inverseFrom<Matrix>(Eigen::PartialPivLU<Matrix>{g});
329template <
typename S,
typename X,
typename D,
typename Moved,
typename Info,
typename Vector>
333 Eigen::MatrixBase<X>
const & x,
334 Eigen::MatrixBase<D>
const & d,
335 Eigen::MatrixBase<Moved>
const & moved,
336 Eigen::MatrixBase<Info>
const & info,
337 Eigen::MatrixBase<Vector>
const & vector
340 forEachInverseResetJacobian(space, x, d, moved, [&](Eigen::Index differences,
auto const & gInverse) {
341 using GInverse = std::remove_cvref_t<
decltype(gInverse)>;
342 GInverse
const gInverseTransposed = gInverse.transpose();
343 congruence(info, differences, gInverseTransposed);
345 Eigen::Index
const k = gInverse.rows();
346 middleRowsOf<GInverse::RowsAtCompileTime>(eta, differences, k) =
347 gInverseTransposed * middleRowsOf<GInverse::RowsAtCompileTime>(eta, differences, k);
375template <Space S,
typename XDerived,
typename DDerived>
377resetJacobian(S
const & space, Eigen::MatrixBase<XDerived>
const & x, Eigen::MatrixBase<DDerived>
const & d)
379 using Scalar =
typename XDerived::Scalar;
383 auto result = internal::MatrixOf<Scalar, N, N, NMax, NMax>{};
384 result.setIdentity(n, n);
388 internal::forEachResetBlock(space, [&](
auto const &
block, Eigen::Index values, Eigen::Index differences) {
389 using Block = std::remove_cvref_t<
decltype(
block)>;
394 internal::blockResetJacobian(
396 internal::middleRowsOf<V>(x, values, v),
397 internal::middleRowsOf<K>(d, differences, k),
398 internal::middleRowsOf<V>(moved, values, v),
399 internal::blockOf<K, K>(result, differences, differences, k, k)
424template <Space S,
typename XDerived,
typename DDerived,
typename CovDerived>
428 Eigen::MatrixBase<XDerived>
const & x,
429 Eigen::MatrixBase<DDerived>
const & d,
430 Eigen::MatrixBase<CovDerived>
const & cov
436 internal::resetCovarianceAt(space, x, d, moved, cov);
Spaces built from other spaces (decisions.md [sizes-and-dimensions], [several-resizable-blocks]): Com...
The macros every header includes first.
Mathematical constants and scalar functions that work in every scalar type the library accepts,...
Products of fixed-size matrices by Eigen's fixed-size product at every size: multiply() is by Eigen'...
Solving by a factorization of a small matrix: transposedSolve() gives , the shape of a Kalman gain an...
The Space concept and what every continuous space shares (decisions.md [sizes-and-dimensions]): the t...
Eigen::Index valueDimension(S const &space)
Definition Space.h:272
auto plus(S const &space, Eigen::MatrixBase< XDerived > const &x, Eigen::MatrixBase< DDerived > const &d)
Definition Space.h:675
Eigen::MatrixBase< Derived > & writable(Eigen::MatrixBase< Derived > const &block)
block, writable: Eigen's idiom for a function that writes through an expression passed as const&.
Definition Space.h:389
auto block(Space auto const &space, X &&x)
Definition TagPath.h:979
auto resetJacobian(S const &space, Eigen::MatrixBase< XDerived > const &x, Eigen::MatrixBase< DDerived > const &d)
Definition Reset.h:377
constexpr bool hasIdentityReset
Whether the reset Jacobian of S is the identity, so that a covariance needs no change when its mean m...
Definition Reset.h:100
Eigen::Index differenceDimension(S const &space)
Definition Space.h:284
void resetCovariance(S const &space, Eigen::MatrixBase< XDerived > const &x, Eigen::MatrixBase< DDerived > const &d, Eigen::MatrixBase< CovDerived > const &cov)
Carries the covariance cov from the tangent space at x to the one at , in place: ,...
Definition Reset.h:426
constexpr int valueDimensionAtCompileTime
The value dimension of Space at compile time, or Eigen::Dynamic if it is resizable.
Definition Space.h:251
constexpr int maxValueDimensionAtCompileTime
The largest valid value dimension of Space, or Eigen::Dynamic if it is unbounded.
Definition Space.h:258