replace Rel with tuple

This commit is contained in:
David Allemang
2022-09-14 21:37:34 -04:00
parent 27a3231cfe
commit 89c216dfe4
5 changed files with 23 additions and 35 deletions

View File

@@ -10,7 +10,5 @@
#include "group.hpp" #include "group.hpp"
namespace tc { namespace tc {
using Coset = unsigned int;
Cosets solve(const Group &group, const std::vector<Coset> &sub_gens); Cosets solve(const Group &group, const std::vector<Coset> &sub_gens);
} }

View File

@@ -5,6 +5,12 @@
#include "cosets.hpp" #include "cosets.hpp"
namespace tc { namespace tc {
using Coset = uint32_t;
using Gen = uint16_t;
using Mult = uint16_t;
using Rel = std::tuple<Gen, Gen, Mult>;
struct Cosets { struct Cosets {
int ngens; int ngens;
std::vector<int> data; std::vector<int> data;

View File

@@ -23,11 +23,12 @@ namespace tc {
} }
void set(const Rel &r) { void set(const Rel &r) {
_mults(r.gens[0], r.gens[1]) = r.mult; auto &[i, j, m] = r;
_mults(i, j) = m;
} }
[[nodiscard]] int get(int a, int b) const { [[nodiscard]] int get(int i, int j) const {
return _mults(a, b); return _mults(i, j);
} }
[[nodiscard]] std::vector<Rel> rels() const { [[nodiscard]] std::vector<Rel> rels() const {

View File

@@ -100,21 +100,4 @@ namespace tc {
return path.size(); return path.size();
} }
}; };
struct Rel {
std::array<int, 2> gens;
int mult;
Rel() = default;
Rel(const Rel &) = default;
Rel(int a, int b, int m)
: gens({a, b}), mult(m) {
}
[[nodiscard]] Rel shift(int off) const {
return Rel(gens[0] + off, gens[1] + off, mult);
}
};
} }

View File

@@ -63,19 +63,19 @@ namespace tc {
Tables rel_tables(rels); Tables rel_tables(rels);
std::vector<std::vector<size_t>> tables_for(ngens); std::vector<std::vector<size_t>> tables_for(ngens);
int rel_idx = 0; int rel_idx = 0;
for (Rel m: rels) { for (const auto &[i, j, m]: rels) {
tables_for[m.gens[0]].push_back(rel_idx); tables_for[i].push_back(rel_idx);
tables_for[m.gens[1]].push_back(rel_idx); tables_for[j].push_back(rel_idx);
rel_idx++; rel_idx++;
} }
std::vector<Coset> lst_vals; std::vector<Coset> lst_vals;
rel_tables.add_row(); rel_tables.add_row();
for (int table_idx = 0; table_idx < rel_tables.size(); ++table_idx) { for (int table_idx = 0; table_idx < rel_tables.size(); ++table_idx) {
Rel &rel = rel_tables.rels[table_idx]; const auto &[i, j, m] = rel_tables.rels[table_idx];
Row &row = rel_tables.rows[0][table_idx]; Row &row = rel_tables.rows[0][table_idx];
if (cosets.get(rel.gens[0]) + cosets.get(rel.gens[1]) == -2) { if (cosets.get(i) + cosets.get(j) == -2) {
row.lst_idx = lst_vals.size(); row.lst_idx = lst_vals.size();
lst_vals.push_back(0); lst_vals.push_back(0);
row.free = false; row.free = false;
@@ -133,12 +133,12 @@ namespace tc {
// If the product stays within the coset todo // If the product stays within the coset todo
for (size_t table_idx: tables_for[gen]) { for (size_t table_idx: tables_for[gen]) {
auto &rel = rel_tables.rels[table_idx]; auto &[i, j, m] = rel_tables.rels[table_idx];
auto &trow = rel_tables.rows[target][table_idx]; auto &trow = rel_tables.rows[target][table_idx];
auto &crow = rel_tables.rows[coset][table_idx]; auto &crow = rel_tables.rows[coset][table_idx];
// Test if loop is closed // Test if loop is closed
Coset other_gen = rel.gens[0] == gen ? rel.gens[1] : rel.gens[0]; Coset other_gen = (i == gen) ? j : i;
if (trow.free) { if (trow.free) {
if (target == coset) { if (target == coset) {
@@ -149,16 +149,16 @@ namespace tc {
trow.gnr++; trow.gnr++;
if (trow.idem) { if (trow.idem) {
if (trow.gnr == rel.mult) { if (trow.gnr == m) {
// loop is closed, but internal, so the target links to itself via this generator. // loop is closed, but internal, so the target links to itself via this generator.
// todo might be able to move this logic up into the (target == coset) block and avoid those computations. // todo might be able to move this logic up into the (target == coset) block and avoid those computations.
facts.push(target * ngens + other_gen); facts.push(target * ngens + other_gen);
} }
} else { } else {
if (trow.gnr == rel.mult - 1) { if (trow.gnr == m - 1) {
// loop is almost closed. record that the target closes this loop. // loop is almost closed. record that the target closes this loop.
lst_vals[trow.lst_idx] = target; lst_vals[trow.lst_idx] = target;
} else if (trow.gnr == rel.mult) { } else if (trow.gnr == m) {
// loop is closed. We know the last element in the loop must link with this one. // loop is closed. We know the last element in the loop must link with this one.
lst = lst_vals[trow.lst_idx]; lst = lst_vals[trow.lst_idx];
// delete trow.lst_ptr; // delete trow.lst_ptr;
@@ -172,12 +172,12 @@ namespace tc {
// If any target row wasn't identified with a loop, // If any target row wasn't identified with a loop,
// then assign it a new loop. // then assign it a new loop.
for (size_t table_idx = 0; table_idx < rel_tables.size(); table_idx++) { for (size_t table_idx = 0; table_idx < rel_tables.size(); table_idx++) {
auto &rel = rel_tables.rels[table_idx]; auto &[i, j, m] = rel_tables.rels[table_idx];
auto &trow = rel_tables.rows[target][table_idx]; auto &trow = rel_tables.rows[target][table_idx];
if (trow.free) { if (trow.free) {
if ((cosets.get(target, rel.gens[0]) != target) and if ((cosets.get(target, i) != target) and
(cosets.get(target, rel.gens[1]) != target)) { (cosets.get(target, j) != target)) {
trow.lst_idx = lst_vals.size(); trow.lst_idx = lst_vals.size();
trow.free = false; trow.free = false;
lst_vals.push_back(0); lst_vals.push_back(0);