Commit cb15708b authored by Tiago Peixoto's avatar Tiago Peixoto
Browse files

Some reorganization and change check_filter() to run_action()

parent db440664
......@@ -389,11 +389,9 @@ size_t GraphInterface::GetNumberOfVertices() const
{
size_t n = 0;
if (IsVertexFilterActive())
check_filter(*this,var(n)=bind<size_t>(HardNumVertices(),_1),
reverse_check(),directed_check());
run_action(*this,var(n)=bind<size_t>(HardNumVertices(),_1));
else
check_filter(*this,var(n)=bind<size_t>(SoftNumVertices(),_1),
reverse_check(),directed_check());
run_action(*this,var(n)=bind<size_t>(SoftNumVertices(),_1));
return n;
}
......@@ -404,11 +402,9 @@ size_t GraphInterface::GetNumberOfEdges() const
{
size_t n = 0;
if (IsEdgeFilterActive() || IsVertexFilterActive())
check_filter(*this,var(n)=bind<size_t>(HardNumEdges(),_1),
reverse_check(),directed_check());
run_action(*this,var(n)=bind<size_t>(HardNumEdges(),_1));
else
check_filter(*this,var(n)=bind<size_t>(SoftNumEdges(),_1),
reverse_check(),directed_check());
run_action(*this,var(n)=bind<size_t>(SoftNumEdges(),_1));
return n;
}
......@@ -441,7 +437,7 @@ struct get_vertex_histogram
struct choose_vertex_histogram
{
choose_vertex_histogram(const GraphInterface& g, GraphInterface::deg_t deg,
GraphInterface::hist_t& hist)
hist_t& hist)
: _g(g), _hist(hist)
{
tie(_deg, _deg_name) = get_degree_type(deg);
......@@ -452,20 +448,19 @@ struct choose_vertex_histogram
if (mpl::at<degree_selector_index,DegreeSelector>::type::value == _deg)
{
DegreeSelector selector(_deg_name, _g, true);
check_filter(_g, bind<void>(get_vertex_histogram<DegreeSelector>
(selector), _1, var(_hist)),
reverse_check(),directed_check());
run_action(_g, bind<void>(get_vertex_histogram<DegreeSelector>
(selector), _1, var(_hist)));
}
}
const GraphInterface &_g;
GraphInterface::hist_t &_hist;
hist_t &_hist;
GraphInterface::degree_t _deg;
string _deg_name;
};
// this will return the vertex histogram of degrees or scalar properties
GraphInterface::hist_t
hist_t
GraphInterface::GetVertexHistogram(GraphInterface::deg_t deg) const
{
hist_t hist;
......@@ -522,14 +517,13 @@ struct get_edge_histogram
// returns the histogram of a given edge property
GraphInterface::hist_t GraphInterface::GetEdgeHistogram(string property) const
hist_t GraphInterface::GetEdgeHistogram(string property) const
{
hist_t hist;
try
{
scalarS prop(property, *this, false);
check_filter(*this, bind<void>(get_edge_histogram(prop), _1, var(hist)),
reverse_check(),directed_check());
run_action(*this, bind<void>(get_edge_histogram(prop), _1, var(hist)));
}
catch (dynamic_get_failure &e)
{
......@@ -576,8 +570,7 @@ void GraphInterface::LabelComponents(string prop)
typedef vector_property_map<size_t, vertex_index_map_t> comp_map_t;
comp_map_t comp_map(_vertex_index);
check_filter(*this, bind<void>(label_components(), _1, comp_map),
reverse_check(), directed_check());
run_action(*this, bind<void>(label_components(), _1, comp_map));
try
{
......@@ -634,17 +627,15 @@ void GraphInterface::LabelParallelEdges(string property)
DynamicPropertyMapWrap<size_t,edge_t>
parallel_map(find_property_map(_properties, property,
typeid(edge_t)));
check_filter(*this, bind<void>(label_parallel_edges(), _1, _edge_index,
parallel_map),
reverse_check(), directed_check());
run_action(*this, bind<void>(label_parallel_edges(), _1, _edge_index,
parallel_map));
}
catch (property_not_found)
{
typedef vector_property_map<size_t,edge_index_map_t> parallel_map_t;
parallel_map_t parallel_map(_edge_index);
check_filter(*this, bind<void>(label_parallel_edges(), _1, _edge_index,
parallel_map),
reverse_check(), directed_check());
run_action(*this, bind<void>(label_parallel_edges(), _1, _edge_index,
parallel_map));
_properties.property(property, parallel_map);
}
}
......
......@@ -19,7 +19,6 @@
#ifndef GRAPH_HH
#define GRAPH_HH
#include <tr1/unordered_map>
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/adjacency_list.hpp>
#include <boost/vector_property_map.hpp>
......@@ -47,39 +46,76 @@ public:
GraphInterface();
~GraphInterface();
// this enum specifies all the different types of degree
enum degree_t
{
IN_DEGREE,
OUT_DEGREE,
TOTAL_DEGREE,
SCALAR
TOTAL_DEGREE, // in + out
SCALAR // scalar vertex property
};
// histogram types
typedef tr1::unordered_map<double,double> hist_t;
typedef tr1::unordered_map<pair<double,double>,double,
hash<pair<double,double> > > hist2d_t;
typedef tr1::unordered_map<tuple<double,double,double>,double,
hash<tuple<double,double,double> > > hist3d_t;
typedef tr1::unordered_map<double,pair<double,double> > avg_corr_t;
typedef variant<degree_t,string> deg_t; // useful when function also expects
// a scalar vertex property
typedef variant<degree_t,string> deg_t;
//
// Basic manipulation
//
//graph generation
void GenerateCorrelatedConfigurationalModel
(size_t N, python::object ppjk, python::object pceil_pjk,
python::object pinv_ceil_pjk, double ceil_pjk_bound,
python::object pcorr, python::object pceil_corr,
python::object pinv_ceil_corr, double ceil_corr_bound,
bool undirected_corr, size_t seed, bool verbose);
// basic stats
size_t GetNumberOfVertices() const;
size_t GetNumberOfEdges() const;
void SetDirected(bool directed) {_directed = directed;}
bool GetDirected() const {return _directed;}
void SetReversed(bool reversed) {_reversed = reversed;}
bool GetReversed() const {return _reversed;}
// graph filtering
void SetVertexFilterProperty(string property);
void SetVertexFilterRange(pair<double,double> allowed_range,
pair<bool,bool> include, bool invert);
bool IsVertexFilterActive() const;
void SetEdgeFilterProperty(string property);
void SetEdgeFilterRange(pair<double,double> allowed_range,
pair<bool,bool> include, bool invert);
bool IsEdgeFilterActive() const;
// graph modification
void RemoveVertexProperty(string property);
void RemoveEdgeProperty(string property);
void RemoveGraphProperty(string property);
void InsertEdgeIndexProperty(string property);
void InsertVertexIndexProperty(string property);
void EditVertexProperty(string property, string type, python::object op,
python::object g);
void EditEdgeProperty(string property, string type, python::object op,
python::object g);
void EditGraphProperty(string property, string type, python::object op,
python::object g);
void ReIndexEdges();
void PurgeVertices(); // removes filtered vertices
void PurgeEdges(); // removes filtered edges
void RandomRewire(std::string strat, bool self_loops, bool parallel_edges,
size_t seed);
// i/o
void WriteToFile(string s);
void WriteToFile(string s, string format);
void ReadFromFile(string s);
void ReadFromFile(string s, string format);
//
// Algorithms
// Below are all the algorithms that operate somehow on the graph
//
// basic statistics
hist_t GetVertexHistogram(deg_t degree) const;
hist_t GetEdgeHistogram(string property) const;
//correlations
// correlations
hist2d_t GetCombinedVertexHistogram(deg_t degree1, deg_t degree2) const;
avg_corr_t GetAverageCombinedVertexCorrelation(deg_t degree1,
deg_t degree2)const;
......@@ -91,11 +127,11 @@ public:
deg_t neighbour_degree,
string weight) const;
// mixing
// vertex mixing
pair<double,double> GetAssortativityCoefficient(deg_t deg) const;
pair<double,double> GetScalarAssortativityCoefficient(deg_t deg) const;
//clustering
// clustering
void SetLocalClusteringToProperty(string property);
pair<double,double> GetGlobalClustering();
void SetExtendedClusteringToProperty(string property_prefix,
......@@ -115,7 +151,7 @@ public:
double GetCentralPointDominance(string vertex_betweenness);
// community structure
enum comm_corr_t
enum comm_corr_t // null model correlation type
{
ERDOS_REYNI,
UNCORRELATED,
......@@ -127,57 +163,24 @@ public:
size_t seed, bool verbose, string history_file,
string weight, string property);
double GetModularity(string weight, string property);
// TODO: this should return a GraphInterface type
void GetCommunityNetwork(string property, string size_property,
string out_file, string format) const;
void RandomRewire(std::string strat, bool self_loops, bool parallel_edges,
size_t seed);
// filtering
void SetDirected(bool directed) {_directed = directed;}
bool GetDirected() const {return _directed;}
void SetReversed(bool reversed) {_reversed = reversed;}
bool GetReversed() const {return _reversed;}
void SetVertexFilterProperty(string property);
void SetVertexFilterRange(pair<double,double> allowed_range,
pair<bool,bool> include, bool invert);
bool IsVertexFilterActive() const;
void SetEdgeFilterProperty(string property);
void SetEdgeFilterRange(pair<double,double> allowed_range,
pair<bool,bool> include, bool invert);
bool IsEdgeFilterActive() const;
// modification
void RemoveVertexProperty(string property);
void RemoveEdgeProperty(string property);
void RemoveGraphProperty(string property);
void InsertEdgeIndexProperty(string property);
void InsertVertexIndexProperty(string property);
void EditVertexProperty(string property, string type, python::object op,
python::object g);
void EditEdgeProperty(string property, string type, python::object op,
python::object g);
void EditGraphProperty(string property, string type, python::object op,
python::object g);
void ReIndexEdges();
void PurgeVertices();
void PurgeEdges();
// Graph generation
void GenerateCorrelatedConfigurationalModel
(size_t N, python::object ppjk, python::object pceil_pjk,
python::object pinv_ceil_pjk, double ceil_pjk_bound,
python::object pcorr, python::object pceil_corr,
python::object pinv_ceil_corr, double ceil_corr_bound,
bool undirected_corr, size_t seed, bool verbose);
// layout
// graph layout
void ComputeGraphLayoutGursoy(string prop, string weight, string topology,
size_t iter = 0, size_t seed = 4357);
void ComputeGraphLayoutSpringBlock(string prop, string weight, string type,
size_t iter = 0, size_t seed = 4357);
// i/o
void WriteToFile(string s);
void WriteToFile(string s, string format);
void ReadFromFile(string s);
void ReadFromFile(string s, string format);
// python interface
python::object Vertices() const;
python::object Edges() const;
......@@ -199,6 +202,10 @@ public:
// signal handling
void InitSignalHandling();
//
// Internal types
//
// the following defines the edges' internal properties
typedef property<edge_index_t, size_t> EdgeProperty;
......@@ -212,15 +219,32 @@ public:
typedef graph_traits<multigraph_t>::edge_descriptor edge_t;
private:
template <class GraphInterfaceType, class Action, class ReverseCheck,
// The following function is very central to the implementation of the above
// member functions. Most of the algorithms are implemented as template
// functors, which must be run on the correct version of the graph, i.e.,
// filtered, unfiltered, directed, undirected, etc. The functor in question
// must be fed to the function below as the "a" variable, which will take
// care of business, selection the correct implementation. The ReverseCheck
// and DirectedCheck below are utility types which allow for limiting the
// implementation generation when you want it to be confined for only
// specific graph types. See graph_filtering.hh for details.
template <class GraphInterfaceType, class Action, class ReverseCheck,
class DirectedCheck>
friend void check_filter(GraphInterfaceType &g, Action a,
ReverseCheck, DirectedCheck, bool run_all=false);
friend void run_action(GraphInterfaceType &g, Action a,
ReverseCheck, DirectedCheck, bool run_all=false);
// useful overload for common case where all graph types should be probed
template <class GraphInterfaceType, class Action>
friend void run_action(GraphInterfaceType &g, Action a);
friend class scalarS;
// this is the main graph
multigraph_t _mg;
// reverse and directed states
bool _reversed;
bool _directed;
......@@ -268,7 +292,6 @@ private:
pair<GraphInterface::degree_t,string>
get_degree_type(GraphInterface::deg_t degree);
// GraphException
// This is the main exception which will be thrown the outside world, when
// things go wrong
......
......@@ -132,10 +132,9 @@ struct choose_assortativity_coefficient
if (mpl::at<degree_selector_index, DegreeSelector>::type::value == _deg)
{
DegreeSelector deg(_deg_name, _g, true);
check_filter(_g, bind<void>(get_assortativity_coefficient
<DegreeSelector>(deg),
_1, var(_a), var(_a_err)),
reverse_check(),directed_check());
run_action(_g, bind<void>(get_assortativity_coefficient
<DegreeSelector>(deg),
_1, var(_a), var(_a_err)));
}
}
......@@ -277,10 +276,9 @@ struct choose_scalar_assortativity_coefficient
if (mpl::at<degree_selector_index, DegreeSelector>::type::value == _deg)
{
DegreeSelector deg(_deg_name, _g, true);
check_filter(_g, bind<void>(get_scalar_assortativity_coefficient
run_action(_g, bind<void>(get_scalar_assortativity_coefficient
<DegreeSelector>(deg),
_1, var(_a), var(_a_err)),
reverse_check(),directed_check());
_1, var(_a), var(_a_err)));
}
}
......
......@@ -149,23 +149,22 @@ void GraphInterface::GetBetweenness(string weight, string edge_betweenness,
if (weight != "")
{
bool found = false;
check_filter(*this, bind<void>(choose_weight_map(), _1,
var(_vertex_index), var(_edge_index),
var(weight), var(_properties),
var(edge_betweenness_map),
var(vertex_betweenness_map),
var(found)),
reverse_check(), directed_check());
run_action(*this, bind<void>(choose_weight_map(), _1,
var(_vertex_index), var(_edge_index),
var(weight), var(_properties),
var(edge_betweenness_map),
var(vertex_betweenness_map),
var(found)));
if (!found)
throw GraphException("error getting scalar property: " + weight);
}
else
{
check_filter(*this, bind<void>(get_betweenness(), _1,
var(_vertex_index),
var(edge_betweenness_map),
var(vertex_betweenness_map)),
reverse_check(), directed_check());
run_action(*this, bind<void>(get_betweenness(), _1,
var(_vertex_index),
var(edge_betweenness_map),
var(vertex_betweenness_map)),
reverse_check(), directed_check());
}
if (vertex_betweenness != "")
......@@ -221,8 +220,8 @@ double GraphInterface::GetCentralPointDominance(string vertex_betweenness)
bool directed = this->GetDirected();
this->SetReversed(false);
this->SetDirected(true);
check_filter(*this, bind<void>(get_central_point_dominance(), _1,
var(betweenness), var(c)),
run_action(*this, bind<void>(get_central_point_dominance(), _1,
var(betweenness), var(c)),
never_reversed(), always_directed());
this->SetReversed(reversed);
this->SetDirected(directed);
......
......@@ -347,14 +347,10 @@ BOOST_PYTHON_MODULE(libgraph_tool)
to_python_converter<pos_t, pos_t_to_tuple>();
pos_t_from_tuple();
pair_from_tuple<bool,bool>();
to_python_converter<GraphInterface::hist_t,
hist_to_dict<GraphInterface::hist_t> >();
to_python_converter<GraphInterface::hist2d_t,
hist_to_dict<GraphInterface::hist2d_t> >();
to_python_converter<GraphInterface::hist3d_t,
hist_to_dict<GraphInterface::hist3d_t> >();
to_python_converter<GraphInterface::avg_corr_t,
hist_to_dict<GraphInterface::avg_corr_t> >();
to_python_converter<hist_t,hist_to_dict<hist_t> >();
to_python_converter<hist2d_t,hist_to_dict<hist2d_t> >();
to_python_converter<hist3d_t,hist_to_dict<hist3d_t> >();
to_python_converter<avg_corr_t,hist_to_dict<avg_corr_t> >();
class_<LibInfo>("mod_info")
.add_property("name", &LibInfo::GetName)
......
......@@ -148,9 +148,9 @@ GraphInterface::GetGlobalClustering()
double c, c_err;
bool directed = _directed;
_directed = false;
check_filter(*this, bind<void>(get_global_clustering(), _1, var(c),
run_action(*this, bind<void>(get_global_clustering(), _1, var(c),
var(c_err)),
reverse_check(), always_undirected());
reverse_check(), always_undirected());
_directed = directed;
return make_pair(c,c_err);
}
......@@ -202,9 +202,9 @@ void GraphInterface::SetLocalClusteringToProperty(string property)
bool directed = _directed;
_directed = false;
check_filter(*this, bind<void>(set_clustering_to_property(), _1,
var(clust_map)),
reverse_check(), always_undirected());
run_action(*this, bind<void>(set_clustering_to_property(), _1,
var(clust_map)),
reverse_check(), always_undirected());
_directed = directed;
try
......
......@@ -20,6 +20,7 @@
#include <boost/lambda/bind.hpp>
#include <boost/random.hpp>
#include <tr1/unordered_set>
#include <fstream>
#include <iomanip>
#include "graph.hh"
......@@ -698,9 +699,9 @@ void GraphInterface::GetCommunityStructure(double gamma, comm_corr_t corr,
{
DynamicPropertyMapWrap<size_t,vertex_t>
old_s(find_property_map(_properties, property, typeid(vertex_t)));
check_filter(*this, bind<void>(copy_spins(), _1, var(old_s),
var(comm_map)),
reverse_check(), always_undirected());
run_action(*this, bind<void>(copy_spins(), _1, var(old_s),
var(comm_map)),
reverse_check(), always_undirected());
RemoveVertexProperty(property);
new_spins = false;
}
......@@ -723,27 +724,26 @@ void GraphInterface::GetCommunityStructure(double gamma, comm_corr_t corr,
get_static_property_map
<vector_property_map<double,edge_index_map_t> >
(weight_prop);
check_filter(*this, bind<void>(get_communities_selector(corr),
_1, var(weight_map),
var(comm_map),
gamma, n_iter,
make_pair(Tmin, Tmax),
make_pair(Nspins, new_spins),
seed,
make_pair(verbose,history_file)),
reverse_check(), always_undirected());
run_action(*this, bind<void>(get_communities_selector(corr),
_1, var(weight_map),
var(comm_map), gamma, n_iter,
make_pair(Tmin, Tmax),
make_pair(Nspins, new_spins),
seed,
make_pair(verbose,history_file)),
reverse_check(), always_undirected());
}
else
{
DynamicPropertyMapWrap<double,edge_t> weight_map(weight_prop);
check_filter(*this, bind<void>(get_communities_selector(corr),
_1, var(weight_map),
var(comm_map), gamma, n_iter,
make_pair(Tmin, Tmax),
make_pair(Nspins, new_spins),
seed,
make_pair(verbose,history_file)),
reverse_check(), always_undirected());
run_action(*this, bind<void>(get_communities_selector(corr),
_1, var(weight_map),
var(comm_map), gamma, n_iter,
make_pair(Tmin, Tmax),
make_pair(Nspins, new_spins),
seed,
make_pair(verbose,history_file)),
reverse_check(), always_undirected());
}
}
catch (property_not_found& e)
......@@ -755,12 +755,12 @@ void GraphInterface::GetCommunityStructure(double gamma, comm_corr_t corr,
else
{
ConstantPropertyMap<double,edge_t> weight_map(1.0);
check_filter(*this, bind<void>(get_communities_selector(corr), _1,
var(weight_map), var(comm_map), gamma,
n_iter, make_pair(Tmin, Tmax),
make_pair(Nspins, new_spins), seed,
make_pair(verbose, history_file)),
reverse_check(), always_undirected());
run_action(*this, bind<void>(get_communities_selector(corr), _1,
var(weight_map), var(comm_map), gamma,
n_iter, make_pair(Tmin, Tmax),
make_pair(Nspins, new_spins), seed,
make_pair(verbose, history_file)),
reverse_check(), always_undirected());
}
_directed = directed;
......@@ -819,17 +819,17 @@ double GraphInterface::GetModularity(string weight, string property)
dynamic_property_map& weight_prop =
find_property_map(_properties, weight, typeid(edge_t));
DynamicPropertyMapWrap<double,edge_t> weight_map(weight_prop);
check_filter(*this, bind<void>(get_modularity(), _1,
var(weight_map), var(comm_map),
var(modularity)),
run_action(*this, bind<void>(get_modularity(), _1,
var(weight_map), var(comm_map),
var(modularity)),
reverse_check(), always_undirected());
}
else
{
ConstantPropertyMap<double,edge_t> weight_map(1.0);
check_filter(*this, bind<void>(get_modularity(), _1,
var(weight_map), var(comm_map),
var(modularity)),
run_action(*this, bind<void>(get_modularity(), _1,
var(weight_map), var(comm_map),
var(modularity)),
reverse_check(), always_undirected());
}
}
......
......@@ -29,6 +29,11 @@
#include "graph_properties.hh"
#include <boost/graph/graphviz.hpp>
#include <boost/graph/graphml.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/iostreams/filtering_stream.hpp>
#include <boost/iostreams/filter/gzip.hpp>
#include <boost/iostreams/filter/bzip2.hpp>
#include <boost/iostreams/device/file.hpp>
using namespace std;
using namespace boost;
......@@ -228,10 +233,9 @@ void GraphInterface::GetCommunityNetwork(string property, string size_property,
auto_ptr<dynamic_property_map>