From d67768d85cf968ece03aa65a32d9e3864e44a371 Mon Sep 17 00:00:00 2001 From: David Allemang Date: Sun, 31 Oct 2021 21:19:46 -0400 Subject: [PATCH] Use Eigen::SelfAdjointView for mults. --- .gitmodules | 3 + CMakeLists.txt | 6 +- ext/CMakeLists.txt | 2 + ext/eigen | 1 + include/tc/core/group.hpp | 130 +++++++++++++++++++++++--------------- include/tc/groups.hpp | 10 +-- 6 files changed, 93 insertions(+), 59 deletions(-) create mode 100644 .gitmodules create mode 100644 ext/CMakeLists.txt create mode 160000 ext/eigen diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..f297983 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "ext/eigen"] + path = ext/eigen + url = https://gitlab.com/libeigen/eigen.git diff --git a/CMakeLists.txt b/CMakeLists.txt index f8a670b..90de0e6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,8 +3,10 @@ project(toddcox-faster) option(TC_BUILD_EXAMPLE "Build example executables" OFF) -add_library(tc INTERFACE - ) +add_subdirectory(ext) + +add_library(tc INTERFACE) +target_link_libraries(tc INTERFACE eigen) target_include_directories(tc INTERFACE include) diff --git a/ext/CMakeLists.txt b/ext/CMakeLists.txt new file mode 100644 index 0000000..d5c2a27 --- /dev/null +++ b/ext/CMakeLists.txt @@ -0,0 +1,2 @@ +add_library(eigen INTERFACE) +target_include_directories(eigen INTERFACE eigen) diff --git a/ext/eigen b/ext/eigen new file mode 160000 index 0000000..b3bea43 --- /dev/null +++ b/ext/eigen @@ -0,0 +1 @@ +Subproject commit b3bea43a2da484d420e20c615cb5c9e3c04024e5 diff --git a/include/tc/core/group.hpp b/include/tc/core/group.hpp index cec60ae..f7ba567 100644 --- a/include/tc/core/group.hpp +++ b/include/tc/core/group.hpp @@ -10,79 +10,63 @@ #include "rel.hpp" #include "cosets.hpp" +#include +#include + namespace tc { struct Group; struct SubGroup; struct Group { - int ngens; - std::vector> _mults; - std::string name; + using Matrix = Eigen::MatrixXi; - Group(const Group &) = default; + int ngens; + std::string name; + Matrix _data; + Eigen::SelfAdjointView _mults; + + Group(const Group &g) + : ngens(g.ngens), + name(g.name), + _data(g._data), + _mults(_data) { + } + + Group(Group &&g) noexcept + : ngens(g.ngens), + name(std::move(g.name)), + _data(std::move(g._data)), + _mults(_data) { + } explicit Group( int ngens, - const std::vector &rels = {}, std::string name = "G" - ) : ngens(ngens), name(std::move(name)) { - _mults.resize(ngens); - - for (auto &mult: _mults) { - mult.resize(ngens, 2); - } - - for (const auto &rel: rels) { - set(rel); - } + ) : ngens(ngens), + name(std::move(name)), + _data(ngens, ngens), + _mults(_data) { + _data.fill(2); } - void set(const Rel &r) { - _mults[r.gens[0]][r.gens[1]] = r.mult; - _mults[r.gens[1]][r.gens[0]] = r.mult; + Matrix::Scalar &operator()(int a, int b) { + return _mults(a, b); } - [[nodiscard]] int get(int a, int b) const { - return _mults[a][b]; + Matrix::Scalar operator()(int a, int b) const { + return _mults(a, b); } [[nodiscard]] std::vector get_rels() const { std::vector res; for (int i = 0; i < ngens - 1; ++i) { for (int j = i + 1; j < ngens; ++j) { - res.emplace_back(i, j, get(i, j)); + res.emplace_back(i, j, operator()(i, j)); } } return res; } - [[nodiscard]] Group product(const Group &other) const { - std::stringstream ss; - ss << name << "*" << other.name; - - Group g(ngens + other.ngens, get_rels(), ss.str()); - - for (const auto &rel: other.get_rels()) { - g.set(rel.shift(ngens)); - } - - return g; - } - - [[nodiscard]] Group power(int p) const { - std::stringstream ss; - ss << name << "^" << p; - - Group g(ngens * p, {}, ss.str()); - for (const auto &rel: get_rels()) { - for (int off = 0; off < g.ngens; off += ngens) { - g.set(rel.shift(off)); - } - } - - return g; - } - [[nodiscard]] SubGroup subgroup( const std::vector &gens ) const; @@ -103,8 +87,8 @@ namespace tc { for (size_t i = 0; i < gen_map.size(); ++i) { for (size_t j = 0; j < gen_map.size(); ++j) { - int mult = parent.get(gen_map[i], gen_map[j]); - set(Rel(i, j, mult)); + int mult = parent(gen_map[i], gen_map[j]); + operator()(i, j) = mult; } } } @@ -114,12 +98,54 @@ namespace tc { return SubGroup(*this, gens); } + Group product(const Group &g, const Group &h) { + std::stringstream ss; + ss << g.name << "*" << h.name; + + Group res(g.ngens + h.ngens, ss.str()); + + int off = 0; + + for (int i = 0; i < g.ngens; ++i) { + for (int j = i; j < g.ngens; ++j) { + res(i + off, j + off) = g(i, j); + } + } + off += g.ngens; + + for (int i = 0; i < h.ngens; ++i) { + for (int j = i; j < h.ngens; ++j) { + res(i + off, j + off) = h(i, j); + } + } + + return res; + } + + Group power(const Group &g, int p) { + std::stringstream ss; + ss << g.name << "^" << p; + + Group res(g.ngens * p, ss.str()); + + for (int i = 0; i < g.ngens; ++i) { + for (int j = i; j < g.ngens; ++j) { + for (int k = 0; k < p; ++k) { + int off = k * g.ngens; + res(i + off, j + off) = g(i, j); + } + } + } + + return res; + } + Group operator*(const Group &g, const Group &h) { - return g.product(h); + return product(g, h); } Group operator^(const Group &g, int p) { - return g.power(p); + return power(g, p); } } diff --git a/include/tc/groups.hpp b/include/tc/groups.hpp index 22012fe..8f60941 100644 --- a/include/tc/groups.hpp +++ b/include/tc/groups.hpp @@ -10,10 +10,10 @@ namespace tc { Group schlafli(const std::vector &mults, const std::string &name) { int ngens = (int) mults.size() + 1; - Group g(ngens, {}, name); + Group g(ngens, name); for (int i = 0; i < (int) mults.size(); i++) { - g.set(Rel(i, i + 1, mults[i])); + g(i, i + 1) = mults[i]; } return g; @@ -46,7 +46,7 @@ namespace tc { ss << "A(" << dim << ")"; if (dim == 0) - return Group(0, {}, ss.str()); + return Group(0, ss.str()); const std::vector &mults = std::vector(dim - 1, 3); @@ -77,7 +77,7 @@ namespace tc { mults[dim - 2] = 2; Group g = schlafli(mults, ss.str()); - g.set(Rel(1, dim - 1, 3)); + g(1, dim - 1) = 3; return g; } @@ -93,7 +93,7 @@ namespace tc { mults[dim - 2] = 2; Group g = schlafli(mults, ss.str()); - g.set(Rel(2, dim - 1, 3)); + g(2, dim - 1) = 3; return g; }