Implement triangulate (like 95% sure it's right) - memoized

Modify recontext to reorient in special cases
Move reorient as Simplexes method
Changes in geomtest and memotest to test triangulate and memoization for triangulate
This commit is contained in:
Jacob
2020-01-25 21:32:17 -05:00
parent 506320200d
commit 6b03b7d9be
5 changed files with 122 additions and 25 deletions

View File

@@ -7,16 +7,22 @@
#include <iostream>
int main () {
auto g = tc::group::B(3);
auto g = tc::schlafli({3,2});
GeomGen gg(g);
Simplexes s(1);
s.vals.push_back(0);
s.vals.push_back(1);
s.vals.push_back(0);
s.vals.push_back(2);
s.vals.push_back(1);
s.vals.push_back(2);
auto path = gg.solve().path;
//std::vector<std::string> = {"a", "b", "c"};
std::string base = "";
auto words = path.walk<std::string, std::string>(base,{"a","b","c"}, [](auto s1, auto g){return s1+g;});
for (const auto word : words) {
std::cout << word << std::endl;
}
std::vector<int> gens = {0,1,2};
auto s = gg.triangulate(gens);
s.print();
return 0;
auto g_gens = gg.group_gens();
std::vector<int> sg_gens = {1,2};

View File

@@ -51,4 +51,20 @@ int main() {
std::chrono::duration<double> t2 = e2 - s2;
std::cout << t2.count() << ": " << res2.size() << std::endl;
std::vector<int> gens = {0,1,2,3,4,5};
auto s3 = std::chrono::system_clock::now();
auto res3 = mbig.triangulate(gens);
auto e3 = std::chrono::system_clock::now();
std::chrono::duration<double> t3 = e3 - s3;
std::cout << t3.count() << ": " << res3.size() << std::endl;
auto s4 = std::chrono::system_clock::now();
auto res4 = mbig.triangulate(gens);
auto e4 = std::chrono::system_clock::now();
std::chrono::duration<double> t4 = e4 - s4;
std::cout << t4.count() << ": " << res4.size() << std::endl;
}

2
vendor/toddcox vendored

View File

@@ -3,6 +3,7 @@
#include <tc/core.hpp>
#include <cmath>
#include <optional>
#include <iostream>
size_t get_key_from_gens(std::vector<int> &gens) {
size_t key = 0;
@@ -31,11 +32,38 @@ struct Simplexes {
explicit Simplexes(int dim): dim(dim) {}
Simplexes(int dim, std::vector<int> &vals): dim(dim), vals(vals) {}
explicit Simplexes(SimplexesList sl);
explicit Simplexes(SimplexesList &sl);
size_t size() const {
[[nodiscard]] size_t size() const {
return vals.size();
}
void reorient() {
if (dim == 0)
return;
for (int i = 0; i < vals.size(); i+=dim+1) {
std::swap(vals[i], vals[i+1]);
}
}
void print() {
if (vals.empty()) {
std::cout << "[]" << std::endl;
}
std::cout << "[(" << vals[0];
for (int i = 1; i < dim+1; i++) {
std::cout << "," << vals[i];
}
std::cout << ")";
for (int i = dim+1; i < vals.size(); i+= dim+1) {
std::cout << ", (" << vals[i];
for (int j = i+1; j < i+dim+1; j++) {
std::cout << "," << vals[j];
}
std::cout << ")";
}
std::cout << "]";
}
};
struct SimplexesList {
@@ -44,7 +72,7 @@ struct SimplexesList {
int elem_size;
Simplexes temp;
explicit SimplexesList(Simplexes s) : dim(s.dim), elem_size(s.size()), temp(s.dim) {
explicit SimplexesList(Simplexes &s) : dim(s.dim), elem_size(s.size()), temp(s.dim) {
temp.vals.reserve(s.size());
}
@@ -63,15 +91,17 @@ struct SimplexesList {
}
};
Simplexes::Simplexes(SimplexesList sl): Simplexes(sl.dim, sl.vals) {}
Simplexes::Simplexes(SimplexesList &sl): Simplexes(sl.dim, sl.vals) {}
struct GeomGen {
std::vector<std::vector<std::optional<tc::Cosets>>> coset_memo;
std::vector<std::optional<Simplexes>> triangulate_memo;
tc::Group &context;
explicit GeomGen(tc::Group &g): context(g) {
size_t num_sg = std::pow(2, g.ngens);
coset_memo.resize(num_sg);
triangulate_memo.resize(num_sg);
for (size_t i = 0; i < num_sg; i++) {
auto num_sg_sg = std::pow(2, num_gens_from_key(i));
coset_memo[i].resize(num_sg_sg, std::nullopt);
@@ -104,6 +134,18 @@ struct GeomGen {
return s_sg_gens;
}
int get_parity(std::vector<int> &g_gens, std::vector<int> &sg_gens) {
if (g_gens.size() != sg_gens.size() + 1)
return 0;
auto s_sg_gens = prepare_gens(g_gens, sg_gens);
const int loop_max = g_gens.size()-1;
for (int i = 0; i < loop_max; i++) {
if (s_sg_gens[i] != i)
return i % 2;
}
return loop_max % 2;
}
tc::Cosets _solve(std::vector<int> &g_gens, std::vector<int> &sg_gens) {
auto s_sg_gens = prepare_gens(g_gens, sg_gens);
@@ -150,6 +192,8 @@ struct GeomGen {
for (const auto val : items.vals) {
ret.vals.push_back(map[val]);
}
if (get_parity(g_gens, sg_gens) == 1)
ret.reorient();
return ret;
}
@@ -167,11 +211,7 @@ struct GeomGen {
ret.vals.push_back(table.get(coset,gen));
}
// Reorient the simplexes
if (ret.dim > 0) {
for (int i = 0; i < ret.size(); i += ret.dim+1) {
std::swap(ret.vals[i],ret.vals[i+1]);
}
}
ret.reorient();
return ret;
};
@@ -180,4 +220,43 @@ struct GeomGen {
return Simplexes(ret);
}
Simplexes triangulate(std::vector<int> &g_gens);
Simplexes _triangulate(std::vector<int> &g_gens) {
Simplexes S(g_gens.size());
if (g_gens.empty()) {
S.vals.push_back(0);
return S;
}
std::vector<int> sg_gens(g_gens.size()-1);
for (int i = 0; i < g_gens.size(); i++) {
int k = 0;
for (int j = 0; j < g_gens.size(); j++) {
if (j != i) {
sg_gens[k++] = g_gens[j];
}
}
auto sub_simps = triangulate(sg_gens);
int start = sub_simps.size();
sub_simps = tile(g_gens, sg_gens, sub_simps);
for (int l = start; l < sub_simps.size(); l+=S.dim) {
S.vals.push_back(0);
for (int m = l; m < l+S.dim; m++) {
S.vals.push_back(sub_simps.vals[m]);
}
}
}
return S;
}
};
Simplexes GeomGen::triangulate(std::vector<int> &g_gens) {
int key = get_key_from_gens(g_gens);
if (!triangulate_memo[key]) {
triangulate_memo[key] = _triangulate(g_gens);
}
return *triangulate_memo[key];
}

View File

@@ -99,16 +99,12 @@ int main(int argc, char *argv[]) {
std::vector<int> edge_count;
std::vector<GLuint> edge_ibo;
Simplexes base(1);
base.vals = {0,1};
std::vector<int> g_gens = gg.group_gens();
auto g_gens = gg.group_gens();
printf("Num Edges:\n");
for (const auto i : g_gens) {
std::vector<int> sg_gens = {i};
const auto data = gg.tile(g_gens, sg_gens, base).vals;
const auto data = gg.tile(g_gens, sg_gens, gg.triangulate(sg_gens)).vals;
edge_count.push_back(data.size());
printf("\t%d: %d", i, data.size());
GLuint ibo;
glGenBuffers(1, &ibo);