diff --git a/CMakeLists.txt b/CMakeLists.txt index 9712e9b..bf41777 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,4 +3,4 @@ project(test) set(CMAKE_CXX_STANDARD 17) -add_executable(test test.cpp) +add_executable(test test.cpp groups.cpp solver.cpp) diff --git a/groups.cpp b/groups.cpp index db140e5..a438ffd 100644 --- a/groups.cpp +++ b/groups.cpp @@ -1,52 +1,132 @@ -#include "solver.cpp" +#include "groups.h" -Group A(const int n) { - if (n == 0) - return Group(0); +namespace tc { + Group::Group(int ngens, const std::vector &rels) : ngens(ngens) { + _mults.resize(ngens); + for (int i = 0; i < ngens; i++) { + _mults[i].resize(ngens, 2); + } - return Group::schlafli(std::vector(n-1,3)); -} + for (Mult m : rels) { + if (m.gen0 < m.gen1) + _mults[m.gen0][m.gen1] = m.mult; + else + _mults[m.gen1][m.gen0] = m.mult; + } + } -Group B(const int n) { - std::vector mults(n-1,3); - mults[0] = 4; - return Group::schlafli(mults); -} + void Group::setmult(Mult m) { + if (m.gen0 < m.gen1) + _mults[m.gen0][m.gen1] = m.mult; + else + _mults[m.gen1][m.gen0] = m.mult; + } -Group D(const int n) { - std::vector mults(n-1,3); - mults[n-2] = 2; - Group g = Group::schlafli(mults); - g.setmult({1,n-1,3}); - return g; -} + std::vector Group::get_mults() const { + std::vector mults; + for (int i = 0; i < ngens - 1; i++) { + for (int j = i + 1; j < ngens; j++) { + mults.push_back({i, j, _mults[i][j]}); + } + } + return mults; + } -Group E(const int n) { - std::vector mults(n-1,3); - mults[n-2] = 2; - Group g = Group::schlafli(mults); - g.setmult({2,n-1,3}); - return g; -} + Group Group::product(const Group &other) const { + int off = ngens; -Group F4() { - return Group::schlafli({3,4,3}); -} + Group g(ngens + other.ngens, get_mults()); -Group G2() { - return Group::schlafli({6}); -} + for (Mult m : other.get_mults()) { + g.setmult({off + m.gen0, off + m.gen1, m.mult}); + } -Group H(const int n) { - std::vector mults(n-1,3); - mults[0] = 5; - return Group::schlafli(mults); -} + return g; + } -Group I2(const int n) { - return Group::schlafli({n}); -} + Group Group::power(int p) const { + Group g(ngens * p); -Group T(const int n) { - return I2(n)^2; -} + for (Mult m : get_mults()) { + for (int off = 0; off < g.ngens; off += ngens) { + g.setmult({off + m.gen0, off + m.gen1, m.mult}); + } + } + + return g; + } + + Group operator*(const Group &g, const Group &h) { + return g.product(h); + } + + Group operator^(const Group &g, const int &p) { + return g.power(p); + } + + Group schlafli(const std::vector &mults) { + int ngens = mults.size() + 1; + Group g(ngens); + for (int i = 0; i < mults.size(); i++) { + g.setmult({i, i + 1, mults[i]}); + } + return g; + } + + namespace group { + Group A(const int n) { + if (n == 0) + return Group(0); + + return schlafli(std::vector(n - 1, 3)); + } + + Group B(const int n) { + std::vector mults(n - 1, 3); + mults[0] = 4; + return schlafli(mults); + } + + Group D(const int n) { + std::vector mults(n - 1, 3); + mults[n - 2] = 2; + Group g = schlafli(mults); + g.setmult({1, n - 1, 3}); + return g; + } + + Group E(const int n) { + std::vector mults(n - 1, 3); + mults[n - 2] = 2; + Group g = schlafli(mults); + g.setmult({2, n - 1, 3}); + return g; + } + + Group F4() { + return schlafli({3, 4, 3}); + } + + Group G2() { + return schlafli({6}); + } + + Group H(const int n) { + std::vector mults(n - 1, 3); + mults[0] = 5; + return schlafli(mults); + } + + Group I2(const int n) { + return schlafli({n}); + } + + Group T(const int n, const int m) { + return I2(n) * I2(m); + } + + Group T(const int n) { + return I2(n) ^ 2; + } + } +} \ No newline at end of file diff --git a/groups.h b/groups.h index c15fc77..627f142 100644 --- a/groups.h +++ b/groups.h @@ -2,50 +2,51 @@ #include -struct Cosets { - int ngens; - std::vector data; - int len; +namespace tc { + struct Mult { + int gen0, gen1, mult; + }; - Cosets(int ngens, const std::vector &data); + struct Group { + int ngens; + std::vector> _mults; - void add_row(); + explicit Group(int ngens, const std::vector &rels = {}); - void put(int coset, int gen, int target); + void setmult(Mult m); - void put(int idx, int target); + [[nodiscard]] std::vector get_mults() const; - [[nodiscard]] int get(int coset, int gen) const; + [[nodiscard]] Group product(const Group &other) const; - [[nodiscard]] int get(int idx) const; -}; + [[nodiscard]] Group power(int p) const; + }; -struct Mult { - int gen0, gen1, mult; -}; + Group operator*(const Group &g, const Group &h); -struct RelTable { - int gens[2]{}; - int mult; - std::vector lst_ptr; - std::vector gen; + Group operator^(const Group &g, const int &p); - explicit RelTable(Mult m); + Group schlafli(const std::vector &mults); - int add_row(); -}; + namespace group { + Group A(int n); -struct Group { - int ngens; - std::vector> _mults; + Group B(int n); - explicit Group(int ngens, const std::vector &rels = {}); + Group D(int n); - void setmult(Mult m); + Group E(int n); - [[nodiscard]] std::vector get_mults() const; + Group F4(); - [[nodiscard]] Group product(const Group &other) const; + Group G2(); - [[nodiscard]] Group power(int p) const; -}; + Group H(int n); + + Group I2(int n); + + Group T(int n, int m); + + Group T(int n); + } +} \ No newline at end of file diff --git a/solver.cpp b/solver.cpp index cea6888..09a71cd 100644 --- a/solver.cpp +++ b/solver.cpp @@ -1,147 +1,61 @@ -#include +#include "solver.h" + #include -#include -#include #include -#include -struct Cosets { - int ngens; - std::vector data; - int len; - - Cosets(int ngens, std::vector data): ngens(ngens), data(data) { +namespace tc { + Cosets::Cosets(int ngens, const std::vector &data) : ngens(ngens), data(data) { len = data.size() / ngens; } - void add_row() { + void Cosets::add_row() { len++; - data.resize(data.size()+ngens, -1); + data.resize(data.size() + ngens, -1); } - void put(int coset, int gen, int target) { + void Cosets::put(int coset, int gen, int target) { data[coset * ngens + gen] = target; data[target * ngens + gen] = coset; } - void put(int idx, int target) { + void Cosets::put(int idx, int target) { int coset = idx / ngens; int gen = idx % ngens; data[idx] = target; data[target * ngens + gen] = coset; } - int get(int coset, int gen) { + int Cosets::get(int coset, int gen) const { return data[coset * ngens + gen]; } - int get(int idx) { + int Cosets::get(int idx) const { return data[idx]; } -}; -struct Mult { - int gen0, gen1, mult; -}; - -struct RelTable { - int gens[2]; - int mult; - std::vector lst_ptr; - std::vector gen; - - RelTable(Mult m): mult(m.mult) { + RelTable::RelTable(Mult m) : mult(m.mult) { gens[0] = m.gen0; gens[1] = m.gen1; } - int add_row() { + int RelTable::add_row() { int idx = lst_ptr.size(); lst_ptr.push_back(nullptr); gen.push_back(-1); return idx; } -}; -struct Group { - int ngens; - std::vector> _mults; - - Group(int ngens, std::vector rels = {}): ngens(ngens) { - _mults.resize(ngens); - for (int i = 0; i < ngens; i++) { - _mults[i].resize(ngens, 2); - } - - for (Mult m : rels) { - if (m.gen0 < m.gen1) - _mults[m.gen0][m.gen1] = m.mult; - else - _mults[m.gen1][m.gen0] = m.mult; - } - } - - void setmult(Mult m) { - if (m.gen0 < m.gen1) - _mults[m.gen0][m.gen1] = m.mult; - else - _mults[m.gen1][m.gen0] = m.mult; - } - - std::vector get_mults() const { - std::vector mults; - for (int i = 0; i < ngens - 1; i++) { - for (int j = i+1; j < ngens; j++) { - mults.push_back({i,j,_mults[i][j]}); - } - } - return mults; - } - - Group operator*(const Group &other) { - int off = ngens; - - Group g(ngens + other.ngens, get_mults()); - - for (Mult m : other.get_mults()) { - g.setmult({off + m.gen0, off + m.gen1, m.mult}); - } - - return g; - } - - Group operator^(int p) { - Group g(ngens * p); - - for (Mult m : get_mults()) { - for (int off = 0; off < g.ngens; off += ngens) { - g.setmult({off + m.gen0, off + m.gen1, m.mult}); - } - } - - return g; - } - - static Group schlafli(std::vector mults) { - int ngens = mults.size() + 1; - Group g(ngens); - for (int i = 0; i < mults.size(); i++) { - g.setmult({i, i+1, mults[i]}); - } - return g; - } - - Cosets solve(std::vector sub_gens = {}) { - std::vector init_row(ngens, -1); + Cosets solve(const Group &group, const std::vector &sub_gens) { + std::vector init_row(group.ngens, -1); for (int i : sub_gens) { init_row[i] = 0; } - Cosets cosets(ngens, init_row); + Cosets cosets(group.ngens, init_row); std::vector rel_tables; - std::vector> gen_map(ngens); + std::vector> gen_map(group.ngens); int rel_idx; - for (Mult m : get_mults()) { + 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); @@ -151,12 +65,11 @@ struct Group { int null_lst_ptr; for (RelTable &rel : rel_tables) { int idx = rel.add_row(); - + if (cosets.get(rel.gens[0]) + cosets.get(rel.gens[1]) == -2) { rel.lst_ptr[idx] = new int; rel.gen[idx] = 0; - } - else { + } else { rel.lst_ptr[idx] = &null_lst_ptr; rel.gen[idx] = -1; } @@ -173,7 +86,7 @@ struct Group { target = cosets.len; cosets.add_row(); - + for (RelTable &rel : rel_tables) { rel.add_row(); } @@ -181,8 +94,8 @@ struct Group { std::vector facts; facts.push_back(idx); - coset = idx / ngens; - gen = idx % ngens; + coset = idx / group.ngens; + gen = idx % group.ngens; while (!facts.empty()) { fact_idx = facts.back(); @@ -193,52 +106,49 @@ struct Group { cosets.put(fact_idx, target); - coset = fact_idx / ngens; - gen = fact_idx % ngens; + coset = fact_idx / group.ngens; + gen = fact_idx % group.ngens; for (int rel_idx : gen_map[gen]) { RelTable &rel = rel_tables[rel_idx]; - if ( rel.lst_ptr[target] == nullptr ) { + if (rel.lst_ptr[target] == nullptr) { rel.lst_ptr[target] = rel.lst_ptr[coset]; rel.gen[target] = rel.gen[coset] + 1; - + if (rel.gen[coset] < 0) rel.gen[target] -= 2; if (rel.gen[target] == rel.mult) { lst = *(rel.lst_ptr[target]); delete rel.lst_ptr[target]; - gen_ = rel.gens[(int)(rel.gens[0] == gen)]; - facts.push_back(lst*ngens + gen_); - } - else if (rel.gen[target] == -rel.mult) { + gen_ = rel.gens[(int) (rel.gens[0] == gen)]; + facts.push_back(lst * group.ngens + gen_); + } else if (rel.gen[target] == -rel.mult) { gen_ = rel.gens[rel.gens[0] == gen]; - facts.push_back(target*ngens + gen_); - } - else if (rel.gen[target] == rel.mult - 1) { + facts.push_back(target * group.ngens + gen_); + } else if (rel.gen[target] == rel.mult - 1) { *(rel.lst_ptr[target]) = target; } } } - std::sort(facts.begin(), facts.end(), std::greater()); + std::sort(facts.begin(), facts.end(), std::greater<>()); } for (RelTable &rel : rel_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.gens[0]) != target) and + (cosets.get(target, rel.gens[1]) != target)) { rel.lst_ptr[target] = new int; rel.gen[target] = 0; - } - else { + } else { rel.lst_ptr[target] = &null_lst_ptr; rel.gen[target] = -1; } } } } - + return cosets; } -}; +} \ No newline at end of file diff --git a/solver.h b/solver.h index e69de29..af19a3c 100644 --- a/solver.h +++ b/solver.h @@ -0,0 +1,37 @@ +#pragma once + +#include "groups.h" +#include + +namespace tc { + struct Cosets { + int ngens; + std::vector data; + int len; + + Cosets(int ngens, const std::vector &data); + + void add_row(); + + void put(int coset, int gen, int target); + + void put(int idx, int target); + + [[nodiscard]] int get(int coset, int gen) const; + + [[nodiscard]] int get(int idx) const; + }; + + struct RelTable { + int gens[2]{}; + int mult; + std::vector lst_ptr; + std::vector gen; + + explicit RelTable(Mult m); + + int add_row(); + }; + + Cosets solve(const Group &g, const std::vector &sub_gens = {}); +} \ No newline at end of file diff --git a/test.cpp b/test.cpp index aec8918..f7c35c1 100644 --- a/test.cpp +++ b/test.cpp @@ -1,12 +1,13 @@ -#include "groups.cpp" +#include "solver.h" +#include "groups.h" #include #include int main() { - Group g = T(100); + tc::Group g = tc::group::T(2, 5000); auto s = std::chrono::system_clock::now(); - auto cosets = g.solve(); + auto cosets = solve(g); auto e = std::chrono::system_clock::now(); std::chrono::duration diff = e - s;