misc table solution optimizations
This commit is contained in:
@@ -20,3 +20,5 @@ add_dependencies(cosets shaders)
|
||||
|
||||
target_link_libraries(${PROJECT_NAME}
|
||||
PRIVATE glad glm glfw)
|
||||
|
||||
add_executable(combos src/combos.cpp)
|
||||
|
||||
@@ -4,18 +4,15 @@
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
template<int NGENS>
|
||||
struct Mults;
|
||||
template<int NGENS>
|
||||
struct Table;
|
||||
struct IRow;
|
||||
|
||||
template<int NGENS>
|
||||
struct Mults {
|
||||
const int dim = NGENS;
|
||||
const int dim;
|
||||
std::map<std::tuple<int, int>, int> mults;
|
||||
|
||||
Mults() {
|
||||
explicit Mults(const int dim) : dim(dim) {
|
||||
mults = std::map<std::tuple<int, int>, int>();
|
||||
}
|
||||
|
||||
@@ -47,28 +44,34 @@ struct Mults {
|
||||
return res;
|
||||
}
|
||||
|
||||
[[nodiscard]] Table<NGENS> *isolve(const std::vector<int> &isubgens) const;
|
||||
[[nodiscard]] Mults sub(const std::vector<int> &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<int IGENS>
|
||||
[[nodiscard]] Table<IGENS> *isolve(const int (&igens)[IGENS], const std::vector<int> &isubgens) const;
|
||||
[[nodiscard]] Table *isolve(const std::vector<int> &isubgens) const;
|
||||
};
|
||||
|
||||
template<int NGENS>
|
||||
struct Table {
|
||||
const Mults<NGENS> mults;
|
||||
const Mults mults;
|
||||
std::vector<std::vector<int>> fwd;
|
||||
|
||||
explicit Table(Mults<NGENS> 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<int NGENS>
|
||||
[[nodiscard]] bool learn(Table<NGENS> *table) {
|
||||
[[nodiscard]] bool learn(Table *table) {
|
||||
if (r - l == 0) {
|
||||
return false;
|
||||
}
|
||||
@@ -139,24 +141,23 @@ struct IRow {
|
||||
}
|
||||
};
|
||||
|
||||
template<int NGENS>
|
||||
Mults<NGENS> schlafli(const int(&symbol)[NGENS - 1]) {
|
||||
Mults<NGENS> mults{};
|
||||
for (int i = 0; i < NGENS; ++i) {
|
||||
Mults schlafli(const std::vector<int> &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<int NGENS>
|
||||
Table<NGENS> *Mults<NGENS>::isolve(const std::vector<int> &isubgens) const {
|
||||
auto *table = new Table<NGENS>(*this);
|
||||
Table *Mults::isolve(const std::vector<int> &isubgens) const {
|
||||
auto *table = new Table(*this);
|
||||
for (int igen : isubgens)
|
||||
table->iset(0, igen, 0);
|
||||
|
||||
std::vector<std::vector<int>> 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<NGENS> *Mults<NGENS>::isolve(const std::vector<int> &isubgens) const {
|
||||
return table;
|
||||
}
|
||||
|
||||
template<int NGENS>
|
||||
template<int IGENS>
|
||||
Table<IGENS> *Mults<NGENS>::isolve(const int (&igens)[IGENS], const std::vector<int> &isubgens) const {
|
||||
auto *table = new Table<IGENS>(*this);
|
||||
for (int igen : isubgens)
|
||||
table->iset(0, igen, 0);
|
||||
|
||||
std::vector<std::vector<int>> 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<IRow> 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;
|
||||
}
|
||||
|
||||
@@ -15,15 +15,13 @@ glm::vec4 identity(const std::vector<glm::vec4> &normals, const std::vector<floa
|
||||
}
|
||||
|
||||
|
||||
template<int NGENS>
|
||||
glm::vec4 identity(const Mults<NGENS> &mults, const std::vector<float> &coords) {
|
||||
glm::vec4 identity(const Mults &mults, const std::vector<float> &coords) {
|
||||
const std::vector<glm::vec4> normals = mirror(mults);
|
||||
return identity(normals, coords);
|
||||
}
|
||||
|
||||
|
||||
template<int NGENS>
|
||||
glm::vec4 center(const Mults<NGENS> &mults) {
|
||||
glm::vec4 center(const Mults &mults) {
|
||||
const std::vector<glm::vec4> normals = mirror(mults);
|
||||
const std::vector<glm::vec4> corners = plane_intersections(normals);
|
||||
std::vector<float> coords{};
|
||||
@@ -43,10 +41,9 @@ struct Buffer {
|
||||
unsigned size = 0;
|
||||
};
|
||||
|
||||
template<int NGENS>
|
||||
struct Mesh {
|
||||
const Mults<NGENS> mults;
|
||||
const Table<NGENS> *t_vert;
|
||||
const Mults mults;
|
||||
const Table *t_vert;
|
||||
|
||||
const std::vector<glm::vec4> normals;
|
||||
glm::vec4 *vert_data;
|
||||
@@ -55,11 +52,12 @@ struct Mesh {
|
||||
Buffer edge;
|
||||
Buffer face;
|
||||
|
||||
explicit Mesh(Mults<NGENS> 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<double>) (b - a)).count() << std::endl;
|
||||
auto delta = (std::chrono::duration<double>) (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<NGENS> 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<double>) (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<int> edges;
|
||||
std::vector<int> faces;
|
||||
std::vector<int> edge_data;
|
||||
|
||||
auto e_table = mults.sub({0, 1}).isolve({});
|
||||
|
||||
// std::cout << "building gens" << std::endl;
|
||||
// const std::vector<int> gens{0, 1};
|
||||
// std::cout << "built gens" << std::endl;
|
||||
// const std::vector<int> &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);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -7,10 +7,9 @@
|
||||
#include "coxeter.hpp"
|
||||
#include "numeric.hpp"
|
||||
|
||||
template<int NGENS>
|
||||
std::vector<glm::vec4> mirror(const Mults<NGENS> &mults) {
|
||||
std::vector<glm::vec4> mirror(const Mults &mults) {
|
||||
std::vector<glm::vec4> 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];
|
||||
|
||||
38
cosets/src/combos.cpp
Normal file
38
cosets/src/combos.cpp
Normal file
@@ -0,0 +1,38 @@
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <array>
|
||||
|
||||
template<class RandIt>
|
||||
bool next_k_permutation(RandIt first, RandIt mid, RandIt last) {
|
||||
typedef typename std::iterator_traits<RandIt>::value_type value_type;
|
||||
|
||||
std::sort(mid, last, std::greater<value_type>());
|
||||
return std::next_permutation(first, last);
|
||||
}
|
||||
|
||||
template<class BiDiIt>
|
||||
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<int> 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;
|
||||
}
|
||||
@@ -8,7 +8,10 @@
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <chrono>
|
||||
|
||||
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);
|
||||
|
||||
Reference in New Issue
Block a user