From 3a96d4a8754e8432cbd0703638aae58e8a66e74e Mon Sep 17 00:00:00 2001 From: David Allemang Date: Fri, 20 Sep 2019 15:44:13 -0400 Subject: [PATCH] misc table solution optimizations --- cosets/CMakeLists.txt | 2 + cosets/include/coxeter.hpp | 92 +++++++++++--------------------------- cosets/include/mesh.hpp | 65 ++++++++++++++++++--------- cosets/include/mirrors.hpp | 5 +-- cosets/src/combos.cpp | 38 ++++++++++++++++ cosets/src/main.cpp | 30 +++++++------ 6 files changed, 128 insertions(+), 104 deletions(-) create mode 100644 cosets/src/combos.cpp diff --git a/cosets/CMakeLists.txt b/cosets/CMakeLists.txt index 1a26a91..b95988f 100644 --- a/cosets/CMakeLists.txt +++ b/cosets/CMakeLists.txt @@ -20,3 +20,5 @@ add_dependencies(cosets shaders) target_link_libraries(${PROJECT_NAME} PRIVATE glad glm glfw) + +add_executable(combos src/combos.cpp) diff --git a/cosets/include/coxeter.hpp b/cosets/include/coxeter.hpp index 80e8bce..379eed4 100644 --- a/cosets/include/coxeter.hpp +++ b/cosets/include/coxeter.hpp @@ -4,18 +4,15 @@ #include #include -template struct Mults; -template struct Table; struct IRow; -template struct Mults { - const int dim = NGENS; + const int dim; std::map, int> mults; - Mults() { + explicit Mults(const int dim) : dim(dim) { mults = std::map, int>(); } @@ -47,28 +44,34 @@ struct Mults { return res; } - [[nodiscard]] Table *isolve(const std::vector &isubgens) const; + [[nodiscard]] Mults sub(const std::vector &igens) const { + Mults res(igens.size()); + for (int a = 0; a < (int) igens.size(); ++a) { + for (int b = a + 1; b < (int) igens.size(); ++b) { + res.set(a, b, get(igens[a], igens[b])); + } + } + return res; + } - template - [[nodiscard]] Table *isolve(const int (&igens)[IGENS], const std::vector &isubgens) const; + [[nodiscard]] Table *isolve(const std::vector &isubgens) const; }; -template struct Table { - const Mults mults; + const Mults mults; std::vector> fwd; - explicit Table(Mults mults) : mults(mults) { + explicit Table(Mults mults) : mults(mults) { add_row(); } void add_row() { - fwd.emplace_back(NGENS, -1); + fwd.emplace_back(mults.dim, -1); } int add_coset() { for (int from = 0; from < (int) size(); ++from) { - for (int igen = 0; igen < (int) NGENS; igen++) { + for (int igen = 0; igen < (int) mults.dim; igen++) { if (iget(from, igen) < 0) { int to = (int) size(); add_row(); @@ -110,8 +113,7 @@ struct IRow { : l(rel.begin()), r(rel.end() - 1), from(cos), to(cos) { } - template - [[nodiscard]] bool learn(Table *table) { + [[nodiscard]] bool learn(Table *table) { if (r - l == 0) { return false; } @@ -139,24 +141,23 @@ struct IRow { } }; -template -Mults schlafli(const int(&symbol)[NGENS - 1]) { - Mults mults{}; - for (int i = 0; i < NGENS; ++i) { +Mults schlafli(const std::vector &symbol) { + unsigned int dim = symbol.size(); + Mults mults(dim + 1); + for (int i = 0; i < dim; ++i) { mults.set(i, i + 1, symbol[i]); } return mults; } -template -Table *Mults::isolve(const std::vector &isubgens) const { - auto *table = new Table(*this); +Table *Mults::isolve(const std::vector &isubgens) const { + auto *table = new Table(*this); for (int igen : isubgens) table->iset(0, igen, 0); std::vector> irels{}; - for (unsigned a = 0; a < NGENS; ++a) { - for (unsigned b = a + 1; b < NGENS; ++b) { + for (unsigned a = 0; a < dim; ++a) { + for (unsigned b = a + 1; b < dim; ++b) { irels.push_back(irelation(a, b)); } } @@ -191,46 +192,3 @@ Table *Mults::isolve(const std::vector &isubgens) const { return table; } -template -template -Table *Mults::isolve(const int (&igens)[IGENS], const std::vector &isubgens) const { - auto *table = new Table(*this); - for (int igen : isubgens) - table->iset(0, igen, 0); - - std::vector> irels{}; - for (unsigned a = 0; a < igens.size(); ++a) { - for (unsigned b = a + 1; b < igens.size(); ++b) { - irels.push_back(irelation(igens[a], igens[b])); - } - } - - std::vector irows; - irows.reserve(irels.size()); - for (const auto &irel : irels) - irows.emplace_back(irel, 0); - - while (!irows.empty()) { - while (true) { - bool learned = false; - for (int i = (int) irows.size() - 1; i >= 0; i--) { - if (irows[i].learn(table)) { - learned = true; - irows.erase(irows.begin() + i); - } - } - if (!learned) - break; - } - - int i = (int) table->size(); - if (table->add_coset() > 0) { - for (const auto &irel : irels) - irows.emplace_back(irel, i); - } else { - break; - } - } - - return table; -} diff --git a/cosets/include/mesh.hpp b/cosets/include/mesh.hpp index 9bc8c80..fa15a09 100644 --- a/cosets/include/mesh.hpp +++ b/cosets/include/mesh.hpp @@ -15,15 +15,13 @@ glm::vec4 identity(const std::vector &normals, const std::vector -glm::vec4 identity(const Mults &mults, const std::vector &coords) { +glm::vec4 identity(const Mults &mults, const std::vector &coords) { const std::vector normals = mirror(mults); return identity(normals, coords); } -template -glm::vec4 center(const Mults &mults) { +glm::vec4 center(const Mults &mults) { const std::vector normals = mirror(mults); const std::vector corners = plane_intersections(normals); std::vector coords{}; @@ -43,10 +41,9 @@ struct Buffer { unsigned size = 0; }; -template struct Mesh { - const Mults mults; - const Table *t_vert; + const Mults mults; + const Table *t_vert; const std::vector normals; glm::vec4 *vert_data; @@ -55,11 +52,12 @@ struct Mesh { Buffer edge; Buffer face; - explicit Mesh(Mults mults) : mults(mults), normals(mirror(mults)) { + explicit Mesh(const Mults &mults) : mults(mults), normals(mirror(mults)) { auto a = std::chrono::high_resolution_clock::now(); t_vert = mults.isolve({}); auto b = std::chrono::high_resolution_clock::now(); - std::cout << "time to solve: " << ((std::chrono::duration) (b - a)).count() << std::endl; + auto delta = (std::chrono::duration) (b - a); + std::cout << "time to solve verts: " << delta.count() << std::endl; vert.size = t_vert->size(); vert_data = new glm::vec4[vert.size]; @@ -71,19 +69,18 @@ struct Mesh { gen_indices(); } - explicit Mesh(Mults mults, const glm::vec4 root) { - this(mults); - gen_vertices(root); - } - void gen_vertices(const glm::vec4 root) { + auto a = std::chrono::high_resolution_clock::now(); vert_data[0] = root; for (unsigned from = 0; from < vert.size; ++from) { - for (unsigned gen = 0; gen < NGENS; ++gen) { + for (unsigned gen = 0; gen < mults.dim; ++gen) { int to = t_vert->iget((int) from, (int) gen); vert_data[to] = reflect(vert_data[from], normals[gen]); } } + auto b = std::chrono::high_resolution_clock::now(); + auto delta = (std::chrono::duration) (b - a); + std::cout << "time to build verts: " << delta.count() << std::endl; glBindBuffer(GL_ARRAY_BUFFER, vert.name); glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec4) * vert.size, vert_data, GL_STATIC_DRAW); @@ -91,11 +88,37 @@ struct Mesh { } void gen_indices() { - std::vector edges; - std::vector faces; + std::vector edge_data; + auto e_table = mults.sub({0, 1}).isolve({}); + +// std::cout << "building gens" << std::endl; +// const std::vector gens{0, 1}; +// std::cout << "built gens" << std::endl; +// const std::vector &igens = gens; +// Mults<2> res{}; +// for (int a = 0; a < 2; ++a) { +// for (int b = a + 1; b < 2; ++b) { +// res.set(a, b, t_vert->mults.get(igens[a], igens[b])); +// } +// } +// const auto &mults = res; +// std::cout << "built mults" << std::endl; + + +// auto *e_table = mults.isolve({}); +// std::cout << "built table" << std::endl; +// std::cout << "edge verts:" << e_table->size() << std::endl; +// +//// for (int i = 0; i < e_table->size(); ++i) { +//// edge_data.push_back(i); +//// } +// +// delete e_table; + + edge.size = edge_data.size(); glBindBuffer(GL_ARRAY_BUFFER, edge.name); -// glBufferData(GL_ARRAY_BUFFER, sizeof(int) * edge.size, edge_data, GL_STATIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, sizeof(int) * edge.size, &edge_data[0], GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); } @@ -103,9 +126,9 @@ struct Mesh { delete t_vert; delete[] vert_data; - glDeleteBuffers(1, &vert.name); - glDeleteBuffers(1, &edge.name); - glDeleteBuffers(1, &face.name); +// glDeleteBuffers(1, &vert.name); +// glDeleteBuffers(1, &edge.name); +// glDeleteBuffers(1, &face.name); } }; diff --git a/cosets/include/mirrors.hpp b/cosets/include/mirrors.hpp index 929f24c..95eadd7 100644 --- a/cosets/include/mirrors.hpp +++ b/cosets/include/mirrors.hpp @@ -7,10 +7,9 @@ #include "coxeter.hpp" #include "numeric.hpp" -template -std::vector mirror(const Mults &mults) { +std::vector mirror(const Mults &mults) { std::vector mirrors{}; - for (int p = 0; p < NGENS; ++p) { + for (int p = 0; p < mults.dim; ++p) { glm::vec4 vp{}; for (int m = 0; m < p; ++m) { glm::vec4 vq = mirrors[m]; diff --git a/cosets/src/combos.cpp b/cosets/src/combos.cpp new file mode 100644 index 0000000..275d1cb --- /dev/null +++ b/cosets/src/combos.cpp @@ -0,0 +1,38 @@ +#include +#include +#include +#include + +template +bool next_k_permutation(RandIt first, RandIt mid, RandIt last) { + typedef typename std::iterator_traits::value_type value_type; + + std::sort(mid, last, std::greater()); + return std::next_permutation(first, last); +} + +template +bool next_combination(BiDiIt first, BiDiIt mid, BiDiIt last) { + bool result; + do { + result = next_k_permutation(first, mid, last); + } while (std::adjacent_find(first, mid, std::greater<>()) != mid); + return result; +} + +int main(int argc, char *argv[]) { + std::vector nums{0, 1, 2, 3, 4, 5}; + + const auto begin = nums.begin(); + const auto mid = begin + 2; + const auto end = nums.end(); + + do { + for (auto e = begin; e < mid; ++e) { + std::cout << *e << " "; + } + std::cout << std::endl; + } while (next_combination(begin, mid, end)); + + return 0; +} \ No newline at end of file diff --git a/cosets/src/main.cpp b/cosets/src/main.cpp index 7d0aa88..33b42fc 100644 --- a/cosets/src/main.cpp +++ b/cosets/src/main.cpp @@ -8,7 +8,10 @@ #include #include #include -#include + +extern "C" { +__declspec(dllexport) int NvOptimusEnablement = 0x00000001; +} using namespace std; @@ -16,7 +19,7 @@ class CosetsWindow : public Window { GLint program; GLuint vert_vao, edge_vao, face_vao; - Mesh<4> *figure; + Mesh *figure; GLint u_proj, u_view, u_color; @@ -45,7 +48,8 @@ public: u_view = glGetUniformLocation(program, "view"); u_color = glGetUniformLocation(program, "color"); - figure = new Mesh(schlafli<4>({5, 3, 3})); + figure = new Mesh(schlafli({5, 3, 3})); + figure->gen_vertices(identity(figure->t_vert->mults, {10, .5, .5, .5})); glGenVertexArrays(1, &vert_vao); glBindVertexArray(vert_vao); @@ -102,13 +106,13 @@ public: 0.0, -s2, 0.0, c2 ); - const float root_x = std::cos((t + 0) * M_PI / 2) / 2 + 0.5; - const float root_y = std::cos((t + 1) * M_PI / 2) / 2 + 0.5; - const float root_z = std::cos((t + 2) * M_PI / 2) / 2 + 0.5; - const float root_w = std::cos((t + 3) * M_PI / 2) / 2 + 0.5; - - const glm::vec4 root = identity<4>(figure->mults, {root_x, root_y, root_z, root_w}); - figure->gen_vertices(root); +// const float root_x = std::cos((t + 0) * M_PI / 2) / 2 + 0.5; +// const float root_y = std::cos((t + 1) * M_PI / 2) / 2 + 0.5; +// const float root_z = std::cos((t + 2) * M_PI / 2) / 2 + 0.5; +// const float root_w = std::cos((t + 3) * M_PI / 2) / 2 + 0.5; +// +// const glm::vec4 root = identity(figure->mults, {root_x, root_y, root_z, root_w}); +// figure->gen_vertices(root); glUseProgram(program); glUniformMatrix4fv(u_proj, 1, false, glm::value_ptr(proj)); @@ -132,9 +136,9 @@ public: glUniform4f(u_color, 1, 0, 0, 1); glDrawElements(GL_LINES, figure->edge.size, GL_UNSIGNED_INT, 0); -// glBindVertexArray(face_vao); -// glCullFace(GL_NONE); -// glUniform4f(u_color, 1, 1, 1, 1); +// glBindVertexArray(face_vao); +// glCullFace(GL_NONE); +// glUniform4f(u_color, 1, 1, 1, 1); // glDrawElements(GL_TRIANGLES, figure->face.size, GL_UNSIGNED_INT, 0); // glCullFace(GL_FRONT);