forked from mirror/toddcox-faster
Compare commits
1 Commits
master
...
path-conte
| Author | SHA1 | Date | |
|---|---|---|---|
| f29724a185 |
@@ -6,6 +6,13 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace tc {
|
namespace tc {
|
||||||
|
struct Action;
|
||||||
|
struct Path;
|
||||||
|
struct Cosets;
|
||||||
|
struct Rel;
|
||||||
|
struct Group;
|
||||||
|
struct SubGroup;
|
||||||
|
|
||||||
struct Action {
|
struct Action {
|
||||||
int from_idx = -1;
|
int from_idx = -1;
|
||||||
int gen = -1;
|
int gen = -1;
|
||||||
@@ -18,9 +25,10 @@ namespace tc {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct Path {
|
struct Path {
|
||||||
|
const tc::Group &context;
|
||||||
std::vector<Action> path;
|
std::vector<Action> path;
|
||||||
|
|
||||||
Path() = default;
|
explicit Path(const tc::Group &context);
|
||||||
|
|
||||||
Path(const Path &) = default;
|
Path(const Path &) = default;
|
||||||
|
|
||||||
@@ -29,25 +37,6 @@ namespace tc {
|
|||||||
[[nodiscard]] Action get(int to_idx) const;
|
[[nodiscard]] Action get(int to_idx) const;
|
||||||
|
|
||||||
void put(int from_idx, int gen, int to_idx);
|
void put(int from_idx, int gen, int to_idx);
|
||||||
|
|
||||||
template<class C, class T, class E>
|
|
||||||
void walk(
|
|
||||||
C& res,
|
|
||||||
T start,
|
|
||||||
std::vector<E> gens,
|
|
||||||
std::function<T(const T &, const E &)> op
|
|
||||||
) const {
|
|
||||||
size_t s = size();
|
|
||||||
res.reserve(s);
|
|
||||||
res.push_back(start);
|
|
||||||
|
|
||||||
for (int i = 1; i < s; ++i) {
|
|
||||||
auto &action = path[i];
|
|
||||||
auto &from = res.get(action.from_idx);
|
|
||||||
auto &val = gens[action.gen];
|
|
||||||
res.push_back(op(from,val));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class T, class E>
|
template<class T, class E>
|
||||||
[[nodiscard]] std::vector<T> walk(
|
[[nodiscard]] std::vector<T> walk(
|
||||||
@@ -55,15 +44,14 @@ namespace tc {
|
|||||||
std::vector<E> gens,
|
std::vector<E> gens,
|
||||||
std::function<T(const T &, const E &)> op
|
std::function<T(const T &, const E &)> op
|
||||||
) const {
|
) const {
|
||||||
std::vector<T> res;
|
std::vector<T> res(size());
|
||||||
res.reserve(size());
|
res[0] = start;
|
||||||
res.push_back(start);
|
|
||||||
|
|
||||||
for (int i = 1; i < size(); ++i) {
|
for (int i = 1; i < res.size(); ++i) {
|
||||||
auto &action = path[i];
|
auto &action = path[i];
|
||||||
auto &from = res[action.from_idx];
|
auto &from = res[action.from_idx];
|
||||||
auto &val = gens[action.gen];
|
auto &val = gens[action.gen];
|
||||||
res.push_back(op(from, val));
|
res[i] = op(from, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
@@ -74,11 +62,10 @@ namespace tc {
|
|||||||
T start,
|
T start,
|
||||||
std::function<T(const T &, const int &)> op
|
std::function<T(const T &, const int &)> op
|
||||||
) const {
|
) const {
|
||||||
std::vector<T> res;
|
std::vector<T> res(size());
|
||||||
res.reserve(size());
|
res[0] = start;
|
||||||
res.push_back(start);
|
|
||||||
|
|
||||||
for (int i = 1; i < size(); ++i) {
|
for (int i = 1; i < res.size(); ++i) {
|
||||||
auto &action = path[i];
|
auto &action = path[i];
|
||||||
auto &from = res[action.from_idx];
|
auto &from = res[action.from_idx];
|
||||||
auto &val = action.gen;
|
auto &val = action.gen;
|
||||||
@@ -92,13 +79,14 @@ namespace tc {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct Cosets {
|
struct Cosets {
|
||||||
int ngens;
|
const tc::Group &context;
|
||||||
|
|
||||||
std::vector<int> data;
|
std::vector<int> data;
|
||||||
Path path;
|
Path path;
|
||||||
|
|
||||||
Cosets(const Cosets &) = default;
|
Cosets(const Cosets &) = default;
|
||||||
|
|
||||||
explicit Cosets(int ngens);
|
explicit Cosets(const tc::Group &context);
|
||||||
|
|
||||||
void add_row();
|
void add_row();
|
||||||
|
|
||||||
@@ -126,10 +114,8 @@ namespace tc {
|
|||||||
[[nodiscard]] Rel shift(int off) const;
|
[[nodiscard]] Rel shift(int off) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SubGroup;
|
|
||||||
|
|
||||||
struct Group {
|
struct Group {
|
||||||
int ngens;
|
const int ngens;
|
||||||
std::vector<std::vector<int>> _mults;
|
std::vector<std::vector<int>> _mults;
|
||||||
std::string name;
|
std::string name;
|
||||||
|
|
||||||
|
|||||||
22
src/core.cpp
22
src/core.cpp
@@ -9,6 +9,10 @@ namespace tc {
|
|||||||
: from_idx(from_idx), gen(gen) {
|
: from_idx(from_idx), gen(gen) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Path::Path(const tc::Group &context)
|
||||||
|
: context(context), path() {
|
||||||
|
}
|
||||||
|
|
||||||
void Path::add_row() {
|
void Path::add_row() {
|
||||||
path.resize(path.size() + 1);
|
path.resize(path.size() + 1);
|
||||||
}
|
}
|
||||||
@@ -25,18 +29,18 @@ namespace tc {
|
|||||||
return path.size();
|
return path.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
Cosets::Cosets(int ngens)
|
Cosets::Cosets(const tc::Group &context)
|
||||||
: ngens(ngens) {
|
: path(context), context(context), data() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cosets::add_row() {
|
void Cosets::add_row() {
|
||||||
data.resize(data.size() + ngens, -1);
|
data.resize(data.size() + context.ngens, -1);
|
||||||
path.add_row();
|
path.add_row();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cosets::put(int coset, int gen, int target) {
|
void Cosets::put(int coset, int gen, int target) {
|
||||||
data[coset * ngens + gen] = target;
|
data[coset * context.ngens + gen] = target;
|
||||||
data[target * ngens + gen] = coset;
|
data[target * context.ngens + gen] = coset;
|
||||||
|
|
||||||
if (path.get(target).from_idx == -1) {
|
if (path.get(target).from_idx == -1) {
|
||||||
path.put(coset, gen, target);
|
path.put(coset, gen, target);
|
||||||
@@ -44,10 +48,10 @@ namespace tc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Cosets::put(int idx, int target) {
|
void Cosets::put(int idx, int target) {
|
||||||
int coset = idx / ngens;
|
int coset = idx / context.ngens;
|
||||||
int gen = idx % ngens;
|
int gen = idx % context.ngens;
|
||||||
data[idx] = target;
|
data[idx] = target;
|
||||||
data[target * ngens + gen] = coset;
|
data[target * context.ngens + gen] = coset;
|
||||||
|
|
||||||
if (path.get(target).from_idx == -1) {
|
if (path.get(target).from_idx == -1) {
|
||||||
path.put(coset, gen, target);
|
path.put(coset, gen, target);
|
||||||
@@ -55,7 +59,7 @@ namespace tc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int Cosets::get(int coset, int gen) const {
|
int Cosets::get(int coset, int gen) const {
|
||||||
return data[coset * ngens + gen];
|
return data[coset * context.ngens + gen];
|
||||||
}
|
}
|
||||||
|
|
||||||
int Cosets::get(int idx) const {
|
int Cosets::get(int idx) const {
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ namespace tc {
|
|||||||
};
|
};
|
||||||
|
|
||||||
Cosets Group::solve(const std::vector<int> &sub_gens) const {
|
Cosets Group::solve(const std::vector<int> &sub_gens) const {
|
||||||
Cosets cosets(ngens);
|
Cosets cosets(*this);
|
||||||
cosets.add_row();
|
cosets.add_row();
|
||||||
|
|
||||||
if (ngens == 0) {
|
if (ngens == 0) {
|
||||||
|
|||||||
Reference in New Issue
Block a user