Loading...
Searching...
No Matches
Group.h
Go to the documentation of this file.
/* ----------------------------------------------------------------------------
* GTSAM Copyright 2010, Georgia Tech Research Corporation,
* Atlanta, Georgia 30332-0415
* All Rights Reserved
* Authors: Frank Dellaert, et al. (see THANKS for the full author list)
* See LICENSE for the license information
* -------------------------------------------------------------------------- */
#pragma once
#include <gtsam/base/Testable.h>
#include <boost/concept_check.hpp>
#include <boost/concept/requires.hpp>
#include <boost/type_traits/is_base_of.hpp>
#include <boost/static_assert.hpp>
#include <utility>
namespace gtsam {
struct group_tag {};
struct multiplicative_group_tag {};
struct additive_group_tag {};
template <typename T> struct traits;
template<typename G>
class IsGroup {
public:
typedef typename traits<G>::structure_category structure_category_tag;
typedef typename traits<G>::group_flavor flavor_tag;
//typedef typename traits<G>::identity::value_type identity_value_type;
BOOST_CONCEPT_USAGE(IsGroup) {
BOOST_STATIC_ASSERT_MSG(
(boost::is_base_of<group_tag, structure_category_tag>::value),
"This type's structure_category trait does not assert it as a group (or derived)");
e = traits<G>::Identity();
e = traits<G>::Compose(g, h);
e = traits<G>::Between(g, h);
e = traits<G>::Inverse(g);
operator_usage(flavor);
// todo: how do we test the act concept? or do we even need to?
}
private:
void operator_usage(multiplicative_group_tag) {
e = g * h;
//e = -g; // todo this should work, but it is failing for Quaternions
}
void operator_usage(additive_group_tag) {
e = g + h;
e = h - g;
e = -g;
}
flavor_tag flavor;
G e, g, h;
bool b;
};
template<typename G>
BOOST_CONCEPT_REQUIRES(((IsGroup<G>)),(bool)) //
check_group_invariants(const G& a, const G& b, double tol = 1e-9) {
G e = traits<G>::Identity();
return traits<G>::Equals(traits<G>::Compose(a, traits<G>::Inverse(a)), e, tol)
&& traits<G>::Equals(traits<G>::Between(a, b), traits<G>::Compose(traits<G>::Inverse(a), b), tol)
&& traits<G>::Equals(traits<G>::Compose(a, traits<G>::Between(a, b)), b, tol);
}
namespace internal {
template<class Class>
struct MultiplicativeGroupTraits {
typedef group_tag structure_category;
typedef multiplicative_group_tag group_flavor;
static Class Identity() { return Class::Identity(); }
static Class Compose(const Class &g, const Class & h) { return g * h;}
static Class Between(const Class &g, const Class & h) { return g.inverse() * h;}
static Class Inverse(const Class &g) { return g.inverse();}
};
template<class Class>
struct MultiplicativeGroup : MultiplicativeGroupTraits<Class>, Testable<Class> {};
template<class Class>
struct AdditiveGroupTraits {
typedef group_tag structure_category;
typedef additive_group_tag group_flavor;
static Class Identity() { return Class::Identity(); }
static Class Compose(const Class &g, const Class & h) { return g + h;}
static Class Between(const Class &g, const Class & h) { return h - g;}
static Class Inverse(const Class &g) { return -g;}
};
template<class Class>
struct AdditiveGroup : AdditiveGroupTraits<Class>, Testable<Class> {};
} // namespace internal
template<typename G>
BOOST_CONCEPT_REQUIRES(((IsGroup<G>)),(G)) //
compose_pow(const G& g, size_t n) {
if (n == 0) return traits<G>::Identity();
else if (n == 1) return g;
else return traits<G>::Compose(compose_pow(g, n - 1), g);
}
template<typename G, typename H>
class DirectProduct: public std::pair<G, H> {
BOOST_CONCEPT_ASSERT((IsGroup<G>));
BOOST_CONCEPT_ASSERT((IsGroup<H>));
public:
DirectProduct():std::pair<G,H>(traits<G>::Identity(),traits<H>::Identity()) {}
// Construct from two subgroup elements
DirectProduct(const G& g, const H& h):std::pair<G,H>(g,h) {}
// identity
static DirectProduct Identity() { return DirectProduct(); }
DirectProduct operator*(const DirectProduct& other) const {
return DirectProduct(traits<G>::Compose(this->first, other.first),
traits<H>::Compose(this->second, other.second));
}
DirectProduct inverse() const {
return DirectProduct(this->first.inverse(), this->second.inverse());
}
};
// Define any direct product group to be a model of the multiplicative Group concept
template<typename G, typename H>
struct traits<DirectProduct<G, H> > :
internal::MultiplicativeGroupTraits<DirectProduct<G, H> > {};
template<typename G, typename H>
class DirectSum: public std::pair<G, H> {
BOOST_CONCEPT_ASSERT((IsGroup<G>)); // TODO(frank): check additive
BOOST_CONCEPT_ASSERT((IsGroup<H>)); // TODO(frank): check additive
const G& g() const { return this->first; }
const H& h() const { return this->second;}
public:
DirectSum():std::pair<G,H>(traits<G>::Identity(),traits<H>::Identity()) {}
// Construct from two subgroup elements
DirectSum(const G& g, const H& h):std::pair<G,H>(g,h) {}
// identity
static DirectSum Identity() { return DirectSum(); }
DirectSum operator+(const DirectSum& other) const {
return DirectSum(g()+other.g(), h()+other.h());
}
DirectSum operator-(const DirectSum& other) const {
return DirectSum(g()-other.g(), h()-other.h());
}
DirectSum operator-() const {
return DirectSum(- g(), - h());
}
};
// Define direct sums to be a model of the Additive Group concept
template<typename G, typename H>
struct traits<DirectSum<G, H> > :
internal::AdditiveGroupTraits<DirectSum<G, H> > {};
} // namespace gtsam
#define GTSAM_CONCEPT_GROUP_INST(T) template class gtsam::IsGroup<T>;
#define GTSAM_CONCEPT_GROUP_TYPE(T) typedef gtsam::IsGroup<T> _gtsam_IsGroup_##T;
Testable.h
Concept check for values that can be used in unit tests.
gtsam
Global functions in a separate testing namespace.
Definition chartTesting.h:28
gtsam::BOOST_CONCEPT_REQUIRES
BOOST_CONCEPT_REQUIRES(((IsGroup< G >)),(bool)) check_group_invariants(const G &a
Check invariants.
gtsam::traits
A manifold defines a space in which there is a notion of a linear tangent space that can be centered ...
Definition concepts.h:30
gtsam::group_tag
tag to assert a type is a group
Definition Group.h:34
gtsam::multiplicative_group_tag
Group operator syntax flavors.
Definition Group.h:37
gtsam::additive_group_tag
Definition Group.h:38
gtsam::IsGroup
Group Concept.
Definition Group.h:46
gtsam::DirectProduct
Definition Group.h:138
gtsam::DirectProduct::DirectProduct
DirectProduct()
Default constructor yields identity.
Definition Group.h:144
gtsam::DirectSum
Template to construct the direct sum of two additive groups Assumes existence of three additive opera...
Definition Group.h:169
gtsam::DirectSum::DirectSum
DirectSum()
Default constructor yields identity.
Definition Group.h:178