GTSAM  4.0.2
C++ library for smoothing and mapping (SAM)
Group.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 
21 #pragma once
22 
23 #include <gtsam/base/Testable.h>
24 
25 #ifdef GTSAM_USE_BOOST_FEATURES
26 #include <boost/concept_check.hpp>
27 #include <boost/concept/requires.hpp>
28 #include <boost/type_traits/is_base_of.hpp>
29 #include <boost/static_assert.hpp>
30 #endif
31 
32 #include <utility>
33 
34 namespace gtsam {
35 
37 struct group_tag {};
38 
42 
43 template <typename T> struct traits;
44 
48 template<typename G>
49 class IsGroup {
50 public:
51  typedef typename traits<G>::structure_category structure_category_tag;
52  typedef typename traits<G>::group_flavor flavor_tag;
53  //typedef typename traits<G>::identity::value_type identity_value_type;
54 
55  BOOST_CONCEPT_USAGE(IsGroup) {
56  static_assert(
57  (std::is_base_of<group_tag, structure_category_tag>::value),
58  "This type's structure_category trait does not assert it as a group (or derived)");
59  e = traits<G>::Identity();
60  e = traits<G>::Compose(g, h);
61  e = traits<G>::Between(g, h);
62  e = traits<G>::Inverse(g);
63  operator_usage(flavor);
64  // todo: how do we test the act concept? or do we even need to?
65  }
66 
67 private:
68  void operator_usage(multiplicative_group_tag) {
69  e = g * h;
70  //e = -g; // todo this should work, but it is failing for Quaternions
71  }
72  void operator_usage(additive_group_tag) {
73  e = g + h;
74  e = h - g;
75  e = -g;
76  }
77 
78  flavor_tag flavor;
79  G e, g, h;
80  bool b;
81 };
82 
84 template<typename G>
86 check_group_invariants(const G& a, const G& b, double tol = 1e-9) {
87  G e = traits<G>::Identity();
91 }
92 
93 namespace internal {
94 
97 template<class Class>
98 struct MultiplicativeGroupTraits {
99  typedef group_tag structure_category;
100  typedef multiplicative_group_tag group_flavor;
101  static Class Identity() { return Class::Identity(); }
102  static Class Compose(const Class &g, const Class & h) { return g * h;}
103  static Class Between(const Class &g, const Class & h) { return g.inverse() * h;}
104  static Class Inverse(const Class &g) { return g.inverse();}
105 };
106 
108 template<class Class>
109 struct MultiplicativeGroup : MultiplicativeGroupTraits<Class>, Testable<Class> {};
110 
113 template<class Class>
114 struct AdditiveGroupTraits {
115  typedef group_tag structure_category;
116  typedef additive_group_tag group_flavor;
117  static Class Identity() { return Class::Identity(); }
118  static Class Compose(const Class &g, const Class & h) { return g + h;}
119  static Class Between(const Class &g, const Class & h) { return h - g;}
120  static Class Inverse(const Class &g) { return -g;}
121 };
122 
124 template<class Class>
125 struct AdditiveGroup : AdditiveGroupTraits<Class>, Testable<Class> {};
126 
127 } // namespace internal
128 
130 template<typename G>
132 compose_pow(const G& g, size_t n) {
133  if (n == 0) return traits<G>::Identity();
134  else if (n == 1) return g;
135  else return traits<G>::Compose(compose_pow(g, n - 1), g);
136 }
137 
140 template<typename G, typename H>
141 class DirectProduct: public std::pair<G, H> {
142  GTSAM_CONCEPT_ASSERT(IsGroup<G>);
143  GTSAM_CONCEPT_ASSERT(IsGroup<H>);
144 
145 public:
147  DirectProduct():std::pair<G,H>(traits<G>::Identity(),traits<H>::Identity()) {}
148 
149  // Construct from two subgroup elements
150  DirectProduct(const G& g, const H& h):std::pair<G,H>(g,h) {}
151 
152  // identity
153  static DirectProduct Identity() { return DirectProduct(); }
154 
155  DirectProduct operator*(const DirectProduct& other) const {
156  return DirectProduct(traits<G>::Compose(this->first, other.first),
157  traits<H>::Compose(this->second, other.second));
158  }
159  DirectProduct inverse() const {
160  return DirectProduct(this->first.inverse(), this->second.inverse());
161  }
162 };
163 
164 // Define any direct product group to be a model of the multiplicative Group concept
165 template<typename G, typename H>
166 struct traits<DirectProduct<G, H> > :
167  internal::MultiplicativeGroupTraits<DirectProduct<G, H> > {};
168 
171 template<typename G, typename H>
172 class DirectSum: public std::pair<G, H> {
173  GTSAM_CONCEPT_ASSERT(IsGroup<G>); // TODO(frank): check additive
174  GTSAM_CONCEPT_ASSERT(IsGroup<H>); // TODO(frank): check additive
175 
176  const G& g() const { return this->first; }
177  const H& h() const { return this->second;}
178 
179 public:
181  DirectSum():std::pair<G,H>(traits<G>::Identity(),traits<H>::Identity()) {}
182 
183  // Construct from two subgroup elements
184  DirectSum(const G& g, const H& h):std::pair<G,H>(g,h) {}
185 
186  // identity
187  static DirectSum Identity() { return DirectSum(); }
188 
189  DirectSum operator+(const DirectSum& other) const {
190  return DirectSum(g()+other.g(), h()+other.h());
191  }
192  DirectSum operator-(const DirectSum& other) const {
193  return DirectSum(g()-other.g(), h()-other.h());
194  }
195  DirectSum operator-() const {
196  return DirectSum(- g(), - h());
197  }
198 };
199 
200 // Define direct sums to be a model of the Additive Group concept
201 template<typename G, typename H>
202 struct traits<DirectSum<G, H> > :
203  internal::AdditiveGroupTraits<DirectSum<G, H> > {};
204 
205 } // namespace gtsam
206 
215 #define GTSAM_CONCEPT_GROUP_INST(T) template class gtsam::IsGroup<T>;
216 #define GTSAM_CONCEPT_GROUP_TYPE(T) typedef gtsam::IsGroup<T> _gtsam_IsGroup_##T;
Concept check for values that can be used in unit tests.
Definition: Testable.h:152
Definition: Group.h:43
Definition: Group.h:49
Point2 operator*(double s, const Point2 &p)
multiply with scalar
Definition: Point2.h:52
DirectProduct()
Default constructor yields identity.
Definition: Group.h:147
Definition: Group.h:172
Group operator syntax flavors.
Definition: Group.h:40
Definition: Group.h:41
Definition: chartTesting.h:28
GTSAM_EXPORT Errors operator-(const Errors &a, const Errors &b)
Subtraction.
GTSAM_CONCEPT_REQUIRES(IsGroup< G >, bool) check_group_invariants(const G &a
Check invariants.
Definition: Group.h:141
tag to assert a type is a group
Definition: Group.h:37
GTSAM_EXPORT Errors operator+(const Errors &a, const Errors &b)
Addition.
DirectSum()
Default constructor yields identity.
Definition: Group.h:181