diff --git a/include/groups.h b/include/groups.h index d5804ee..94f7392 100644 --- a/include/groups.h +++ b/include/groups.h @@ -4,21 +4,24 @@ #include namespace tc { - struct Mult { + struct Rel { std::array gens; int mult; }; + /** + * A presentation of a coxeter group. Contains a number of generators and some relations of the form (ab)^n = e + */ struct Group { - int ngens; - std::vector> _mults; + const int ngens; + std::vector> _mults; // lookup table for multiplicities std::string name; - explicit Group(int ngens, const std::vector &rels = {}, std::string name = "G"); + explicit Group(int ngens, const std::vector &rels = {}, std::string name = "G"); - void setmult(Mult m); + void setmult(Rel rel); - [[nodiscard]] std::vector get_mults() const; + [[nodiscard]] std::vector get_rels() const; [[nodiscard]] Group product(const Group &other) const; @@ -29,6 +32,10 @@ namespace tc { Group operator^(const Group &g, const int &p); + /** + * Construct a group from a (simplified) Schlafli Symbol of the form [a, b, ..., c] + * @param mults: The sequence of multiplicites between adjacent generators. + */ Group schlafli(const std::vector &mults); namespace group { diff --git a/src/groups.cpp b/src/groups.cpp index d8753e5..7ffde72 100644 --- a/src/groups.cpp +++ b/src/groups.cpp @@ -1,48 +1,47 @@ #include "groups.h" -//#include #include #include namespace tc { - Group::Group(int ngens, const std::vector &rels, std::string name) : ngens(ngens), name(std::move(name)) { + Group::Group(int ngens, const std::vector &rels, std::string name) : ngens(ngens), name(std::move(name)) { _mults.resize(ngens); for (int i = 0; i < ngens; i++) { _mults[i].resize(ngens, 2); } - for (Mult m : rels) { - if (m.gens[0] < m.gens[1]) - _mults[m.gens[0]][m.gens[1]] = m.mult; + for (Rel rel : rels) { + if (rel.gens[0] < rel.gens[1]) + _mults[rel.gens[0]][rel.gens[1]] = rel.mult; else - _mults[m.gens[1]][m.gens[0]] = m.mult; + _mults[rel.gens[1]][rel.gens[0]] = rel.mult; } } - void Group::setmult(Mult m) { - if (m.gens[0] < m.gens[1]) - _mults[m.gens[0]][m.gens[1]] = m.mult; + void Group::setmult(Rel rel) { + if (rel.gens[0] < rel.gens[1]) + _mults[rel.gens[0]][rel.gens[1]] = rel.mult; else - _mults[m.gens[1]][m.gens[0]] = m.mult; + _mults[rel.gens[1]][rel.gens[0]] = rel.mult; } - std::vector Group::get_mults() const { - std::vector mults; + std::vector Group::get_rels() const { + std::vector rels; for (int i = 0; i < ngens - 1; i++) { for (int j = i + 1; j < ngens; j++) { - mults.push_back({i, j, _mults[i][j]}); + rels.push_back({i, j, _mults[i][j]}); } } - return mults; + return rels; } Group Group::product(const Group &other) const { int off = ngens; - Group g(ngens + other.ngens, get_mults()); + Group g(ngens + other.ngens, get_rels()); - for (Mult m : other.get_mults()) { - g.setmult({off + m.gens[0], off + m.gens[1], m.mult}); + for (Rel rel : other.get_rels()) { + g.setmult({off + rel.gens[0], off + rel.gens[1], rel.mult}); } std::stringstream ss; @@ -55,9 +54,9 @@ namespace tc { Group Group::power(int p) const { Group g(ngens * p); - for (Mult m : get_mults()) { + for (Rel rel : get_rels()) { for (int off = 0; off < g.ngens; off += ngens) { - g.setmult({off + m.gens[0], off + m.gens[1], m.mult}); + g.setmult({off + rel.gens[0], off + rel.gens[1], rel.mult}); } } @@ -76,12 +75,12 @@ namespace tc { return g.power(p); } - Group schlafli(const std::vector &mults, const std::string name) { - int ngens = mults.size() + 1; + Group schlafli(const std::vector &mults, const std::string& name) { + int ngens = (int) mults.size() + 1; Group g(ngens, {}, name); - for (int i = 0; i < mults.size(); i++) { + for (int i = 0; i < (int) mults.size(); i++) { g.setmult({i, i + 1, mults[i]}); } diff --git a/src/solver.cpp b/src/solver.cpp index 4d7e4b4..affe004 100644 --- a/src/solver.cpp +++ b/src/solver.cpp @@ -4,12 +4,15 @@ namespace tc { struct RelTable { - Mult mult; + Rel rel; std::vector lst_ptr; std::vector gen; - explicit RelTable(tc::Mult mult) : mult(mult) { + int &mult = rel.mult; + std::array &gens = rel.gens; + + explicit RelTable(Rel rel) : rel(rel) { } int add_row() { @@ -27,12 +30,12 @@ namespace tc { std::vector> gen_map; // which relations involve which generators explicit RelationSet(const Group &g, const Cosets &cosets) : gen_map(g.ngens), cosets(cosets) { - 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); + const std::vector &rels = g.get_rels(); + tables.reserve(rels.size()); + for (const auto &rel : rels) { + RelTable &table = tables.emplace_back(rel); + gen_map[rel.gens[0]].push_back(&table); + gen_map[rel.gens[1]].push_back(&table); } } @@ -48,8 +51,8 @@ namespace tc { table.lst_ptr[idx] = new int; - if ((cosets.get(idx, table.mult.gens[0]) != idx) and - (cosets.get(idx, table.mult.gens[1]) != idx)) { + if ((cosets.get(idx, table.gens[0]) != idx) and + (cosets.get(idx, table.gens[1]) != idx)) { table.gen[idx] = 0; } else { table.gen[idx] = -1; @@ -97,24 +100,26 @@ namespace tc { coset = fact_idx / group.ngens; gen = fact_idx % group.ngens; - for (RelTable *rel : rels.gen_map[gen]) { - if (rel->lst_ptr[target] == nullptr) { - rel->lst_ptr[target] = rel->lst_ptr[coset]; - rel->gen[target] = rel->gen[coset] + 1; + for (RelTable *pTable : rels.gen_map[gen]) { + RelTable &table = *pTable; - if (rel->gen[coset] < 0) - rel->gen[target] -= 2; + if (table.lst_ptr[target] == nullptr) { + table.lst_ptr[target] = table.lst_ptr[coset]; + table.gen[target] = table.gen[coset] + 1; - if (rel->gen[target] == rel->mult.mult) { - lst = *(rel->lst_ptr[target]); - delete rel->lst_ptr[target]; - gen_ = rel->mult.gens[(int) (rel->mult.gens[0] == gen)]; + if (table.gen[coset] < 0) + table.gen[target] -= 2; + + if (table.gen[target] == table.rel.mult) { + lst = *(table.lst_ptr[target]); + delete table.lst_ptr[target]; + gen_ = table.gens[table.gens[0] == gen]; facts.push_back(lst * group.ngens + gen_); - } else if (rel->gen[target] == -rel->mult.mult) { - gen_ = rel->mult.gens[rel->mult.gens[0] == gen]; + } else if (table.gen[target] == -table.mult) { + gen_ = table.gens[table.gens[0] == gen]; facts.push_back(target * group.ngens + gen_); - } else if (rel->gen[target] == rel->mult.mult - 1) { - *(rel->lst_ptr[target]) = target; + } else if (table.gen[target] == table.mult - 1) { + *(table.lst_ptr[target]) = target; } } }