Test DirectProduct by constructing dihedral group Dih6
							parent
							
								
									6c6abe0b6c
								
							
						
					
					
						commit
						9fc9e70dd6
					
				| 
						 | 
					@ -16,36 +16,56 @@
 | 
				
			||||||
 **/
 | 
					 **/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <gtsam/base/Group.h>
 | 
					#include <gtsam/base/Group.h>
 | 
				
			||||||
 | 
					#include <gtsam/base/Testable.h>
 | 
				
			||||||
#include <Eigen/Core>
 | 
					#include <Eigen/Core>
 | 
				
			||||||
#include <iostream>
 | 
					#include <iostream>
 | 
				
			||||||
 | 
					#include <boost/foreach.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace gtsam {
 | 
					namespace gtsam {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Symmetric group
 | 
				
			||||||
template<int N>
 | 
					template<int N>
 | 
				
			||||||
class Permutation: public Eigen::PermutationMatrix<N> {
 | 
					class Symmetric: private Eigen::PermutationMatrix<N> {
 | 
				
			||||||
public:
 | 
					  Symmetric(const Eigen::PermutationMatrix<N>& P) :
 | 
				
			||||||
  Permutation() {
 | 
					 | 
				
			||||||
    Eigen::PermutationMatrix<N>::setIdentity();
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  Permutation(const Eigen::PermutationMatrix<N>& P) :
 | 
					 | 
				
			||||||
      Eigen::PermutationMatrix<N>(P) {
 | 
					      Eigen::PermutationMatrix<N>(P) {
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  Permutation inverse() const {
 | 
					public:
 | 
				
			||||||
 | 
					  Symmetric() {
 | 
				
			||||||
 | 
					    Eigen::PermutationMatrix<N>::setIdentity();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  static Symmetric Transposition(int i, int j) {
 | 
				
			||||||
 | 
					    Symmetric g;
 | 
				
			||||||
 | 
					    return g.applyTranspositionOnTheRight(i, j);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  Symmetric operator*(const Symmetric& other) const {
 | 
				
			||||||
 | 
					    return Eigen::PermutationMatrix<N>::operator*(other);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  bool operator==(const Symmetric& other) const {
 | 
				
			||||||
 | 
					    for (size_t i = 0; i < N; i++)
 | 
				
			||||||
 | 
					      if (this->indices()[i] != other.indices()[i])
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    return true;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  Symmetric inverse() const {
 | 
				
			||||||
    return Eigen::PermutationMatrix<N>(Eigen::PermutationMatrix<N>::inverse());
 | 
					    return Eigen::PermutationMatrix<N>(Eigen::PermutationMatrix<N>::inverse());
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					  friend std::ostream &operator<<(std::ostream &os, const Symmetric& m) {
 | 
				
			||||||
 | 
					    for (size_t i = 0; i < N; i++)
 | 
				
			||||||
 | 
					      os << m.indices()[i] << " ";
 | 
				
			||||||
 | 
					    return os;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  void print(const std::string& s = "") const {
 | 
				
			||||||
 | 
					    std::cout << s << *this << std::endl;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  bool equals(const Symmetric<N>& other, double tol = 0) const {
 | 
				
			||||||
 | 
					    return this->indices() == other.indices();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Define permutation group traits to be a model of the Multiplicative Group concept
 | 
					/// Define permutation group traits to be a model of the Multiplicative Group concept
 | 
				
			||||||
template<int N>
 | 
					template<int N>
 | 
				
			||||||
struct traits<Permutation<N> > : internal::MultiplicativeGroupTraits<
 | 
					struct traits<Symmetric<N> > : internal::MultiplicativeGroupTraits<Symmetric<N> >,
 | 
				
			||||||
    Permutation<N> > {
 | 
					    Testable<Symmetric<N> > {
 | 
				
			||||||
  static void Print(const Permutation<N>& m, const std::string& str = "") {
 | 
					 | 
				
			||||||
    std::cout << m << std::endl;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  static bool Equals(const Permutation<N>& m1, const Permutation<N>& m2,
 | 
					 | 
				
			||||||
      double tol = 1e-8) {
 | 
					 | 
				
			||||||
    return m1.indices() == m2.indices();
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace gtsam
 | 
					} // namespace gtsam
 | 
				
			||||||
| 
						 | 
					@ -56,17 +76,61 @@ struct traits<Permutation<N> > : internal::MultiplicativeGroupTraits<
 | 
				
			||||||
using namespace std;
 | 
					using namespace std;
 | 
				
			||||||
using namespace gtsam;
 | 
					using namespace gtsam;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef Permutation<3> G; // Let's use the permutation group of order 3
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//******************************************************************************
 | 
					//******************************************************************************
 | 
				
			||||||
TEST(Group, Concept) {
 | 
					typedef Symmetric<2> S2;
 | 
				
			||||||
  BOOST_CONCEPT_ASSERT((IsGroup<G>));
 | 
					TEST(Group, S2) {
 | 
				
			||||||
 | 
					  S2 e, s1 = S2::Transposition(0, 1);
 | 
				
			||||||
 | 
					  BOOST_CONCEPT_ASSERT((IsGroup<S2>));
 | 
				
			||||||
 | 
					  EXPECT(check_group_invariants(e, s1));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//******************************************************************************
 | 
					//******************************************************************************
 | 
				
			||||||
TEST(Group , Invariants) {
 | 
					typedef Symmetric<3> S3;
 | 
				
			||||||
  G g, h;
 | 
					TEST(Group, S3) {
 | 
				
			||||||
  EXPECT(check_group_invariants(g, h));
 | 
					  S3 e, s1 = S3::Transposition(0, 1), s2 = S3::Transposition(1, 2);
 | 
				
			||||||
 | 
					  BOOST_CONCEPT_ASSERT((IsGroup<S3>));
 | 
				
			||||||
 | 
					  EXPECT(check_group_invariants(e, s1));
 | 
				
			||||||
 | 
					  EXPECT(assert_equal(s1, s1 * e));
 | 
				
			||||||
 | 
					  EXPECT(assert_equal(s1, e * s1));
 | 
				
			||||||
 | 
					  EXPECT(assert_equal(e, s1 * s1));
 | 
				
			||||||
 | 
					  S3 g = s1 * s2; // 1 2 0
 | 
				
			||||||
 | 
					  EXPECT(assert_equal(s1, g * s2));
 | 
				
			||||||
 | 
					  EXPECT(assert_equal(e, compose_pow(g, 0)));
 | 
				
			||||||
 | 
					  EXPECT(assert_equal(g, compose_pow(g, 1)));
 | 
				
			||||||
 | 
					  EXPECT(assert_equal(e, compose_pow(g, 3))); // g is generator of Z3 subgroup
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//******************************************************************************
 | 
				
			||||||
 | 
					// The direct product of S2=Z2 and S3 is the symmetry group of a hexagon,
 | 
				
			||||||
 | 
					// i.e., the dihedral group of order 12 (denoted Dih6 because 6-sided polygon)
 | 
				
			||||||
 | 
					typedef DirectProduct<S2, S3> Dih6;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					std::ostream &operator<<(std::ostream &os, const Dih6& m) {
 | 
				
			||||||
 | 
					  os << "( " << m.first << ", " << m.second << ")";
 | 
				
			||||||
 | 
					  return os;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Provide traits with Testable
 | 
				
			||||||
 | 
					namespace gtsam {
 | 
				
			||||||
 | 
					template<>
 | 
				
			||||||
 | 
					struct traits<Dih6> : internal::MultiplicativeGroupTraits<Dih6> {
 | 
				
			||||||
 | 
					  static void Print(const Dih6& m, const string& s = "") {
 | 
				
			||||||
 | 
					    cout << s << m << endl;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  static bool Equals(const Dih6& m1, const Dih6& m2, double tol = 1e-8) {
 | 
				
			||||||
 | 
					    return m1 == m2;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					} // namespace gtsam
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TEST(Group, Dih6) {
 | 
				
			||||||
 | 
					  Dih6 e, g(S2::Transposition(0, 1),
 | 
				
			||||||
 | 
					      S3::Transposition(0, 1) * S3::Transposition(1, 2));
 | 
				
			||||||
 | 
					  BOOST_CONCEPT_ASSERT((IsGroup<Dih6>));
 | 
				
			||||||
 | 
					  EXPECT(check_group_invariants(e, g));
 | 
				
			||||||
 | 
					  EXPECT(assert_equal(e, compose_pow(g, 0)));
 | 
				
			||||||
 | 
					  EXPECT(assert_equal(g, compose_pow(g, 1)));
 | 
				
			||||||
 | 
					  EXPECT(assert_equal(e, compose_pow(g, 6))); // g is generator of Z6 subgroup
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//******************************************************************************
 | 
					//******************************************************************************
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue