Commit 0b66e272 authored by Tiago Peixoto's avatar Tiago Peixoto

Refactor metaprogramming engine

This is a huge commit which completely refactors the metaprogramming
engine which generates and selects (at run time) the graph view type and
the desired algorithm implementation (template instantiation) that runs
on it.

Things are laid out now as following. There exists a main underlying
graph type (GraphInterface::multigraph_t) and several other template
classes that mask it some way or another, in a hierarchic fashion:

     multigraph_t -> filtered_graph (edges only, vertices only, both)
         |                               |           |           |
         |                               |           |           |
         |-------(reversed_graph)--------|-----------|-----------|
         |                               |           |           |
         \------(UndirectedAdaptor)------------------------------/

The filtered_graph filters out edges and/or vertices from the graph
based on some scalar boolean property. The reversed_graph reversed the
direction of the edges and, finally, the UndirectedAdaptor treats the
original directed graphs as undirected, transversing the in- and
out-edges of each vertex indifferently. Thus, the total number of graph
view types is 12. (The option --disable-graph-filtering can be passed to
the configure script, which will disable graph filtering altogether and
bring the total number down to 3, to reduce compile time and memory
usage)

In general, some specific algorithm, implemented as a template function
object, needs to be instantiated for each of those types. Furthermore,
the algorithm may also depend on other types, such as specific
property_maps. Thus, the following scheme is used:

    struct my_algorithm // algorithm to be implemented
    {
        template <class Graph, class PropertyMap>
        void operator()(Graph *g, PropertyMap p, double& result) const
        {
            // ...
        }
    };

    // in order for the above code to be instantiated at compile time
    // and selected at run time, the run_action template function object
    // is used from a member function of the GraphInterface class:

    double GraphInterface::MyAlgorithm(string prop_name)
    {
        double result;
        boost::any vprop = prop(property, _vertex_index, _properties);
        run_action<>()(*this, bind<void>(my_algorithm(), _1, _2,
                                         var(result)),
                       vertex_scalar_properties())(vprop);
        return result;
    }

The whole code was changed to reflect this scheme, but now things are
more centralized and less ad-hoc code needed to be
written. Unfortunately, due to GCC's high memory usage during template
instantiations, some of the code (namely all the degree correlation
things) had to be split in multiple compilation units... Maybe this will
change in the future if GCC gets optimized.

This commit also touches other parts of code. More specifically, the way
filtering gets done is very different. Now we only filter on boolean
properties, and with the above scheme, the desired implementation runs
with the correct chosen type, and no implicit type conversions should
ever happen, which would have a bad impact on performance.
parent 1e9d11d1
dnl Process this file with autoconf to produce a configure script. dnl Process this file with autoconf to produce a configure script.
AC_INIT(graph-tool, 1.2.0devel, [http://graph-tool.forked.de]) dnl graph-tool package version number
dnl An odd micro number indicates in-progress development.
dnl An even micro number indicates a released version.
m4_define(graph_tool_version_major, 1)
m4_define(graph_tool_version_minor, 9)
m4_define(graph_tool_version_micro, 0)
AC_INIT([graph-tool],
[graph_tool_version_major().graph_tool_version_minor().graph_tool_version_micro()],
[http://graph-tool.forked.de])
GRAPH_TOOL_VERSION_MAJOR=graph_tool_version_major()
GRAPH_TOOL_VERSION_MINOR=graph_tool_version_minor()
GRAPH_TOOL_VERSION_MICRO=graph_tool_version_micro()
AC_SUBST(GRAPH_TOOL_VERSION_MAJOR)
AC_SUBST(GRAPH_TOOL_VERSION_MINOR)
AC_SUBST(GRAPH_TOOL_VERSION_MICRO)
AC_CONFIG_SRCDIR(src/graph-tool) AC_CONFIG_SRCDIR(src/graph-tool)
AM_INIT_AUTOMAKE AM_INIT_AUTOMAKE
AM_PROG_CC_C_O AM_PROG_CC_C_O
...@@ -74,19 +91,19 @@ AC_ARG_ENABLE([visibility], [AC_HELP_STRING([--disable-visibility], ...@@ -74,19 +91,19 @@ AC_ARG_ENABLE([visibility], [AC_HELP_STRING([--disable-visibility],
) )
AC_MSG_CHECKING(whether to enable graph range filtering...) AC_MSG_CHECKING(whether to enable graph filtering...)
AC_ARG_ENABLE([range-filtering], [AC_HELP_STRING([--disable-range-filtering], AC_ARG_ENABLE([graph-filtering], [AC_HELP_STRING([--disable-graph-filtering],
[disable range filtering [default=enabled] ])], [disable graph filtering [default=enabled] ])],
if test $enableval = no; then if test $enableval = no; then
[AC_MSG_RESULT(no)] [AC_MSG_RESULT(no)]
[AC_DEFINE([NO_RANGE_FILTERING], 1, [disable range filtering])] [AC_DEFINE([NO_GRAPH_FILTERING], 1, [disable graph filtering])]
NO_RANGE_FILTERING=yes NO_GRAPH_FILTERING=yes
else else
[AC_MSG_RESULT(yes)] [AC_MSG_RESULT(yes)]
fi fi
, ,
[AC_MSG_RESULT(yes)] [AC_MSG_RESULT(yes)]
NO_RANGE_FILTERING=no NO_GRAPH_FILTERING=no
) )
AC_MSG_CHECKING(whether to enable parallel algorithms with openmp...) AC_MSG_CHECKING(whether to enable parallel algorithms with openmp...)
...@@ -126,8 +143,8 @@ dnl AX_BOOST_PYTHON ...@@ -126,8 +143,8 @@ dnl AX_BOOST_PYTHON
dnl expat dnl expat
AC_CHECK_LIB(expat,main) AC_CHECK_LIB(expat,main)
AM_PATH_PYTHON([2.4]) AM_PATH_PYTHON([2.5])
AC_PYTHON_DEVEL(>= '2.4') AC_PYTHON_DEVEL(>= '2.5')
dnl Checks for header files. dnl Checks for header files.
AC_CHECK_HEADER([expat.h]) AC_CHECK_HEADER([expat.h])
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
# NOTE: Changing this file will not affect anything until you rerun configure. # NOTE: Changing this file will not affect anything until you rerun configure.
# #
# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006,
# 2007 Free Software Foundation, Inc. # 2007, 2008 Free Software Foundation, Inc.
# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996 # Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
# #
# This program is free software; you can redistribute it and/or modify # This program is free software; you can redistribute it and/or modify
...@@ -43,8 +43,8 @@ EXIT_FAILURE=1 ...@@ -43,8 +43,8 @@ EXIT_FAILURE=1
PROGRAM=ltmain.sh PROGRAM=ltmain.sh
PACKAGE=libtool PACKAGE=libtool
VERSION=1.5.24 VERSION=1.5.26
TIMESTAMP=" (1.1220.2.456 2007/06/24 02:25:32)" TIMESTAMP=" (1.1220.2.493 2008/02/01 16:58:18)"
# Be Bourne compatible (taken from Autoconf:_AS_BOURNE_COMPATIBLE). # Be Bourne compatible (taken from Autoconf:_AS_BOURNE_COMPATIBLE).
if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
...@@ -113,15 +113,21 @@ esac ...@@ -113,15 +113,21 @@ esac
# These must not be set unconditionally because not all systems understand # These must not be set unconditionally because not all systems understand
# e.g. LANG=C (notably SCO). # e.g. LANG=C (notably SCO).
# We save the old values to restore during execute mode. # We save the old values to restore during execute mode.
for lt_var in LANG LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES lt_env=
for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
do do
eval "if test \"\${$lt_var+set}\" = set; then eval "if test \"\${$lt_var+set}\" = set; then
save_$lt_var=\$$lt_var save_$lt_var=\$$lt_var
lt_env=\"$lt_var=\$$lt_var \$lt_env\"
$lt_var=C $lt_var=C
export $lt_var export $lt_var
fi" fi"
done done
if test -n "$lt_env"; then
lt_env="env $lt_env"
fi
# Make sure IFS has a sensible default # Make sure IFS has a sensible default
lt_nl=' lt_nl='
' '
...@@ -499,7 +505,7 @@ do ...@@ -499,7 +505,7 @@ do
echo "\ echo "\
$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP $PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP
Copyright (C) 2007 Free Software Foundation, Inc. Copyright (C) 2008 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
exit $? exit $?
...@@ -802,6 +808,7 @@ if test -z "$show_help"; then ...@@ -802,6 +808,7 @@ if test -z "$show_help"; then
*.for) xform=for ;; *.for) xform=for ;;
*.java) xform=java ;; *.java) xform=java ;;
*.obj) xform=obj ;; *.obj) xform=obj ;;
*.sx) xform=sx ;;
esac esac
libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"` libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"`
...@@ -970,7 +977,7 @@ EOF ...@@ -970,7 +977,7 @@ EOF
$run $rm "$lobj" "$output_obj" $run $rm "$lobj" "$output_obj"
$show "$command" $show "$command"
if $run eval "$command"; then : if $run eval $lt_env "$command"; then :
else else
test -n "$output_obj" && $run $rm $removelist test -n "$output_obj" && $run $rm $removelist
exit $EXIT_FAILURE exit $EXIT_FAILURE
...@@ -1042,7 +1049,7 @@ EOF ...@@ -1042,7 +1049,7 @@ EOF
command="$command$suppress_output" command="$command$suppress_output"
$run $rm "$obj" "$output_obj" $run $rm "$obj" "$output_obj"
$show "$command" $show "$command"
if $run eval "$command"; then : if $run eval $lt_env "$command"; then :
else else
$run $rm $removelist $run $rm $removelist
exit $EXIT_FAILURE exit $EXIT_FAILURE
...@@ -1175,6 +1182,7 @@ EOF ...@@ -1175,6 +1182,7 @@ EOF
thread_safe=no thread_safe=no
vinfo= vinfo=
vinfo_number=no vinfo_number=no
single_module="${wl}-single_module"
func_infer_tag $base_compile func_infer_tag $base_compile
...@@ -1660,6 +1668,11 @@ EOF ...@@ -1660,6 +1668,11 @@ EOF
continue continue
;; ;;
-multi_module)
single_module="${wl}-multi_module"
continue
;;
-module) -module)
module=yes module=yes
continue continue
...@@ -2163,7 +2176,12 @@ EOF ...@@ -2163,7 +2176,12 @@ EOF
continue continue
fi fi
name=`$echo "X$deplib" | $Xsed -e 's/^-l//'` name=`$echo "X$deplib" | $Xsed -e 's/^-l//'`
for searchdir in $newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path; do if test "$linkmode" = lib; then
searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path"
else
searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path"
fi
for searchdir in $searchdirs; do
for search_ext in .la $std_shrext .so .a; do for search_ext in .la $std_shrext .so .a; do
# Search the libtool library # Search the libtool library
lib="$searchdir/lib${name}${search_ext}" lib="$searchdir/lib${name}${search_ext}"
...@@ -2959,12 +2977,18 @@ EOF ...@@ -2959,12 +2977,18 @@ EOF
# we do not want to link against static libs, # we do not want to link against static libs,
# but need to link against shared # but need to link against shared
eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib`
eval deplibdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
if test -n "$deplibrary_names" ; then if test -n "$deplibrary_names" ; then
for tmp in $deplibrary_names ; do for tmp in $deplibrary_names ; do
depdepl=$tmp depdepl=$tmp
done done
if test -f "$path/$depdepl" ; then if test -f "$deplibdir/$depdepl" ; then
depdepl="$deplibdir/$depdepl"
elif test -f "$path/$depdepl" ; then
depdepl="$path/$depdepl" depdepl="$path/$depdepl"
else
# Can't find it, oh well...
depdepl=
fi fi
# do not add paths which are already there # do not add paths which are already there
case " $newlib_search_path " in case " $newlib_search_path " in
...@@ -3112,9 +3136,10 @@ EOF ...@@ -3112,9 +3136,10 @@ EOF
case $linkmode in case $linkmode in
oldlib) oldlib)
if test -n "$deplibs"; then case " $deplibs" in
$echo "$modename: warning: \`-l' and \`-L' are ignored for archives" 1>&2 *\ -l* | *\ -L*)
fi $echo "$modename: warning: \`-l' and \`-L' are ignored for archives" 1>&2 ;;
esac
if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
$echo "$modename: warning: \`-dlopen' is ignored for archives" 1>&2 $echo "$modename: warning: \`-dlopen' is ignored for archives" 1>&2
...@@ -4251,9 +4276,10 @@ EOF ...@@ -4251,9 +4276,10 @@ EOF
;; ;;
obj) obj)
if test -n "$deplibs"; then case " $deplibs" in
$echo "$modename: warning: \`-l' and \`-L' are ignored for objects" 1>&2 *\ -l* | *\ -L*)
fi $echo "$modename: warning: \`-l' and \`-L' are ignored for objects" 1>&2 ;;
esac
if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
$echo "$modename: warning: \`-dlopen' is ignored for objects" 1>&2 $echo "$modename: warning: \`-dlopen' is ignored for objects" 1>&2
...@@ -5688,53 +5714,9 @@ fi\ ...@@ -5688,53 +5714,9 @@ fi\
$echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2 $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2
exit $EXIT_FAILURE exit $EXIT_FAILURE
fi fi
if test "X$EGREP" = X ; then newdependency_libs="$newdependency_libs $libdir/$name"
EGREP=egrep
fi
# We do not want portage's install root ($D) present. Check only for
# this if the .la is being installed.
if test "$installed" = yes && test "$D"; then
eval mynewdependency_lib=`echo "$libdir/$name" |sed -e "s:$D:/:g" -e 's:/\+:/:g'`
else
mynewdependency_lib="$libdir/$name"
fi
# Do not add duplicates
if test "$mynewdependency_lib"; then
my_little_ninja_foo_1=`echo $newdependency_libs |$EGREP -e "$mynewdependency_lib"`
if test -z "$my_little_ninja_foo_1"; then
newdependency_libs="$newdependency_libs $mynewdependency_lib"
fi
fi
;;
*)
if test "$installed" = yes; then
# Rather use S=WORKDIR if our version of portage supports it.
# This is because some ebuild (gcc) do not use $S as buildroot.
if test "$PWORKDIR"; then
S="$PWORKDIR"
fi
# We do not want portage's build root ($S) present.
my_little_ninja_foo_2=`echo $deplib |$EGREP -e "$S"`
# We do not want portage's install root ($D) present.
my_little_ninja_foo_3=`echo $deplib |$EGREP -e "$D"`
if test -n "$my_little_ninja_foo_2" && test "$S"; then
mynewdependency_lib=""
elif test -n "$my_little_ninja_foo_3" && test "$D"; then
eval mynewdependency_lib=`echo "$deplib" |sed -e "s:$D:/:g" -e 's:/\+:/:g'`
else
mynewdependency_lib="$deplib"
fi
else
mynewdependency_lib="$deplib"
fi
# Do not add duplicates
if test "$mynewdependency_lib"; then
my_little_ninja_foo_4=`echo $newdependency_libs |$EGREP -e "$mynewdependency_lib"`
if test -z "$my_little_ninja_foo_4"; then
newdependency_libs="$newdependency_libs $mynewdependency_lib"
fi
fi
;; ;;
*) newdependency_libs="$newdependency_libs $deplib" ;;
esac esac
done done
dependency_libs="$newdependency_libs" dependency_libs="$newdependency_libs"
...@@ -5786,10 +5768,6 @@ fi\ ...@@ -5786,10 +5768,6 @@ fi\
case $host,$output,$installed,$module,$dlname in case $host,$output,$installed,$module,$dlname in
*cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;; *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;;
esac esac
# Do not add duplicates
if test "$installed" = yes && test "$D"; then
install_libdir=`echo "$install_libdir" |sed -e "s:$D:/:g" -e 's:/\+:/:g'`
fi
$echo > $output "\ $echo > $output "\
# $outputname - a libtool library file # $outputname - a libtool library file
# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP # Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
...@@ -6545,7 +6523,7 @@ relink_command=\"$relink_command\"" ...@@ -6545,7 +6523,7 @@ relink_command=\"$relink_command\""
fi fi
# Restore saved environment variables # Restore saved environment variables
for lt_var in LANG LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
do do
eval "if test \"\${save_$lt_var+set}\" = set; then eval "if test \"\${save_$lt_var+set}\" = set; then
$lt_var=\$save_$lt_var; export $lt_var $lt_var=\$save_$lt_var; export $lt_var
......
...@@ -19,30 +19,47 @@ libgraph_tool_LTLIBRARIES = libgraph_tool.la ...@@ -19,30 +19,47 @@ libgraph_tool_LTLIBRARIES = libgraph_tool.la
libgraph_tool_la_includedir = $(pythondir)/graph_tool/include libgraph_tool_la_includedir = $(pythondir)/graph_tool/include
libgraph_tool_la_SOURCES = \ libgraph_tool_la_SOURCES = \
graph.hh\ graph_assortativity.cc \
graph.cc\ graph_betweenness.cc \
graph_python_interface.cc\ graph_bind.cc \
graph_properties.cc\ graph.cc \
graph_correlations.cc\ graph_clustering.cc \
graph_edge_correlations.cc\ graph_community.cc \
graph_correlations_combined.cc\ graph_community_network.cc \
graph_correlations_neighbours.cc\ graph_correlations.cc \
graph_assortativity.cc\ graph_correlations_combined.cc \
graph_clustering.cc\ graph_correlations_combined_corr.cc \
graph_extended_clustering.cc\ graph_correlations_imp1.cc \
graph_generation.cc\ graph_correlations_imp2.cc \
graph_distance.cc\ graph_correlations_imp3.cc \
graph_distance_sampled.cc\ graph_correlations_neighbours.cc \
graph_reciprocity.cc\ graph_correlations_neighbours_imp1.cc \
graph_minimum_spanning_tree.cc\ graph_correlations_neighbours_imp2.cc \
graph_community.cc\ graph_correlations_neighbours_imp3.cc \
graph_community_network.cc\ graph_correlations_neighbours_imp4.cc \
graph_line_graph.cc\ graph_correlations_neighbours_imp5.cc \
graph_betweenness.cc\ graph_correlations_neighbours_imp6.cc \
graph_rewiring.cc\ graph_distance.cc \
graph_layout.cc\ graph_distance_sampled.cc \
graph_io.cc\ graph_edge_correlations.cc \
graph_bind.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_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\ graphml.cpp\
read_graphviz_spirit.cpp\ read_graphviz_spirit.cpp\
../boost-workaround/boost/graph/filtered_graph.hpp\ ../boost-workaround/boost/graph/filtered_graph.hpp\
...@@ -50,16 +67,42 @@ libgraph_tool_la_SOURCES = \ ...@@ -50,16 +67,42 @@ libgraph_tool_la_SOURCES = \
../boost-workaround/boost/graph/graphml.hpp ../boost-workaround/boost/graph/graphml.hpp
libgraph_tool_la_include_HEADERS = \ libgraph_tool_la_include_HEADERS = \
graph_adaptor.hh\ graph_adaptor.hh \
graph.hh\ graph_assortativity.hh \
graph_filtering.hh\ graph_clustering.hh \
graph_python_interface.hh\ graph_community.hh \
graph_selectors.hh\ graph_community_network.hh \
graph_properties.hh\ graph_correlations_combined.hh \
shared_map.hh\ graph_correlations.hh \
histogram.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 \
mpl_nested_loop.hh \
shared_map.hh \
../../config.h ../../config.h
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):
$(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_la_LIBADD = \
$(PYTHON_LDFLAGS) \ $(PYTHON_LDFLAGS) \
$(BOOST_LDFLAGS) \ $(BOOST_LDFLAGS) \
......
This diff is collapsed.
...@@ -21,12 +21,16 @@ ...@@ -21,12 +21,16 @@
#include <boost/graph/graph_traits.hpp> #include <boost/graph/graph_traits.hpp>
#include <boost/graph/adjacency_list.hpp> #include <boost/graph/adjacency_list.hpp>
#include <boost/graph/filtered_graph.hpp>
#include <boost/vector_property_map.hpp> #include <boost/vector_property_map.hpp>
#include <boost/dynamic_property_map.hpp> #include <boost/dynamic_property_map.hpp>
#include <boost/variant.hpp> #include <boost/variant.hpp>
#include <boost/python/object.hpp> #include <boost/python/object.hpp>
#include <boost/python/dict.hpp> #include <boost/python/dict.hpp>
#include <boost/lambda/lambda.hpp> #include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>
#include "histogram.hh" #include "histogram.hh"
#include "config.h" #include "config.h"
#include "graph_properties.hh" #include "graph_properties.hh"
...@@ -41,6 +45,15 @@ using namespace boost; ...@@ -41,6 +45,15 @@ using namespace boost;
// the external world will manipulate the graph. All the algorithms should be // the external world will manipulate the graph. All the algorithms should be
// registered here. This class will be exported to python in graph_bind.hh // registered here. This class will be exported to python in graph_bind.hh
namespace detail
{
// Generic graph_action functor. See graph_filtering.hh for details.
template <class Action, class GraphViews,
class TR1=boost::mpl::vector<>, class TR2=boost::mpl::vector<>,
class TR3=boost::mpl::vector<>, class TR4=boost::mpl::vector<> >
struct graph_action;
}
// default visibility is necessary for related typeinfo objects to work across // default visibility is necessary for related typeinfo objects to work across
// DSO boundaries // DSO boundaries
#pragma GCC visibility push(default) #pragma GCC visibility push(default)
...@@ -56,7 +69,6 @@ public: ...@@ -56,7 +69,6 @@ public:
IN_DEGREE, IN_DEGREE,
OUT_DEGREE, OUT_DEGREE,
TOTAL_DEGREE, // in + out TOTAL_DEGREE, // in + out
SCALAR // scalar vertex property
}; };
typedef variant<degree_t,string> deg_t; // useful when function also expects typedef variant<degree_t,string> deg_t; // useful when function also expects
...@@ -73,16 +85,10 @@ public: ...@@ -73,16 +85,10 @@ public:
void SetReversed(bool reversed) {_reversed = reversed;} void SetReversed(bool reversed) {_reversed = reversed;}
bool GetReversed() const {return _reversed;} bool GetReversed() const {return _reversed;}
// graph filtering // graph filtering
void SetVertexFilterProperty(string property); void SetVertexFilterProperty(string property, bool invert);
void SetVertexFilterRange(pair<double,double> allowed_range,
pair<bool,bool> include, bool invert);
bool IsVertexFilterActive() const; bool IsVertexFilterActive() const;
void SetEdgeFilterProperty(string property, bool invert);
void SetEdgeFilterProperty(string property);
void SetEdgeFilterRange(pair<double,double> allowed_range,
pair<bool,bool> include, bool invert);
bool IsEdgeFilterActive() const; bool IsEdgeFilterActive() const;
...@@ -92,15 +98,13 @@ public: ...@@ -92,15 +98,13 @@ public:
void RemoveGraphProperty(string property); void RemoveGraphProperty(string property);
void InsertEdgeIndexProperty(string property); void InsertEdgeIndexProperty(string property);
void InsertVertexIndexProperty(string property); void InsertVertexIndexProperty(string property);
void EditVertexProperty(string property, string type, python::object op, void AddVertexProperty(string property, string type);
python::object g); void AddEdgeProperty(string property, string type);
void EditEdgeProperty(string property, string type, python::object op, void AddGraphProperty(string property, string type);
python::object g);
void EditGraphProperty(string property, string type, python::object op,
python::object g);
void ReIndexEdges(); void ReIndexEdges();
void PurgeVertices(); // removes filtered vertices void PurgeVertices(); // removes filtered vertices
void PurgeEdges(); // removes filtered edges void PurgeEdges(); // removes filtered edges
void Clear();
void RandomRewire(std::string strat, bool self_loops, bool parallel_edges, void RandomRewire(std::string strat, bool self_loops, bool parallel_edges,
size_t seed); size_t seed);
...@@ -183,10 +187,13 @@ public: ...@@ -183,10 +187,13 @@ public:
void ComputeGraphLayoutGursoy(string prop, string weight, string topology, void ComputeGraphLayoutGursoy(string prop, string weight, string topology,
size_t iter = 0, size_t seed = 4357); size_t iter = 0, size_t seed = 4357);
void ComputeGraphLayoutSpringBlock(string prop, string weight, string type, void ComputeGraphLayoutSpringBlock(string prop, string weight