Harmonized traits internal helper classes

release/4.3a0
dellaert 2015-05-25 22:02:42 -07:00
parent 111d0d39dd
commit e65f510ebf
4 changed files with 48 additions and 34 deletions

View File

@ -20,6 +20,8 @@
#pragma once #pragma once
#include <gtsam/base/Testable.h>
#include <boost/concept_check.hpp> #include <boost/concept_check.hpp>
#include <boost/concept/requires.hpp> #include <boost/concept/requires.hpp>
#include <boost/type_traits/is_base_of.hpp> #include <boost/type_traits/is_base_of.hpp>
@ -87,34 +89,38 @@ check_group_invariants(const G& a, const G& b, double tol = 1e-9) {
namespace internal { namespace internal {
/// A helper class that implements the traits interface for groups. /// A helper class that implements the traits interface for multiplicative groups.
/// Assumes that constructor yields identity /// Assumes existence of identity, operator* and inverse method
template<class Class> template<class Class>
struct GroupTraits { struct MultiplicativeGroupTraits {
typedef group_tag structure_category; typedef group_tag structure_category;
static Class Identity() { return Class(); } 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();}
}; };
/// A helper class that implements the traits interface for multiplicative groups. /// Both multiplicative group traits and Testable
/// Assumes existence of operator* and inverse method
template<class Class> template<class Class>
struct MultiplicativeGroupTraits : GroupTraits<Class> { struct MultiplicativeGroup : MultiplicativeGroupTraits<Class>, Testable<Class> {};
typedef multiplicative_group_tag group_flavor; \
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();}
};
/// A helper class that implements the traits interface for additive groups. /// A helper class that implements the traits interface for additive groups.
/// Assumes existence of three additive operators /// Assumes existence of identity and three additive operators
template<class Class> template<class Class>
struct AdditiveGroupTraits : GroupTraits<Class> { struct AdditiveGroupTraits {
typedef additive_group_tag group_flavor; \ typedef group_tag structure_category;
static Class Compose(const Class &g, const Class & h) { return g + h;} \ typedef additive_group_tag group_flavor;
static Class Between(const Class &g, const Class & h) { return h - g;} \ static Class Identity() { return Class::identity(); }
static Class Inverse(const Class &g) { return -g;} 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;}
}; };
/// Both additive group traits and Testable
template<class Class>
struct AdditiveGroup : AdditiveGroupTraits<Class>, Testable<Class> {};
} // namespace internal } // namespace internal
/// compose multiple times /// compose multiple times
@ -127,7 +133,7 @@ compose_pow(const G& g, size_t n) {
} }
/// Template to construct the direct product of two arbitrary groups /// Template to construct the direct product of two arbitrary groups
/// Assumes nothing except group structure from G and H /// Assumes nothing except group structure and Testable from G and H
template<typename G, typename H> template<typename G, typename H>
class DirectProduct: public std::pair<G, H> { class DirectProduct: public std::pair<G, H> {
BOOST_CONCEPT_ASSERT((IsGroup<G>)); BOOST_CONCEPT_ASSERT((IsGroup<G>));
@ -140,6 +146,9 @@ public:
// Construct from two subgroup elements // Construct from two subgroup elements
DirectProduct(const G& g, const H& h):std::pair<G,H>(g,h) {} 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 { DirectProduct operator*(const DirectProduct& other) const {
return DirectProduct(traits<G>::Compose(this->first, other.first), return DirectProduct(traits<G>::Compose(this->first, other.first),
traits<H>::Compose(this->second, other.second)); traits<H>::Compose(this->second, other.second));
@ -171,6 +180,9 @@ public:
// Construct from two subgroup elements // Construct from two subgroup elements
DirectSum(const G& g, const H& h):std::pair<G,H>(g,h) {} 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 { DirectSum operator+(const DirectSum& other) const {
return DirectSum(g()+other.g(), h()+other.h()); return DirectSum(g()+other.g(), h()+other.h());
} }

View File

@ -136,8 +136,10 @@ namespace internal {
/// A helper class that implements the traits interface for GTSAM lie groups. /// A helper class that implements the traits interface for GTSAM lie groups.
/// To use this for your gtsam type, define: /// To use this for your gtsam type, define:
/// template<> struct traits<Class> : public internal::LieGroupTraits<Class> {}; /// template<> struct traits<Class> : public internal::LieGroupTraits<Class> {};
/// Assumes existence of: identity, dimension, localCoordinates, retract,
/// and additionally Logmap, Expmap, compose, between, and inverse
template<class Class> template<class Class>
struct LieGroupTraits : Testable<Class> { struct LieGroupTraits {
typedef lie_group_tag structure_category; typedef lie_group_tag structure_category;
/// @name Group /// @name Group
@ -167,12 +169,10 @@ struct LieGroupTraits : Testable<Class> {
ChartJacobian Horigin = boost::none, ChartJacobian Hv = boost::none) { ChartJacobian Horigin = boost::none, ChartJacobian Hv = boost::none) {
return origin.retract(v, Horigin, Hv); return origin.retract(v, Horigin, Hv);
} }
/// @} /// @}
/// @name Lie Group /// @name Lie Group
/// @{ /// @{
static TangentVector Logmap(const Class& m, ChartJacobian Hm = boost::none) { static TangentVector Logmap(const Class& m, ChartJacobian Hm = boost::none) {
return Class::Logmap(m, Hm); return Class::Logmap(m, Hm);
} }
@ -195,11 +195,12 @@ struct LieGroupTraits : Testable<Class> {
ChartJacobian H = boost::none) { ChartJacobian H = boost::none) {
return m.inverse(H); return m.inverse(H);
} }
/// @} /// @}
}; };
/// Both LieGroupTraits and Testable
template<class Class> struct LieGroup: LieGroupTraits<Class>, Testable<Class> {};
} // \ namepsace internal } // \ namepsace internal
/** /**

View File

@ -116,10 +116,8 @@ struct ManifoldTraits: ManifoldImpl<Class, Class::dimension> {
} }
}; };
/// Implement both manifold and testable traits at the same time /// Both ManifoldTraits and Testable
template<class Class> template<class Class> struct Manifold: ManifoldTraits<Class>, Testable<Class> {};
struct Manifold: Testable<Class>, ManifoldTraits<Class> {
};
} // \ namespace internal } // \ namespace internal

View File

@ -20,7 +20,7 @@ template<typename T> struct traits;
namespace internal { namespace internal {
/// VectorSpace Implementation for Fixed sizes /// VectorSpaceTraits Implementation for Fixed sizes
template<class Class, int N> template<class Class, int N>
struct VectorSpaceImpl { struct VectorSpaceImpl {
@ -83,7 +83,7 @@ struct VectorSpaceImpl {
/// @} /// @}
}; };
/// VectorSpace implementation for dynamic types. /// VectorSpaceTraits implementation for dynamic types.
template<class Class> template<class Class>
struct VectorSpaceImpl<Class,Eigen::Dynamic> { struct VectorSpaceImpl<Class,Eigen::Dynamic> {
@ -159,11 +159,11 @@ struct VectorSpaceImpl<Class,Eigen::Dynamic> {
/// @} /// @}
}; };
/// A helper that implements the traits interface for GTSAM lie groups. /// A helper that implements the traits interface for GTSAM vector space types.
/// To use this for your gtsam type, define: /// To use this for your gtsam type, define:
/// template<> struct traits<Type> : public VectorSpace<Type> { }; /// template<> struct traits<Type> : public VectorSpaceTraits<Type> { };
template<class Class> template<class Class>
struct VectorSpace: Testable<Class>, VectorSpaceImpl<Class, Class::dimension> { struct VectorSpaceTraits: VectorSpaceImpl<Class, Class::dimension> {
typedef vector_space_tag structure_category; typedef vector_space_tag structure_category;
@ -178,9 +178,12 @@ struct VectorSpace: Testable<Class>, VectorSpaceImpl<Class, Class::dimension> {
enum { dimension = Class::dimension}; enum { dimension = Class::dimension};
typedef Class ManifoldType; typedef Class ManifoldType;
/// @} /// @}
}; };
/// Both VectorSpaceTRaits and Testable
template<class Class>
struct VectorSpace: Testable<Class>, VectorSpaceTraits<Class> {};
/// A helper that implements the traits interface for GTSAM lie groups. /// A helper that implements the traits interface for GTSAM lie groups.
/// To use this for your gtsam type, define: /// To use this for your gtsam type, define:
/// template<> struct traits<Type> : public ScalarTraits<Type> { }; /// template<> struct traits<Type> : public ScalarTraits<Type> { };