From ddeb7649121942ab803ce40cba3cf2ee3b17fedf Mon Sep 17 00:00:00 2001 From: dellaert Date: Sat, 6 Dec 2014 11:37:14 +0100 Subject: [PATCH] group::traits, and group::compose --- gtsam/base/concepts.h | 172 +++++++++++++++------------- gtsam/geometry/tests/testCyclic.cpp | 19 ++- 2 files changed, 109 insertions(+), 82 deletions(-) diff --git a/gtsam/base/concepts.h b/gtsam/base/concepts.h index 393bb69b1..6910518da 100644 --- a/gtsam/base/concepts.h +++ b/gtsam/base/concepts.h @@ -23,8 +23,9 @@ namespace traits { * @brief Associate a unique tag with each of the main GTSAM concepts */ //@{ -template -struct structure_category; // specializations should be derived from one of the following tags +template +struct structure_category; +// specializations should be derived from one of the following tags //@} /** @@ -32,97 +33,111 @@ struct structure_category; // specializations should be derived from one of the * @brief Possible values for traits::structure_category::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 +}// namespace traits namespace traits { /** @name Manifold Traits */ //@{ -template struct TangentVector; -template struct DefaultChart; +template struct TangentVector; +template struct DefaultChart; //@} -} // namespace traits +}// namespace traits /* -template -class ManifoldConcept { + template + class ManifoldConcept { public: - typedef T Manifold; - typedef typename traits::TangentVector::type TangentVector; - typedef typename traits::DefaultChart::type DefaultChart; - static const size_t dim = traits::dimension::value; + typedef T Manifold; + typedef typename traits::TangentVector::type TangentVector; + typedef typename traits::DefaultChart::type DefaultChart; + static const size_t dim = traits::dimension::value; - BOOST_CONCEPT_USAGE(ManifoldConcept) { - BOOST_STATIC_ASSERT(boost::is_base_of >); - BOOST_STATIC_ASSERT(TangentVector::SizeAtCompileTime == dim); - // no direct usage for manifold since most usage is through a chart - } + BOOST_CONCEPT_USAGE(ManifoldConcept) { + BOOST_STATIC_ASSERT(boost::is_base_of >); + BOOST_STATIC_ASSERT(TangentVector::SizeAtCompileTime == dim); + // no direct usage for manifold since most usage is through a chart + } private: - Manifold p; - TangentVector v; -}; + Manifold p; + TangentVector v; + }; -template -class ChartConcept { + template + class ChartConcept { public: - typedef C Chart; - typedef typename traits::Manifold::type Manifold; - typedef typename traits::TangentVector::type TangentVector; + typedef C Chart; + typedef typename traits::Manifold::type Manifold; + typedef typename traits::TangentVector::type TangentVector; - BOOST_CONCEPT_USAGE(ChartConcept) { - v = Chart::local(p,q); // returns local coordinates of q w.r.t. origin p - q = Chart::retract(p,v); // returns retracted update of p with v - } + BOOST_CONCEPT_USAGE(ChartConcept) { + v = Chart::local(p,q); // returns local coordinates of q w.r.t. origin p + q = Chart::retract(p,v); // returns retracted update of p with v + } private: - Manifold p,q; - TangentVector v; + Manifold p,q; + TangentVector v; -}; -*/ + }; + */ + +namespace group { + +template +G compose(const G&g, const G& h); namespace traits { /** @name Group Traits */ //@{ -template struct identity; -template struct group_flavor; +template struct identity; +template 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 +template class Group { public: - typedef typename traits::identity::value_type identity_value_type; - typedef typename traits::group_flavor::type group_flavor_tag; typedef typename traits::structure_category::type structure_category_tag; + typedef typename group::traits::identity::value_type identity_value_type; + typedef typename group::traits::flavor::type group_flavor_tag; BOOST_CONCEPT_USAGE(Group) { - e = traits::identity::value; -// BOOST_STATIC_ASSERT(boost::is_base_of::type>::value ); + using group::compose; + BOOST_STATIC_ASSERT( + boost::is_base_of::value); + e = group::traits::identity::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::type); +// test2 = operator_usage(p, q, group::traits::_flavor::type); } bool check_invariants(const G& a, const G& b) { @@ -134,54 +149,53 @@ 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); } }; /* -template -class LieGroupConcept : public GroupConcept, public ManifoldConcept { + template + class LieGroupConcept : public GroupConcept, public ManifoldConcept { - BOOST_CONCEPT_USAGE(LieGroupConcept) { - BOOST_STATIC_ASSERT(boost::is_base_of >); - } -}; + BOOST_CONCEPT_USAGE(LieGroupConcept) { + BOOST_STATIC_ASSERT(boost::is_base_of >); + } + }; -template -class VectorSpaceConcept : public LieGroupConcept { - typedef typename traits::DefaultChart::type Chart; - typedef typename GroupConcept::identity identity; + template + class VectorSpaceConcept : public LieGroupConcept { + typedef typename traits::DefaultChart::type Chart; + typedef typename GroupConcept::identity identity; - BOOST_CONCEPT_USAGE(VectorSpaceConcept) { - BOOST_STATIC_ASSERT(boost::is_base_of >); - r = p+q; - r = -p; - r = p-q; - } + BOOST_CONCEPT_USAGE(VectorSpaceConcept) { + BOOST_STATIC_ASSERT(boost::is_base_of >); + r = p+q; + r = -p; + r = p-q; + } - bool check_invariants(const V& a, const V& b) { - return equal(compose(a, b), a+b) - && equal(inverse(a), -a) - && equal(between(a, b), b-a) - && equal(Chart::retract(a, b), a+b) - && equal(Chart::local(a, b), b-a); - } + bool check_invariants(const V& a, const V& b) { + return equal(compose(a, b), a+b) + && equal(inverse(a), -a) + && equal(between(a, b), b-a) + && equal(Chart::retract(a, b), a+b) + && equal(Chart::local(a, b), b-a); + } private: - V p,q,r; -}; -*/ + V p,q,r; + }; + */ } // namespace gtsam - diff --git a/gtsam/geometry/tests/testCyclic.cpp b/gtsam/geometry/tests/testCyclic.cpp index 8ea678a0f..7bc19a2b7 100644 --- a/gtsam/geometry/tests/testCyclic.cpp +++ b/gtsam/geometry/tests/testCyclic.cpp @@ -35,17 +35,28 @@ public: }; namespace traits { +/// Define Cyclic to be a model of the Group concept template struct structure_category > { typedef group_tag type; }; +} // \namespace traits + +namespace group { +template +Cyclic compose(const Cyclic&g, const Cyclic& h); + +namespace traits { +/// Define the trait that specifies Cyclic's identity element template struct identity > { static const Cyclic value; typedef Cyclic value_type; }; -template struct group_flavor > { - typedef additive_group_tag type; +/// Define the trait that asserts Cyclic is an additive group +template struct flavor > { + typedef additive_tag type; }; } // \namespace traits +} // \namespace group } // \namespace gtsam @@ -57,10 +68,12 @@ template struct group_flavor > { namespace gtsam { +namespace group { namespace traits { template const Cyclic identity >::value = Cyclic(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::value); + EXPECT_LONGS_EQUAL(0, group::traits::identity::value); BOOST_CONCEPT_ASSERT((Group)); }