X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?p=moebius2.git;a=blobdiff_plain;f=bgl.cpp;h=ae36ea4abb5d6ecf8a8027a00598aff5048a95c4;hp=eb7e096955bf507cf1445446237259b9dd63b423;hb=bb0e48bffe4373fabc17a954bbae651bf41def2d;hpb=1050281a7d39f56431d9f36a6af4b19774419b75 diff --git a/bgl.cpp b/bgl.cpp index eb7e096..ae36ea4 100644 --- a/bgl.cpp +++ b/bgl.cpp @@ -1,4 +1,23 @@ +/* + * Everything that needs the Boost Graph Library and C++ templates etc. + * (and what a crazy set of stuff that all is) + */ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + extern "C" { +#include "bgl.h" #include "mgraph.h" } @@ -27,9 +46,30 @@ extern "C" { #define VMASK (YMASK|XMASK) #define ESHIFT (YBITS|XBITS) +class Graph { }; // this is a dummy as our graph has no actual representation + +using namespace boost; + +struct OutEdgeIterator : + public iterator_facade< + OutEdgeIterator, + int const, + forward_traversal_tag +> { + int f; + void increment() { f += 1< VertexIterator; + namespace boost { - // We make Layout a model of various BGL Graph concepts. - // This mainly means that graph_traits has lots of stuff. + // We make Graph a model of various BGL Graph concepts. + // This mainly means that graph_traits has lots of stuff. // First, some definitions used later: @@ -37,61 +77,58 @@ namespace boost { public virtual incidence_graph_tag, public virtual vertex_list_graph_tag, public virtual edge_list_graph_tag { }; - - struct OutEdgeIncrable { - int f; - OutEdgeIncrable& operator++() { f += 1< { + struct graph_traits { // Concept Graph: - typedef int vertex_descriptor; /* vertex number, -1 => none */ typedef int edge_descriptor; /* see above */ typedef undirected_tag directed_category; - typedef disallow_parallel_ege edge_parallel_category; + typedef disallow_parallel_edge_tag edge_parallel_category; typedef layout_graph_traversal_category traversal_category; - inline int null_vertex() { return -1; } // Concept IncidenceGraph: - - typedef counting_iterator out_edge_iterator; - typedef int degree_size_type; - - inline int source(int f, const Layout&) { return f&VMASK; } - inline int target(int f, const Layout&) { return EDGE_END2(f&VMASK, f>>ESHIFT); } - inline std::pair - out_edges(int v, const Layout&) { - return std::make_pair(out_edge_iterator(OutEdgeIncrable(v, VE_MIN(v))), - out_edge_iterator(OutEdgeIncrable(v, VE_MAX(v)))); - } - out_degree(int v, const Layout&) { return VE_MAX(v) - VE_MIN(v); } + typedef OutEdgeIterator out_edge_iterator; + typedef unsigned degree_size_type; // Concept VertexListGraph: - typedef counting_iterator vertex_iterator; + typedef VertexIterator vertex_iterator; typedef unsigned vertices_size_type; - inline std::pair - vertices(const Layout&) { - return std::make_pair(vertex_iterator(0), vertex_iterator(N)); - } - inline unsigned num_vertices(const Layout&) { return N; } + }; + + // Concept Graph: + inline int null_vertex() { return -1; } -} + // Concept IncidenceGraph: + inline int source(int f, const Graph&) { return f&VMASK; } + inline int target(int f, const Graph&) { return EDGE_END2(f&VMASK, f>>ESHIFT); } + inline std::pair + out_edges(int v, const Graph&) { + return std::make_pair(OutEdgeIterator(v, VE_MIN(v)), + OutEdgeIterator(v, VE_MAX(v))); + } + inline unsigned out_degree(int v, const Graph&) { + return VE_MAX(v) - VE_MIN(v); + } + + // Concept VertexListGraph: + inline std::pair vertices(const Graph&) { + return std::make_pair(VertexIterator(0), VertexIterator(N)); + } + inline unsigned num_vertices(const Graph&) { return N; } +}; static void single_source_shortest_paths(int v1, const double edge_weights[/*f*/], double vertex_distances[/*v*/]) { - boost::dijkstra_shortest_paths - (g, v1, + Graph g; + + dijkstra_shortest_paths(g, v1, weight_map(edge_weights). vertex_index_map(identity_property_map()). distance_map(vertex_distances)); } -double graph_layout_cost(const Layout *g, const double vertex_areas[N]) { +double graph_layout_cost(const Vertices v, const double vertex_areas[N]) { /* For each (vi,vj) computes shortest path s_ij = |vi..vj| * along edges, and actual distance d_ij = |vi-vj|. * @@ -108,23 +145,26 @@ double graph_layout_cost(const Layout *g, const double vertex_areas[N]) { * (In practice we compute d^2+epsilon and use it for the * divisions, to avoid division by zero.) */ - double edge_weights[N*V6], vertex_distances[N], total_cost; - int v1, e, f; + static const double d2_epsilon= 1e-6; + + double edge_weights[N*V6], vertex_distances[N], total_cost=0; + int v1,v2,e,f; - FOR_VEDGE_X(v1,e, - f= v1 | e << ESHIFT, - edge_weights[f]= NaN) - edge_weights[f]= hypotD(g.v[v1], g.v[v2]); + FOR_VERTEX(v1) + FOR_VEDGE_X(v1,e,v2, + f= v1 | e << ESHIFT, + edge_weights[f]= NAN) + edge_weights[f]= hypotD(v[v1], v[v2]); FOR_VERTEX(v1) { double a1= vertex_areas[v1]; single_source_shortest_paths(v1, edge_weights, vertex_distances); FOR_VERTEX(v2) { double a2= vertex_areas[v2]; - double d2= hypotD2plus(g->v[v1],g->v[v2], d2_epsilon); + double d2= hypotD2plus(v[v1],v[v2], d2_epsilon); double sd= vertex_distances[v2] / d2; double sd2= sd*sd; - total_cost= fma_fast(a1*a2, (sd2 - 1.0)/(d2*d2), total_cost); + total_cost += a1*a2 * (sd2 - 1) / (d2*d2); } } return total_cost;