From 1c72acfda984f73ddc96d51596f9e761a963944a Mon Sep 17 00:00:00 2001 From: Jaron Kent-Dobias Date: Mon, 23 Sep 2019 23:40:02 -0400 Subject: ran clang-format --- lib/include/array_hash.hpp | 34 +++++------ lib/include/clusters.hpp | 2 +- lib/include/graph.hpp | 79 +++++++++++++------------ lib/include/hooks.hpp | 9 ++- lib/include/network.hpp | 61 ++++++++++--------- lib/include/problem.hpp | 41 +++++++------ lib/src/graph.cpp | 143 ++++++++++++++++++++++++--------------------- lib/src/network.cpp | 83 +++++++++++++++++--------- lib/src/problem.cpp | 84 +++++++++++++------------- 9 files changed, 280 insertions(+), 256 deletions(-) diff --git a/lib/include/array_hash.hpp b/lib/include/array_hash.hpp index 3b35e4a..fd0d0f7 100644 --- a/lib/include/array_hash.hpp +++ b/lib/include/array_hash.hpp @@ -4,24 +4,18 @@ #include #include -namespace std -{ - template - struct hash > - { - typedef array argument_type; - typedef size_t result_type; - - result_type operator()(const argument_type& a) const - { - hash hasher; - result_type h = 0; - for (result_type i = 0; i < N; ++i) - { - h = h * 31 + hasher(a[i]); - } - return h; - } - }; -} +namespace std { +template struct hash> { + typedef array argument_type; + typedef size_t result_type; + result_type operator()(const argument_type& a) const { + hash hasher; + result_type h = 0; + for (result_type i = 0; i < N; ++i) { + h = h * 31 + hasher(a[i]); + } + return h; + } +}; +} // namespace std diff --git a/lib/include/clusters.hpp b/lib/include/clusters.hpp index 4cc9073..0c562d8 100644 --- a/lib/include/clusters.hpp +++ b/lib/include/clusters.hpp @@ -1,6 +1,6 @@ -#include #include "graph.hpp" +#include class ClusterTree { private: diff --git a/lib/include/graph.hpp b/lib/include/graph.hpp index 0452339..9d2b5a1 100644 --- a/lib/include/graph.hpp +++ b/lib/include/graph.hpp @@ -1,50 +1,49 @@ #pragma once -#include -#include +#include #include -#include -#include -#include +#include #include -#include +#include +#include +#include +#include #include "array_hash.hpp" class graph { - public: - typedef struct coordinate { - double x; - double y; - } coordinate; - - typedef struct vertex { - coordinate r; - std::vector nd; - std::vector ne; - std::vector polygon; - } vertex; - - typedef struct edge { - std::array v; - coordinate r; - std::array crossings; - } edge; - - coordinate L; - - std::vector vertices; - std::vector edges; - - std::vector dual_vertices; - std::vector dual_edges; - - graph(unsigned Nx, unsigned Ny); - graph(double Lx, double Ly, std::mt19937& rng); - graph(unsigned n, double a, std::mt19937& rng); - - void helper(unsigned n, std::mt19937& rng); - graph const rotate(); +public: + typedef struct coordinate { + double x; + double y; + } coordinate; + + typedef struct vertex { + coordinate r; + std::vector nd; + std::vector ne; + std::vector polygon; + } vertex; + + typedef struct edge { + std::array v; + coordinate r; + std::array crossings; + } edge; + + coordinate L; + + std::vector vertices; + std::vector edges; + + std::vector dual_vertices; + std::vector dual_edges; + + graph(unsigned Nx, unsigned Ny); + graph(double Lx, double Ly, std::mt19937& rng); + graph(unsigned n, double a, std::mt19937& rng); + + void helper(unsigned n, std::mt19937& rng); + graph const rotate(); }; - diff --git a/lib/include/hooks.hpp b/lib/include/hooks.hpp index 67313cc..ba85ff7 100644 --- a/lib/include/hooks.hpp +++ b/lib/include/hooks.hpp @@ -6,9 +6,8 @@ class network; class hooks { - public: - virtual void pre_fracture(const network&) {}; - virtual void bond_broken(const network&, const current_info&, unsigned) {}; - virtual void post_fracture(network&) {}; // post fracture hook can be destructive +public: + virtual void pre_fracture(const network&){}; + virtual void bond_broken(const network&, const current_info&, unsigned){}; + virtual void post_fracture(network&){}; // post fracture hook can be destructive }; - diff --git a/lib/include/network.hpp b/lib/include/network.hpp index 8748ea9..29bf55a 100644 --- a/lib/include/network.hpp +++ b/lib/include/network.hpp @@ -1,20 +1,20 @@ #pragma once -#include #include -#include -#include #include -#include +#include #include +#include +#include +#include -#include "problem.hpp" -#include "graph.hpp" -#include "hooks.hpp" -#include "current_info.hpp" #include "array_hash.hpp" #include "clusters.hpp" +#include "current_info.hpp" +#include "graph.hpp" +#include "hooks.hpp" +#include "problem.hpp" #define CURRENT_CUTOFF 1e-10 @@ -27,7 +27,7 @@ class network { friend class elastic_network; friend class percolation_network; - private: +private: problem px; problem py; std::unordered_map, bool> seen_pairs; @@ -36,14 +36,15 @@ class network { void break_edge(unsigned, bool unbreak = false); void get_cycle_edges_helper(std::set&, std::set&, unsigned, unsigned) const; std::set get_cycle_edges(unsigned) const; - bool find_cycle_helper(std::array&, const std::set&, unsigned, unsigned, unsigned) const; + bool find_cycle_helper(std::array&, const std::set&, unsigned, unsigned, + unsigned) const; std::array find_cycle(const std::set&, unsigned, unsigned) const; void get_cluster_edges_helper(std::set&, unsigned) const; std::set get_cluster_edges(unsigned) const; void get_tie_flaps_helper(std::set&, unsigned, unsigned) const; std::list> get_tie_flaps(unsigned) const; - public: +public: const graph& G; ClusterTree C; @@ -57,36 +58,38 @@ class network { void set_thresholds(double, std::mt19937&); void fracture(hooks&, bool one_axis = true); - virtual current_info get_current_info() {current_info empty; return empty;}; + virtual current_info get_current_info() { + current_info empty; + return empty; + }; }; class fuse_network : public network { - private: - double weight; +private: + double weight; - public: - fuse_network(const graph&, cholmod_common*, double weight = 1.0); - fuse_network(const fuse_network&); +public: + fuse_network(const graph&, cholmod_common*, double weight = 1.0); + fuse_network(const fuse_network&); - current_info get_current_info() override; + current_info get_current_info() override; }; class elastic_network : public network { - private: - double weight; +private: + double weight; - public: - elastic_network(const graph&, cholmod_common*, double weight = 0.5); - elastic_network(const elastic_network&); +public: + elastic_network(const graph&, cholmod_common*, double weight = 0.5); + elastic_network(const elastic_network&); - current_info get_current_info() override; + current_info get_current_info() override; }; class percolation_network : public network { - public: - percolation_network(const graph&, cholmod_common*); - percolation_network(const percolation_network&); +public: + percolation_network(const graph&, cholmod_common*); + percolation_network(const percolation_network&); - current_info get_current_info() override; + current_info get_current_info() override; }; - diff --git a/lib/include/problem.hpp b/lib/include/problem.hpp index 740751d..c454a35 100644 --- a/lib/include/problem.hpp +++ b/lib/include/problem.hpp @@ -1,10 +1,10 @@ -#include #include +#include -#include -#include "graph.hpp" #include "current_info.hpp" +#include "graph.hpp" +#include #ifdef FRACTURE_LONGINT @@ -19,22 +19,21 @@ #endif class problem { - private: - const graph& G; - unsigned axis; - cholmod_dense* b; - cholmod_factor* factor; - cholmod_sparse* voltcurmat; - cholmod_common* c; - - public: - current_info sol; - - problem(const graph&, unsigned, cholmod_common*); - problem(const graph&, unsigned, cholmod_sparse*, cholmod_common*); - problem(const problem&); - ~problem(); - void solve(std::vector& fuses); - void break_edge(unsigned, bool unbreak = false); +private: + const graph& G; + unsigned axis; + cholmod_dense* b; + cholmod_factor* factor; + cholmod_sparse* voltcurmat; + cholmod_common* c; + +public: + current_info sol; + + problem(const graph&, unsigned, cholmod_common*); + problem(const graph&, unsigned, cholmod_sparse*, cholmod_common*); + problem(const problem&); + ~problem(); + void solve(std::vector& fuses); + void break_edge(unsigned, bool unbreak = false); }; - diff --git a/lib/src/graph.cpp b/lib/src/graph.cpp index a5063de..1475c40 100644 --- a/lib/src/graph.cpp +++ b/lib/src/graph.cpp @@ -34,23 +34,21 @@ graph::graph(unsigned Nx, unsigned Ny) { vertices[i].r.x = (double)((1 + i / (Nx / 2)) % 2 + 2 * (i % (Nx / 2))); vertices[i].r.y = (double)(i / (Nx / 2)); signed f = (1 + i / (Nx / 2)) % 2 == 1 ? 1 : -1; - vertices[i].nd = {i, (i + Nx / 2) % nv, Nx / 2 * (i / (Nx / 2)) + ((i + f) % (Nx / 2)), (nv + i - Nx / 2) % nv}; - vertices[i].polygon = { - {vertices[i].r.x - 1.0, vertices[i].r.y}, - {vertices[i].r.x, vertices[i].r.y - 1.0}, - {vertices[i].r.x + 1.0, vertices[i].r.y}, - {vertices[i].r.x, vertices[i].r.y + 1.0} - }; + vertices[i].nd = {i, (i + Nx / 2) % nv, Nx / 2 * (i / (Nx / 2)) + ((i + f) % (Nx / 2)), + (nv + i - Nx / 2) % nv}; + vertices[i].polygon = {{vertices[i].r.x - 1.0, vertices[i].r.y}, + {vertices[i].r.x, vertices[i].r.y - 1.0}, + {vertices[i].r.x + 1.0, vertices[i].r.y}, + {vertices[i].r.x, vertices[i].r.y + 1.0}}; dual_vertices[i].r.x = (double)((i / (Nx / 2)) % 2 + 2 * (i % (Nx / 2))); dual_vertices[i].r.y = (double)(i / (Nx / 2)); - dual_vertices[i].nd = {i, (i + Nx / 2) % nv, Nx / 2 * (i / (Nx / 2)) + ((i + f) % (Nx / 2)), (nv + i - Nx / 2) % nv}; - dual_vertices[i].polygon = { - {dual_vertices[i].r.x - 1.0, vertices[i].r.y}, - {dual_vertices[i].r.x, vertices[i].r.y - 1.0}, - {dual_vertices[i].r.x + 1.0, vertices[i].r.y}, - {dual_vertices[i].r.x, vertices[i].r.y + 1.0} - }; + dual_vertices[i].nd = {i, (i + Nx / 2) % nv, Nx / 2 * (i / (Nx / 2)) + ((i + f) % (Nx / 2)), + (nv + i - Nx / 2) % nv}; + dual_vertices[i].polygon = {{dual_vertices[i].r.x - 1.0, vertices[i].r.y}, + {dual_vertices[i].r.x, vertices[i].r.y - 1.0}, + {dual_vertices[i].r.x + 1.0, vertices[i].r.y}, + {dual_vertices[i].r.x, vertices[i].r.y + 1.0}}; } for (unsigned y = 0; y < Ny; y++) { @@ -66,7 +64,8 @@ graph::graph(unsigned Nx, unsigned Ny) { unsigned dv1 = (Nx * y) / 2 + ((x + (y + 1) % 2) / 2) % (Nx / 2); unsigned dv2 = ((Nx * (y + 1)) / 2 + ((x + y % 2) / 2) % (Nx / 2)) % nv; - dual_edges.push_back({{dv1, dv2}, {0.5 + (double)x, 0.5 + (double)y}, {crossed_x, crossed_y}}); + dual_edges.push_back( + {{dv1, dv2}, {0.5 + (double)x, 0.5 + (double)y}, {crossed_x, crossed_y}}); } } @@ -102,29 +101,23 @@ graph::graph(unsigned Nx, unsigned Ny) { dual_vertices[vi].ne.push_back(i); } } - } -class eulerException: public std::exception -{ - virtual const char* what() const throw() - { - return "The voronoi tessellation generated has the incorrect Euler characteristic for a torus and is malformed."; +class eulerException : public std::exception { + virtual const char* what() const throw() { + return "The voronoi tessellation generated has the incorrect Euler characteristic for a torus " + "and is malformed."; } } eulerex; -class clippingException: public std::exception -{ - virtual const char* what() const throw() - { +class clippingException : public std::exception { + virtual const char* what() const throw() { return "An interior site has a clipped edge and the tesselation is malformed."; } } clippingex; -class triangleException: public std::exception -{ - virtual const char* what() const throw() - { +class triangleException : public std::exception { + virtual const char* what() const throw() { return "A dual-centered triangle has an impossible geometry and the tesselation is malformed."; } } triex; @@ -147,29 +140,45 @@ unsigned get_triangle_signature(unsigned j1, unsigned j2, unsigned j3) { if ((j1 == j2) && (j2 == j3)) { return 0; - } else if (((j1 == j2) && (x2 < x3) && (y2 == y3)) || ((j1 == j3) && (x3 < x2) && (y2 == y3)) || ((j2 == j3) && (x3 < x1) && (y1 == y3))) { + } else if (((j1 == j2) && (x2 < x3) && (y2 == y3)) || ((j1 == j3) && (x3 < x2) && (y2 == y3)) || + ((j2 == j3) && (x3 < x1) && (y1 == y3))) { return 1; - } else if (((j1 == j2) && (x2 > x3) && (y2 == y3)) || ((j1 == j3) && (x3 > x2) && (y2 == y3)) || ((j2 == j3) && (x3 > x1) && (y1 == y3))) { + } else if (((j1 == j2) && (x2 > x3) && (y2 == y3)) || ((j1 == j3) && (x3 > x2) && (y2 == y3)) || + ((j2 == j3) && (x3 > x1) && (y1 == y3))) { return 2; - } else if (((j1 == j2) && (y2 < y3) && (x2 == x3)) || ((j1 == j3) && (y3 < y2) && (x2 == x3)) || ((j2 == j3) && (y3 < y1) && (x1 == x3))) { + } else if (((j1 == j2) && (y2 < y3) && (x2 == x3)) || ((j1 == j3) && (y3 < y2) && (x2 == x3)) || + ((j2 == j3) && (y3 < y1) && (x1 == x3))) { return 3; - } else if (((j1 == j2) && (y2 > y3) && (x2 == x3)) || ((j1 == j3) && (y3 > y2) && (x2 == x3)) || ((j2 == j3) && (y3 > y1) && (x1 == x3))) { + } else if (((j1 == j2) && (y2 > y3) && (x2 == x3)) || ((j1 == j3) && (y3 > y2) && (x2 == x3)) || + ((j2 == j3) && (y3 > y1) && (x1 == x3))) { return 4; - } else if (((j1 == j2) && (x2 < x3) && (y2 < y3)) || ((j1 == j3) && (x3 < x2) && (y3 < y2)) || ((j2 == j3) && (x3 < x1) && (y3 < y1))) { + } else if (((j1 == j2) && (x2 < x3) && (y2 < y3)) || ((j1 == j3) && (x3 < x2) && (y3 < y2)) || + ((j2 == j3) && (x3 < x1) && (y3 < y1))) { return 5; - } else if (((j1 == j2) && (x2 < x3) && (y2 > y3)) || ((j1 == j3) && (x3 < x2) && (y3 > y2)) || ((j2 == j3) && (x3 < x1) && (y3 > y1))) { + } else if (((j1 == j2) && (x2 < x3) && (y2 > y3)) || ((j1 == j3) && (x3 < x2) && (y3 > y2)) || + ((j2 == j3) && (x3 < x1) && (y3 > y1))) { return 6; - } else if (((j1 == j2) && (x2 > x3) && (y2 < y3)) || ((j1 == j3) && (x3 > x2) && (y3 < y2)) || ((j2 == j3) && (x3 > x1) && (y3 < y1))) { + } else if (((j1 == j2) && (x2 > x3) && (y2 < y3)) || ((j1 == j3) && (x3 > x2) && (y3 < y2)) || + ((j2 == j3) && (x3 > x1) && (y3 < y1))) { return 7; - } else if (((j1 == j2) && (x2 > x3) && (y2 > y3)) || ((j1 == j3) && (x3 > x2) && (y3 > y2)) || ((j2 == j3) && (x3 > x1) && (y3 > y1))) { + } else if (((j1 == j2) && (x2 > x3) && (y2 > y3)) || ((j1 == j3) && (x3 > x2) && (y3 > y2)) || + ((j2 == j3) && (x3 > x1) && (y3 > y1))) { return 8; - } else if (((x1 == x2) && (x2 < x3) && ((y1 < y3) || (y2 < y3))) || ((x1 == x3) && (x3 < x2) && ((y1 < y2) || (y3 < y2))) || ((x2 == x3) && (x2 < x1) && ((y2 < y1) || (y3 < y1)))) { + } else if (((x1 == x2) && (x2 < x3) && ((y1 < y3) || (y2 < y3))) || + ((x1 == x3) && (x3 < x2) && ((y1 < y2) || (y3 < y2))) || + ((x2 == x3) && (x2 < x1) && ((y2 < y1) || (y3 < y1)))) { return 9; - } else if (((x1 == x2) && (x2 > x3) && ((y1 < y3) || (y2 < y3))) || ((x1 == x3) && (x3 > x2) && ((y1 < y2) || (y3 < y2))) || ((x2 == x3) && (x2 > x1) && ((y2 < y1) || (y3 < y1)))) { + } else if (((x1 == x2) && (x2 > x3) && ((y1 < y3) || (y2 < y3))) || + ((x1 == x3) && (x3 > x2) && ((y1 < y2) || (y3 < y2))) || + ((x2 == x3) && (x2 > x1) && ((y2 < y1) || (y3 < y1)))) { return 10; - } else if (((x1 == x2) && (x2 < x3) && ((y1 > y3) || (y2 > y3))) || ((x1 == x3) && (x3 < x2) && ((y1 > y2) || (y3 > y2))) || ((x2 == x3) && (x2 < x1) && ((y2 > y1) || (y3 > y1)))) { + } else if (((x1 == x2) && (x2 < x3) && ((y1 > y3) || (y2 > y3))) || + ((x1 == x3) && (x3 < x2) && ((y1 > y2) || (y3 > y2))) || + ((x2 == x3) && (x2 < x1) && ((y2 > y1) || (y3 > y1)))) { return 11; - } else if (((x1 == x2) && (x2 > x3) && ((y1 > y3) || (y2 > y3))) || ((x1 == x3) && (x3 > x2) && ((y1 > y2) || (y3 > y2))) || ((x2 == x3) && (x2 > x1) && ((y2 > y1) || (y3 > y1)))) { + } else if (((x1 == x2) && (x2 > x3) && ((y1 > y3) || (y2 > y3))) || + ((x1 == x3) && (x3 > x2) && ((y1 > y2) || (y3 > y2))) || + ((x2 == x3) && (x2 > x1) && ((y2 > y1) || (y3 > y1)))) { return 12; } else { throw triex; @@ -200,7 +209,7 @@ void graph::helper(unsigned nv, std::mt19937& rng) { // the coordinates of the lattice, from which a delaunay triangulation // and corresponding voronoi tessellation will be built. Everyone is in the // rectangle (0, 0) (Lx, Ly) - for (vertex &v : vertices) { + for (vertex& v : vertices) { v = {{L.x * d(rng), L.y * d(rng)}}; } @@ -243,7 +252,7 @@ void graph::helper(unsigned nv, std::mt19937& rng) { ep = ep->next; } // for each edge on the site's cell - while(e) { + while (e) { // assess whether the edge needs to be added. only neighboring // sites whose index is larger than ours are given edges, so we // don't double up later @@ -275,7 +284,8 @@ void graph::helper(unsigned nv, std::mt19937& rng) { if (it1 == known_vertices.end()) { vi1 = dual_vertices.size(); - dual_vertices.push_back({{mod(e->pos[0].x, L.x), mod(e->pos[0].y, L.y)},{i1},{},{{site->p.x, site->p.y}}}); + dual_vertices.push_back( + {{mod(e->pos[0].x, L.x), mod(e->pos[0].y, L.y)}, {i1}, {}, {{site->p.x, site->p.y}}}); known_vertices[t1] = vi1; } else { vi1 = it1->second; @@ -284,7 +294,7 @@ void graph::helper(unsigned nv, std::mt19937& rng) { } vertices[i1].nd.push_back(vi1); - + if (i1 < i2 || (i1 == i2 && !self_bonded)) { if (i1 == i2) { self_bonded = true; @@ -292,12 +302,11 @@ void graph::helper(unsigned nv, std::mt19937& rng) { bool crossed_x = x2 != 1; bool crossed_y = y2 != 1; edges.push_back({{i1, i2}, - {mod((site->p.x + neighbor->p.x) / 2, L.x), - mod((site->p.y + neighbor->p.y) / 2, L.y)}, - {crossed_x, crossed_y} - }); + {mod((site->p.x + neighbor->p.x) / 2, L.x), + mod((site->p.y + neighbor->p.y) / 2, L.y)}, + {crossed_x, crossed_y}}); - jcv_graphedge *en; + jcv_graphedge* en; if (e->next == NULL) { en = site->edges; } else { @@ -322,20 +331,21 @@ void graph::helper(unsigned nv, std::mt19937& rng) { if (it2 == known_vertices.end()) { vi2 = dual_vertices.size(); - dual_vertices.push_back({{mod(e->pos[1].x, L.x), mod(e->pos[1].y, L.y)},{}}); + dual_vertices.push_back({{mod(e->pos[1].x, L.x), mod(e->pos[1].y, L.y)}, {}}); known_vertices[t2] = vi2; } else { vi2 = it2->second; } - bool dcrossed_x = (unsigned)floor(e->pos[0].x / L.x) != (unsigned)floor(e->pos[1].x / L.x); - bool dcrossed_y = (unsigned)floor(e->pos[0].y / L.y) != (unsigned)floor(e->pos[1].y / L.y); + bool dcrossed_x = + (unsigned)floor(e->pos[0].x / L.x) != (unsigned)floor(e->pos[1].x / L.x); + bool dcrossed_y = + (unsigned)floor(e->pos[0].y / L.y) != (unsigned)floor(e->pos[1].y / L.y); dual_edges.push_back({{vi1, vi2}, - {mod((e->pos[0].x + e->pos[1].x) / 2, L.x), - mod((e->pos[0].y + e->pos[1].y) / 2, L.y)}, - {dcrossed_x, dcrossed_y} - }); + {mod((e->pos[0].x + e->pos[1].x) / 2, L.x), + mod((e->pos[0].y + e->pos[1].y) / 2, L.y)}, + {dcrossed_x, dcrossed_y}}); } ep = e; @@ -348,7 +358,7 @@ void graph::helper(unsigned nv, std::mt19937& rng) { throw eulerex; } - for (vertex &v : dual_vertices) { + for (vertex& v : dual_vertices) { if (fabs(v.polygon[0].x - v.polygon[1].x) > L.x / 2) { if (v.polygon[0].x < L.x / 2) { v.polygon[0].x += L.x; @@ -434,33 +444,31 @@ void graph::helper(unsigned nv, std::mt19937& rng) { jcv_diagram_free(&diagram); } -graph::coordinate reverse(const graph::coordinate &x) { - return {x.y, x.x}; -} +graph::coordinate reverse(const graph::coordinate& x) { return {x.y, x.x}; } graph const graph::rotate() { graph g2(*this); - for (graph::vertex &v : g2.vertices) { + for (graph::vertex& v : g2.vertices) { v.r = reverse(v.r); - for (graph::coordinate &r : v.polygon) { + for (graph::coordinate& r : v.polygon) { r = reverse(r); } } - for (graph::edge &e : g2.edges) { + for (graph::edge& e : g2.edges) { e.r = reverse(e.r); e.crossings = {e.crossings[1], e.crossings[0]}; } - for (graph::vertex &v : g2.dual_vertices) { + for (graph::vertex& v : g2.dual_vertices) { v.r = reverse(v.r); - for (graph::coordinate &r : v.polygon) { + for (graph::coordinate& r : v.polygon) { r = reverse(r); } } - for (graph::edge &e : g2.dual_edges) { + for (graph::edge& e : g2.dual_edges) { e.r = reverse(e.r); e.crossings = {e.crossings[1], e.crossings[0]}; } @@ -469,4 +477,3 @@ graph const graph::rotate() { return g2; } - diff --git a/lib/src/network.cpp b/lib/src/network.cpp index 0cf50c7..eef7e9a 100644 --- a/lib/src/network.cpp +++ b/lib/src/network.cpp @@ -11,7 +11,8 @@ network::network(const graph& G, cholmod_common* c) void network::set_thresholds(double beta, std::mt19937& rng) { if (beta == 0.0) { - /* zero beta doesn't make any sense computationally, we interpret it as "infinity" */ + /* zero beta doesn't make any sense computationally, we interpret it as + * "infinity" */ for (long double& threshold : thresholds) { threshold = 1.0; } @@ -104,7 +105,8 @@ std::set network::get_cycle_edges(unsigned v0) const { return cycle_edges; } -bool network::find_cycle_helper(std::array& sig, const std::set& cycle_edges, unsigned vPrev, unsigned vCur, unsigned vEnd) const { +bool network::find_cycle_helper(std::array& sig, const std::set& cycle_edges, + unsigned vPrev, unsigned vCur, unsigned vEnd) const { for (unsigned ei : G.dual_vertices[vCur].ne) { if (fuses[ei]) { auto it = cycle_edges.find(ei); @@ -113,13 +115,17 @@ bool network::find_cycle_helper(std::array& sig, const std::setfind_cycle_helper(sig, cycle_edges, vCur, vn, vEnd)) { - if (G.dual_edges[ei].crossings[0]) sig[0]++; - if (G.dual_edges[ei].crossings[1]) sig[1]++; + if (G.dual_edges[ei].crossings[0]) + sig[0]++; + if (G.dual_edges[ei].crossings[1]) + sig[1]++; return true; } } @@ -131,7 +137,8 @@ bool network::find_cycle_helper(std::array& sig, const std::set network::find_cycle(const std::set& cycle_edges, unsigned v0, unsigned v1) const { +std::array network::find_cycle(const std::set& cycle_edges, unsigned v0, + unsigned v1) const { std::array sig = {0, 0}; this->find_cycle_helper(sig, cycle_edges, v0, v0, v1); return sig; @@ -158,7 +165,8 @@ std::set network::get_cluster_edges(unsigned v0) const { return cluster_edges; } -void network::get_tie_flaps_helper(std::set& added_edges, unsigned v0, unsigned vCur) const { +void network::get_tie_flaps_helper(std::set& added_edges, unsigned v0, + unsigned vCur) const { for (unsigned ei : G.vertices[vCur].ne) { if (!backbone[ei]) { auto it = added_edges.find(ei); @@ -219,7 +227,8 @@ void network::update_backbone(const std::vector& c) { // Now, we create a crossing signature for each cycle. First, we do it // for the new cycle that would form by removing the stem. - std::array base_sig = this->find_cycle(cedges, G.dual_edges[i].v[0], G.dual_edges[i].v[1]); + std::array base_sig = + this->find_cycle(cedges, G.dual_edges[i].v[0], G.dual_edges[i].v[1]); if (G.dual_edges[i].crossings[0]) base_sig[0]++; if (G.dual_edges[i].crossings[1]) @@ -229,9 +238,12 @@ void network::update_backbone(const std::vector& c) { // previous step. std::list> all_sigs = {base_sig}; for (unsigned e : cedges) { - std::array new_sig_1 = this->find_cycle(cedges, G.dual_edges[i].v[0], G.dual_edges[e].v[0]); - std::array new_sig_2 = this->find_cycle(cedges, G.dual_edges[i].v[1], G.dual_edges[e].v[1]); - std::array new_sig = {new_sig_1[0] + new_sig_2[0], new_sig_1[1] + new_sig_2[1]}; + std::array new_sig_1 = + this->find_cycle(cedges, G.dual_edges[i].v[0], G.dual_edges[e].v[0]); + std::array new_sig_2 = + this->find_cycle(cedges, G.dual_edges[i].v[1], G.dual_edges[e].v[1]); + std::array new_sig = {new_sig_1[0] + new_sig_2[0], + new_sig_1[1] + new_sig_2[1]}; if (G.dual_edges[i].crossings[0]) new_sig[0]++; @@ -248,10 +260,10 @@ void network::update_backbone(const std::vector& c) { // Now, having found all cycles involving the candidate stem, we check // if any of them spans the torus and therefore can carry current. if (std::any_of(all_sigs.begin(), all_sigs.end(), - [done_x, done_y](std::array c) { - return (c[0] % 2 == 0 && c[1] % 2 == 0) || - ((c[0] % 2 == 0 && done_x) || (c[1] % 2 == 0 && done_y)); - })) { + [done_x, done_y](std::array c) { + return (c[0] % 2 == 0 && c[1] % 2 == 0) || + ((c[0] % 2 == 0 && done_x) || (c[1] % 2 == 0 && done_y)); + })) { // If it does, we remove it from the backbone! seen_pairs[{G.dual_edges[i].v[0], G.dual_edges[i].v[1]}] = true; backbone[i] = true; @@ -297,6 +309,7 @@ void network::update_backbone(const std::vector& c) { // Now, we will check for bow ties! std::set bb_verts; + // First we get a list of all vertices that remain in the backbone. for (unsigned i = 0; i < G.edges.size(); i++) { if (!backbone[i]) { bb_verts.insert(G.edges[i].v[0]); @@ -307,6 +320,10 @@ void network::update_backbone(const std::vector& c) { for (unsigned v : bb_verts) { bool found_pair = false; unsigned d1, d2, p1, p2; + // For each vertex, we check to see if two of the faces adjacent to the + // vertex are in the same component of the dual lattice and if so, we make + // sure they do not belong to a contiguously connected series of such + // faces. for (unsigned i = 0; i < G.vertices[v].nd.size(); i++) { for (unsigned j = 2; j < G.vertices[v].nd.size() - 1; j++) { unsigned l = (i + j) % G.vertices[v].nd.size(); @@ -316,12 +333,11 @@ void network::update_backbone(const std::vector& c) { auto it_search = seen_pairs.find({G.vertices[v].nd[il], G.vertices[v].nd[ig]}); if (it_search == seen_pairs.end()) { bool any_intervening1 = false; - bool any_intervening_e_1 = false; bool any_intervening2 = false; - bool any_intervening_e_2 = false; unsigned ie1 = 0; unsigned ie2 = 0; + // yuck, think of something more elegant? for (unsigned k = il + 1; k < ig; k++) { if (!C.same_component(G.vertices[v].nd[i], G.vertices[v].nd[k])) { any_intervening1 = true; @@ -330,7 +346,7 @@ void network::update_backbone(const std::vector& c) { } for (unsigned k = (ig + 1); k % G.vertices[v].nd.size() != il; k++) { if (!C.same_component(G.vertices[v].nd[i], - G.vertices[v].nd[k % G.vertices[v].nd.size()])) { + G.vertices[v].nd[k % G.vertices[v].nd.size()])) { any_intervening2 = true; break; } @@ -349,6 +365,9 @@ void network::update_backbone(const std::vector& c) { } } } + + // If all these conditions are true, we process the pair. The same + // cycle analysis as in the lollipop case is done. if ((any_intervening1 && any_intervening2) || (any_intervening1 && ie2 > 1) || (any_intervening2 && ie1 > 1)) { found_pair = true; @@ -367,13 +386,14 @@ void network::update_backbone(const std::vector& c) { base_sig[1]++; } - // Then, we do it for each of the existing cycles we found in the - // previous step. std::list> all_sigs = {base_sig}; for (unsigned e : cedges) { - std::array new_sig_1 = this->find_cycle(cedges, d1, G.dual_edges[e].v[0]); - std::array new_sig_2 = this->find_cycle(cedges, d2, G.dual_edges[e].v[1]); - std::array new_sig = {new_sig_1[0] + new_sig_2[0], new_sig_1[1] + new_sig_2[1]}; + std::array new_sig_1 = + this->find_cycle(cedges, d1, G.dual_edges[e].v[0]); + std::array new_sig_2 = + this->find_cycle(cedges, d2, G.dual_edges[e].v[1]); + std::array new_sig = {new_sig_1[0] + new_sig_2[0], + new_sig_1[1] + new_sig_2[1]}; for (unsigned k = p1; k < p2; k++) { if (G.dual_edges[G.vertices[v].ne[k]].crossings[0]) @@ -390,15 +410,20 @@ void network::update_backbone(const std::vector& c) { } if (std::any_of(all_sigs.begin(), all_sigs.end(), - [done_x, done_y](std::array c) { - return ((c[0] % 2 == 0 && c[1] % 2 == 0) || - (c[0] % 2 == 0 && done_x)) || - (c[1] % 2 == 0 && done_y); - })) { + [done_x, done_y](std::array c) { + return ((c[0] % 2 == 0 && c[1] % 2 == 0) || + (c[0] % 2 == 0 && done_x)) || + (c[1] % 2 == 0 && done_y); + })) { + // one of our pairs qualifies for trimming! seen_pairs[{d1, d2}] = true; + // We separate the flaps of the bowtie (there may be more than + // two!) into distinct sets. std::list> flaps = this->get_tie_flaps(v); + // All the bonds in each flap without current are removed from + // the backbone. for (const std::set& flap : flaps) { std::array total_current = {0.0, 0.0}; for (unsigned e : flap) { diff --git a/lib/src/problem.cpp b/lib/src/problem.cpp index 0645244..ab87b0c 100644 --- a/lib/src/problem.cpp +++ b/lib/src/problem.cpp @@ -1,15 +1,12 @@ #include "problem.hpp" -class nanException: public std::exception -{ - virtual const char* what() const throw() - { - return "The linear problem returned NaN."; - } +class nanException : public std::exception { + virtual const char* what() const throw() { return "The linear problem returned NaN."; } } nanex; -problem::problem(const graph& G, unsigned axis, cholmod_sparse *vcmat, cholmod_common *c) : G(G), axis(axis), voltcurmat(vcmat), c(c) { +problem::problem(const graph& G, unsigned axis, cholmod_sparse* vcmat, cholmod_common* c) + : G(G), axis(axis), voltcurmat(vcmat), c(c) { b = CHOL_F(zeros)(G.vertices.size(), 1, CHOLMOD_REAL, c); for (unsigned i = 0; i < G.edges.size(); i++) { graph::coordinate v0 = G.vertices[G.edges[i].v[0]].r; @@ -23,19 +20,20 @@ problem::problem(const graph& G, unsigned axis, cholmod_sparse *vcmat, cholmod_c ind = v0.x < v1.x ? 0 : 1; } - ((double *)b->x)[G.edges[i].v[ind]] += 1.0; - ((double *)b->x)[G.edges[i].v[!ind]] -= 1.0; + ((double*)b->x)[G.edges[i].v[ind]] += 1.0; + ((double*)b->x)[G.edges[i].v[!ind]] -= 1.0; } } unsigned nnz = G.vertices.size() + G.edges.size(); - cholmod_triplet *t = CHOL_F(allocate_triplet)(G.vertices.size(), G.vertices.size(), nnz, 1, CHOLMOD_REAL, c); + cholmod_triplet* t = + CHOL_F(allocate_triplet)(G.vertices.size(), G.vertices.size(), nnz, 1, CHOLMOD_REAL, c); for (unsigned i = 0; i < G.vertices.size(); i++) { - ((CHOL_INT *)t->i)[i] = i; - ((CHOL_INT *)t->j)[i] = i; - ((double *)t->x)[i] = 0.0; + ((CHOL_INT*)t->i)[i] = i; + ((CHOL_INT*)t->j)[i] = i; + ((double*)t->x)[i] = 0.0; } unsigned terms = G.vertices.size(); @@ -46,8 +44,8 @@ problem::problem(const graph& G, unsigned axis, cholmod_sparse *vcmat, cholmod_c unsigned v0 = G.edges[i].v[0]; unsigned v1 = G.edges[i].v[1]; - ((double *)t->x)[v0]++; - ((double *)t->x)[v1]++; + ((double*)t->x)[v0]++; + ((double*)t->x)[v1]++; unsigned s0 = v0 < v1 ? v0 : v1; unsigned s1 = v0 < v1 ? v1 : v0; @@ -55,22 +53,22 @@ problem::problem(const graph& G, unsigned axis, cholmod_sparse *vcmat, cholmod_c auto it = known_edges.find({s0, s1}); if (it == known_edges.end()) { - ((CHOL_INT *)t->i)[terms] = s1; - ((CHOL_INT *)t->j)[terms] = s0; - ((double *)t->x)[terms] = -1.0; + ((CHOL_INT*)t->i)[terms] = s1; + ((CHOL_INT*)t->j)[terms] = s0; + ((double*)t->x)[terms] = -1.0; known_edges[{s0, s1}] = terms; terms++; } else { - ((double *)t->x)[it->second] -= 1.0; + ((double*)t->x)[it->second] -= 1.0; } } - ((double *)t->x)[0]++; + ((double*)t->x)[0]++; t->nnz = terms; - cholmod_sparse *laplacian = CHOL_F(triplet_to_sparse)(t, terms, c); + cholmod_sparse* laplacian = CHOL_F(triplet_to_sparse)(t, terms, c); CHOL_F(free_triplet)(&t, c); factor = CHOL_F(analyze)(laplacian, c); CHOL_F(factorize)(laplacian, factor, c); @@ -79,19 +77,20 @@ problem::problem(const graph& G, unsigned axis, cholmod_sparse *vcmat, cholmod_c sol.currents.resize(G.edges.size()); } -problem::problem(const graph& G, unsigned axis, cholmod_common *c) : problem(G, axis, NULL, c) { - cholmod_triplet *t = CHOL_F(allocate_triplet)(G.edges.size(), G.vertices.size(), 2 * G.edges.size(), 0, CHOLMOD_REAL, c); +problem::problem(const graph& G, unsigned axis, cholmod_common* c) : problem(G, axis, NULL, c) { + cholmod_triplet* t = CHOL_F(allocate_triplet)(G.edges.size(), G.vertices.size(), + 2 * G.edges.size(), 0, CHOLMOD_REAL, c); t->nnz = 2 * G.edges.size(); for (unsigned i = 0; i < G.edges.size(); i++) { - ((CHOL_INT *)t->i)[2 * i] = i; - ((CHOL_INT *)t->j)[2 * i] = G.edges[i].v[0]; - ((double *)t->x)[2 * i] = 1.0; + ((CHOL_INT*)t->i)[2 * i] = i; + ((CHOL_INT*)t->j)[2 * i] = G.edges[i].v[0]; + ((double*)t->x)[2 * i] = 1.0; - ((CHOL_INT *)t->i)[2 * i + 1] = i; - ((CHOL_INT *)t->j)[2 * i + 1] = G.edges[i].v[1]; - ((double *)t->x)[2 * i + 1] = -1.0; + ((CHOL_INT*)t->i)[2 * i + 1] = i; + ((CHOL_INT*)t->j)[2 * i + 1] = G.edges[i].v[1]; + ((double*)t->x)[2 * i + 1] = -1.0; } voltcurmat = CHOL_F(triplet_to_sparse)(t, 2 * G.edges.size(), c); @@ -103,7 +102,7 @@ problem::problem(const problem& other) : G(other.G), axis(other.axis), c(other.c b = CHOL_F(copy_dense)(other.b, c); factor = CHOL_F(copy_factor)(other.factor, c); voltcurmat = CHOL_F(copy_sparse)(other.voltcurmat, c); -} +} problem::~problem() { CHOL_F(free_dense)(&b, c); @@ -112,13 +111,13 @@ problem::~problem() { } void problem::solve(std::vector& fuses) { - cholmod_dense *x = CHOL_F(solve)(CHOLMOD_A, factor, b, c); + cholmod_dense* x = CHOL_F(solve)(CHOLMOD_A, factor, b, c); - if (((double *)x->x)[0] != ((double *)x->x)[0]) { + if (((double*)x->x)[0] != ((double*)x->x)[0]) { throw nanex; } - cholmod_dense *y = CHOL_F(allocate_dense)(G.edges.size(), 1, G.edges.size(), CHOLMOD_REAL, c); + cholmod_dense* y = CHOL_F(allocate_dense)(G.edges.size(), 1, G.edges.size(), CHOLMOD_REAL, c); double alpha[2] = {1, 0}; double beta[2] = {0, 0}; @@ -130,7 +129,7 @@ void problem::solve(std::vector& fuses) { if (fuses[i]) { sol.currents[i] = 0; } else { - sol.currents[i] = ((double *)y->x)[i]; + sol.currents[i] = ((double*)y->x)[i]; graph::coordinate v0 = G.vertices[G.edges[i].v[0]].r; graph::coordinate v1 = G.vertices[G.edges[i].v[1]].r; @@ -166,15 +165,15 @@ void problem::break_edge(unsigned e, bool unbreak) { unsigned n = factor->n; - cholmod_sparse *update_mat = CHOL_F(allocate_sparse)(n, n, 2, true, true, 0, CHOLMOD_REAL, c); + cholmod_sparse* update_mat = CHOL_F(allocate_sparse)(n, n, 2, true, true, 0, CHOLMOD_REAL, c); unsigned s1, s2; s1 = v0 < v1 ? v0 : v1; s2 = v0 < v1 ? v1 : v0; - CHOL_INT *pp = (CHOL_INT *)update_mat->p; - CHOL_INT *ii = (CHOL_INT *)update_mat->i; - double *xx = (double *)update_mat->x; + CHOL_INT* pp = (CHOL_INT*)update_mat->p; + CHOL_INT* ii = (CHOL_INT*)update_mat->i; + double* xx = (double*)update_mat->x; for (unsigned i = 0; i <= s1; i++) { pp[i] = 0; @@ -189,8 +188,8 @@ void problem::break_edge(unsigned e, bool unbreak) { xx[0] = 1; xx[1] = -1; - cholmod_sparse *perm_update_mat = CHOL_F(submatrix)( - update_mat, (CHOL_INT *)factor->Perm, factor->n, NULL, -1, true, true, c); + cholmod_sparse* perm_update_mat = + CHOL_F(submatrix)(update_mat, (CHOL_INT*)factor->Perm, factor->n, NULL, -1, true, true, c); CHOL_F(updown)(unbreak, perm_update_mat, factor, c); @@ -208,8 +207,7 @@ void problem::break_edge(unsigned e, bool unbreak) { ind = r0.x < r1.x ? unbreak : !unbreak; } - ((double *)b->x)[G.edges[e].v[ind]] -= 1.0; - ((double *)b->x)[G.edges[e].v[!ind]] += 1.0; + ((double*)b->x)[G.edges[e].v[ind]] -= 1.0; + ((double*)b->x)[G.edges[e].v[!ind]] += 1.0; } } - -- cgit v1.2.3-54-g00ecf