Now work with MACROS instead - but get linking error. Upside (if we can fix that): uniform treatment between foreign types (see Quaternion) and GTSAM types (Cyclic). Downside: seems I had to create a different macro for different number of template arguments. Help?
parent
38a0842090
commit
9194b92cf6
|
@ -149,6 +149,17 @@ check_invariants(const T& a, const T& b, double tol = 1e-9) {
|
|||
}
|
||||
} // \ namespace group
|
||||
|
||||
#define GTSAM_ADDITIVE_GROUP1(T1,A1,GROUP) \
|
||||
namespace group { \
|
||||
template<T1 A1> GROUP<A1> compose(const GROUP<A1> &g, const GROUP<A1> & h) { return g + h;} \
|
||||
template<T1 A1> GROUP<A1> between(const GROUP<A1> &g, const GROUP<A1> & h) { return h - g;} \
|
||||
template<T1 A1> GROUP<A1> inverse(const GROUP<A1> &g) { return -g;} \
|
||||
namespace traits { \
|
||||
template<T1 A1> struct identity<GROUP<A1> > { static const GROUP<A1> value; typedef GROUP<A1> value_type;};\
|
||||
template<T1 A1> const GROUP<A1> identity<GROUP<A1> >::value = GROUP<A1>::Identity();\
|
||||
template<T1 A1> struct flavor<GROUP<A1> > { typedef additive_tag type;};\
|
||||
}}
|
||||
|
||||
#define GTSAM_MULTIPLICATIVE_GROUP2(T1,A1,T2,A2,GROUP) \
|
||||
namespace group { \
|
||||
template<T1 A1, T2 A2> GROUP<A1,A2> compose(const GROUP<A1,A2> &g, const GROUP<A1,A2> & h) { return g * h;} \
|
||||
|
|
|
@ -20,34 +20,15 @@
|
|||
|
||||
namespace gtsam {
|
||||
|
||||
/// Additive Group, using CRTP
|
||||
template<typename Derived>
|
||||
struct AdditiveGroup {
|
||||
static Derived Identity() {
|
||||
return Derived::Identity();
|
||||
}
|
||||
Derived const * derived() const {
|
||||
return static_cast<Derived const*>(this);
|
||||
}
|
||||
Derived operator+(const AdditiveGroup& h) const {
|
||||
return derived()->operator+(*h.derived());
|
||||
}
|
||||
Derived operator-(const AdditiveGroup& h) const {
|
||||
return derived()->operator-(*h.derived());
|
||||
}
|
||||
Derived operator-() const {
|
||||
return derived()->operator-();
|
||||
}
|
||||
};
|
||||
|
||||
/// Cyclic group of order N
|
||||
template<size_t N>
|
||||
class Cyclic : public AdditiveGroup<Cyclic<N> > {
|
||||
class Cyclic {
|
||||
size_t i_; ///< we just use an unsigned int
|
||||
public:
|
||||
/// Constructor
|
||||
Cyclic(size_t i) :
|
||||
i_(i) {
|
||||
assert(i<N);
|
||||
}
|
||||
// Idenity element
|
||||
static Cyclic Identity() {
|
||||
|
@ -81,48 +62,15 @@ public:
|
|||
|
||||
};
|
||||
|
||||
GTSAM_ADDITIVE_GROUP1(size_t,N,Cyclic)
|
||||
|
||||
namespace traits {
|
||||
/// Define any additive group to be at least a model of the Group concept
|
||||
template<typename G>
|
||||
struct structure_category<AdditiveGroup<G> > {
|
||||
/// Define cyclic group to be a model of the Group concept
|
||||
template<size_t N>
|
||||
struct structure_category<Cyclic<N> > {
|
||||
typedef group_tag type;
|
||||
};
|
||||
} // \namespace gtsam::traits
|
||||
|
||||
namespace group {
|
||||
|
||||
template<typename G>
|
||||
G compose(const AdditiveGroup<G>&g, const AdditiveGroup<G>& h) {
|
||||
return g + h;
|
||||
}
|
||||
|
||||
template<typename G>
|
||||
G between(const AdditiveGroup<G>&g, const AdditiveGroup<G>& h) {
|
||||
return h - g;
|
||||
}
|
||||
|
||||
template<typename G>
|
||||
G inverse(const AdditiveGroup<G>&g) {
|
||||
return -g;
|
||||
}
|
||||
|
||||
namespace traits {
|
||||
|
||||
/// Define the trait that specifies Cyclic's identity element
|
||||
template<typename G> struct identity<AdditiveGroup<G> > {
|
||||
static const G value;
|
||||
typedef G value_type;
|
||||
};
|
||||
|
||||
template<typename G>
|
||||
const G identity<AdditiveGroup<G> >::value = AdditiveGroup<G>::Identity();
|
||||
|
||||
/// Define the trait that asserts AdditiveGroup is an additive group
|
||||
template<typename G> struct flavor<AdditiveGroup<G> > {
|
||||
typedef additive_tag type;
|
||||
};
|
||||
|
||||
} // \namespace gtsam::group::traits
|
||||
} // \namespace gtsam::group
|
||||
} // \namespace gtsam
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ typedef Cyclic<6> G; // Let's use the cyclic group of order 6
|
|||
|
||||
//******************************************************************************
|
||||
TEST(Cyclic, Concept) {
|
||||
// BOOST_CONCEPT_ASSERT((IsGroup<G>));
|
||||
BOOST_CONCEPT_ASSERT((IsGroup<G>));
|
||||
// BOOST_CONCEPT_ASSERT((IsGroup<AdditiveGroup<G> >));
|
||||
EXPECT_LONGS_EQUAL(0, group::traits::identity<G>::value);
|
||||
G g(2), h(3);
|
||||
|
|
Loading…
Reference in New Issue