gtsam 4.1.1
gtsam
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#include <boost/concept_check.hpp>
26#include <boost/concept/requires.hpp>
27#include <boost/type_traits/is_base_of.hpp>
28#include <boost/static_assert.hpp>
29#include <utility>
30
31namespace gtsam {
32
34struct group_tag {};
35
39
40template <typename T> struct traits;
41
45template<typename G>
46class IsGroup {
47public:
48 typedef typename traits<G>::structure_category structure_category_tag;
49 typedef typename traits<G>::group_flavor flavor_tag;
50 //typedef typename traits<G>::identity::value_type identity_value_type;
51
52 BOOST_CONCEPT_USAGE(IsGroup) {
53 BOOST_STATIC_ASSERT_MSG(
54 (boost::is_base_of<group_tag, structure_category_tag>::value),
55 "This type's structure_category trait does not assert it as a group (or derived)");
57 e = traits<G>::Compose(g, h);
58 e = traits<G>::Between(g, h);
59 e = traits<G>::Inverse(g);
60 operator_usage(flavor);
61 // todo: how do we test the act concept? or do we even need to?
62 }
63
64private:
65 void operator_usage(multiplicative_group_tag) {
66 e = g * h;
67 //e = -g; // todo this should work, but it is failing for Quaternions
68 }
69 void operator_usage(additive_group_tag) {
70 e = g + h;
71 e = h - g;
72 e = -g;
73 }
74
75 flavor_tag flavor;
76 G e, g, h;
77 bool b;
78};
79
81template<typename G>
83check_group_invariants(const G& a, const G& b, double tol = 1e-9) {
84 G e = traits<G>::Identity();
88}
89
90namespace internal {
91
94template<class Class>
95struct MultiplicativeGroupTraits {
96 typedef group_tag structure_category;
97 typedef multiplicative_group_tag group_flavor;
98 static Class Identity() { return Class::identity(); }
99 static Class Compose(const Class &g, const Class & h) { return g * h;}
100 static Class Between(const Class &g, const Class & h) { return g.inverse() * h;}
101 static Class Inverse(const Class &g) { return g.inverse();}
102};
103
105template<class Class>
106struct MultiplicativeGroup : MultiplicativeGroupTraits<Class>, Testable<Class> {};
107
110template<class Class>
111struct AdditiveGroupTraits {
112 typedef group_tag structure_category;
113 typedef additive_group_tag group_flavor;
114 static Class Identity() { return Class::identity(); }
115 static Class Compose(const Class &g, const Class & h) { return g + h;}
116 static Class Between(const Class &g, const Class & h) { return h - g;}
117 static Class Inverse(const Class &g) { return -g;}
118};
119
121template<class Class>
122struct AdditiveGroup : AdditiveGroupTraits<Class>, Testable<Class> {};
123
124} // namespace internal
125
127template<typename G>
128BOOST_CONCEPT_REQUIRES(((IsGroup<G>)),(G)) //
129compose_pow(const G& g, size_t n) {
130 if (n == 0) return traits<G>::Identity();
131 else if (n == 1) return g;
132 else return traits<G>::Compose(compose_pow(g, n - 1), g);
133}
134
137template<typename G, typename H>
138class DirectProduct: public std::pair<G, H> {
139 BOOST_CONCEPT_ASSERT((IsGroup<G>));
140 BOOST_CONCEPT_ASSERT((IsGroup<H>));
141
142public:
144 DirectProduct():std::pair<G,H>(traits<G>::Identity(),traits<H>::Identity()) {}
145
146 // Construct from two subgroup elements
147 DirectProduct(const G& g, const H& h):std::pair<G,H>(g,h) {}
148
149 // identity
150 static DirectProduct identity() { return DirectProduct(); }
151
152 DirectProduct operator*(const DirectProduct& other) const {
153 return DirectProduct(traits<G>::Compose(this->first, other.first),
154 traits<H>::Compose(this->second, other.second));
155 }
156 DirectProduct inverse() const {
157 return DirectProduct(this->first.inverse(), this->second.inverse());
158 }
159};
160
161// Define any direct product group to be a model of the multiplicative Group concept
162template<typename G, typename H>
163struct traits<DirectProduct<G, H> > :
164 internal::MultiplicativeGroupTraits<DirectProduct<G, H> > {};
165
168template<typename G, typename H>
169class DirectSum: public std::pair<G, H> {
170 BOOST_CONCEPT_ASSERT((IsGroup<G>)); // TODO(frank): check additive
171 BOOST_CONCEPT_ASSERT((IsGroup<H>)); // TODO(frank): check additive
172
173 const G& g() const { return this->first; }
174 const H& h() const { return this->second;}
175
176public:
178 DirectSum():std::pair<G,H>(traits<G>::Identity(),traits<H>::Identity()) {}
179
180 // Construct from two subgroup elements
181 DirectSum(const G& g, const H& h):std::pair<G,H>(g,h) {}
182
183 // identity
184 static DirectSum identity() { return DirectSum(); }
185
186 DirectSum operator+(const DirectSum& other) const {
187 return DirectSum(g()+other.g(), h()+other.h());
188 }
189 DirectSum operator-(const DirectSum& other) const {
190 return DirectSum(g()-other.g(), h()-other.h());
191 }
192 DirectSum operator-() const {
193 return DirectSum(- g(), - h());
194 }
195};
196
197// Define direct sums to be a model of the Additive Group concept
198template<typename G, typename H>
199struct traits<DirectSum<G, H> > :
200 internal::AdditiveGroupTraits<DirectSum<G, H> > {};
201
202} // namespace gtsam
203
212#define GTSAM_CONCEPT_GROUP_INST(T) template class gtsam::IsGroup<T>;
213#define GTSAM_CONCEPT_GROUP_TYPE(T) typedef gtsam::IsGroup<T> _gtsam_IsGroup_##T;
Concept check for values that can be used in unit tests.
Global functions in a separate testing namespace.
Definition: chartTesting.h:28
BOOST_CONCEPT_REQUIRES(((IsGroup< G >)),(bool)) check_group_invariants(const G &a
Check invariants.
A manifold defines a space in which there is a notion of a linear tangent space that can be centered ...
Definition: concepts.h:30
tag to assert a type is a group
Definition: Group.h:34
Group operator syntax flavors.
Definition: Group.h:37
Definition: Group.h:38
Group Concept.
Definition: Group.h:46
Definition: Group.h:138
DirectProduct()
Default constructor yields identity.
Definition: Group.h:144
Template to construct the direct sum of two additive groups Assumes existence of three additive opera...
Definition: Group.h:169
DirectSum()
Default constructor yields identity.
Definition: Group.h:178