mirror of
https://github.com/allemangD/toddcox-visualize.git
synced 2025-11-10 03:52:48 -05:00
add bound to support for infinite groups and free relations
special values tc::UNBOUND and tc::FREE used for this.
This commit is contained in:
@@ -10,19 +10,26 @@
|
|||||||
|
|
||||||
#define NAMED(x) #x, x
|
#define NAMED(x) #x, x
|
||||||
|
|
||||||
void bench(std::string group_expr, tc::Group group, const std::vector<tc::Gen> &gens) {
|
void bench(
|
||||||
|
std::string group_expr,
|
||||||
|
const tc::Group &group,
|
||||||
|
const std::vector<tc::Gen> &gens,
|
||||||
|
const tc::Coset bound = tc::UNBOUNDED
|
||||||
|
) {
|
||||||
std::clock_t s = std::clock();
|
std::clock_t s = std::clock();
|
||||||
tc::Cosets cosets = tc::solve(group, gens);
|
tc::Cosets cosets = tc::solve(group, gens, bound);
|
||||||
std::clock_t e = std::clock();
|
std::clock_t e = std::clock();
|
||||||
|
|
||||||
double time = (double) (e - s) / CLOCKS_PER_SEC;
|
auto time = (double) (e - s) / CLOCKS_PER_SEC;
|
||||||
tc::Coset order = cosets.size();
|
tc::Coset order = cosets.size();
|
||||||
size_t cos_s = (size_t) (order / time);
|
auto cos_s = (size_t) (order / time);
|
||||||
|
|
||||||
|
bool complete = cosets.complete;
|
||||||
|
|
||||||
std::string name = fmt::format("{}/{}", group_expr, gens);
|
std::string name = fmt::format("{}/{}", group_expr, gens);
|
||||||
std::string row = fmt::format(
|
std::string row = fmt::format(
|
||||||
"{:>24},{:>10},{:>8.3f}s,{:>10L}",
|
"{:>24},{:>10},{:>6},{:>8.3f}s,{:>10L}",
|
||||||
name, order, time, cos_s
|
name, order, complete, time, cos_s
|
||||||
);
|
);
|
||||||
fmt::print("{}\n", row);
|
fmt::print("{}\n", row);
|
||||||
}
|
}
|
||||||
@@ -40,6 +47,11 @@ int main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
fmt::print("{:>24},{:>10},{:>9},{:>10}\n", "NAME", "ORDER", "TIME", "COS/S");
|
fmt::print("{:>24},{:>10},{:>9},{:>10}\n", "NAME", "ORDER", "TIME", "COS/S");
|
||||||
|
|
||||||
|
auto g = tc::group::A(4);
|
||||||
|
g.set(tc::Rel{0, 3, 3});
|
||||||
|
bench("~A(3)", g, {}, 4385964);
|
||||||
|
bench("~I(1)", sch(tc::FREE), {}, 4385964);
|
||||||
|
|
||||||
bench(NAMED(H(2)), {});
|
bench(NAMED(H(2)), {});
|
||||||
bench(NAMED(H(3)), {});
|
bench(NAMED(H(3)), {});
|
||||||
bench(NAMED(H(4)), {});
|
bench(NAMED(H(4)), {});
|
||||||
|
|||||||
@@ -10,5 +10,7 @@
|
|||||||
#include "group.hpp"
|
#include "group.hpp"
|
||||||
|
|
||||||
namespace tc {
|
namespace tc {
|
||||||
Cosets solve(const Group &group, const std::vector<Gen> &sub_gens);
|
constexpr Coset UNBOUNDED = (Coset) (-1);
|
||||||
|
|
||||||
|
Cosets solve(const Group &group, const std::vector<Gen> &sub_gens, const Coset &bound = UNBOUNDED);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,15 +8,16 @@ namespace tc {
|
|||||||
using Coset = uint32_t;
|
using Coset = uint32_t;
|
||||||
using Gen = uint8_t;
|
using Gen = uint8_t;
|
||||||
using Mult = uint16_t;
|
using Mult = uint16_t;
|
||||||
|
constexpr Mult FREE = Mult(-1);
|
||||||
|
constexpr Coset UNSET = Coset(-1);
|
||||||
|
|
||||||
using Rel = std::tuple<Gen, Gen, Mult>;
|
using Rel = std::tuple<Gen, Gen, Mult>;
|
||||||
|
|
||||||
struct Cosets {
|
struct Cosets {
|
||||||
const Coset UNSET = Coset(-1);
|
|
||||||
|
|
||||||
Gen ngens;
|
Gen ngens;
|
||||||
std::vector<int> data;
|
std::vector<int> data;
|
||||||
Path path;
|
Path path;
|
||||||
|
bool complete = false;
|
||||||
|
|
||||||
Cosets(const Cosets &) = default;
|
Cosets(const Cosets &) = default;
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,23 @@ namespace tc {
|
|||||||
struct Group;
|
struct Group;
|
||||||
struct SubGroup;
|
struct SubGroup;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Manage the presentation of a Coxeter group and enforce constraints
|
||||||
|
* on the multiplicities of its relations.
|
||||||
|
* <ul>
|
||||||
|
* <li>
|
||||||
|
* <code>m_ij = 1</code> iff <code>i != j</code>
|
||||||
|
* </li>
|
||||||
|
* <li>
|
||||||
|
* <code>m_ij = m_ji</code>
|
||||||
|
* </li>
|
||||||
|
* <li>
|
||||||
|
* If <code>m_ij == inf</code> (<code>tc::FREE</code>) then no relation is imposed.
|
||||||
|
* </li>
|
||||||
|
* </ul>
|
||||||
|
* @see
|
||||||
|
* <a href="https://en.wikipedia.org/wiki/Coxeter_group#Definition">Coxeter Group (Wikipedia)</a>
|
||||||
|
*/
|
||||||
struct Group {
|
struct Group {
|
||||||
int ngens;
|
int ngens;
|
||||||
tc::pair_map<int> _mults;
|
tc::pair_map<int> _mults;
|
||||||
@@ -17,6 +34,10 @@ namespace tc {
|
|||||||
explicit Group(int ngens, const std::vector<Rel> &rels = {})
|
explicit Group(int ngens, const std::vector<Rel> &rels = {})
|
||||||
: ngens(ngens), _mults(ngens, 2) {
|
: ngens(ngens), _mults(ngens, 2) {
|
||||||
|
|
||||||
|
for (int i = 0; i < ngens; ++i) {
|
||||||
|
set(Rel{i, i, 1});
|
||||||
|
}
|
||||||
|
|
||||||
for (const auto &rel: rels) {
|
for (const auto &rel: rels) {
|
||||||
set(rel);
|
set(rel);
|
||||||
}
|
}
|
||||||
@@ -24,6 +45,9 @@ namespace tc {
|
|||||||
|
|
||||||
void set(const Rel &r) {
|
void set(const Rel &r) {
|
||||||
auto &[i, j, m] = r;
|
auto &[i, j, m] = r;
|
||||||
|
if (i == j && m != 1) {
|
||||||
|
throw std::runtime_error("Coxeter groups must satisfy m_ii=1.");
|
||||||
|
}
|
||||||
_mults(i, j) = m;
|
_mults(i, j) = m;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -31,16 +55,6 @@ namespace tc {
|
|||||||
return _mults(i, j);
|
return _mults(i, j);
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] std::vector<Rel> rels() const {
|
|
||||||
std::vector<Rel> res;
|
|
||||||
for (int i = 0; i < ngens - 1; ++i) {
|
|
||||||
for (int j = i + 1; j < ngens; ++j) {
|
|
||||||
res.emplace_back(i, j, get(i, j));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] SubGroup subgroup(const std::vector<int> &gens) const;
|
[[nodiscard]] SubGroup subgroup(const std::vector<int> &gens) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ namespace tc {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Cosets solve(const Group &group, const std::vector<Gen> &sub_gens) {
|
Cosets solve(const Group &group, const std::vector<Gen> &sub_gens, const Coset &bound) {
|
||||||
auto ngens = group.ngens;
|
auto ngens = group.ngens;
|
||||||
|
|
||||||
// region Initialize Cosets Table
|
// region Initialize Cosets Table
|
||||||
@@ -48,6 +48,7 @@ namespace tc {
|
|||||||
cosets.add_row();
|
cosets.add_row();
|
||||||
|
|
||||||
if (ngens == 0) {
|
if (ngens == 0) {
|
||||||
|
cosets.complete = true;
|
||||||
return cosets;
|
return cosets;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,9 +58,22 @@ namespace tc {
|
|||||||
}
|
}
|
||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
auto rels = group.rels();
|
|
||||||
|
|
||||||
// region Initialize Relation Tables
|
// region Initialize Relation Tables
|
||||||
|
std::vector<std::tuple<Gen, Gen, Mult>> rels;
|
||||||
|
for (const auto &[i, j, m]: group._mults) {
|
||||||
|
// The algorithm only works for Coxeter groups; multiplicities m_ii=1 are assumed. Relation tables
|
||||||
|
// _may_ be added for them, but they are redundant and hurt performance so are skipped.
|
||||||
|
if (i == j) continue;
|
||||||
|
|
||||||
|
// Coxeter groups admit infinite multiplicities, represented by contexpr tc::FREE. Relation tables
|
||||||
|
// for these should be skipped.
|
||||||
|
if (m == FREE) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
rels.emplace_back(i, j, m);
|
||||||
|
}
|
||||||
|
|
||||||
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;
|
||||||
@@ -97,6 +111,10 @@ namespace tc {
|
|||||||
while (idx < cosets.data.size() and cosets.isset(idx))
|
while (idx < cosets.data.size() and cosets.isset(idx))
|
||||||
idx++;
|
idx++;
|
||||||
|
|
||||||
|
if (cosets.size() >= bound) {
|
||||||
|
return cosets;
|
||||||
|
}
|
||||||
|
|
||||||
// if there are none, then return
|
// if there are none, then return
|
||||||
if (idx == cosets.data.size()) {
|
if (idx == cosets.data.size()) {
|
||||||
// todo unrolled linked list interval
|
// todo unrolled linked list interval
|
||||||
@@ -191,6 +209,7 @@ namespace tc {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cosets.complete = true;
|
||||||
return cosets;
|
return cosets;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user