Commit 3cfff0cb authored by Tiago Peixoto's avatar Tiago Peixoto

Split libgraph_tool into sub-modules and add test cases

This commit splits libraph_tool into different libraries:
 
   - libgraph_tool_core
   - libgraph_tool_clustering (*)
   - libgraph_tool_community (*)
   - libgraph_tool_correlations (*)
   - libgraph_tool_distance (*)
   - libgraph_tool_generation (*)
   - libgraph_tool_layout (*)
   - libgraph_tool_misc (*)
   - libgraph_tool_stats (*)

It also adds the python sub-module 'test', which provides extensive unit
testing of the core functionality. The core library is fully functional
and all test pass successfully.

(*) -> module needs to be ported to new refactoring, and does not yet build
parent 0b66e272
...@@ -12,7 +12,7 @@ graphtooldoc_DATA = \ ...@@ -12,7 +12,7 @@ graphtooldoc_DATA = \
TODO TODO
EXTRA_DIST = $(graphtooldoc_DATA) EXTRA_DIST = $(graphtooldoc_DATA)
# Copy all the spec files. Of cource, only one is actually used. # Copy all the spec files. Of cource, only one is actually used.
dist-hook: dist-hook:
......
...@@ -204,6 +204,7 @@ AC_OUTPUT([ ...@@ -204,6 +204,7 @@ AC_OUTPUT([
Makefile Makefile
src/Makefile src/Makefile
src/graph/Makefile src/graph/Makefile
src/graph/correlations/Makefile
src/graph_tool/Makefile src/graph_tool/Makefile
]) ])
...@@ -49,7 +49,7 @@ namespace detail { namespace graph { ...@@ -49,7 +49,7 @@ namespace detail { namespace graph {
IncomingMap incoming, IncomingMap incoming,
DistanceMap distance, DistanceMap distance,
PathCountMap path_count) PathCountMap path_count)
: ordered_vertices(ordered_vertices), weight(weight), : ordered_vertices(ordered_vertices), weight(weight),
incoming(incoming), distance(distance), incoming(incoming), distance(distance),
path_count(path_count) path_count(path_count)
{ } { }
...@@ -59,8 +59,8 @@ namespace detail { namespace graph { ...@@ -59,8 +59,8 @@ namespace detail { namespace graph {
* for w is set to {(v, w)} and the shortest path count of w is set to * for w is set to {(v, w)} and the shortest path count of w is set to
* the number of paths that reach {v}. * the number of paths that reach {v}.
*/ */
void edge_relaxed(edge_descriptor e, const Graph& g) void edge_relaxed(edge_descriptor e, const Graph& g)
{ {
vertex_descriptor v = source(e, g), w = target(e, g); vertex_descriptor v = source(e, g), w = target(e, g);
incoming[w].clear(); incoming[w].clear();
incoming[w].push_back(e); incoming[w].push_back(e);
...@@ -73,7 +73,7 @@ namespace detail { namespace graph { ...@@ -73,7 +73,7 @@ namespace detail { namespace graph {
* incoming edges of w and add all of the shortest paths to v to the * incoming edges of w and add all of the shortest paths to v to the
* shortest path count of w. * shortest path count of w.
*/ */
void edge_not_relaxed(edge_descriptor e, const Graph& g) void edge_not_relaxed(edge_descriptor e, const Graph& g)
{ {
typedef typename property_traits<WeightMap>::value_type weight_type; typedef typename property_traits<WeightMap>::value_type weight_type;
typedef typename property_traits<DistanceMap>::value_type distance_type; typedef typename property_traits<DistanceMap>::value_type distance_type;
...@@ -89,8 +89,8 @@ namespace detail { namespace graph { ...@@ -89,8 +89,8 @@ namespace detail { namespace graph {
} }
/// Keep track of vertices as they are reached /// Keep track of vertices as they are reached
void examine_vertex(vertex_descriptor w, const Graph&) void examine_vertex(vertex_descriptor w, const Graph&)
{ {
ordered_vertices.push(w); ordered_vertices.push(w);
} }
...@@ -110,13 +110,13 @@ namespace detail { namespace graph { ...@@ -110,13 +110,13 @@ namespace detail { namespace graph {
template<typename WeightMap> template<typename WeightMap>
struct brandes_dijkstra_shortest_paths struct brandes_dijkstra_shortest_paths
{ {
brandes_dijkstra_shortest_paths(WeightMap weight_map) brandes_dijkstra_shortest_paths(WeightMap weight_map)
: weight_map(weight_map) { } : weight_map(weight_map) { }
template<typename Graph, typename IncomingMap, typename DistanceMap, template<typename Graph, typename IncomingMap, typename DistanceMap,
typename PathCountMap, typename VertexIndexMap> typename PathCountMap, typename VertexIndexMap>
void void
operator()(Graph& g, operator()(Graph& g,
typename graph_traits<Graph>::vertex_descriptor s, typename graph_traits<Graph>::vertex_descriptor s,
std::stack<typename graph_traits<Graph>::vertex_descriptor>& ov, std::stack<typename graph_traits<Graph>::vertex_descriptor>& ov,
IncomingMap incoming, IncomingMap incoming,
...@@ -124,11 +124,11 @@ namespace detail { namespace graph { ...@@ -124,11 +124,11 @@ namespace detail { namespace graph {
PathCountMap path_count, PathCountMap path_count,
VertexIndexMap vertex_index) VertexIndexMap vertex_index)
{ {
typedef brandes_dijkstra_visitor<Graph, WeightMap, IncomingMap, typedef brandes_dijkstra_visitor<Graph, WeightMap, IncomingMap,
DistanceMap, PathCountMap> visitor_type; DistanceMap, PathCountMap> visitor_type;
visitor_type visitor(ov, weight_map, incoming, distance, path_count); visitor_type visitor(ov, weight_map, incoming, distance, path_count);
dijkstra_shortest_paths(g, s, dijkstra_shortest_paths(g, s,
boost::weight_map(weight_map) boost::weight_map(weight_map)
.vertex_index_map(vertex_index) .vertex_index_map(vertex_index)
.distance_map(distance) .distance_map(distance)
...@@ -150,18 +150,18 @@ namespace detail { namespace graph { ...@@ -150,18 +150,18 @@ namespace detail { namespace graph {
* records predecessor and the number of shortest paths to each * records predecessor and the number of shortest paths to each
* vertex. * vertex.
*/ */
template<typename Graph, typename IncomingMap, typename DistanceMap, template<typename Graph, typename IncomingMap, typename DistanceMap,
typename PathCountMap> typename PathCountMap>
struct visitor_type : public bfs_visitor<> struct visitor_type : public bfs_visitor<>
{ {
typedef typename graph_traits<Graph>::edge_descriptor edge_descriptor; typedef typename graph_traits<Graph>::edge_descriptor edge_descriptor;
typedef typename graph_traits<Graph>::vertex_descriptor typedef typename graph_traits<Graph>::vertex_descriptor
vertex_descriptor; vertex_descriptor;
visitor_type(IncomingMap incoming, DistanceMap distance, visitor_type(IncomingMap incoming, DistanceMap distance,
PathCountMap path_count, PathCountMap path_count,
std::stack<vertex_descriptor>& ordered_vertices) std::stack<vertex_descriptor>& ordered_vertices)
: incoming(incoming), distance(distance), : incoming(incoming), distance(distance),
path_count(path_count), ordered_vertices(ordered_vertices) { } path_count(path_count), ordered_vertices(ordered_vertices) { }
/// Keep track of vertices as they are reached /// Keep track of vertices as they are reached
...@@ -180,7 +180,7 @@ namespace detail { namespace graph { ...@@ -180,7 +180,7 @@ namespace detail { namespace graph {
vertex_descriptor v = source(e, g); vertex_descriptor v = source(e, g);
vertex_descriptor w = target(e, g); vertex_descriptor w = target(e, g);
put(distance, w, get(distance, v) + 1); put(distance, w, get(distance, v) + 1);
put(path_count, w, get(path_count, v)); put(path_count, w, get(path_count, v));
incoming[w].push_back(e); incoming[w].push_back(e);
} }
...@@ -208,10 +208,10 @@ namespace detail { namespace graph { ...@@ -208,10 +208,10 @@ namespace detail { namespace graph {
std::stack<vertex_descriptor>& ordered_vertices; std::stack<vertex_descriptor>& ordered_vertices;
}; };
template<typename Graph, typename IncomingMap, typename DistanceMap, template<typename Graph, typename IncomingMap, typename DistanceMap,
typename PathCountMap, typename VertexIndexMap> typename PathCountMap, typename VertexIndexMap>
void void
operator()(Graph& g, operator()(Graph& g,
typename graph_traits<Graph>::vertex_descriptor s, typename graph_traits<Graph>::vertex_descriptor s,
std::stack<typename graph_traits<Graph>::vertex_descriptor>& ov, std::stack<typename graph_traits<Graph>::vertex_descriptor>& ov,
IncomingMap incoming, IncomingMap incoming,
...@@ -224,12 +224,12 @@ namespace detail { namespace graph { ...@@ -224,12 +224,12 @@ namespace detail { namespace graph {
visitor_type<Graph, IncomingMap, DistanceMap, PathCountMap> visitor_type<Graph, IncomingMap, DistanceMap, PathCountMap>
visitor(incoming, distance, path_count, ov); visitor(incoming, distance, path_count, ov);
std::vector<default_color_type> std::vector<default_color_type>
colors(num_vertices(g), color_traits<default_color_type>::white()); colors(num_vertices(g), color_traits<default_color_type>::white());
boost::queue<vertex_descriptor> Q; boost::queue<vertex_descriptor> Q;
breadth_first_visit(g, s, Q, visitor, breadth_first_visit(g, s, Q, visitor,
make_iterator_property_map(colors.begin(), make_iterator_property_map(colors.begin(),
vertex_index)); vertex_index));
} }
}; };
...@@ -237,16 +237,16 @@ namespace detail { namespace graph { ...@@ -237,16 +237,16 @@ namespace detail { namespace graph {
// When the edge centrality map is a dummy property map, no // When the edge centrality map is a dummy property map, no
// initialization is needed. // initialization is needed.
template<typename Iter> template<typename Iter>
inline void inline void
init_centrality_map(std::pair<Iter, Iter>, dummy_property_map) { } init_centrality_map(std::pair<Iter, Iter>, dummy_property_map) { }
// When we have a real edge centrality map, initialize all of the // When we have a real edge centrality map, initialize all of the
// centralities to zero. // centralities to zero.
template<typename Iter, typename Centrality> template<typename Iter, typename Centrality>
void void
init_centrality_map(std::pair<Iter, Iter> keys, Centrality centrality_map) init_centrality_map(std::pair<Iter, Iter> keys, Centrality centrality_map)
{ {
typedef typename property_traits<Centrality>::value_type typedef typename property_traits<Centrality>::value_type
centrality_type; centrality_type;
while (keys.first != keys.second) { while (keys.first != keys.second) {
put(centrality_map, *keys.first, centrality_type(0)); put(centrality_map, *keys.first, centrality_type(0));
...@@ -257,22 +257,22 @@ namespace detail { namespace graph { ...@@ -257,22 +257,22 @@ namespace detail { namespace graph {
// When the edge centrality map is a dummy property map, no update // When the edge centrality map is a dummy property map, no update
// is performed. // is performed.
template<typename Key, typename T> template<typename Key, typename T>
inline void inline void
update_centrality(dummy_property_map, const Key&, const T&) { } update_centrality(dummy_property_map, const Key&, const T&) { }
// When we have a real edge centrality map, add the value to the map // When we have a real edge centrality map, add the value to the map
template<typename CentralityMap, typename Key, typename T> template<typename CentralityMap, typename Key, typename T>
inline void inline void
update_centrality(CentralityMap centrality_map, Key k, const T& x) update_centrality(CentralityMap centrality_map, Key k, const T& x)
{ put(centrality_map, k, get(centrality_map, k) + x); } { put(centrality_map, k, get(centrality_map, k) + x); }
template<typename Iter> template<typename Iter>
inline void inline void
divide_centrality_by_two(std::pair<Iter, Iter>, dummy_property_map) {} divide_centrality_by_two(std::pair<Iter, Iter>, dummy_property_map) {}
template<typename Iter, typename CentralityMap> template<typename Iter, typename CentralityMap>
inline void inline void
divide_centrality_by_two(std::pair<Iter, Iter> keys, divide_centrality_by_two(std::pair<Iter, Iter> keys,
CentralityMap centrality_map) CentralityMap centrality_map)
{ {
typename property_traits<CentralityMap>::value_type two(2); typename property_traits<CentralityMap>::value_type two(2);
...@@ -283,11 +283,11 @@ namespace detail { namespace graph { ...@@ -283,11 +283,11 @@ namespace detail { namespace graph {
} }
template<typename Graph, typename CentralityMap, typename EdgeCentralityMap, template<typename Graph, typename CentralityMap, typename EdgeCentralityMap,
typename IncomingMap, typename DistanceMap, typename IncomingMap, typename DistanceMap,
typename DependencyMap, typename PathCountMap, typename DependencyMap, typename PathCountMap,
typename VertexIndexMap, typename ShortestPaths> typename VertexIndexMap, typename ShortestPaths>
void void
brandes_betweenness_centrality_impl(const Graph& g, brandes_betweenness_centrality_impl(const Graph& g,
CentralityMap centrality, // C_B CentralityMap centrality, // C_B
EdgeCentralityMap edge_centrality_map, EdgeCentralityMap edge_centrality_map,
IncomingMap, //incoming, // P IncomingMap, //incoming, // P
...@@ -306,7 +306,7 @@ namespace detail { namespace graph { ...@@ -306,7 +306,7 @@ namespace detail { namespace graph {
init_centrality_map(edges(g), edge_centrality_map); init_centrality_map(edges(g), edge_centrality_map);
int i, N = num_vertices(g); int i, N = num_vertices(g);
#pragma omp parallel for default(shared) private(i) schedule(dynamic) #pragma omp parallel for default(shared) private(i) schedule(dynamic)
for (i = 0; i < N; ++i) for (i = 0; i < N; ++i)
{ {
typename graph_traits<Graph>::vertex_descriptor s = vertex(i, g); typename graph_traits<Graph>::vertex_descriptor s = vertex(i, g);
...@@ -328,24 +328,24 @@ namespace detail { namespace graph { ...@@ -328,24 +328,24 @@ namespace detail { namespace graph {
put(dependency, *w, 0); put(dependency, *w, 0);
} }
put(path_count, s, 1); put(path_count, s, 1);
// Execute the shortest paths algorithm. This will be either // Execute the shortest paths algorithm. This will be either
// Dijkstra's algorithm or a customized breadth-first search, // Dijkstra's algorithm or a customized breadth-first search,
// depending on whether the graph is weighted or unweighted. // depending on whether the graph is weighted or unweighted.
shortest_paths(g, s, ordered_vertices, incoming, distance, shortest_paths(g, s, ordered_vertices, incoming, distance,
path_count, vertex_index); path_count, vertex_index);
while (!ordered_vertices.empty()) while (!ordered_vertices.empty())
{ {
vertex_descriptor w = ordered_vertices.top(); vertex_descriptor w = ordered_vertices.top();
ordered_vertices.pop(); ordered_vertices.pop();
typedef typename property_traits<IncomingMap>::value_type typedef typename property_traits<IncomingMap>::value_type
incoming_type; incoming_type;
typedef typename incoming_type::iterator incoming_iterator; typedef typename incoming_type::iterator incoming_iterator;
typedef typename property_traits<DependencyMap>::value_type typedef typename property_traits<DependencyMap>::value_type
dependency_type; dependency_type;
for (incoming_iterator vw = incoming[w].begin(); for (incoming_iterator vw = incoming[w].begin();
vw != incoming[w].end(); ++vw) { vw != incoming[w].end(); ++vw) {
vertex_descriptor v = source(*vw, g); vertex_descriptor v = source(*vw, g);
...@@ -355,17 +355,17 @@ namespace detail { namespace graph { ...@@ -355,17 +355,17 @@ namespace detail { namespace graph {
put(dependency, v, get(dependency, v) + factor); put(dependency, v, get(dependency, v) + factor);
update_centrality(edge_centrality_map, *vw, factor); update_centrality(edge_centrality_map, *vw, factor);
} }
if (w != s) { if (w != s) {
update_centrality(centrality, w, get(dependency, w)); update_centrality(centrality, w, get(dependency, w));
} }
} }
} }
typedef typename graph_traits<Graph>::directed_category directed_category; typedef typename graph_traits<Graph>::directed_category directed_category;
const bool is_undirected = const bool is_undirected =
is_convertible<directed_category*, undirected_tag*>::value; is_convertible<directed_category*, undirected_tag*>::value;
if (is_undirected) { if (is_undirected) {
divide_centrality_by_two(vertices(g), centrality); divide_centrality_by_two(vertices(g), centrality);
...@@ -376,11 +376,11 @@ namespace detail { namespace graph { ...@@ -376,11 +376,11 @@ namespace detail { namespace graph {
} } // end namespace detail::graph } } // end namespace detail::graph
template<typename Graph, typename CentralityMap, typename EdgeCentralityMap, template<typename Graph, typename CentralityMap, typename EdgeCentralityMap,
typename IncomingMap, typename DistanceMap, typename IncomingMap, typename DistanceMap,
typename DependencyMap, typename PathCountMap, typename DependencyMap, typename PathCountMap,
typename VertexIndexMap> typename VertexIndexMap>
void void
brandes_betweenness_centrality(const Graph& g, brandes_betweenness_centrality(const Graph& g,
CentralityMap centrality, // C_B CentralityMap centrality, // C_B
EdgeCentralityMap edge_centrality_map, EdgeCentralityMap edge_centrality_map,
IncomingMap incoming, // P IncomingMap incoming, // P
...@@ -391,20 +391,20 @@ brandes_betweenness_centrality(const Graph& g, ...@@ -391,20 +391,20 @@ brandes_betweenness_centrality(const Graph& g,
{ {
detail::graph::brandes_unweighted_shortest_paths shortest_paths; detail::graph::brandes_unweighted_shortest_paths shortest_paths;
detail::graph::brandes_betweenness_centrality_impl(g, centrality, detail::graph::brandes_betweenness_centrality_impl(g, centrality,
edge_centrality_map, edge_centrality_map,
incoming, distance, incoming, distance,
dependency, path_count, dependency, path_count,
vertex_index, vertex_index,
shortest_paths); shortest_paths);
} }
template<typename Graph, typename CentralityMap, typename EdgeCentralityMap, template<typename Graph, typename CentralityMap, typename EdgeCentralityMap,
typename IncomingMap, typename DistanceMap, typename IncomingMap, typename DistanceMap,
typename DependencyMap, typename PathCountMap, typename DependencyMap, typename PathCountMap,
typename VertexIndexMap, typename WeightMap> typename VertexIndexMap, typename WeightMap>
void void
brandes_betweenness_centrality(const Graph& g, brandes_betweenness_centrality(const Graph& g,
CentralityMap centrality, // C_B CentralityMap centrality, // C_B
EdgeCentralityMap edge_centrality_map, EdgeCentralityMap edge_centrality_map,
IncomingMap incoming, // P IncomingMap incoming, // P
...@@ -417,18 +417,18 @@ brandes_betweenness_centrality(const Graph& g, ...@@ -417,18 +417,18 @@ brandes_betweenness_centrality(const Graph& g,
detail::graph::brandes_dijkstra_shortest_paths<WeightMap> detail::graph::brandes_dijkstra_shortest_paths<WeightMap>
shortest_paths(weight_map); shortest_paths(weight_map);
detail::graph::brandes_betweenness_centrality_impl(g, centrality, detail::graph::brandes_betweenness_centrality_impl(g, centrality,
edge_centrality_map, edge_centrality_map,
incoming, distance, incoming, distance,
dependency, path_count, dependency, path_count,
vertex_index, vertex_index,
shortest_paths); shortest_paths);
} }
namespace detail { namespace graph { namespace detail { namespace graph {
template<typename Graph, typename CentralityMap, typename EdgeCentralityMap, template<typename Graph, typename CentralityMap, typename EdgeCentralityMap,
typename WeightMap, typename VertexIndexMap> typename WeightMap, typename VertexIndexMap>
void void
brandes_betweenness_centrality_dispatch2(const Graph& g, brandes_betweenness_centrality_dispatch2(const Graph& g,
CentralityMap centrality, CentralityMap centrality,
EdgeCentralityMap edge_centrality_map, EdgeCentralityMap edge_centrality_map,
...@@ -438,15 +438,15 @@ namespace detail { namespace graph { ...@@ -438,15 +438,15 @@ namespace detail { namespace graph {
typedef typename graph_traits<Graph>::degree_size_type degree_size_type; typedef typename graph_traits<Graph>::degree_size_type degree_size_type;
typedef typename graph_traits<Graph>::vertex_descriptor vertex_descriptor; typedef typename graph_traits<Graph>::vertex_descriptor vertex_descriptor;
typedef typename graph_traits<Graph>::edge_descriptor edge_descriptor; typedef typename graph_traits<Graph>::edge_descriptor edge_descriptor;
typedef typename mpl::if_c<(is_same<CentralityMap, typedef typename mpl::if_c<(is_same<CentralityMap,
dummy_property_map>::value), dummy_property_map>::value),
EdgeCentralityMap, EdgeCentralityMap,
CentralityMap>::type a_centrality_map; CentralityMap>::type a_centrality_map;
typedef typename property_traits<a_centrality_map>::value_type typedef typename property_traits<a_centrality_map>::value_type
centrality_type; centrality_type;
typename graph_traits<Graph>::vertices_size_type V = num_vertices(g); typename graph_traits<Graph>::vertices_size_type V = num_vertices(g);
std::vector<std::vector<edge_descriptor> > incoming(V); std::vector<std::vector<edge_descriptor> > incoming(V);
std::vector<centrality_type> distance(V); std::vector<centrality_type> distance(V);
std::vector<centrality_type> dependency(V); std::vector<centrality_type> dependency(V);
...@@ -461,11 +461,11 @@ namespace detail { namespace graph { ...@@ -461,11 +461,11 @@ namespace detail { namespace graph {
vertex_index, vertex_index,
weight_map); weight_map);
} }
template<typename Graph, typename CentralityMap, typename EdgeCentralityMap, template<typename Graph, typename CentralityMap, typename EdgeCentralityMap,
typename VertexIndexMap> typename VertexIndexMap>
void void
brandes_betweenness_centrality_dispatch2(const Graph& g, brandes_betweenness_centrality_dispatch2(const Graph& g,
CentralityMap centrality, CentralityMap centrality,
EdgeCentralityMap edge_centrality_map, EdgeCentralityMap edge_centrality_map,
...@@ -474,15 +474,15 @@ namespace detail { namespace graph { ...@@ -474,15 +474,15 @@ namespace detail { namespace graph {
typedef typename graph_traits<Graph>::degree_size_type degree_size_type; typedef typename graph_traits<Graph>::degree_size_type degree_size_type;
typedef typename graph_traits<Graph>::vertex_descriptor vertex_descriptor; typedef typename graph_traits<Graph>::vertex_descriptor vertex_descriptor;
typedef typename graph_traits<Graph>::edge_descriptor edge_descriptor; typedef typename graph_traits<Graph>::edge_descriptor edge_descriptor;
typedef typename mpl::if_c<(is_same<CentralityMap, typedef typename mpl::if_c<(is_same<CentralityMap,
dummy_property_map>::value), dummy_property_map>::value),
EdgeCentralityMap, EdgeCentralityMap,
CentralityMap>::type a_centrality_map; CentralityMap>::type a_centrality_map;
typedef typename property_traits<a_centrality_map>::value_type typedef typename property_traits<a_centrality_map>::value_type
centrality_type; centrality_type;