From 58f3945605de00aac3daba22c6b272e01563b19a Mon Sep 17 00:00:00 2001 From: dellaert Date: Sat, 23 May 2015 22:25:44 -0700 Subject: [PATCH] Moved DirectSum template to Group.h header --- gtsam/base/Group.h | 36 +++++++++++ gtsam/geometry/tests/testCyclic.cpp | 93 +++++++++++------------------ 2 files changed, 70 insertions(+), 59 deletions(-) diff --git a/gtsam/base/Group.h b/gtsam/base/Group.h index f97be5376..a9abf968d 100644 --- a/gtsam/base/Group.h +++ b/gtsam/base/Group.h @@ -24,6 +24,7 @@ #include #include #include +#include namespace gtsam { @@ -111,6 +112,41 @@ struct MultiplicativeGroupTraits : GroupTraits { static Class Inverse(const Class &g) { return g.inverse();} }; } // namespace internal + +/// Template to construct the direct sum of two additive groups +template +class DirectSum: public std::pair { + BOOST_CONCEPT_ASSERT((IsGroup)); // TODO(frank): check additive + BOOST_CONCEPT_ASSERT((IsGroup)); // TODO(frank): check additive + + const G& g() const { return this->first; } + const H& h() const { return this->second;} + +public: + // Construct from two subgroup elements + DirectSum(const G& g, const H& h):std::pair(g,h) { + } + /// Default constructor yields identity + DirectSum():std::pair(G::Identity(),H::Identity()) { + } + static DirectSum Identity() { + return DirectSum(); + } + DirectSum operator+(const DirectSum& other) const { + return DirectSum(g()+other.g(), h()+other.h()); + } + DirectSum operator-(const DirectSum& other) const { + return DirectSum(g()-other.g(), h()-other.h()); + } + DirectSum operator-() const { + return DirectSum(- g(), - h()); + } +}; + +// Define direct sums to be a model of the Additive Group concept +template +struct traits > : internal::AdditiveGroupTraits > {}; + } // namespace gtsam /** diff --git a/gtsam/geometry/tests/testCyclic.cpp b/gtsam/geometry/tests/testCyclic.cpp index eaacea5c3..22b4dc209 100644 --- a/gtsam/geometry/tests/testCyclic.cpp +++ b/gtsam/geometry/tests/testCyclic.cpp @@ -85,60 +85,21 @@ TEST(Cyclic , Invariants) { } //****************************************************************************** +// The Direct sum of Cyclic<2> and Cyclic<2> is *not* Cyclic<4>, but the +// smallest non-cyclic group called the Klein four-group: +typedef DirectSum, Cyclic<2> > K4; + namespace gtsam { -template -class DirectSum: public std::pair { - BOOST_CONCEPT_ASSERT((IsGroup)); // TODO(frank): check additive - BOOST_CONCEPT_ASSERT((IsGroup)); // TODO(frank): check additive - BOOST_CONCEPT_ASSERT((IsTestable)); - BOOST_CONCEPT_ASSERT((IsTestable)); - - const G& g() const { return this->first; } - const H& h() const { return this->second;} - -public: - // Construct from two subgroup elements - DirectSum(const G& g, const H& h):std::pair(g,h) {} - - /// Default constructor yields identity - DirectSum():std::pair(G::Identity(),H::Identity()) { +/// Define K4 to be a model of the Additive Group concept, and provide Testable +template<> +struct traits : internal::AdditiveGroupTraits { + static void Print(const K4& m, const string& s = "") { + cout << s << "(" << m.first << "," << m.second << ")" << endl; } - - /// Identity element - static DirectSum Identity() { - return DirectSum(); + static bool Equals(const K4& m1, const K4& m2, double tol = 1e-8) { + return m1 == m2; } - /// Addition - DirectSum operator+(const DirectSum& other) const { - return DirectSum(g()+other.g(), h()+other.h()); - } - /// Subtraction - DirectSum operator-(const DirectSum& other) const { - return DirectSum(g()-other.g(), h()-other.h()); - } - /// Inverse - DirectSum operator-() const { - return DirectSum(- g(), - h()); - } - /// print with optional string - void print(const std::string& s = "") const { - std::cout << s << "(\n"; - traits::Print(g()); - std::cout << ",\n"; - traits::Print(h()); - std::cout << ")" << std::endl; - } - /// equals with an tolerance, prints out message if unequal - bool equals(const DirectSum& other, double tol = 1e-9) const { - return *this == other; // uses std::pair operator - } -}; - -/// Define direct sums to be a model of the Additive Group concept -template -struct traits > : internal::AdditiveGroupTraits >, // - Testable > { }; } // namespace gtsam @@ -146,16 +107,30 @@ struct traits > : internal::AdditiveGroupTraits TEST(Cyclic , DirectSum) { // The Direct sum of Cyclic<2> and Cyclic<2> is *not* Cyclic<4>, but the // smallest non-cyclic group called the Klein four-group: - typedef DirectSum, Cyclic<2> > K; - BOOST_CONCEPT_ASSERT((IsGroup)); - BOOST_CONCEPT_ASSERT((IsTestable)); + typedef DirectSum, Cyclic<2> > K4; + BOOST_CONCEPT_ASSERT((IsGroup)); + BOOST_CONCEPT_ASSERT((IsTestable)); - K g(0, 1), h(1, 1); - EXPECT(assert_equal(K(0, 1), - g)); - EXPECT(assert_equal(K(), g + g)); - EXPECT(assert_equal(K(1, 0), g + h)); - EXPECT(assert_equal(K(1, 0), g - h)); - check_group_invariants(g, h); + // Refer to http://en.wikipedia.org/wiki/Klein_four-group + K4 e(0,0), a(0, 1), b(1, 0), c(1, 1); + EXPECT(assert_equal(a, - a)); + EXPECT(assert_equal(b, - b)); + EXPECT(assert_equal(c, - c)); + EXPECT(assert_equal(a, a + e)); + EXPECT(assert_equal(b, b + e)); + EXPECT(assert_equal(c, c + e)); + EXPECT(assert_equal(e, a + a)); + EXPECT(assert_equal(e, b + b)); + EXPECT(assert_equal(e, c + c)); + EXPECT(assert_equal(c, a + b)); + EXPECT(assert_equal(b, a + c)); + EXPECT(assert_equal(a, b + c)); + EXPECT(assert_equal(c, a - b)); + EXPECT(assert_equal(a, b - c)); + EXPECT(assert_equal(b, c - a)); + check_group_invariants(a, b); + check_group_invariants(b, c); + check_group_invariants(c, a); } //******************************************************************************