mirror of
https://github.com/allemangD/toddcox-visualize.git
synced 2025-11-10 12:02:47 -05:00
Fixed memoization module
Implement "raise" (called recontext) Implement tile
This commit is contained in:
@@ -1,2 +1,5 @@
|
|||||||
add_executable(memo memotest.cpp)
|
add_executable(memo memotest.cpp)
|
||||||
target_link_libraries(memo PRIVATE tc vis-util)
|
target_link_libraries(memo PRIVATE tc vis-util)
|
||||||
|
|
||||||
|
add_executable(geom geomtest.cpp)
|
||||||
|
target_link_libraries(geom PRIVATE tc vis-util)
|
||||||
40
examples/geomtest.cpp
Normal file
40
examples/geomtest.cpp
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
//
|
||||||
|
// Created by raymo on 1/20/2020.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <tc/groups.hpp>
|
||||||
|
#include <geometry.hpp>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
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<int> 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;
|
||||||
|
}
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
#include <geometry.hpp>
|
#include <geometry.hpp>
|
||||||
#include <tc/groups.hpp>
|
#include <tc/groups.hpp>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <ctime>
|
#include <chrono>
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
tc::Group g = tc::group::B(3);
|
tc::Group g = tc::group::B(3);
|
||||||
CosetMemo m(g);
|
GeomGen m(g);
|
||||||
|
|
||||||
m.solve({}, {});
|
m.solve({}, {});
|
||||||
m.solve({0}, {});
|
m.solve({0}, {});
|
||||||
@@ -36,19 +36,19 @@ int main() {
|
|||||||
m.solve({0, 1, 2}, {0, 1, 2});
|
m.solve({0, 1, 2}, {0, 1, 2});
|
||||||
|
|
||||||
tc::Group big = tc::group::B(8);
|
tc::Group big = tc::group::B(8);
|
||||||
CosetMemo mbig(big);
|
GeomGen mbig(big);
|
||||||
|
|
||||||
auto s1 = clock();
|
auto s1 = std::chrono::system_clock::now();
|
||||||
m.solve({0, 1, 2, 3, 4, 5, 6, 7}, {});
|
auto res1 = mbig.solve({0,1,2,3,4,7}, {2,4,7});
|
||||||
auto e1 = clock();
|
auto e1 = std::chrono::system_clock::now();
|
||||||
|
|
||||||
double t1 = (double) (e1 - s1) / (double) CLOCKS_PER_SEC;
|
std::chrono::duration<double> t1 = e1 - s1;
|
||||||
std::cout << t1 << std::endl;
|
std::cout << t1.count() << ": " << res1.size() << std::endl;
|
||||||
|
|
||||||
auto s2 = clock();
|
auto s2 = std::chrono::system_clock::now();
|
||||||
m.solve({0, 1, 2, 3, 4, 5, 6, 7}, {});
|
auto res2 = mbig.solve({0,2,4,7,1,3}, {4,7,2});
|
||||||
auto e2 = clock();
|
auto e2 = std::chrono::system_clock::now();
|
||||||
|
|
||||||
double t2 = (double) (e2 - s2) / (double) CLOCKS_PER_SEC;
|
std::chrono::duration<double> t2 = e2 - s2;
|
||||||
std::cout << t2 << std::endl;
|
std::cout << t2.count() << ": " << res2.size() << std::endl;
|
||||||
}
|
}
|
||||||
|
|||||||
2
vendor/toddcox
vendored
2
vendor/toddcox
vendored
Submodule vendor/toddcox updated: 7cfb0a3803...def45ed671
@@ -1,38 +1,183 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <tc/core.hpp>
|
#include <tc/core.hpp>
|
||||||
#include <optional>
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
size_t key(const std::vector<int> &gens) {
|
size_t get_key_from_gens(std::vector<int> &gens) {
|
||||||
size_t bits = 0;
|
size_t key = 0;
|
||||||
for (const auto &gen : gens) {
|
for (const auto gen : gens) {
|
||||||
bits |= 1U << gen;
|
key += (1u << (unsigned)gen);
|
||||||
}
|
}
|
||||||
return bits;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct CosetMemo {
|
size_t num_gens_from_key(size_t key) {
|
||||||
const tc::Group &parent;
|
size_t mask = 1;
|
||||||
std::vector<std::vector<std::optional<tc::Cosets>>> results;
|
size_t count = 0;
|
||||||
|
while (mask <= key) {
|
||||||
explicit CosetMemo(const tc::Group &parent)
|
if (key & mask)
|
||||||
: parent(parent) {
|
count++;
|
||||||
size_t W = std::pow(2, parent.ngens);
|
mask <<= 1u;
|
||||||
|
|
||||||
for (size_t i = 0; i < W; ++i) {
|
|
||||||
results.emplace_back(W, std::nullopt);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
tc::Cosets solve(const std::vector<int> &group_gens, const std::vector<int> &sub_gens) {
|
struct SimplexesList;
|
||||||
size_t group_key = key(group_gens);
|
|
||||||
size_t sub_key = key(sub_gens);
|
|
||||||
|
|
||||||
if (!results[group_key][sub_key]) {
|
struct Simplexes {
|
||||||
results[group_key][sub_key] = parent.subgroup(group_gens).solve(sub_gens);
|
int dim;
|
||||||
}
|
std::vector<int> vals;
|
||||||
|
|
||||||
return results[group_key][sub_key].value();
|
explicit Simplexes(int dim): dim(dim) {}
|
||||||
|
Simplexes(int dim, std::vector<int> &vals): dim(dim), vals(vals) {}
|
||||||
|
Simplexes(SimplexesList sl);
|
||||||
|
|
||||||
|
size_t size() {
|
||||||
|
return vals.size();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct SimplexesList {
|
||||||
|
int dim;
|
||||||
|
std::vector<int> 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<std::vector<std::optional<tc::Cosets>>> 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<int> group_gens() {
|
||||||
|
std::vector<int> gens(context.ngens);
|
||||||
|
for (int i=0; i < context.ngens; i++) {
|
||||||
|
gens[i] = i;
|
||||||
|
}
|
||||||
|
return gens;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<int> prepare_gens(std::vector<int> &g_gens, std::vector<int> &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<int> 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<int> &g_gens, std::vector<int> &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<int> g_gens, std::vector<int> sg_gens) {
|
||||||
|
return _solve(g_gens, sg_gens);
|
||||||
|
}
|
||||||
|
|
||||||
|
tc::Cosets solve_sg(std::vector<int> &sg_gens) {
|
||||||
|
auto g_gens = group_gens();
|
||||||
|
return _solve(g_gens, sg_gens);
|
||||||
|
}
|
||||||
|
|
||||||
|
tc::Cosets solve_g(std::vector<int> &g_gens) {
|
||||||
|
std::vector<int> sg_gens;
|
||||||
|
return _solve(g_gens, sg_gens);
|
||||||
|
}
|
||||||
|
|
||||||
|
tc::Cosets solve() {
|
||||||
|
std::vector<int> sg_gens;
|
||||||
|
return solve_sg(sg_gens);
|
||||||
|
}
|
||||||
|
|
||||||
|
Simplexes recontext(std::vector<int> &g_gens, std::vector<int> &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<int,int>(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<int> &g_gens, std::vector<int> &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<SimplexesList, Simplexes, int>(ret, base, group_gens(), simplex_map);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -57,7 +57,7 @@ int main(int argc, char *argv[]) {
|
|||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto group = tc::schlafli({5, 3, 3});
|
auto group = tc::group::H(4);
|
||||||
auto res = group.solve();
|
auto res = group.solve();
|
||||||
auto mirrors = mirror(group);
|
auto mirrors = mirror(group);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user