Commit aca4479d authored by Tiago Peixoto's avatar Tiago Peixoto

add support for weights in degree correlations


git-svn-id: https://svn.forked.de/graph-tool/trunk@63 d4600afd-f417-0410-95de-beed9576f240
parent 9795ffe9
......@@ -120,8 +120,8 @@ statistics.add_option("--line-graph", action="callback", callback=push_option, t
correlations = parser.add_option_group("Correlations")
correlations.add_option("--average-combined-vertex-correlation", action="callback", callback=push_option, type="string", metavar="DEGREE1|DEGREE2|FILE", help="get the average of DEGREE2 in function of DEGREE1. Scalar properties are also accepted as DEGREE1 or DEGREE2")
correlations.add_option("--vertex-correlation-histogram", action="callback", callback=push_option, type="string", metavar="DEGREE1|DEGREE2|FILE", help="get the degree correlation histogram. Scalar properties are also accepted in place of DEGREE")
correlations.add_option("--average-nearest-neighbours-correlation", action="callback", callback=push_option, type="string", metavar="ORIGIN-DEGREE|DEGREE|FILE", help="get the average nearest neighbours correlation")
correlations.add_option("--vertex-correlation-histogram", action="callback", callback=push_option, type="string", metavar="DEGREE1|DEGREE2[|WEIGHT]|FILE", help="get the degree correlation histogram. Scalar properties are also accepted in place of DEGREE. An optional edge weight property can be passed by WEIGHT")
correlations.add_option("--average-nearest-neighbours-correlation", action="callback", callback=push_option, type="string", metavar="ORIGIN-DEGREE|DEGREE[|WEIGHT]|FILE", help="get the average nearest neighbours correlation. An optional edge weight property can be passed by WEIGHT")
correlations.add_option("--edge-vertex-correlation-histogram", action="callback", callback=push_option, type="string", metavar="DEGREE1|EDGE-PROP|DEGREE2|FILE", help="get the source degree vs. edge scalar vs. target degree correlation histogram. Scalar properties are also accepted in place of DEGREE-TYPE")
correlations.add_option("--assortativity-coefficient", action="callback", callback=push_option, type="string", metavar="DEGREE|FILE", help="get the assortativity coefficient. Scalar properties are also accepted in place of DEGREE")
correlations.add_option("--scalar-assortativity-coefficient", action="callback", callback=push_option, type="string", metavar="DEGREE|FILE", help="get the scalar assortativity coefficient. Scalar properties are also accepted in place of DEGREE")
......@@ -500,13 +500,19 @@ def parse_option(opt, just_file=False):
graph.GetLineGraph(values[0], format)
elif opt.name == "vertex-correlation-histogram":
values = parse_values(opt.value)
if len(values) != 3:
if len(values) < 3 or len(values) > 4:
raise OptionError(opt.name, "invalid value '%s'" % opt.value)
deg1 = degree(values[0])
deg2 = degree(values[1])
if len(values) == 4:
weight = values[2]
file_name = values[3]
else:
weight = ""
file_name = values[2]
if just_file:
return values[2]
return (graph.GetVertexCorrelationHistogram(deg1,deg2), values[2])
return file_name
return (graph.GetVertexCorrelationHistogram(deg1, deg2, weight), file_name)
elif opt.name == "edge-vertex-correlation-histogram":
values = parse_values(opt.value)
if len(values) != 4:
......@@ -518,13 +524,19 @@ def parse_option(opt, just_file=False):
return (graph.GetEdgeVertexCorrelationHistogram(deg1,values[1],deg2), values[3])
elif opt.name == "average-nearest-neighbours-correlation":
values = parse_values(opt.value)
if len(values) != 3:
if len(values) < 3 or len(values) > 4:
raise OptionError(opt.name, "invalid value '%s'" % opt.value)
deg1 = degree(values[0])
deg2 = degree(values[1])
if len(values) == 4:
weight = values[2]
file_name = values[3]
else:
weight = ""
file_name = values[2]
if just_file:
return values[2]
return (graph.GetAverageNearestNeighboursCorrelation(deg1,deg2), values[2])
return file_name
return (graph.GetAverageNearestNeighboursCorrelation(deg1, deg2, weight), file_name)
elif opt.name == "assortativity-coefficient":
values = parse_values(opt.value)
if len(values) != 2:
......
......@@ -26,6 +26,7 @@ libgraph_tool_la_SOURCES = \
graph_properties.hh\
graph_properties.cc\
graph_correlations.cc\
graph_edge_correlations.cc\
graph_correlations_combined.cc\
graph_correlations_neighbours.cc\
graph_assortativity.cc\
......
......@@ -54,8 +54,8 @@ public:
// histogram types
typedef std::tr1::unordered_map<double,size_t> hist_t;
typedef std::tr1::unordered_map<std::pair<double,double>,size_t, boost::hash<std::pair<double,double> > > hist2d_t;
typedef std::tr1::unordered_map<boost::tuple<double,double,double>,size_t, boost::hash<boost::tuple<double,double,double> > > hist3d_t;
typedef std::tr1::unordered_map<std::pair<double,double>,double, boost::hash<std::pair<double,double> > > hist2d_t;
typedef std::tr1::unordered_map<boost::tuple<double,double,double>,double_t, boost::hash<boost::tuple<double,double,double> > > hist3d_t;
typedef std::tr1::unordered_map<double,std::pair<double,double> > avg_corr_t;
typedef boost::variant<degree_t,std::string> deg_t;
......@@ -76,9 +76,9 @@ public:
//correlations
hist2d_t GetCombinedVertexHistogram(deg_t degree1, deg_t degree2) const;
avg_corr_t GetAverageCombinedVertexCorrelation(deg_t degree1, deg_t degree2) const;
hist2d_t GetVertexCorrelationHistogram(deg_t degree1, deg_t degree2) const;
hist2d_t GetVertexCorrelationHistogram(deg_t degree1, deg_t degree2, std::string weight) const;
hist3d_t GetEdgeVertexCorrelationHistogram(deg_t deg1, std::string scalar, deg_t deg2) const;
avg_corr_t GetAverageNearestNeighboursCorrelation(deg_t origin_degree, deg_t neighbour_degree) const;
avg_corr_t GetAverageNearestNeighboursCorrelation(deg_t origin_degree, deg_t neighbour_degree, std::string weight) const;
// mixing
std::pair<double,double> GetAssortativityCoefficient(deg_t deg) const;
......
......@@ -43,8 +43,8 @@ struct get_correlation_histogram
{
get_correlation_histogram(DegreeSelector1& deg1, DegreeSelector2& deg2): _deg1(deg1), _deg2(deg2) {}
template <class Graph, class Hist>
void operator()(Graph &g, Hist &hist) const
template <class Graph, class WeightMap, class Hist>
void operator()(Graph &g, WeightMap weight, Hist &hist) const
{
typename graph_traits<Graph>::edge_iterator e, e_begin, e_end;
tie(e_begin, e_end) = edges(g);
......@@ -53,11 +53,11 @@ struct get_correlation_histogram
typename Hist::key_type key;
key.first = _deg1(source(*e,g),g);
key.second = _deg2(target(*e,g),g);
hist[key]++;
hist[key] += typename Hist::value_type::second_type(get(weight, *e));
if(is_convertible<typename graph_traits<Graph>::directed_category, undirected_tag>::value)
{
swap(key.first, key.second);
hist[key]++;
hist[key] += get(weight, *e);
}
}
}
......@@ -70,12 +70,12 @@ struct get_correlation_histogram
// retrieves the degree correlation histogram
//==============================================================================
template <class SecondDegreeSelectors>
template <class WeightMap, class SecondDegreeSelectors>
struct choose_vertex_correlation_histogram
{
choose_vertex_correlation_histogram(const GraphInterface &g, GraphInterface::deg_t deg1,
choose_vertex_correlation_histogram(const GraphInterface &g, WeightMap weight, GraphInterface::deg_t deg1,
GraphInterface::deg_t deg2, GraphInterface::hist2d_t &hist)
: _g(g), _hist(hist)
: _g(g), _weight(weight), _hist(hist)
{
tie(_deg1, _deg_name1) = get_degree_type(deg1);
tie(_deg2, _deg_name2) = get_degree_type(deg2);
......@@ -84,7 +84,7 @@ struct choose_vertex_correlation_histogram
template <class DegreeSelector1>
struct check_second_degree
{
check_second_degree(choose_vertex_correlation_histogram<SecondDegreeSelectors> &parent):_parent(parent) {}
check_second_degree(choose_vertex_correlation_histogram<WeightMap,SecondDegreeSelectors> &parent):_parent(parent) {}
template <class DegreeSelector2>
void operator()(DegreeSelector2)
{
......@@ -92,11 +92,11 @@ struct choose_vertex_correlation_histogram
{
DegreeSelector1 deg1(_parent._deg_name1, _parent._g);
DegreeSelector2 deg2(_parent._deg_name2, _parent._g);
check_filter(_parent._g, bind<void>(get_correlation_histogram<DegreeSelector1,DegreeSelector2>(deg1,deg2), _1, var(_parent._hist)),
check_filter(_parent._g, bind<void>(get_correlation_histogram<DegreeSelector1,DegreeSelector2>(deg1,deg2), _1, var(_parent._weight), var(_parent._hist)),
reverse_check(),directed_check());
}
}
choose_vertex_correlation_histogram<SecondDegreeSelectors> _parent;
choose_vertex_correlation_histogram<WeightMap,SecondDegreeSelectors> _parent;
};
template <class DegreeSelector>
......@@ -105,7 +105,9 @@ struct choose_vertex_correlation_histogram
if (mpl::at<degree_selector_index,DegreeSelector>::type::value == _deg1)
mpl::for_each<SecondDegreeSelectors>(check_second_degree<DegreeSelector>(*this));
}
const GraphInterface &_g;
WeightMap _weight;
GraphInterface::hist2d_t &_hist;
GraphInterface::degree_t _deg1;
string _deg_name1;
......@@ -115,123 +117,43 @@ struct choose_vertex_correlation_histogram
};
GraphInterface::hist2d_t
GraphInterface::GetVertexCorrelationHistogram(GraphInterface::deg_t deg1, GraphInterface::deg_t deg2) const
GraphInterface::GetVertexCorrelationHistogram(GraphInterface::deg_t deg1, GraphInterface::deg_t deg2, string weight) const
{
hist2d_t hist;
typedef mpl::vector<in_degreeS, out_degreeS, total_degreeS, scalarS> degree_selectors;
try
{
mpl::for_each<degree_selectors>(choose_vertex_correlation_histogram<degree_selectors>(*this, deg1, deg2, hist));
}
catch (dynamic_get_failure &e)
{
throw GraphException("error getting scalar property: " + string(e.what()));
}
return hist;
}
//==============================================================================
// get_edge_correlation_histogram
// retrieves the generalized vertex-edge-vertex correlation histogram
//==============================================================================
template <class DegreeSelector1, class DegreeSelector2>
struct get_edge_correlation_histogram
{
get_edge_correlation_histogram(DegreeSelector1& deg1, DegreeSelector2& deg2, scalarS& scalar)
: _edge_scalar(scalar), _deg1(deg1), _deg2(deg2) {}
template <class Graph, class Hist>
void operator()(Graph &g, Hist &hist) const
try
{
typename graph_traits<Graph>::edge_iterator e, e_begin, e_end;
tie(e_begin, e_end) = edges(g);
for (e = e_begin; e != e_end; ++e)
if(weight != "")
{
typename Hist::key_type key;
get<0>(key) = _deg1(source(*e,g),g);
get<1>(key) = _edge_scalar(*e, g);
get<2>(key) = _deg2(target(*e,g),g);
hist[key]++;
if(is_convertible<typename graph_traits<Graph>::directed_category, undirected_tag>::value)
try
{
swap(get<0>(key), get<2>(key));
hist[key]++;
}
}
}
scalarS& _edge_scalar;
DegreeSelector1& _deg1;
DegreeSelector2& _deg2;
};
//==============================================================================
// GetEdgeVertexCorrelationHistogram(deg1, scalar, deg2)
// retrieves the degree-edge-degree correlation histogram
//==============================================================================
// FIXME: it would be good also to have a version for a static map (vector_property_map),
// but adding this makes GCC use more than 1 GB of RAM in my system.
template <class SecondDegreeSelectors>
struct choose_edge_vertex_correlation_histogram
{
choose_edge_vertex_correlation_histogram(const GraphInterface& g, GraphInterface::deg_t deg1, scalarS& edge_scalar,
GraphInterface::deg_t deg2, GraphInterface::hist3d_t& hist)
: _g(g), _edge_scalar(edge_scalar), _hist(hist)
{
tie(_deg1, _deg_name1) = get_degree_type(deg1);
tie(_deg2, _deg_name2) = get_degree_type(deg2);
}
template <class DegreeSelector1>
struct check_second_degree
{
check_second_degree(choose_edge_vertex_correlation_histogram<SecondDegreeSelectors> &parent):_parent(parent) {}
template <class DegreeSelector2>
void operator()(DegreeSelector2)
{
if (mpl::at<degree_selector_index,DegreeSelector2>::type::value == _parent._deg2)
dynamic_property_map& weight_prop = find_property_map(_properties, weight, typeid(graph_traits<multigraph_t>::edge_descriptor));
typedef DynamicPropertyMapWrap<double,graph_traits<multigraph_t>::edge_descriptor> weight_map_t;
weight_map_t weight_map(weight_prop);
mpl::for_each<degree_selectors>(choose_vertex_correlation_histogram<weight_map_t, degree_selectors>(*this, weight_map, deg1, deg2, hist));
}
catch (property_not_found& e)
{
DegreeSelector1 deg1(_parent._deg_name1, _parent._g);
DegreeSelector2 deg2(_parent._deg_name2, _parent._g);
check_filter(_parent._g, bind<void>(get_edge_correlation_histogram<DegreeSelector1,DegreeSelector2>(deg1,deg2,_parent._edge_scalar),
_1, var(_parent._hist)),
reverse_check(),directed_check());
throw GraphException("error getting scalar property: " + string(e.what()));
}
}
choose_edge_vertex_correlation_histogram<SecondDegreeSelectors> _parent;
};
template <class DegreeSelector>
void operator()(DegreeSelector)
{
if (mpl::at<degree_selector_index,DegreeSelector>::type::value == _deg1)
mpl::for_each<SecondDegreeSelectors>(check_second_degree<DegreeSelector>(*this));
}
const GraphInterface& _g;
scalarS& _edge_scalar;
GraphInterface::hist3d_t& _hist;
GraphInterface::degree_t _deg1;
string _deg_name1;
GraphInterface::degree_t _deg2;
string _deg_name2;
};
GraphInterface::hist3d_t
GraphInterface::GetEdgeVertexCorrelationHistogram(GraphInterface::deg_t deg1, string edge_scalar, GraphInterface::deg_t deg2) const
{
hist3d_t hist;
scalarS scalar(edge_scalar, *this);
try
{
typedef mpl::vector<in_degreeS, out_degreeS, total_degreeS, scalarS> degree_selectors;
mpl::for_each<degree_selectors>(choose_edge_vertex_correlation_histogram<degree_selectors>(*this, deg1, scalar, deg2, hist));
else
{
typedef ConstantPropertyMap<double,graph_traits<multigraph_t>::edge_descriptor> weight_map_t;
weight_map_t weight_map(1.0);
mpl::for_each<degree_selectors>(choose_vertex_correlation_histogram<weight_map_t, degree_selectors>(*this, weight_map, deg1, deg2, hist));
}
}
catch (dynamic_get_failure& e)
catch (dynamic_get_failure &e)
{
throw GraphException("error getting scalar property: " + string(e.what()));
}
return hist;
}
......@@ -44,10 +44,10 @@ struct get_average_nearest_neighbours_correlation
get_average_nearest_neighbours_correlation(DegreeSelectorOrigin& origin_deg, DegreeSelectorNeighbours& neighbours_deg)
: _origin_degree(origin_deg), _neighbours_degree(neighbours_deg) {}
template <class Graph, class AvgDeg>
void operator()(const Graph& g, AvgDeg& avg_deg) const
template <class Graph, class WeightMap, class AvgDeg>
void operator()(const Graph& g, WeightMap weight, AvgDeg& avg_deg) const
{
tr1::unordered_map<double,size_t> count;
tr1::unordered_map<double,double> count;
typename graph_traits<Graph>::vertex_iterator v, v_begin, v_end;
tie(v_begin,v_end) = vertices(g);
......@@ -59,15 +59,15 @@ struct get_average_nearest_neighbours_correlation
{
typename AvgDeg::value_type::second_type::first_type deg = _neighbours_degree(target(*e,g),g);
typename AvgDeg::key_type orig_deg = _origin_degree(*v,g);
avg_deg[orig_deg].first += deg;
avg_deg[orig_deg].first += deg*get(weight, *e);
avg_deg[orig_deg].second += deg*deg;
count[orig_deg]++;
count[orig_deg] += get(weight,*e);
}
}
for (typeof(avg_deg.begin()) iter = avg_deg.begin(); iter != avg_deg.end(); ++iter)
{
size_t N = count[iter->first];
double N = count[iter->first];
iter->second.first /= N;
if (N > 1)
iter->second.second = sqrt((iter->second.second - N*iter->second.first*iter->second.first)/(N*(N-1)));
......@@ -79,11 +79,11 @@ struct get_average_nearest_neighbours_correlation
DegreeSelectorNeighbours& _neighbours_degree;
};
template <class DegreeSelectors>
template <class WeightMap, class DegreeSelectors>
struct choose_average_nearest_neighbours_correlation
{
choose_average_nearest_neighbours_correlation(const GraphInterface &g, GraphInterface::deg_t origin_deg, GraphInterface::deg_t neighbour_deg, GraphInterface::avg_corr_t &avg_deg)
: _g(g), _avg_deg(avg_deg)
choose_average_nearest_neighbours_correlation(const GraphInterface &g, WeightMap weight, GraphInterface::deg_t origin_deg, GraphInterface::deg_t neighbour_deg, GraphInterface::avg_corr_t &avg_deg)
: _g(g), _weight(weight), _avg_deg(avg_deg)
{
tie(_origin_deg, _origin_deg_name) = get_degree_type(origin_deg);
tie(_neighbour_deg, _neighbour_deg_name) = get_degree_type(neighbour_deg);
......@@ -92,7 +92,7 @@ struct choose_average_nearest_neighbours_correlation
template <class OriginDegreeSelector>
struct choose_neighbour_degree
{
choose_neighbour_degree(choose_average_nearest_neighbours_correlation<DegreeSelectors>& parent):_parent(parent) {}
choose_neighbour_degree(choose_average_nearest_neighbours_correlation<WeightMap,DegreeSelectors>& parent):_parent(parent) {}
template <class DegreeSelector>
void operator()(DegreeSelector)
{
......@@ -101,11 +101,11 @@ struct choose_average_nearest_neighbours_correlation
OriginDegreeSelector origin_deg(_parent._origin_deg_name, _parent._g);
DegreeSelector deg(_parent._neighbour_deg_name, _parent._g);
check_filter(_parent._g, bind<void>(get_average_nearest_neighbours_correlation<OriginDegreeSelector,DegreeSelector>(origin_deg, deg),
_1, var(_parent._avg_deg)),
_1, var(_parent._weight), var(_parent._avg_deg)),
reverse_check(),directed_check());
}
}
choose_average_nearest_neighbours_correlation<DegreeSelectors> &_parent;
choose_average_nearest_neighbours_correlation<WeightMap,DegreeSelectors> &_parent;
};
template <class DegreeSelector>
......@@ -116,6 +116,7 @@ struct choose_average_nearest_neighbours_correlation
}
const GraphInterface &_g;
WeightMap _weight;
GraphInterface::avg_corr_t &_avg_deg;
GraphInterface::degree_t _origin_deg;
string _origin_deg_name;
......@@ -127,14 +128,36 @@ struct choose_average_nearest_neighbours_correlation
// GetAverageNearestNeighboursCorrelation(neigh, orign_deg, neighbours_deg)
//==============================================================================
GraphInterface::avg_corr_t
GraphInterface::GetAverageNearestNeighboursCorrelation(deg_t origin_deg, deg_t neighbours_deg ) const
GraphInterface::GetAverageNearestNeighboursCorrelation(deg_t origin_deg, deg_t neighbours_deg, std::string weight) const
{
GraphInterface::avg_corr_t avg_corr;
try
{
typedef mpl::vector<in_degreeS,out_degreeS,total_degreeS,scalarS> degrees;
mpl::for_each<degrees>(choose_average_nearest_neighbours_correlation<degrees>(*this, origin_deg, neighbours_deg, avg_corr));
if(weight != "")
{
try
{
// FIXME: it would be good also to have a version for a static map (vector_property_map),
// but adding this makes GCC use more than 1 GB of RAM in my system.
dynamic_property_map& weight_prop = find_property_map(_properties, weight, typeid(graph_traits<multigraph_t>::edge_descriptor));
typedef DynamicPropertyMapWrap<double,graph_traits<multigraph_t>::edge_descriptor> weight_map_t;
weight_map_t weight_map(weight_prop);
mpl::for_each<degrees>(choose_average_nearest_neighbours_correlation<weight_map_t,degrees>(*this, weight_map, origin_deg, neighbours_deg, avg_corr));
}
catch (property_not_found& e)
{
throw GraphException("error getting scalar property: " + string(e.what()));
}
}
else
{
typedef ConstantPropertyMap<double,graph_traits<multigraph_t>::edge_descriptor> weight_map_t;
weight_map_t weight_map(1.0);
mpl::for_each<degrees>(choose_average_nearest_neighbours_correlation<weight_map_t,degrees>(*this, weight_map, origin_deg, neighbours_deg, avg_corr));
}
}
catch (dynamic_get_failure &e)
{
......
// graph-tool -- a general graph modification and manipulation thingy
//
// Copyright (C) 2006 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 2
// 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, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include <algorithm>
#include <tr1/unordered_set>
#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>
#include <boost/random.hpp>
#include "graph.hh"
#include "histogram.hh"
#include "graph_filtering.hh"
#include "graph_selectors.hh"
#include "graph_properties.hh"
using namespace std;
using namespace boost;
using namespace boost::lambda;
using namespace graph_tool;
//==============================================================================
// get_edge_correlation_histogram
// retrieves the generalized vertex-edge-vertex correlation histogram
//==============================================================================
template <class DegreeSelector1, class DegreeSelector2>
struct get_edge_correlation_histogram
{
get_edge_correlation_histogram(DegreeSelector1& deg1, DegreeSelector2& deg2, scalarS& scalar)
: _edge_scalar(scalar), _deg1(deg1), _deg2(deg2) {}
template <class Graph, class Hist>
void operator()(Graph &g, Hist &hist) const
{
typename graph_traits<Graph>::edge_iterator e, e_begin, e_end;
tie(e_begin, e_end) = edges(g);
for (e = e_begin; e != e_end; ++e)
{
typename Hist::key_type key;
get<0>(key) = _deg1(source(*e,g),g);
get<1>(key) = _edge_scalar(*e, g);
get<2>(key) = _deg2(target(*e,g),g);
hist[key]++;
if(is_convertible<typename graph_traits<Graph>::directed_category, undirected_tag>::value)
{
swap(get<0>(key), get<2>(key));
hist[key]++;
}
}
}
scalarS& _edge_scalar;
DegreeSelector1& _deg1;
DegreeSelector2& _deg2;
};
//==============================================================================
// GetEdgeVertexCorrelationHistogram(deg1, scalar, deg2)
// retrieves the degree-edge-degree correlation histogram
//==============================================================================
template <class SecondDegreeSelectors>
struct choose_edge_vertex_correlation_histogram
{
choose_edge_vertex_correlation_histogram(const GraphInterface& g, GraphInterface::deg_t deg1, scalarS& edge_scalar,
GraphInterface::deg_t deg2, GraphInterface::hist3d_t& hist)
: _g(g), _edge_scalar(edge_scalar), _hist(hist)
{
tie(_deg1, _deg_name1) = get_degree_type(deg1);
tie(_deg2, _deg_name2) = get_degree_type(deg2);
}
template <class DegreeSelector1>
struct check_second_degree
{
check_second_degree(choose_edge_vertex_correlation_histogram<SecondDegreeSelectors> &parent):_parent(parent) {}
template <class DegreeSelector2>
void operator()(DegreeSelector2)
{
if (mpl::at<degree_selector_index,DegreeSelector2>::type::value == _parent._deg2)
{
DegreeSelector1 deg1(_parent._deg_name1, _parent._g);
DegreeSelector2 deg2(_parent._deg_name2, _parent._g);
check_filter(_parent._g, bind<void>(get_edge_correlation_histogram<DegreeSelector1,DegreeSelector2>(deg1,deg2,_parent._edge_scalar),
_1, var(_parent._hist)),
reverse_check(),directed_check());
}
}
choose_edge_vertex_correlation_histogram<SecondDegreeSelectors> _parent;
};
template <class DegreeSelector>
void operator()(DegreeSelector)
{
if (mpl::at<degree_selector_index,DegreeSelector>::type::value == _deg1)
mpl::for_each<SecondDegreeSelectors>(check_second_degree<DegreeSelector>(*this));
}
const GraphInterface& _g;
scalarS& _edge_scalar;
GraphInterface::hist3d_t& _hist;
GraphInterface::degree_t _deg1;
string _deg_name1;
GraphInterface::degree_t _deg2;
string _deg_name2;
};
GraphInterface::hist3d_t
GraphInterface::GetEdgeVertexCorrelationHistogram(GraphInterface::deg_t deg1, string edge_scalar, GraphInterface::deg_t deg2) const
{
hist3d_t hist;
scalarS scalar(edge_scalar, *this);
try
{
typedef mpl::vector<in_degreeS, out_degreeS, total_degreeS, scalarS> degree_selectors;
mpl::for_each<degree_selectors>(choose_edge_vertex_correlation_histogram<degree_selectors>(*this, deg1, scalar, deg2, hist));
}
catch (dynamic_get_failure& e)
{
throw GraphException("error getting scalar property: " + string(e.what()));
}
return hist;
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment