From c3e304391263d66733a3d53e081bb228388f9e15 Mon Sep 17 00:00:00 2001 From: David Allemang Date: Tue, 13 Sep 2022 22:28:56 -0400 Subject: [PATCH] convert Group::solve to tc::solve function --- tc/CMakeLists.txt | 3 +- tc/include/tc/core.hpp | 4 ++ tc/include/tc/group.hpp | 2 - tc/src/core.cpp | 150 ++++++++++++++++++++++++++++++++++++++ tc/src/solve.cpp | 155 ---------------------------------------- tc/test/test_solve.cpp | 4 +- 6 files changed, 157 insertions(+), 161 deletions(-) delete mode 100644 tc/src/solve.cpp diff --git a/tc/CMakeLists.txt b/tc/CMakeLists.txt index 294c5ce..ef41cad 100644 --- a/tc/CMakeLists.txt +++ b/tc/CMakeLists.txt @@ -6,8 +6,7 @@ add_library(tc include/tc/groups.hpp include/tc/util.hpp src/core.cpp - src/groups.cpp - src/solve.cpp) + src/groups.cpp) target_include_directories(tc PUBLIC include) diff --git a/tc/include/tc/core.hpp b/tc/include/tc/core.hpp index 4bc516b..685f15c 100644 --- a/tc/include/tc/core.hpp +++ b/tc/include/tc/core.hpp @@ -8,3 +8,7 @@ #include "util.hpp" #include "cosets.hpp" #include "group.hpp" + +namespace tc { + Cosets solve(const Group &group, const std::vector &sub_gens); +} diff --git a/tc/include/tc/group.hpp b/tc/include/tc/group.hpp index 85d5e7b..6d4190d 100644 --- a/tc/include/tc/group.hpp +++ b/tc/include/tc/group.hpp @@ -41,8 +41,6 @@ namespace tc { } [[nodiscard]] SubGroup subgroup(const std::vector &gens) const; - - [[nodiscard]] Cosets solve(const std::vector &sub_gens = {}) const; }; struct SubGroup : public Group { diff --git a/tc/src/core.cpp b/tc/src/core.cpp index 221fc41..6945b1c 100644 --- a/tc/src/core.cpp +++ b/tc/src/core.cpp @@ -1,7 +1,157 @@ #include +#include + namespace tc { SubGroup Group::subgroup(const std::vector &gens) const { return {*this, gens}; } + + struct Row { + std::vector gnrs; + std::vector lst_ptrs; + + Row(int num_tables) + : gnrs(num_tables, 0), lst_ptrs(num_tables, nullptr) { + } + }; + + struct Tables { + std::vector rels; + std::vector rows; + int num_tables; + + explicit Tables(const std::vector &rels) + : num_tables(rels.size()), rels(rels) { + } + + void add_row() { + rows.emplace_back(num_tables); + } + }; + + Cosets solve(const Group &group, const std::vector &sub_gens) { + auto ngens = group.ngens; + Cosets cosets(ngens); + cosets.add_row(); + + if (ngens == 0) { + return cosets; + } + + for (int g: sub_gens) { + if (g < ngens) + cosets.put(0, g, 0); + } + + auto rels = group.rels(); + Tables rel_tables(rels); + std::vector> gen_map(ngens); + int rel_idx = 0; + for (Rel m: rels) { + gen_map[m.gens[0]].push_back(rel_idx); + gen_map[m.gens[1]].push_back(rel_idx); + rel_idx++; + } + + int null_lst_ptr; + rel_tables.add_row(); + Row &row = rel_tables.rows[0]; + for (int table_idx = 0; table_idx < rel_tables.num_tables; table_idx++) { + Rel &ti = rel_tables.rels[table_idx]; + + if (cosets.get(ti.gens[0]) + cosets.get(ti.gens[1]) == -2) { + row.lst_ptrs[table_idx] = new int; + row.gnrs[table_idx] = 0; + } else { + row.lst_ptrs[table_idx] = &null_lst_ptr; + row.gnrs[table_idx] = -1; + } + } + + int idx = 0; + int coset, gen, target, fact_idx, lst, gen_; + while (true) { + while (idx < cosets.data.size() and cosets.get(idx) >= 0) + idx++; + + if (idx == cosets.data.size()) { +// rel_tables.del_rows_to(idx / ngens); + break; + } + + target = cosets.size(); + cosets.add_row(); + rel_tables.add_row(); + + std::vector facts; + facts.push_back(idx); + + coset = idx / ngens; + gen = idx % ngens; + +// rel_tables.del_rows_to(coset); + + Row &target_row = rel_tables.rows[target]; + while (!facts.empty()) { + fact_idx = facts.back(); + facts.pop_back(); + + if (cosets.get(fact_idx) != -1) + continue; + + cosets.put(fact_idx, target); + + coset = fact_idx / ngens; + gen = fact_idx % ngens; + + if (target == coset) + for (int table_idx: gen_map[gen]) + if (target_row.lst_ptrs[table_idx] == nullptr) + target_row.gnrs[table_idx] = -1; + + Row &coset_row = rel_tables.rows[coset]; + for (int table_idx: gen_map[gen]) { + if (target_row.lst_ptrs[table_idx] == nullptr) { + Rel &ti = rel_tables.rels[table_idx]; + target_row.lst_ptrs[table_idx] = coset_row.lst_ptrs[table_idx]; + target_row.gnrs[table_idx] = coset_row.gnrs[table_idx] + 1; + + if (coset_row.gnrs[table_idx] < 0) + target_row.gnrs[table_idx] -= 2; + + if (target_row.gnrs[table_idx] == ti.mult) { + lst = *(target_row.lst_ptrs[table_idx]); + delete target_row.lst_ptrs[table_idx]; + gen_ = ti.gens[(int) (ti.gens[0] == gen)]; + facts.push_back(lst * ngens + gen_); + } else if (target_row.gnrs[table_idx] == -ti.mult) { + gen_ = ti.gens[ti.gens[0] == gen]; + facts.push_back(target * ngens + gen_); + } else if (target_row.gnrs[table_idx] == ti.mult - 1) { + *(target_row.lst_ptrs[table_idx]) = target; + } + } + } + + std::sort(facts.begin(), facts.end(), std::greater<>()); + } + + for (int table_idx = 0; table_idx < rel_tables.num_tables; table_idx++) { + Rel &ti = rel_tables.rels[table_idx]; + if (target_row.lst_ptrs[table_idx] == nullptr) { + if ((cosets.get(target, ti.gens[0]) != target) and + (cosets.get(target, ti.gens[1]) != target)) { + target_row.lst_ptrs[table_idx] = new int; // todo slow; memory leak. + target_row.gnrs[table_idx] = 0; + } else { + target_row.lst_ptrs[table_idx] = &null_lst_ptr; + target_row.gnrs[table_idx] = -1; + } + } + } + } + + return cosets; + } } diff --git a/tc/src/solve.cpp b/tc/src/solve.cpp deleted file mode 100644 index 5cc6d28..0000000 --- a/tc/src/solve.cpp +++ /dev/null @@ -1,155 +0,0 @@ -#include "tc/core.hpp" - -#include - -namespace { - using namespace tc; - - struct Row { - std::vector gnrs; - std::vector lst_ptrs; - - Row(int num_tables) - : gnrs(num_tables, 0), lst_ptrs(num_tables, nullptr) { - } - }; - - struct Tables { - std::vector rels; - std::vector rows; - int num_tables; - - explicit Tables(const std::vector &rels) - : num_tables(rels.size()), rels(rels) { - } - - void add_row() { - rows.emplace_back(num_tables); - } - }; -} - -namespace tc { - Cosets Group::solve(const std::vector &sub_gens) const { - Cosets cosets(ngens); - cosets.add_row(); - - if (ngens == 0) { - return cosets; - } - - for (int g: sub_gens) { - if (g < ngens) - cosets.put(0, g, 0); - } - - Tables rel_tables(rels()); - std::vector> gen_map(ngens); - int rel_idx = 0; - for (Rel m: rels()) { - gen_map[m.gens[0]].push_back(rel_idx); - gen_map[m.gens[1]].push_back(rel_idx); - rel_idx++; - } - - int null_lst_ptr; - rel_tables.add_row(); - Row &row = rel_tables.rows[0]; - for (int table_idx = 0; table_idx < rel_tables.num_tables; table_idx++) { - Rel &ti = rel_tables.rels[table_idx]; - - if (cosets.get(ti.gens[0]) + cosets.get(ti.gens[1]) == -2) { - row.lst_ptrs[table_idx] = new int; - row.gnrs[table_idx] = 0; - } else { - row.lst_ptrs[table_idx] = &null_lst_ptr; - row.gnrs[table_idx] = -1; - } - } - - int idx = 0; - int coset, gen, target, fact_idx, lst, gen_; - while (true) { - while (idx < cosets.data.size() and cosets.get(idx) >= 0) - idx++; - - if (idx == cosets.data.size()) { -// rel_tables.del_rows_to(idx / ngens); - break; - } - - target = cosets.size(); - cosets.add_row(); - rel_tables.add_row(); - - std::vector facts; - facts.push_back(idx); - - coset = idx / ngens; - gen = idx % ngens; - -// rel_tables.del_rows_to(coset); - - Row &target_row = rel_tables.rows[target]; - while (!facts.empty()) { - fact_idx = facts.back(); - facts.pop_back(); - - if (cosets.get(fact_idx) != -1) - continue; - - cosets.put(fact_idx, target); - - coset = fact_idx / ngens; - gen = fact_idx % ngens; - - if (target == coset) - for (int table_idx: gen_map[gen]) - if (target_row.lst_ptrs[table_idx] == nullptr) - target_row.gnrs[table_idx] = -1; - - Row &coset_row = rel_tables.rows[coset]; - for (int table_idx: gen_map[gen]) { - if (target_row.lst_ptrs[table_idx] == nullptr) { - Rel &ti = rel_tables.rels[table_idx]; - target_row.lst_ptrs[table_idx] = coset_row.lst_ptrs[table_idx]; - target_row.gnrs[table_idx] = coset_row.gnrs[table_idx] + 1; - - if (coset_row.gnrs[table_idx] < 0) - target_row.gnrs[table_idx] -= 2; - - if (target_row.gnrs[table_idx] == ti.mult) { - lst = *(target_row.lst_ptrs[table_idx]); - delete target_row.lst_ptrs[table_idx]; - gen_ = ti.gens[(int) (ti.gens[0] == gen)]; - facts.push_back(lst * ngens + gen_); - } else if (target_row.gnrs[table_idx] == -ti.mult) { - gen_ = ti.gens[ti.gens[0] == gen]; - facts.push_back(target * ngens + gen_); - } else if (target_row.gnrs[table_idx] == ti.mult - 1) { - *(target_row.lst_ptrs[table_idx]) = target; - } - } - } - - std::sort(facts.begin(), facts.end(), std::greater<>()); - } - - for (int table_idx = 0; table_idx < rel_tables.num_tables; table_idx++) { - Rel &ti = rel_tables.rels[table_idx]; - if (target_row.lst_ptrs[table_idx] == nullptr) { - if ((cosets.get(target, ti.gens[0]) != target) and - (cosets.get(target, ti.gens[1]) != target)) { - target_row.lst_ptrs[table_idx] = new int; // todo slow; memory leak. - target_row.gnrs[table_idx] = 0; - } else { - target_row.lst_ptrs[table_idx] = &null_lst_ptr; - target_row.gnrs[table_idx] = -1; - } - } - } - } - - return cosets; - } -} diff --git a/tc/test/test_solve.cpp b/tc/test/test_solve.cpp index f9eb8e8..2a0cb28 100644 --- a/tc/test/test_solve.cpp +++ b/tc/test/test_solve.cpp @@ -8,7 +8,7 @@ int main(int argc, char *argv[]) { std::string key = argv[1]; - std::vector, size_t>> groups; + std::vector, size_t>> groups; // See the group orders here https://en.wikipedia.org/wiki/Coxeter_group#Properties if (key == "A") { @@ -91,7 +91,7 @@ int main(int argc, char *argv[]) { int status = EXIT_SUCCESS; for (const auto &[name, group, sub_gens, expected]: groups) { - auto cos = group.solve(sub_gens); + auto cos = tc::solve(group, sub_gens); auto actual = cos.size(); std::cout << name << " : " << actual; if (expected != actual) {