From 6b03b7d9bea88ab11b1d89d2c949f120301e2fd5 Mon Sep 17 00:00:00 2001 From: Jacob Date: Sat, 25 Jan 2020 21:32:17 -0500 Subject: [PATCH] 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 --- examples/geomtest.cpp | 22 +++++---- examples/memotest.cpp | 16 +++++++ vendor/toddcox | 2 +- vis/include/geometry.hpp | 99 ++++++++++++++++++++++++++++++++++++---- vis/src/main.cpp | 8 +--- 5 files changed, 122 insertions(+), 25 deletions(-) diff --git a/examples/geomtest.cpp b/examples/geomtest.cpp index 0a22aaf..d094c58 100644 --- a/examples/geomtest.cpp +++ b/examples/geomtest.cpp @@ -7,16 +7,22 @@ #include 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 = {"a", "b", "c"}; + std::string base = ""; + auto words = path.walk(base,{"a","b","c"}, [](auto s1, auto g){return s1+g;}); + for (const auto word : words) { + std::cout << word << std::endl; + } + + std::vector gens = {0,1,2}; + auto s = gg.triangulate(gens); + s.print(); + return 0; auto g_gens = gg.group_gens(); std::vector sg_gens = {1,2}; diff --git a/examples/memotest.cpp b/examples/memotest.cpp index 2698b64..d7bce38 100644 --- a/examples/memotest.cpp +++ b/examples/memotest.cpp @@ -51,4 +51,20 @@ int main() { std::chrono::duration t2 = e2 - s2; std::cout << t2.count() << ": " << res2.size() << std::endl; + + std::vector 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 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 t4 = e4 - s4; + std::cout << t4.count() << ": " << res4.size() << std::endl; + } diff --git a/vendor/toddcox b/vendor/toddcox index 16c9d7d..def45ed 160000 --- a/vendor/toddcox +++ b/vendor/toddcox @@ -1 +1 @@ -Subproject commit 16c9d7d62f728196c5d2c078d268fe46d81a17be +Subproject commit def45ed6717457b159c65c3fbe24ebe4f450fb35 diff --git a/vis/include/geometry.hpp b/vis/include/geometry.hpp index b06642d..a95eadd 100644 --- a/vis/include/geometry.hpp +++ b/vis/include/geometry.hpp @@ -3,6 +3,7 @@ #include #include #include +#include size_t get_key_from_gens(std::vector &gens) { size_t key = 0; @@ -31,11 +32,38 @@ struct Simplexes { explicit Simplexes(int dim): dim(dim) {} Simplexes(int dim, std::vector &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>> coset_memo; + std::vector> 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 &g_gens, std::vector &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 &g_gens, std::vector &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); } -}; \ No newline at end of file + + Simplexes triangulate(std::vector &g_gens); + + Simplexes _triangulate(std::vector &g_gens) { + Simplexes S(g_gens.size()); + if (g_gens.empty()) { + S.vals.push_back(0); + return S; + } + std::vector 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 &g_gens) { + int key = get_key_from_gens(g_gens); + if (!triangulate_memo[key]) { + triangulate_memo[key] = _triangulate(g_gens); + } + return *triangulate_memo[key]; +} \ No newline at end of file diff --git a/vis/src/main.cpp b/vis/src/main.cpp index 6715ccb..05633b0 100644 --- a/vis/src/main.cpp +++ b/vis/src/main.cpp @@ -99,16 +99,12 @@ int main(int argc, char *argv[]) { std::vector edge_count; std::vector edge_ibo; - Simplexes base(1); - base.vals = {0,1}; - std::vector g_gens = gg.group_gens(); + auto g_gens = gg.group_gens(); - printf("Num Edges:\n"); for (const auto i : g_gens) { std::vector 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);