structure_tag works

release/4.3a0
dellaert 2014-12-06 11:17:54 +01:00
parent 71e77b8c87
commit 07ef30039a
2 changed files with 38 additions and 30 deletions

View File

@ -24,7 +24,7 @@ namespace traits {
*/ */
//@{ //@{
template <class T> 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
//@} //@}
/** /**
@ -92,8 +92,8 @@ namespace traits {
/** @name Group Traits */ /** @name Group Traits */
//@{ //@{
template <class Group> struct identity {}; template <class Group> struct identity;
template <class Group> struct group_flavor {}; template <class Group> struct group_flavor;
//@} //@}
/** @name Group Flavor Tags */ /** @name Group Flavor Tags */
@ -104,41 +104,50 @@ struct multiplicative_group_tag {};
} // namespace traits } // namespace traits
/**
* Group Concept
*/
template<class G> template<class G>
class GroupConcept { class Group {
public: public:
typedef G Group;
static const Group identity = traits::identity<G>::value;
BOOST_CONCEPT_USAGE(GroupConcept) { typedef typename traits::identity<G>::value_type identity_value_type;
BOOST_STATIC_ASSERT(boost::is_base_of<traits::group_tag,typename traits::structure_category<Group>::type>::value ); typedef typename traits::group_flavor<G>::type group_flavor_tag;
Group ip = inverse(p); typedef typename traits::structure_category<G>::type structure_category_tag;
Group pq = compose(p, q);
Group d = between(p, q); BOOST_CONCEPT_USAGE(Group) {
test = equal(p, q); e = traits::identity<G>::value;
test2 = operator_usage(p, q, traits::group_flavor<Group>::type); // BOOST_STATIC_ASSERT(boost::is_base_of<traits::group_tag,typename traits::structure_category<Group>::type>::value );
// 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);
} }
bool check_invariants(const Group& a, const Group& b) { bool check_invariants(const G& a, const G& b) {
return (equal(compose(a, inverse(a)), identity)) group_flavor_tag group_flavor;
return (equal(compose(a, inverse(a)), e))
&& (equal(between(a, b), compose(inverse(a), b))) && (equal(between(a, b), compose(inverse(a), b)))
&& (equal(compose(a, between(a, b)), b)) && (equal(compose(a, between(a, b)), b))
&& operator_usage(a, b, traits::group_flavor<Group>::type); && operator_usage(a, b, group_flavor);
} }
private: private:
Group p,q; G p, q, e;
bool test, test2; bool test, test2;
bool operator_usage(const Group& a, const Group& b, const traits::multiplicative_group_tag&) { bool operator_usage(const G& a, const G& b,
traits::multiplicative_group_tag) {
return equal(compose(a, b), a * b); return equal(compose(a, b), a * b);
} }
bool operator_usage(const Group& a, const Group& b, const traits::additive_group_tag&) { bool operator_usage(const G& a, const G& b, traits::additive_group_tag) {
return equal(compose(a, b), a + b); return equal(compose(a, b), a + b);
} }
}; };
/* /*
template <class L> template <class L>
class LieGroupConcept : public GroupConcept<L>, public ManifoldConcept<L> { class LieGroupConcept : public GroupConcept<L>, public ManifoldConcept<L> {

View File

@ -11,7 +11,7 @@
/** /**
* @file Cyclic.h * @file Cyclic.h
* @brief Cyclic group, can act on 2D vector spaces * @brief Cyclic group, i.e., the integers modulo N
* @author Frank Dellaert * @author Frank Dellaert
**/ **/
@ -35,6 +35,9 @@ public:
}; };
namespace traits { namespace traits {
template<size_t N> struct structure_category<Cyclic<N> > {
typedef group_tag type;
};
template<size_t N> struct identity<Cyclic<N> > { template<size_t N> struct identity<Cyclic<N> > {
static const Cyclic<N> value; static const Cyclic<N> value;
typedef Cyclic<N> value_type; typedef Cyclic<N> value_type;
@ -74,21 +77,17 @@ const Cyclic<N> identity<Cyclic<N> >::value = Cyclic<N>(0);
using namespace std; using namespace std;
using namespace gtsam; using namespace gtsam;
typedef Cyclic<6> G; typedef Cyclic<6> G; // Let's use the cyclic group of order 6
//****************************************************************************** //******************************************************************************
TEST(Cyclic, Concept) { TEST(Cyclic, Concept) {
EXPECT_LONGS_EQUAL(0,traits::identity<G>::value); EXPECT_LONGS_EQUAL(0,traits::identity<G>::value);
//BOOST_CONCEPT_ASSERT((GroupConcept<Cyclic<6> >)); BOOST_CONCEPT_ASSERT((Group<G>));
// EXPECT(assert_equal(p1, p2));
// EXPECT_LONGS_EQUAL(2,offset2.size());
} }
//****************************************************************************** //******************************************************************************
TEST(Cyclic, Constructor) { TEST(Cyclic, Constructor) {
G g(0); G g(0);
// EXPECT(assert_equal(p1, p2));
// EXPECT_LONGS_EQUAL(2,offset2.size());
} }
//****************************************************************************** //******************************************************************************