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
......@@ -204,6 +204,7 @@ AC_OUTPUT([
Makefile
src/Makefile
src/graph/Makefile
src/graph/correlations/Makefile
src/graph_tool/Makefile
])
## Process this file with automake to produce Makefile.in
SUBDIRS = correlations
AM_CPPFLAGS =\
-I. -I.. \
-I../boost-workaround \
......@@ -12,78 +14,33 @@ AM_CXXFLAGS =\
AM_CFLAGS=$(AM_CXXFLAGS)
libgraph_tooldir = $(pythondir)/graph_tool
libgraph_tool_coredir = $(pythondir)/graph_tool
libgraph_tool_LTLIBRARIES = libgraph_tool.la
libgraph_tool_core_LTLIBRARIES = libgraph_tool_core.la
libgraph_tool_la_includedir = $(pythondir)/graph_tool/include
libgraph_tool_core_la_includedir = $(pythondir)/graph_tool/include
libgraph_tool_la_SOURCES = \
graph_assortativity.cc \
graph_betweenness.cc \
libgraph_tool_core_la_SOURCES = \
graph_bind.cc \
graph.cc \
graph_clustering.cc \
graph_community.cc \
graph_community_network.cc \
graph_correlations.cc \
graph_correlations_combined.cc \
graph_correlations_combined_corr.cc \
graph_correlations_imp1.cc \
graph_correlations_imp2.cc \
graph_correlations_imp3.cc \
graph_correlations_neighbours.cc \
graph_correlations_neighbours_imp1.cc \
graph_correlations_neighbours_imp2.cc \
graph_correlations_neighbours_imp3.cc \
graph_correlations_neighbours_imp4.cc \
graph_correlations_neighbours_imp5.cc \
graph_correlations_neighbours_imp6.cc \
graph_distance.cc \
graph_distance_sampled.cc \
graph_edge_correlations.cc \
graph_edge_correlations_imp1.cc \
graph_edge_correlations_imp2.cc \
graph_edge_correlations_imp3.cc \
graph_edge_correlations_imp4.cc \
graph_edge_correlations_imp5.cc \
graph_extended_clustering.cc \
graph_copy.cc \
graph_filtering.cc \
graph_generation.cc \
graph_io.cc \
graph_layout.cc \
graph_line_graph.cc \
graph_minimum_spanning_tree.cc \
graph_properties.cc \
graph_python_interface.cc \
graph_python_interface_export.cc \
graph_reciprocity.cc \
graph_rewiring.cc \
graph_selectors.cc \
graphml.cpp\
read_graphviz_spirit.cpp\
../boost-workaround/boost/graph/filtered_graph.hpp\
../boost-workaround/boost/graph/fruchterman_reingold.hpp\
../boost-workaround/boost/graph/graphml.hpp
libgraph_tool_la_include_HEADERS = \
libgraph_tool_core_la_include_HEADERS = \
graph_adaptor.hh \
graph_assortativity.hh \
graph_clustering.hh \
graph_community.hh \
graph_community_network.hh \
graph_correlations_combined.hh \
graph_correlations.hh \
graph_correlations_neighbours.hh \
graph_distance.hh \
graph_distance_sampled.hh \
graph_edge_correlations.hh \
graph_extended_clustering.hh \
graph_filtering.hh \
graph.hh \
graph_properties.hh \
graph_python_interface.hh \
graph_rewiring.hh \
graph_selectors.hh \
graph_util.hh \
histogram.hh \
......@@ -91,19 +48,20 @@ libgraph_tool_la_include_HEADERS = \
shared_map.hh \
../../config.h
BUILT_SOURCES = \
graph_filtering.hh.gch
# leave out precompiled headers for now, since it doesn't seem to help much
# BUILT_SOURCES = \
# graph_filtering.hh.gch
## Header precompilation
## FIXME: need a better way to convince libtool to let us do this.
$(libgraph_tool_la_include_HEADERS):
# ## Header precompilation
# ## FIXME: need a better way to convince libtool to let us do this.
# $(libgraph_tool_la_include_HEADERS):
$(BUILT_SOURCES):
$(CXXCOMPILE) $(CXXFLAGS) $(AM_CXXFLAGS) $(AM_CPPFLAGS) -fPIC -DPIC -x c++-header `basename $@ .gch`
mostlyclean-local:
-rm -f *.gch
# $(BUILT_SOURCES):
# $(CXXCOMPILE) $(CXXFLAGS) $(AM_CXXFLAGS) $(AM_CPPFLAGS) -fPIC -DPIC -x c++-header `basename $@ .gch`
# mostlyclean-local:
# -rm -f *.gch
libgraph_tool_la_LIBADD = \
libgraph_tool_core_la_LIBADD = \
$(PYTHON_LDFLAGS) \
$(BOOST_LDFLAGS) \
$(OPENMP_LDFLAGS) \
......@@ -113,7 +71,7 @@ libgraph_tool_la_LIBADD = \
# needed for typeinfo objects to work across DSO boundaries.
# see http://gcc.gnu.org/faq.html#dso
libgraph_tool_la_LDFLAGS = \
libgraph_tool_core_la_LDFLAGS = \
-module \
-avoid-version \
-export-dynamic \
......
## Process this file with automake to produce Makefile.in
AM_CPPFLAGS =\
-I. -I.. \
-I../boost-workaround \
-DHAVE_CONFIG_H
AM_CXXFLAGS =\
-Wall \
$(PYTHON_CPPFLAGS) \
$(BOOST_CPPFLAGS)
AM_CFLAGS=$(AM_CXXFLAGS)
libgraph_tool_correlationsdir = $(pythondir)/graph_tool
libgraph_tool_correlations_LTLIBRARIES = libgraph_tool_correlations.la
libgraph_tool_correlations_la_includedir = $(pythondir)/graph_tool/include
libgraph_tool_correlations_la_SOURCES = \
graph_assortativity.cc \
graph_correlations.cc \
graph_correlations_combined.cc \
graph_correlations_combined_imp1.cc \
graph_correlations_combined_corr.cc \
graph_correlations_combined_corr_imp1.cc \
graph_correlations_imp1.cc \
graph_correlations_imp2.cc \
graph_correlations_imp3.cc \
graph_correlations_neighbours.cc \
graph_correlations_neighbours_imp1.cc \
graph_correlations_neighbours_imp2.cc \
graph_correlations_neighbours_imp3.cc \
graph_correlations_neighbours_imp4.cc \
graph_correlations_neighbours_imp5.cc \
graph_correlations_neighbours_imp6.cc \
graph_edge_correlations.cc \
graph_edge_correlations_imp1.cc \
graph_edge_correlations_imp2.cc \
graph_edge_correlations_imp3.cc \
graph_edge_correlations_imp4.cc \
graph_edge_correlations_imp5.cc
libgraph_tool_correlations_la_include_HEADERS = \
graph_assortativity.hh \
graph_correlations_combined.hh \
graph_correlations.hh \
graph_correlations_neighbours.hh \
graph_edge_correlations.hh
libgraph_tool_correlations_la_LIBADD = \
$(PYTHON_LDFLAGS) \
$(BOOST_LDFLAGS) \
$(OPENMP_LDFLAGS) \
-lboost_python \
-lboost_iostreams \
-lexpat
# needed for typeinfo objects to work across DSO boundaries.
# see http://gcc.gnu.org/faq.html#dso
libgraph_tool_correlations_la_LDFLAGS = \
-module \
-avoid-version \
-export-dynamic \
-no-undefined \
-Wl,-E
......@@ -31,6 +31,10 @@ using namespace boost;
using namespace boost::lambda;
using namespace graph_tool;
void graph_correlations_combined_imp1(const GraphInterface& g,
hist2d_t& hist,
boost::any deg1, boost::any deg2);
hist2d_t
GraphInterface::GetCombinedVertexHistogram(deg_t deg1, deg_t deg2) const
{
......@@ -39,10 +43,13 @@ GraphInterface::GetCombinedVertexHistogram(deg_t deg1, deg_t deg2) const
{
run_action<>()(*this, bind<void>(get_combined_degree_histogram(),
_1, _2, _3, var(hist)),
all_selectors(), all_selectors())
all_selectors(),
detail::split::apply<all_selectors>::type::first())
(degree_selector(deg1, _properties),
degree_selector(deg2, _properties));
graph_correlations_combined_imp1(*this, hist,
degree_selector(deg1, _properties),
degree_selector(deg2, _properties));
}
catch (dynamic_get_failure &e)
{
......
......@@ -31,6 +31,10 @@ using namespace boost;
using namespace boost::lambda;
using namespace graph_tool;
void graph_correlations_combined_corr_imp1
(const GraphInterface& g, avg_corr_t& avg_corr,
boost::any deg1, boost::any deg2);
avg_corr_t
GraphInterface::GetAverageCombinedVertexCorrelation(deg_t deg1, deg_t deg2)
const
......@@ -42,9 +46,13 @@ const
run_action<>()(*this,
bind<void>(get_average_combined_degree_correlation(),
_1, _2, _3, var(avg_corr)),
all_selectors(), all_selectors())
all_selectors(),
detail::split::apply<all_selectors>::type::first())
(degree_selector(deg1, _properties),
degree_selector(deg2, _properties));
graph_correlations_combined_corr_imp1
(*this, avg_corr, degree_selector(deg1, _properties),
degree_selector(deg2, _properties));
}
catch (dynamic_get_failure &e)
......
// graph-tool -- a general graph modification and manipulation thingy
//
// Copyright (C) 2007 Tiago de Paula Peixoto <tiago@forked.de>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "graph_filtering.hh"
#include "graph.hh"
#include "histogram.hh"
#include "graph_selectors.hh"
#include "graph_properties.hh"
#include "shared_map.hh"
#include <boost/lambda/bind.hpp>
#include "graph_correlations_combined.hh"
using namespace std;
using namespace boost;
using namespace boost::lambda;
using namespace graph_tool;
void graph_correlations_combined_corr_imp1
(const GraphInterface& g, avg_corr_t& avg_corr,
boost::any deg1, boost::any deg2)
{
run_action<>()(g, bind<void>(get_average_combined_degree_correlation(),
_1, _2, _3, var(avg_corr)),
all_selectors(),
graph_tool::detail::split::apply<all_selectors>::type
::second())
(deg1, deg2);
}
// graph-tool -- a general graph modification and manipulation thingy
//
// Copyright (C) 2007 Tiago de Paula Peixoto <tiago@forked.de>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "graph_filtering.hh"
#include "graph.hh"
#include "histogram.hh"
#include "graph_selectors.hh"
#include "graph_properties.hh"
#include "shared_map.hh"
#include <boost/lambda/bind.hpp>
#include "graph_correlations_combined.hh"
using namespace std;
using namespace boost;
using namespace boost::lambda;
using namespace graph_tool;
void graph_correlations_combined_imp1(const GraphInterface& g,
hist2d_t& hist,
boost::any deg1, boost::any deg2)
{
run_action<>()(g, bind<void>(get_combined_degree_histogram(),
_1, _2, _3, var(hist)),
all_selectors(),
graph_tool::detail::split::apply<all_selectors>::type
::second())
(deg1, deg2);
}
......@@ -15,16 +15,9 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <algorithm>
#include <tr1/unordered_set>
#include <iostream>
#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>
#include <boost/graph/graphviz.hpp>
#include <boost/graph/breadth_first_search.hpp>
#include <boost/graph/strong_components.hpp>
#include <boost/graph/connected_components.hpp>
#include <boost/random.hpp>
#include <boost/python/make_function.hpp>
#include <unistd.h> /* standard unix functions, like getpid() */
#include <sys/types.h> /* various type definitions, like pid_t */
......@@ -33,10 +26,7 @@
#include "graph.hh"
#include "histogram.hh"
#include "graph_filtering.hh"
#include "graph_selectors.hh"
#include "graph_properties.hh"
#include "graph_util.hh"
#include "shared_map.hh"
using namespace std;
using namespace boost;
......@@ -91,227 +81,6 @@ size_t GraphInterface::GetNumberOfEdges() const
return n;
}
// generalized functor to obtain histogram of different types of "degrees"
struct get_vertex_histogram
{
template <class Graph, class DegreeSelector, class Hist>
void operator()(const Graph* gp, DegreeSelector deg, Hist& hist) const
{
const Graph& g = *gp;
SharedMap<Hist> s_hist(hist);
int i, N = num_vertices(g);
#pragma omp parallel for default(shared) private(i) \
firstprivate(s_hist) schedule(dynamic)
for (i = 0; i < N; ++i)
{
typename graph_traits<Graph>::vertex_descriptor v = vertex(i, g);
if (v == graph_traits<Graph>::null_vertex())
continue;
s_hist[deg(v,g)]++;
}
s_hist.Gather();
}
};
// this will return the vertex histogram of degrees or scalar properties
hist_t
GraphInterface::GetVertexHistogram(GraphInterface::deg_t deg) const
{
hist_t hist;
try
{
run_action<>()(*this, bind<void>(get_vertex_histogram(), _1, _2,
var(hist)),
all_selectors())(degree_selector(deg, _properties));
}
catch (dynamic_get_failure &e)
{
throw GraphException("error getting scalar property: " +
string(e.what()));
}
return hist;
}
// generalized functor to obtain histogram of edge properties
struct get_edge_histogram
{
template <class Graph, class Prop, class Hist>
void operator()(const Graph* gp, Prop eprop, Hist& hist) const
{
const Graph& g = *gp;
SharedMap<Hist> s_hist(hist);
int i, N = num_vertices(g);
#pragma omp parallel for default(shared) private(i) \
firstprivate(s_hist) schedule(dynamic)
for (i = 0; i < N; ++i)
{
typename graph_traits<Graph>::vertex_descriptor v = vertex(i, g);
if (v == graph_traits<Graph>::null_vertex())
continue;
typename graph_traits<Graph>::out_edge_iterator e, e_begin, e_end;
tie(e_begin,e_end) = out_edges(v,g);
for(e = e_begin; e != e_end; ++e)
s_hist[eprop[*e]]++;
}
s_hist.Gather();
typedef typename graph_traits<Graph>::directed_category
directed_category;
if(is_convertible<directed_category,undirected_tag>::value)
{
for (typeof(s_hist.begin()) iter = s_hist.begin();
iter != s_hist.end(); ++iter)
iter->second /= typename Hist::value_type::second_type(2);
}
}
};
// returns the histogram of a given edge property
hist_t GraphInterface::GetEdgeHistogram(string property) const
{
hist_t hist;
try
{
run_action<>()(*this, bind<void>(get_edge_histogram(), _1, _2,
var(hist)),
edge_scalar_properties())
(prop(property, _edge_index, _properties));
}
catch (dynamic_get_failure& e)
{
throw GraphException("error getting scalar property: " +
string(e.what()));
}
return hist;
}
// this will label the components of a graph to a given vertex property, from
// [0, number of components - 1]. If the graph is directed the "strong
// components" are used.
struct label_components
{
template <class Graph, class CompMap>
void operator()(const Graph* gp, CompMap comp_map) const
{
const Graph& g = *gp;
typedef typename graph_traits<Graph>::directed_category
directed_category;
get_components(g, comp_map,
typename is_convertible<directed_category,
directed_tag>::type());
}
template <class Graph, class CompMap>
void get_components(const Graph& g, CompMap comp_map,
boost::true_type is_directed) const
{
strong_components(g, comp_map);
}
template <class Graph, class CompMap>
void get_components(const Graph& g, CompMap comp_map,
boost::false_type is_directed) const
{
connected_components(g, comp_map);