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