Correctly typed cosets/indexes

Coset type is now `unsigned int`. Half the size as before; speeds up malloc.

Index type is now `size_t` for correctness. More expressive and ___might___ speed up array lookup?? Difference seems negligible since we aren't allocating tons and tons of those.
This commit is contained in:
David Allemang
2022-09-14 20:44:40 -04:00
parent c346817743
commit 4347f1f9ec
4 changed files with 26 additions and 28 deletions

View File

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

View File

@@ -15,8 +15,8 @@ namespace tc {
* Rows document the "loops" formed by * Rows document the "loops" formed by
*/ */
struct Row { struct Row {
int gnr = 0; int gnr = 0; // the number of cosets identified so far
size_t lst_idx = -1; // identifies the loop or "family" size_t lst_idx = -1; // the index of the coset that would complete the loop
}; };
struct Tables { struct Tables {
@@ -36,7 +36,7 @@ namespace tc {
} }
}; };
Cosets solve(const Group &group, const std::vector<size_t> &sub_gens) { Cosets solve(const Group &group, const std::vector<Coset> &sub_gens) {
auto ngens = group.ngens; auto ngens = group.ngens;
// region Initialize Cosets Table // region Initialize Cosets Table
@@ -47,7 +47,7 @@ namespace tc {
return cosets; return cosets;
} }
for (int g: sub_gens) { for (Coset g: sub_gens) {
if (g < ngens) if (g < ngens)
cosets.put(0, g, 0); cosets.put(0, g, 0);
} }
@@ -57,16 +57,16 @@ namespace tc {
// region Initialize Relation Tables // region Initialize Relation Tables
Tables rel_tables(rels); Tables rel_tables(rels);
std::vector<std::vector<int>> gen_map(ngens); std::vector<std::vector<size_t>> tables_for(ngens);
int rel_idx = 0; int rel_idx = 0;
for (Rel m: rels) { for (Rel m: rels) {
gen_map[m.gens[0]].push_back(rel_idx); tables_for[m.gens[0]].push_back(rel_idx);
gen_map[m.gens[1]].push_back(rel_idx); tables_for[m.gens[1]].push_back(rel_idx);
rel_idx++; rel_idx++;
} }
std::vector<int> lst_vals; std::vector<Coset> lst_vals;
size_t null_lst_idx = 0; Coset null_lst_idx = 0;
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]; Rel &rel = rel_tables.rels[table_idx];
@@ -83,8 +83,9 @@ namespace tc {
} }
// endregion // endregion
int idx = 0; size_t idx = 0;
int coset, gen, target, fact_idx, lst; size_t fact_idx;
Coset coset, gen, target, lst;
while (true) { while (true) {
// find next unknown product // find next unknown product
@@ -104,7 +105,7 @@ namespace tc {
rel_tables.add_row(); rel_tables.add_row();
// queue of products that equal target // queue of products that equal target
std::queue<int> facts; std::queue<size_t> facts;
facts.push(idx); // new product should be recorded and propagated facts.push(idx); // new product should be recorded and propagated
// todo unrolled linked list interval // todo unrolled linked list interval
@@ -126,24 +127,19 @@ namespace tc {
gen = fact_idx % ngens; gen = fact_idx % ngens;
// If the product stays within the coset todo // If the product stays within the coset todo
if (target == coset) for (size_t table_idx: tables_for[gen]) {
for (int table_idx: gen_map[gen]) {
auto &trow = rel_tables.rows[target][table_idx];
if (trow.lst_idx == -1) {
trow.gnr = -1;
}
}
// Test if loop is closed
for (int table_idx: gen_map[gen]) {
auto &rel = rel_tables.rels[table_idx]; auto &rel = 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];
auto other_gen = rel.gens[0] == gen ? rel.gens[1] : rel.gens[0]; // Test if loop is closed
Coset other_gen = rel.gens[0] == gen ? rel.gens[1] : rel.gens[0];
if (trow.lst_idx == -1) { if (trow.lst_idx == -1) {
if (target == coset) {
trow.gnr = -1;
}
trow.lst_idx = crow.lst_idx; trow.lst_idx = crow.lst_idx;
trow.gnr = crow.gnr + 1; trow.gnr = crow.gnr + 1;
@@ -168,7 +164,7 @@ namespace tc {
} }
// Find rows which are still not part of any loop, and assign them to a new loop. // Find rows which are still not part of any loop, and assign them to a new loop.
for (int 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 &rel = rel_tables.rels[table_idx];
auto &trow = rel_tables.rows[target][table_idx]; auto &trow = rel_tables.rows[target][table_idx];

View File

@@ -8,7 +8,7 @@
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
std::string key = argv[1]; std::string key = argv[1];
std::vector<std::tuple<std::string, tc::Group, std::vector<size_t>, size_t>> groups; std::vector<std::tuple<std::string, tc::Group, std::vector<tc::Coset>, size_t>> groups;
// See the group orders here https://en.wikipedia.org/wiki/Coxeter_group#Properties // See the group orders here https://en.wikipedia.org/wiki/Coxeter_group#Properties
if (key == "A") { if (key == "A") {

View File

@@ -9,7 +9,7 @@ int main(int argc, char *argv[]) {
std::string key = argv[1]; std::string key = argv[1];
std::cerr << "Min. cos/s: " << MINIMUM_COS_PER_SEC << std::endl; std::cerr << "Min. cos/s: " << MINIMUM_COS_PER_SEC << std::endl;
std::vector<std::tuple<std::string, tc::Group, std::vector<size_t>, size_t>> groups; std::vector<std::tuple<std::string, tc::Group, std::vector<unsigned int>, size_t>> groups;
// See the group orders here https://en.wikipedia.org/wiki/Coxeter_group#Properties // See the group orders here https://en.wikipedia.org/wiki/Coxeter_group#Properties
if (key == "B") { if (key == "B") {