group::traits, and group::compose

release/4.3a0
dellaert 2014-12-06 11:37:14 +01:00
parent 07ef30039a
commit ddeb764912
2 changed files with 109 additions and 82 deletions

View File

@ -24,7 +24,8 @@ namespace traits {
*/
//@{
template<class T>
struct structure_category; // specializations should be derived from one of the following tags
struct structure_category;
// specializations should be derived from one of the following tags
//@}
/**
@ -32,10 +33,14 @@ struct structure_category; // specializations should be derived from one of the
* @brief Possible values for traits::structure_category<T>::type
*/
//@{
struct manifold_tag {};
struct group_tag {};
struct lie_group_tag : public manifold_tag, public group_tag {};
struct vector_space_tag : public lie_group_tag {};
struct manifold_tag {
};
struct group_tag {
};
struct lie_group_tag: public manifold_tag, public group_tag {
};
struct vector_space_tag: public lie_group_tag {
};
//@}
}// namespace traits
@ -88,41 +93,51 @@ class ChartConcept {
};
*/
namespace group {
template<typename G>
G compose(const G&g, const G& h);
namespace traits {
/** @name Group Traits */
//@{
template <class Group> struct identity;
template <class Group> struct group_flavor;
template<class G> struct identity;
template<class G> struct flavor;
//@}
/** @name Group Flavor Tags */
//@{
struct additive_group_tag {};
struct multiplicative_group_tag {};
struct additive_tag {
};
struct multiplicative_tag {
};
//@}
} // namespace traits
} // \ namespace traits
} // \ namespace group
/**
* Group Concept
*/
template<class G>
template<typename G>
class Group {
public:
typedef typename traits::identity<G>::value_type identity_value_type;
typedef typename traits::group_flavor<G>::type group_flavor_tag;
typedef typename traits::structure_category<G>::type structure_category_tag;
typedef typename group::traits::identity<G>::value_type identity_value_type;
typedef typename group::traits::flavor<G>::type group_flavor_tag;
BOOST_CONCEPT_USAGE(Group) {
e = traits::identity<G>::value;
// BOOST_STATIC_ASSERT(boost::is_base_of<traits::group_tag,typename traits::structure_category<Group>::type>::value );
using group::compose;
BOOST_STATIC_ASSERT(
boost::is_base_of<traits::group_tag, structure_category_tag>::value);
e = group::traits::identity<G>::value;
pq = compose(p, q);
// G ip = inverse(p);
// G pq = compose(p, q);
// G d = between(p, q);
// test = equal(p, q);
// test2 = operator_usage(p, q, traits::group_flavor<Group>::type);
// test2 = operator_usage(p, q, group::traits::_flavor<Group>::type);
}
bool check_invariants(const G& a, const G& b) {
@ -134,15 +149,15 @@ public:
}
private:
G p, q, e;
G e, p, q, pq, ip, d;
bool test, test2;
bool operator_usage(const G& a, const G& b,
traits::multiplicative_group_tag) {
group::traits::multiplicative_tag) {
return equal(compose(a, b), a * b);
}
bool operator_usage(const G& a, const G& b, traits::additive_group_tag) {
bool operator_usage(const G& a, const G& b, group::traits::additive_tag) {
return equal(compose(a, b), a + b);
}
@ -184,4 +199,3 @@ class VectorSpaceConcept : public LieGroupConcept {
} // namespace gtsam

View File

@ -35,17 +35,28 @@ public:
};
namespace traits {
/// Define Cyclic to be a model of the Group concept
template<size_t N> struct structure_category<Cyclic<N> > {
typedef group_tag type;
};
} // \namespace traits
namespace group {
template<size_t N>
Cyclic<N> compose(const Cyclic<N>&g, const Cyclic<N>& h);
namespace traits {
/// Define the trait that specifies Cyclic's identity element
template<size_t N> struct identity<Cyclic<N> > {
static const Cyclic<N> value;
typedef Cyclic<N> value_type;
};
template<size_t N> struct group_flavor<Cyclic<N> > {
typedef additive_group_tag type;
/// Define the trait that asserts Cyclic is an additive group
template<size_t N> struct flavor<Cyclic<N> > {
typedef additive_tag type;
};
} // \namespace traits
} // \namespace group
} // \namespace gtsam
@ -57,10 +68,12 @@ template<size_t N> struct group_flavor<Cyclic<N> > {
namespace gtsam {
namespace group {
namespace traits {
template<size_t N>
const Cyclic<N> identity<Cyclic<N> >::value = Cyclic<N>(0);
} // \namespace traits
} // \namespace group
} // \namespace gtsam
@ -81,7 +94,7 @@ typedef Cyclic<6> G; // Let's use the cyclic group of order 6
//******************************************************************************
TEST(Cyclic, Concept) {
EXPECT_LONGS_EQUAL(0,traits::identity<G>::value);
EXPECT_LONGS_EQUAL(0, group::traits::identity<G>::value);
BOOST_CONCEPT_ASSERT((Group<G>));
}