From e2295687bf95985c66458b3beb07ab1082ab9ec8 Mon Sep 17 00:00:00 2001 From: Jacob Date: Mon, 20 Jan 2020 17:47:39 -0500 Subject: [PATCH] Fixed memoization module Implement "raise" (called recontext) Implement tile --- examples/CMakeLists.txt | 3 + examples/geomtest.cpp | 40 ++++++++ examples/memotest.cpp | 26 +++--- vendor/toddcox | 2 +- vis/include/geometry.hpp | 193 ++++++++++++++++++++++++++++++++++----- vis/src/main.cpp | 2 +- 6 files changed, 227 insertions(+), 39 deletions(-) create mode 100644 examples/geomtest.cpp diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 1608af9..5aaae27 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,2 +1,5 @@ add_executable(memo memotest.cpp) target_link_libraries(memo PRIVATE tc vis-util) + +add_executable(geom geomtest.cpp) +target_link_libraries(geom PRIVATE tc vis-util) \ No newline at end of file diff --git a/examples/geomtest.cpp b/examples/geomtest.cpp new file mode 100644 index 0000000..0a22aaf --- /dev/null +++ b/examples/geomtest.cpp @@ -0,0 +1,40 @@ +// +// Created by raymo on 1/20/2020. +// + +#include +#include +#include + +int main () { + auto g = tc::group::B(3); + 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 g_gens = gg.group_gens(); + std::vector sg_gens = {1,2}; + auto ns = gg.tile(g_gens,sg_gens,s); + + std::cout << "Before: " << std::endl; + std::cout << '\t'; + for (int val : s.vals) { + std::cout << val << " "; + } + std::cout << std::endl; + + std::cout << " After: " << std::endl; + std::cout << '\t'; + for (int val : ns.vals) { + std::cout << val << " "; + } + std::cout << std::endl; + + return 0; +} \ No newline at end of file diff --git a/examples/memotest.cpp b/examples/memotest.cpp index 6e42afb..2698b64 100644 --- a/examples/memotest.cpp +++ b/examples/memotest.cpp @@ -1,11 +1,11 @@ #include #include #include -#include +#include int main() { tc::Group g = tc::group::B(3); - CosetMemo m(g); + GeomGen m(g); m.solve({}, {}); m.solve({0}, {}); @@ -36,19 +36,19 @@ int main() { m.solve({0, 1, 2}, {0, 1, 2}); tc::Group big = tc::group::B(8); - CosetMemo mbig(big); + GeomGen mbig(big); - auto s1 = clock(); - m.solve({0, 1, 2, 3, 4, 5, 6, 7}, {}); - auto e1 = clock(); + auto s1 = std::chrono::system_clock::now(); + auto res1 = mbig.solve({0,1,2,3,4,7}, {2,4,7}); + auto e1 = std::chrono::system_clock::now(); - double t1 = (double) (e1 - s1) / (double) CLOCKS_PER_SEC; - std::cout << t1 << std::endl; + std::chrono::duration t1 = e1 - s1; + std::cout << t1.count() << ": " << res1.size() << std::endl; - auto s2 = clock(); - m.solve({0, 1, 2, 3, 4, 5, 6, 7}, {}); - auto e2 = clock(); + auto s2 = std::chrono::system_clock::now(); + auto res2 = mbig.solve({0,2,4,7,1,3}, {4,7,2}); + auto e2 = std::chrono::system_clock::now(); - double t2 = (double) (e2 - s2) / (double) CLOCKS_PER_SEC; - std::cout << t2 << std::endl; + std::chrono::duration t2 = e2 - s2; + std::cout << t2.count() << ": " << res2.size() << std::endl; } diff --git a/vendor/toddcox b/vendor/toddcox index 7cfb0a3..def45ed 160000 --- a/vendor/toddcox +++ b/vendor/toddcox @@ -1 +1 @@ -Subproject commit 7cfb0a380311cdd7c050407b3642bbb8a07f417d +Subproject commit def45ed6717457b159c65c3fbe24ebe4f450fb35 diff --git a/vis/include/geometry.hpp b/vis/include/geometry.hpp index 4775a64..15128a1 100644 --- a/vis/include/geometry.hpp +++ b/vis/include/geometry.hpp @@ -1,38 +1,183 @@ #pragma once #include -#include #include +#include -size_t key(const std::vector &gens) { - size_t bits = 0; - for (const auto &gen : gens) { - bits |= 1U << gen; +size_t get_key_from_gens(std::vector &gens) { + size_t key = 0; + for (const auto gen : gens) { + key += (1u << (unsigned)gen); } - return bits; + return key; } -struct CosetMemo { - const tc::Group &parent; - std::vector>> results; - - explicit CosetMemo(const tc::Group &parent) - : parent(parent) { - size_t W = std::pow(2, parent.ngens); - - for (size_t i = 0; i < W; ++i) { - results.emplace_back(W, std::nullopt); - } +size_t num_gens_from_key(size_t key) { + size_t mask = 1; + size_t count = 0; + while (mask <= key) { + if (key & mask) + count++; + mask <<= 1u; } + return count; +} - tc::Cosets solve(const std::vector &group_gens, const std::vector &sub_gens) { - size_t group_key = key(group_gens); - size_t sub_key = key(sub_gens); +struct SimplexesList; - if (!results[group_key][sub_key]) { - results[group_key][sub_key] = parent.subgroup(group_gens).solve(sub_gens); - } +struct Simplexes { + int dim; + std::vector vals; - return results[group_key][sub_key].value(); + explicit Simplexes(int dim): dim(dim) {} + Simplexes(int dim, std::vector &vals): dim(dim), vals(vals) {} + Simplexes(SimplexesList sl); + + size_t size() { + return vals.size(); } }; + +struct SimplexesList { + int dim; + std::vector vals; + int elem_size; + Simplexes temp; + + explicit SimplexesList(Simplexes s) : dim(s.dim), elem_size(s.size()), temp(s.dim) { + temp.vals.reserve(s.size()); + } + + void reserve(size_t i) { + vals.reserve(elem_size * i); + } + + Simplexes& get(size_t i) { + temp.vals.clear(); + temp.vals.insert(temp.vals.end(), vals.begin()+elem_size*i, vals.begin()+elem_size*(i+1)); + return temp; + } + + void push_back(Simplexes s) { + vals.insert(vals.end(), s.vals.begin(), s.vals.end()); + } +}; + +Simplexes::Simplexes(SimplexesList sl): Simplexes(sl.dim, sl.vals) {} + +struct GeomGen { + std::vector>> coset_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); + 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); + } + } + + std::vector group_gens() { + std::vector gens(context.ngens); + for (int i=0; i < context.ngens; i++) { + gens[i] = i; + } + return gens; + } + + std::vector prepare_gens(std::vector &g_gens, std::vector &sg_gens) { + std::sort(g_gens.begin(), g_gens.end()); + + int inv_gen_map[context.ngens]; + for (size_t i = 0; i < g_gens.size(); i++) { + inv_gen_map[g_gens[i]] = i; + } + + std::vector s_sg_gens; + s_sg_gens.reserve(sg_gens.size()); + for (const auto gen : sg_gens) { + s_sg_gens.push_back(inv_gen_map[gen]); + } + std::sort(s_sg_gens.begin(), s_sg_gens.end()); + + return s_sg_gens; + } + + tc::Cosets _solve(std::vector &g_gens, std::vector &sg_gens) { + auto s_sg_gens = prepare_gens(g_gens, sg_gens); + + size_t group_key = get_key_from_gens(g_gens); + size_t subgroup_key = get_key_from_gens(s_sg_gens); + + if (!coset_memo[group_key][subgroup_key]) { + tc::SubGroup g = context.subgroup(g_gens); + coset_memo[group_key][subgroup_key] = g.solve(s_sg_gens); + } + return *coset_memo[group_key][subgroup_key]; + } + + tc::Cosets solve(std::vector g_gens, std::vector sg_gens) { + return _solve(g_gens, sg_gens); + } + + tc::Cosets solve_sg(std::vector &sg_gens) { + auto g_gens = group_gens(); + return _solve(g_gens, sg_gens); + } + + tc::Cosets solve_g(std::vector &g_gens) { + std::vector sg_gens; + return _solve(g_gens, sg_gens); + } + + tc::Cosets solve() { + std::vector sg_gens; + return solve_sg(sg_gens); + } + + Simplexes recontext(std::vector &g_gens, std::vector &sg_gens, Simplexes &items) { + auto s_sg_gens = prepare_gens(g_gens, sg_gens); + auto table = solve_g(g_gens); + auto path = solve_g(sg_gens).path; + + auto coset_map = [table](int coset, int gen){return table.get(coset,gen);}; + + auto map = path.walk(0, s_sg_gens, coset_map); + + Simplexes ret(items.dim); + ret.vals.reserve(items.size()); + for (const auto val : items.vals) { + ret.vals.push_back(map[val]); + } + return ret; + } + + Simplexes tile(std::vector &g_gens, std::vector &sg_gens, Simplexes &items) { + Simplexes base = recontext(g_gens, sg_gens, items); + auto s_sg_gens = prepare_gens(g_gens, sg_gens); + auto table = solve_g(g_gens); + auto path = _solve(g_gens, sg_gens).path; + + auto simplex_map = [table](const Simplexes& items, int gen) -> Simplexes { + Simplexes ret(items.dim); + ret.vals.reserve(items.vals.size()); + // Move the simplexes + for (const auto coset : items.vals) { + 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]); + } + } + return ret; + }; + + SimplexesList ret(base); + path.walk(ret, base, group_gens(), simplex_map); + + return ret; + } +}; \ No newline at end of file diff --git a/vis/src/main.cpp b/vis/src/main.cpp index aa2fbb7..b9665c1 100644 --- a/vis/src/main.cpp +++ b/vis/src/main.cpp @@ -57,7 +57,7 @@ int main(int argc, char *argv[]) { exit(EXIT_FAILURE); } - auto group = tc::schlafli({5, 3, 3}); + auto group = tc::group::H(4); auto res = group.solve(); auto mirrors = mirror(group);