From 873102a8c381b8258daa4f03c10b92ebb6208b7e Mon Sep 17 00:00:00 2001 From: David Allemang Date: Fri, 27 Dec 2019 21:58:15 -0500 Subject: [PATCH] introduce RelationSet, fix namespace for groups.cpp/.h --- example/bench.cpp | 3 ++- include/cosets.h | 40 +++++++++++++++-------------- include/groups.h | 4 ++- src/cosets.cpp | 64 +++++++++++++++++++++++------------------------ src/groups.cpp | 16 ++++++------ src/solver.cpp | 55 +++++++++++++++++++++------------------- 6 files changed, 95 insertions(+), 87 deletions(-) diff --git a/example/bench.cpp b/example/bench.cpp index f7c35c1..2034529 100644 --- a/example/bench.cpp +++ b/example/bench.cpp @@ -4,7 +4,8 @@ #include int main() { - tc::Group g = tc::group::T(2, 5000); + tc::Group g = tc::group::H(4); +// tc::Group g = tc::group::T(2, 5000); auto s = std::chrono::system_clock::now(); auto cosets = solve(g); diff --git a/include/cosets.h b/include/cosets.h index d6e5efe..59bc3c4 100644 --- a/include/cosets.h +++ b/include/cosets.h @@ -3,31 +3,33 @@ #include "groups.h" #include -struct Cosets { - int ngens; - std::vector data; - int len; +namespace tc { + struct Cosets { + int ngens; + std::vector data; + int len; - Cosets(int ngens, const std::vector &data); + Cosets(int ngens, const std::vector &data); - void add_row(); + void add_row(); - void put(int coset, int gen, int target); + void put(int coset, int gen, int target); - void put(int idx, int target); + void put(int idx, int target); - [[nodiscard]] int get(int coset, int gen) const; + [[nodiscard]] int get(int coset, int gen) const; - [[nodiscard]] int get(int idx) const; -}; + [[nodiscard]] int get(int idx) const; + }; -struct RelTable { - int gens[2]{}; - int mult; - std::vector lst_ptr; - std::vector gen; + struct RelTable { + Mult mult; - explicit RelTable(tc::Mult m); + std::vector lst_ptr; + std::vector gen; - int add_row(); -}; + explicit RelTable(tc::Mult m); + + int add_row(); + }; +} \ No newline at end of file diff --git a/include/groups.h b/include/groups.h index 78d7a63..8bd29e3 100644 --- a/include/groups.h +++ b/include/groups.h @@ -1,10 +1,12 @@ #pragma once +#include #include namespace tc { struct Mult { - int gen0, gen1, mult; + std::array gens; + int mult; }; struct Group { diff --git a/src/cosets.cpp b/src/cosets.cpp index 5f5db61..5140c57 100644 --- a/src/cosets.cpp +++ b/src/cosets.cpp @@ -1,42 +1,42 @@ #include "cosets.h" -Cosets::Cosets(int ngens, const std::vector &data) : ngens(ngens), data(data) { - len = data.size() / ngens; -} +namespace tc { + Cosets::Cosets(int ngens, const std::vector &data) : ngens(ngens), data(data) { + len = data.size() / ngens; + } -void Cosets::add_row() { - len++; - data.resize(data.size() + ngens, -1); -} + void Cosets::add_row() { + len++; + data.resize(data.size() + ngens, -1); + } -void Cosets::put(int coset, int gen, int target) { - data[coset * ngens + gen] = target; - data[target * ngens + gen] = coset; -} + void Cosets::put(int coset, int gen, int target) { + data[coset * ngens + gen] = target; + data[target * ngens + gen] = coset; + } -void Cosets::put(int idx, int target) { - int coset = idx / ngens; - int gen = idx % ngens; - data[idx] = target; - data[target * ngens + gen] = coset; -} + void Cosets::put(int idx, int target) { + int coset = idx / ngens; + int gen = idx % ngens; + data[idx] = target; + data[target * ngens + gen] = coset; + } -int Cosets::get(int coset, int gen) const { - return data[coset * ngens + gen]; -} + int Cosets::get(int coset, int gen) const { + return data[coset * ngens + gen]; + } -int Cosets::get(int idx) const { - return data[idx]; -} + int Cosets::get(int idx) const { + return data[idx]; + } -RelTable::RelTable(tc::Mult m) : mult(m.mult) { - gens[0] = m.gen0; - gens[1] = m.gen1; -} + RelTable::RelTable(tc::Mult m) : mult(m) { + } -int RelTable::add_row() { - int idx = lst_ptr.size(); - lst_ptr.push_back(nullptr); - gen.push_back(-1); - return idx; + int RelTable::add_row() { + int idx = lst_ptr.size(); + lst_ptr.push_back(nullptr); + gen.push_back(-1); + return idx; + } } \ No newline at end of file diff --git a/src/groups.cpp b/src/groups.cpp index 61663f6..02756b5 100644 --- a/src/groups.cpp +++ b/src/groups.cpp @@ -8,18 +8,18 @@ namespace tc { } for (Mult m : rels) { - if (m.gen0 < m.gen1) - _mults[m.gen0][m.gen1] = m.mult; + if (m.gens[0] < m.gens[1]) + _mults[m.gens[0]][m.gens[1]] = m.mult; else - _mults[m.gen1][m.gen0] = m.mult; + _mults[m.gens[1]][m.gens[0]] = m.mult; } } void Group::setmult(Mult m) { - if (m.gen0 < m.gen1) - _mults[m.gen0][m.gen1] = m.mult; + if (m.gens[0] < m.gens[1]) + _mults[m.gens[0]][m.gens[1]] = m.mult; else - _mults[m.gen1][m.gen0] = m.mult; + _mults[m.gens[1]][m.gens[0]] = m.mult; } std::vector Group::get_mults() const { @@ -38,7 +38,7 @@ namespace tc { Group g(ngens + other.ngens, get_mults()); for (Mult m : other.get_mults()) { - g.setmult({off + m.gen0, off + m.gen1, m.mult}); + g.setmult({off + m.gens[0], off + m.gens[1], m.mult}); } return g; @@ -49,7 +49,7 @@ namespace tc { for (Mult m : get_mults()) { for (int off = 0; off < g.ngens; off += ngens) { - g.setmult({off + m.gen0, off + m.gen1, m.mult}); + g.setmult({off + m.gens[0], off + m.gens[1], m.mult}); } } diff --git a/src/solver.cpp b/src/solver.cpp index 1cc41b3..a4fab24 100644 --- a/src/solver.cpp +++ b/src/solver.cpp @@ -1,9 +1,23 @@ #include "solver.h" #include -#include namespace tc { + struct RelationSet { + std::vector tables; + std::vector> gen_map; // which relations involve which generators + + explicit RelationSet(const Group &g) : gen_map(g.ngens) { + const std::vector &mults = g.get_mults(); + tables.reserve(mults.size()); + for (const auto &mult : mults) { + RelTable &table = tables.emplace_back(mult); + gen_map[mult.gens[0]].push_back(&table); + gen_map[mult.gens[1]].push_back(&table); + } + } + }; + Cosets solve(const Group &group, const std::vector &sub_gens) { std::vector init_row(group.ngens, -1); for (int i : sub_gens) { @@ -11,21 +25,13 @@ namespace tc { } Cosets cosets(group.ngens, init_row); - std::vector rel_tables; - std::vector> gen_map(group.ngens); - int rel_idx; - for (Mult m : group.get_mults()) { - rel_idx = rel_tables.size(); - gen_map[m.gen0].push_back(rel_idx); - gen_map[m.gen1].push_back(rel_idx); - rel_tables.emplace_back(m); - } + RelationSet rels(group); int null_lst_ptr; - for (RelTable &rel : rel_tables) { + for (RelTable &rel : rels.tables) { int idx = rel.add_row(); - if (cosets.get(rel.gens[0]) + cosets.get(rel.gens[1]) == -2) { + if (cosets.get(rel.mult.gens[0]) + cosets.get(rel.mult.gens[1]) == -2) { rel.lst_ptr[idx] = new int; rel.gen[idx] = 0; } else { @@ -46,16 +52,13 @@ namespace tc { target = cosets.len; cosets.add_row(); - for (RelTable &rel : rel_tables) { + for (RelTable &rel : rels.tables) { rel.add_row(); } std::vector facts; facts.push_back(idx); - coset = idx / group.ngens; - gen = idx % group.ngens; - while (!facts.empty()) { fact_idx = facts.back(); facts.pop_back(); @@ -68,8 +71,8 @@ namespace tc { coset = fact_idx / group.ngens; gen = fact_idx % group.ngens; - for (int rel_idx : gen_map[gen]) { - RelTable &rel = rel_tables[rel_idx]; + for (RelTable *rel_idx : rels.gen_map[gen]) { + RelTable &rel = *rel_idx; if (rel.lst_ptr[target] == nullptr) { rel.lst_ptr[target] = rel.lst_ptr[coset]; rel.gen[target] = rel.gen[coset] + 1; @@ -77,15 +80,15 @@ namespace tc { if (rel.gen[coset] < 0) rel.gen[target] -= 2; - if (rel.gen[target] == rel.mult) { + if (rel.gen[target] == rel.mult.mult) { lst = *(rel.lst_ptr[target]); delete rel.lst_ptr[target]; - gen_ = rel.gens[(int) (rel.gens[0] == gen)]; + gen_ = rel.mult.gens[(int) (rel.mult.gens[0] == gen)]; facts.push_back(lst * group.ngens + gen_); - } else if (rel.gen[target] == -rel.mult) { - gen_ = rel.gens[rel.gens[0] == gen]; + } else if (rel.gen[target] == -rel.mult.mult) { + gen_ = rel.mult.gens[rel.mult.gens[0] == gen]; facts.push_back(target * group.ngens + gen_); - } else if (rel.gen[target] == rel.mult - 1) { + } else if (rel.gen[target] == rel.mult.mult - 1) { *(rel.lst_ptr[target]) = target; } } @@ -94,10 +97,10 @@ namespace tc { std::sort(facts.begin(), facts.end(), std::greater<>()); } - for (RelTable &rel : rel_tables) { + for (RelTable &rel : rels.tables) { if (rel.lst_ptr[target] == nullptr) { - if ((cosets.get(target, rel.gens[0]) != target) and - (cosets.get(target, rel.gens[1]) != target)) { + if ((cosets.get(target, rel.mult.gens[0]) != target) and + (cosets.get(target, rel.mult.gens[1]) != target)) { rel.lst_ptr[target] = new int; rel.gen[target] = 0; } else {