gtsam
Loading...
Searching...
No Matches
ProductLieGroup.h
Go to the documentation of this file.
1/* ----------------------------------------------------------------------------
2
3 * GTSAM Copyright 2010, Georgia Tech Research Corporation,
4 * Atlanta, Georgia 30332-0415
5 * All Rights Reserved
6 * Authors: Frank Dellaert, et al. (see THANKS for the full author list)
7
8 * See LICENSE for the license information
9
10 * -------------------------------------------------------------------------- */
11
20
21#pragma once
22
23#include <gtsam/base/Lie.h>
24#include <gtsam/base/Testable.h>
25
26#include <algorithm>
27#include <array>
28#include <iostream>
29#include <stdexcept>
30#include <string>
31#include <type_traits>
32#include <utility> // pair
33#include <vector>
34
35namespace gtsam {
36
37namespace internal {
38
47template <typename T>
48struct ProductLieGroupIsVector : std::false_type {};
49template <int N>
50struct ProductLieGroupIsVector<Eigen::Matrix<double, N, 1>> : std::true_type {};
51
52} // namespace internal
53
64template <typename G, typename H>
66 : public std::pair<G, H>,
67 public LieGroup<ProductLieGroup<G, H>,
68 internal::dimensionSum(traits<G>::dimension,
69 traits<H>::dimension)> {
70 GTSAM_CONCEPT_ASSERT(IsLieGroup<G>);
71 GTSAM_CONCEPT_ASSERT(IsLieGroup<H>);
72 GTSAM_CONCEPT_ASSERT(IsTestable<G>);
73 GTSAM_CONCEPT_ASSERT(IsTestable<H>);
74
75 public:
76 using This = ProductLieGroup<G, H>;
78 using Base = std::pair<G, H>;
81
82 protected:
84 inline constexpr static int n = traits<G>::dimension;
85 inline constexpr static int m = traits<H>::dimension;
86 inline constexpr static bool firstDynamic = n == Eigen::Dynamic;
87 inline constexpr static bool secondDynamic = m == Eigen::Dynamic;
88
89 public:
90 using LieBase::Dim;
91 using LieBase::dimension;
92 using TangentVector = typename LieBase::TangentVector;
93 using ChartJacobian = typename LieBase::ChartJacobian;
94 using Jacobian = typename LieBase::Jacobian;
95 using Jacobian1 = typename traits<G>::Jacobian;
96 using Jacobian2 = typename traits<H>::Jacobian;
97
113 static This Retract(const TangentVector& v, ChartJacobian Hv = {}) {
114 if constexpr (dimension == Eigen::Dynamic) {
115 const This identity = This::Expmap(TangentVector::Zero(v.size()));
116 return identity.retract(v, {}, Hv);
117 } else {
118 return This::Identity().retract(v, {}, Hv);
119 }
120 }
121
122 static TangentVector Local(const This& value, ChartJacobian Hv = {}) {
123 if constexpr (dimension == Eigen::Dynamic) {
124 const This identity(traits<G>::Between(value.first, value.first),
125 traits<H>::Between(value.second, value.second));
126 return identity.localCoordinates(value, {}, Hv);
127 } else {
128 return This::Identity().localCoordinates(value, {}, Hv);
129 }
130 }
131 };
132
133 public:
136
139
141 ProductLieGroup(const G& g, const H& h) : Base(g, h) {}
142
144 ProductLieGroup(const Base& base) : Base(base) {}
145
149
151
154
157
160
161 using LieBase::between;
162 using LieBase::compose;
163 using LieBase::expmap;
164 using LieBase::inverse;
165 using LieBase::logmap;
166
170
172 size_t dim() const { return firstDim() + secondDim(); }
173
175 ProductLieGroup retract(const TangentVector& v, ChartJacobian H1 = {},
176 ChartJacobian H2 = {}) const;
177
179 TangentVector localCoordinates(const ProductLieGroup& g,
180 ChartJacobian H1 = {},
181 ChartJacobian H2 = {}) const;
182
186
188 static ProductLieGroup Expmap(const TangentVector& v, ChartJacobian Hv = {});
189
192 const Eigen::Ref<const typename traits<G>::TangentVector>& v1,
193 const Eigen::Ref<const typename traits<H>::TangentVector>& v2,
196
198 static TangentVector Logmap(const ProductLieGroup& p, ChartJacobian Hp = {});
199
201 static TangentVector LocalCoordinates(const ProductLieGroup& p,
202 ChartJacobian Hp = {}) {
203 return Logmap(p, Hp);
204 }
205
207 Jacobian AdjointMap() const;
208
214 static Jacobian adjointMap(const TangentVector& xi);
215
217
218 protected:
221 template <typename T>
222 static T defaultIdentity();
223
224 size_t firstDim() const { return traits<G>::GetDimension(this->first); }
225 size_t secondDim() const { return traits<H>::GetDimension(this->second); }
226
228 template <typename T, int ComponentDimension = traits<T>::dimension>
230 const TangentVector& v, size_t start, size_t d);
231
233 template <typename T>
235 const typename traits<T>::TangentVector& xi);
236
238 static TangentVector makeTangentVector(
239 const typename traits<G>::TangentVector& v1,
240 const typename traits<H>::TangentVector& v2, size_t d1, size_t d2);
241
243 static Jacobian zeroJacobian(size_t d);
244
247 const char* operation) const;
248
249 public:
252 void print(const std::string& s = "") const;
253
254 bool equals(const ProductLieGroup& other, double tol = 1e-9) const {
255 return traits<G>::Equals(this->first, other.first, tol) &&
256 traits<H>::Equals(this->second, other.second, tol);
257 }
259};
260
268template <typename T, int N>
271 using type = std::array<T, N>;
272};
273
274template <typename T>
275struct PowerLieGroupJacobianStorage<T, Eigen::Dynamic> {
277 using type = std::vector<T>;
278};
279
280template <typename G, int N, typename Derived>
282 : public LieGroup<Derived,
283 internal::dimensionProduct(N, traits<G>::dimension)> {
284 protected:
285 static constexpr bool isDynamic = (N == Eigen::Dynamic);
286 static constexpr int n = traits<G>::dimension;
287
288 public:
289 using LieBase =
291 typedef multiplicative_group_tag group_flavor;
292 using LieBase::Dim;
293 using LieBase::dimension;
294 using TangentVector = typename LieBase::TangentVector;
295 using ChartJacobian = typename LieBase::ChartJacobian;
296 using Jacobian = typename LieBase::Jacobian;
297
307 static Derived Retract(const TangentVector& v, ChartJacobian H = {}) {
308 if constexpr (isDynamic) {
309 if (v.size() % n != 0) {
310 throw std::invalid_argument(
311 "PowerLieGroup::Retract tangent dimension must be divisible by "
312 "base group dimension");
313 }
314 const size_t count =
315 static_cast<size_t>(v.size() / static_cast<Eigen::Index>(n));
316 return Derived(count).retract(v, {}, H);
317 } else {
318 return Derived::Identity().retract(v, {}, H);
319 }
320 }
321
322 static TangentVector Local(const Derived& value, ChartJacobian H = {}) {
323 if constexpr (isDynamic) {
324 return Derived(value.size()).localCoordinates(value, {}, H);
325 } else {
326 return Derived::Identity().localCoordinates(value, {}, H);
327 }
328 }
329 };
330
331 using BaseJacobian = typename traits<G>::Jacobian;
332 using JacobianStorage =
334
335 protected:
337 const Derived& derived() const { return static_cast<const Derived&>(*this); }
338
340 Derived& derived() { return static_cast<Derived&>(*this); }
341
343 static size_t totalDimension(size_t count) {
344 return count * static_cast<size_t>(n);
345 }
346
348 static Eigen::Index offset(size_t i) {
349 return static_cast<Eigen::Index>(i * static_cast<size_t>(n));
350 }
351
353 size_t componentCount() const {
354 if constexpr (isDynamic) {
355 return derived().size();
356 } else {
357 return N;
358 }
359 }
360
362 static void checkDynamicTangentSize(const TangentVector& v, size_t count,
363 const char* operation);
364
366 void checkMatchingCounts(const Derived& other, const char* operation) const;
367
370 const TangentVector& v, size_t i);
371
373 static Derived makeResult(size_t count);
374
376 static JacobianStorage makeJacobianStorage(size_t count);
377
379 static void assignTangentSegment(TangentVector& v, size_t i,
380 const typename traits<G>::TangentVector& vi);
381
383 template <typename MatrixType>
384 static void assignJacobianBlock(MatrixType& H, size_t i,
385 const BaseJacobian& block);
386
388 static void fillJacobianBlocks(ChartJacobian H,
389 const JacobianStorage& jacobians,
390 size_t count);
391
392 public:
394 size_t dim() const { return totalDimension(componentCount()); }
395
397 Derived operator*(const Derived& other) const;
398
400 Derived inverse() const;
401
402 using LieBase::between;
403 using LieBase::compose;
404 using LieBase::expmap;
405 using LieBase::inverse;
406 using LieBase::logmap;
407
409 Derived retract(const TangentVector& v, ChartJacobian H1 = {},
410 ChartJacobian H2 = {}) const;
411
413 TangentVector localCoordinates(const Derived& g, ChartJacobian H1 = {},
414 ChartJacobian H2 = {}) const;
415
417 static Derived Expmap(const TangentVector& v, ChartJacobian Hv = {});
418
420 static TangentVector Logmap(const Derived& p, ChartJacobian Hp = {});
421
423 static TangentVector LocalCoordinates(const Derived& p,
424 ChartJacobian Hp = {}) {
425 return Logmap(p, Hp);
426 }
427
429 Jacobian AdjointMap() const;
430
432 void print(const std::string& s = "") const;
433
435 bool equals(const Derived& other, double tol = 1e-9) const;
436
437 protected:
439 static TangentVector zeroTangent(size_t count);
440
442 static Jacobian zeroJacobian(size_t count);
443};
444
450template <typename G, int N>
451class PowerLieGroup : public std::array<G, N>,
452 public PowerLieGroupBase<G, N, PowerLieGroup<G, N>> {
453 static_assert(N >= 1, "PowerLieGroup requires N >= 1");
454 GTSAM_CONCEPT_ASSERT(IsLieGroup<G>);
455 GTSAM_CONCEPT_ASSERT(IsTestable<G>);
456 static_assert(traits<G>::dimension != Eigen::Dynamic,
457 "PowerLieGroup requires a fixed-size base group");
458
459 public:
461 typedef std::array<G, N> Base;
463 using Helper::Dim;
464 using Helper::dimension;
465 using typename Helper::BaseJacobian;
466 using typename Helper::ChartJacobian;
467 using typename Helper::Jacobian;
468 using typename Helper::TangentVector;
469
470 public:
473
476
478 PowerLieGroup(const Base& elements) : Base(elements) {}
479
481 PowerLieGroup(const std::initializer_list<G>& elements);
482
486
488 static PowerLieGroup Identity() { return PowerLieGroup(); }
489
491};
492
497template <typename G>
498class PowerLieGroup<G, Eigen::Dynamic>
499 : public std::vector<G>,
500 public PowerLieGroupBase<G, Eigen::Dynamic,
501 PowerLieGroup<G, Eigen::Dynamic>> {
502 GTSAM_CONCEPT_ASSERT(IsLieGroup<G>);
503 GTSAM_CONCEPT_ASSERT(IsTestable<G>);
504 static_assert(traits<G>::dimension != Eigen::Dynamic,
505 "PowerLieGroup requires a fixed-size base group");
506
507 public:
509 typedef std::vector<G> Base;
511 using Helper::Dim;
512 using Helper::dimension;
513 using typename Helper::BaseJacobian;
514 using typename Helper::ChartJacobian;
515 using typename Helper::Jacobian;
516 using typename Helper::TangentVector;
517
518 public:
521
523 PowerLieGroup() = default;
524
526 explicit PowerLieGroup(size_t count) : Base(count, traits<G>::Identity()) {}
527
529 PowerLieGroup(const Base& elements) : Base(elements) {}
530
532 PowerLieGroup(const std::initializer_list<G>& elements) : Base(elements) {}
533
537
539 static PowerLieGroup Identity() { return PowerLieGroup(); }
540
542};
543
545template <typename G, typename H>
547 : internal::LieGroup<ProductLieGroup<G, H>> {};
548
550template <typename G, int N>
551struct traits<PowerLieGroup<G, N>> : internal::LieGroup<PowerLieGroup<G, N>> {};
552
553} // namespace gtsam
554
Internals for ProductLieGroup.h, not for general consumption.
Concept check for values that can be used in unit tests.
Base class and basic functions for Lie types.
constexpr int dimensionSum(int n, int m)
Sum compile-time dimensions, propagating Eigen::Dynamic.
Definition Lie.h:46
constexpr int dimensionProduct(int n, int m)
Multiply compile-time dimensions, propagating Eigen::Dynamic.
Definition Lie.h:51
Global functions in a separate testing namespace.
Definition chartTesting.h:28
Group operator syntax flavors.
Definition Group.h:34
A manifold defines a space in which there is a notion of a linear tangent space that can be centered ...
Definition Group.h:37
A CRTP helper class that implements Lie group methods Prerequisites: methods operator*,...
Definition Lie.h:114
static constexpr int Dim()
Static method to get the dimension (compile-time or dynamic).
Definition Lie.h:121
TangentVector logmap(const Class &g) const
logmap as required by manifold concept Applies logarithmic map to group element that takes *this to g
Definition Lie.h:161
Class expmap(const TangentVector &v) const
expmap as required by manifold concept Applies exponential map to v and composes with *this
Definition Lie.h:155
Both LieGroupTraits and Testable.
Definition Lie.h:346
Lie Group Concept.
Definition Lie.h:377
OptionalJacobian is an Eigen::Ref like class that can take be constructed using either a fixed size o...
Definition OptionalJacobian.h:40
Detects vector-space Lie groups (Eigen column vectors, group law = addition).
Definition ProductLieGroup.h:48
Direct product Lie group G × H.
Definition ProductLieGroup.h:69
ProductLieGroup retract(const TangentVector &v, ChartJacobian H1={}, ChartJacobian H2={}) const
Retract to manifold.
Definition ProductLieGroup-inl.h:63
void checkMatchingDimensions(const ProductLieGroup &other, const char *operation) const
static traits< T >::TangentVector tangentSegment(const TangentVector &v, size_t start, size_t d)
size_t dim() const
Definition ProductLieGroup.h:172
static TangentVector LocalCoordinates(const ProductLieGroup &p, ChartJacobian Hp={})
Definition ProductLieGroup.h:201
static ProductLieGroup Expmap(const TangentVector &v, ChartJacobian Hv={})
Exponential map.
Definition ProductLieGroup-inl.h:130
static traits< T >::Jacobian componentAdjointMap(const typename traits< T >::TangentVector &xi)
static constexpr int n
Definition ProductLieGroup.h:84
ProductLieGroup(const Base &base)
Definition ProductLieGroup.h:144
static TangentVector Logmap(const ProductLieGroup &p, ChartJacobian Hp={})
ProductLieGroup()
Default constructor yields identity.
Definition ProductLieGroup.h:138
static Jacobian adjointMap(const TangentVector &xi)
static ProductLieGroup Expmap(const Eigen::Ref< const typename traits< Pose3 >::TangentVector > &v1, const Eigen::Ref< const typename traits< Calibrations< n > >::TangentVector > &v2, OptionalJacobian< Eigen::Dynamic, Eigen::Dynamic > H1={}, OptionalJacobian< Eigen::Dynamic, Eigen::Dynamic > H2={})
static ProductLieGroup Identity()
Identity element.
Definition ProductLieGroup.h:153
static TangentVector makeTangentVector(const typename traits< Pose3 >::TangentVector &v1, const typename traits< Calibrations< n > >::TangentVector &v2, size_t d1, size_t d2)
std::pair< G, H > Base
Base pair type.
Definition ProductLieGroup.h:78
ProductLieGroup operator*(const ProductLieGroup &other) const
ProductLieGroup(const Pose3 &g, const Calibrations< n > &h)
Definition ProductLieGroup.h:141
TangentVector localCoordinates(const ProductLieGroup &g, ChartJacobian H1={}, ChartJacobian H2={}) const
Local coordinates on manifold.
Definition ProductLieGroup-inl.h:99
Component-wise chart at the product identity.
Definition ProductLieGroup.h:112
Shared implementation for fixed-size and dynamic-count PowerLieGroup.
Definition ProductLieGroup.h:269
std::array< T, N > type
Container type for per-component Jacobians.
Definition ProductLieGroup.h:271
std::vector< T > type
Container type for per-component Jacobians.
Definition ProductLieGroup.h:277
Definition ProductLieGroup.h:283
static Derived makeResult(size_t count)
Create a result object with the requested component count.
Definition ProductLieGroup-inl.h:430
Derived operator*(const Derived &other) const
Group multiplication.
Definition ProductLieGroup-inl.h:482
static Jacobian zeroJacobian(size_t count)
Create a zero Jacobian with the requested runtime size.
Definition ProductLieGroup-inl.h:626
Derived & derived()
Downcast to the derived storage type.
Definition ProductLieGroup.h:340
static void assignJacobianBlock(MatrixType &H, size_t i, const BaseJacobian &block)
Write one component block into a block-diagonal Jacobian.
Definition ProductLieGroup-inl.h:462
static TangentVector Logmap(const Derived &p, ChartJacobian Hp={})
Logarithmic map.
Definition ProductLieGroup-inl.h:567
static TangentVector zeroTangent(size_t count)
Create a zero tangent with the requested runtime size.
Definition ProductLieGroup-inl.h:615
static void assignTangentSegment(TangentVector &v, size_t i, const typename traits< G >::TangentVector &vi)
Write one component tangent into the concatenated tangent.
Definition ProductLieGroup-inl.h:451
Derived retract(const TangentVector &v, ChartJacobian H1={}, ChartJacobian H2={}) const
Retract to manifold.
Definition ProductLieGroup-inl.h:502
static TangentVector LocalCoordinates(const Derived &p, ChartJacobian Hp={})
Local coordinates (same as Logmap).
Definition ProductLieGroup.h:423
static void fillJacobianBlocks(ChartJacobian H, const JacobianStorage &jacobians, size_t count)
Assemble a block-diagonal Jacobian from per-component blocks.
Definition ProductLieGroup-inl.h:472
bool equals(const Derived &other, double tol=1e-9) const
Equality with tolerance.
Definition ProductLieGroup-inl.h:598
Derived inverse() const
Group inverse.
Definition ProductLieGroup-inl.h:493
const Derived & derived() const
Downcast to the derived storage type.
Definition ProductLieGroup.h:337
static Derived Expmap(const TangentVector &v, ChartJacobian Hv={})
Exponential map.
Definition ProductLieGroup-inl.h:542
size_t componentCount() const
Runtime component count.
Definition ProductLieGroup.h:353
static traits< G >::TangentVector tangentSegment(const TangentVector &v, size_t i)
Extract one component tangent from the concatenated tangent.
Definition ProductLieGroup-inl.h:420
Jacobian AdjointMap() const
Adjoint map.
Definition ProductLieGroup-inl.h:581
static void checkDynamicTangentSize(const TangentVector &v, size_t count, const char *operation)
Validate tangent size for dynamic-count groups.
Definition ProductLieGroup-inl.h:389
void print(const std::string &s="") const
Print for debugging.
Definition ProductLieGroup-inl.h:590
size_t dim() const
Return manifold dimension.
Definition ProductLieGroup.h:394
void checkMatchingCounts(const Derived &other, const char *operation) const
Validate matching component counts for binary operations.
Definition ProductLieGroup-inl.h:405
static size_t totalDimension(size_t count)
Total tangent dimension for a given component count.
Definition ProductLieGroup.h:343
TangentVector localCoordinates(const Derived &g, ChartJacobian H1={}, ChartJacobian H2={}) const
Local coordinates on manifold.
Definition ProductLieGroup-inl.h:522
static Eigen::Index offset(size_t i)
Starting offset of one component inside the concatenated tangent.
Definition ProductLieGroup.h:348
static JacobianStorage makeJacobianStorage(size_t count)
Create per-component Jacobian storage.
Definition ProductLieGroup-inl.h:441
Component-wise chart at the identity.
Definition ProductLieGroup.h:306
Template to construct the N-fold power of a Lie group Represents the group G^N = G x G x ....
Definition ProductLieGroup.h:452
static PowerLieGroup Identity()
Identity element.
Definition ProductLieGroup.h:488
PowerLieGroup(const std::initializer_list< G > &elements)
Construct from initializer list.
Definition ProductLieGroup-inl.h:636
PowerLieGroup()
Default constructor yields identity.
Definition ProductLieGroup.h:475
std::array< G, N > Base
Base array type.
Definition ProductLieGroup.h:461
PowerLieGroup(const Base &elements)
Construct from array of group elements.
Definition ProductLieGroup.h:478
PowerLieGroup(size_t count)
Construct a runtime-sized identity element.
Definition ProductLieGroup.h:526
std::vector< G > Base
Base vector type.
Definition ProductLieGroup.h:509
static PowerLieGroup Identity()
Identity element.
Definition ProductLieGroup.h:539
PowerLieGroup(const Base &elements)
Construct from vector of group elements.
Definition ProductLieGroup.h:529
PowerLieGroup()=default
Default constructor yields a zero-length placeholder identity.
PowerLieGroup(const std::initializer_list< G > &elements)
Construct from initializer list.
Definition ProductLieGroup.h:532
A testable concept check that should be placed in applicable unit tests and in generic algorithms.
Definition Testable.h:59