between and inverse, as well as tag dispatching

release/4.3a0
dellaert 2014-12-06 11:51:44 +01:00
parent ddeb764912
commit 5407232e36
2 changed files with 26 additions and 14 deletions

View File

@ -95,8 +95,12 @@ template<class Manifold> struct DefaultChart;
namespace group { namespace group {
template<typename G> /** @name Free functions any Group needs to define */
G compose(const G&g, const G& h); //@{
template<typename G> G compose(const G&g, const G& h);
template<typename G> G between(const G&g, const G& h);
template<typename G> G inverse(const G&g);
//@}
namespace traits { namespace traits {
@ -126,39 +130,41 @@ public:
typedef typename traits::structure_category<G>::type structure_category_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::identity<G>::value_type identity_value_type;
typedef typename group::traits::flavor<G>::type group_flavor_tag; typedef typename group::traits::flavor<G>::type flavor_tag;
BOOST_CONCEPT_USAGE(Group) { BOOST_CONCEPT_USAGE(Group) {
using group::compose; using group::compose;
using group::between;
using group::inverse;
BOOST_STATIC_ASSERT( BOOST_STATIC_ASSERT(
boost::is_base_of<traits::group_tag, structure_category_tag>::value); boost::is_base_of<traits::group_tag, structure_category_tag>::value);
e = group::traits::identity<G>::value; e = group::traits::identity<G>::value;
pq = compose(p, q); d = compose(g, h);
// G ip = inverse(p); d = between(g, h);
// G d = between(p, q); ig = inverse(g);
// test = equal(p, q); test = operator_usage(g, h, flavor);
// test2 = operator_usage(p, q, group::traits::_flavor<Group>::type); // test2 = equal(g, h);
} }
bool check_invariants(const G& a, const G& b) { bool check_invariants(const G& a, const G& b) {
group_flavor_tag group_flavor;
return (equal(compose(a, inverse(a)), e)) 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, group_flavor); && operator_usage(a, b, flavor);
} }
private: private:
G e, p, q, pq, ip, d; flavor_tag flavor;
G e, g, h, gh, ig, d;
bool test, test2; bool test, test2;
bool operator_usage(const G& a, const G& b, bool operator_usage(const G& a, const G& b,
group::traits::multiplicative_tag) { group::traits::multiplicative_tag) {
return equal(compose(a, b), a * b); return group::compose(a, b) == a * b;
} }
bool operator_usage(const G& a, const G& b, group::traits::additive_tag) { bool operator_usage(const G& a, const G& b, group::traits::additive_tag) {
return equal(compose(a, b), a + b); return group::compose(a, b) == a + b;
} }
}; };
@ -193,7 +199,7 @@ private:
} }
private: private:
V p,q,r; V g,q,r;
}; };
*/ */

View File

@ -45,6 +45,12 @@ namespace group {
template<size_t N> template<size_t N>
Cyclic<N> compose(const Cyclic<N>&g, const Cyclic<N>& h); Cyclic<N> compose(const Cyclic<N>&g, const Cyclic<N>& h);
template<size_t N>
Cyclic<N> between(const Cyclic<N>&g, const Cyclic<N>& h);
template<size_t N>
Cyclic<N> inverse(const Cyclic<N>&g);
namespace traits { namespace traits {
/// Define the trait that specifies Cyclic's identity element /// Define the trait that specifies Cyclic's identity element
template<size_t N> struct identity<Cyclic<N> > { template<size_t N> struct identity<Cyclic<N> > {