Commit 55cdce65 authored by Tiago Peixoto's avatar Tiago Peixoto
Browse files

removing edge selectors, since the same behaviour can be obtained by using the...

removing edge selectors, since the same behaviour can be obtained by using the --undirected and --reverse filters, as long as the in-degree is also seen when the undirected filter is turned on


git-svn-id: https://svn.forked.de/graph-tool/trunk@7 d4600afd-f417-0410-95de-beed9576f240
parent de3bae43
......@@ -96,10 +96,10 @@ statistics.add_option("--component-size-histogram", action="callback", callback=
correlations = parser.add_option_group("Correlations")
correlations.add_option("--degree-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-degree", action="callback", callback=push_option, type="string", metavar="NEIGHBOURS|ORIGIN-DEGREE|DEGREE|FILE", help="get the average nearest neighbours degree")
correlations.add_option("--average-nearest-neighbours-degree", action="callback", callback=push_option, type="string", metavar="ORIGIN-DEGREE|DEGREE|FILE", help="get the average nearest neighbours degree")
correlations.add_option("--edge-degree-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("--vertex-scalar-correlation-histogram", action="callback", callback=push_option, type="string", metavar="DEGREE|VERTEX-PROP|FILE", help="get the degree vs. vertex scalar correlation histogram. Scalar properties are also accepted in place of DEGREE")
correlations.add_option("--assortativity-coefficient", action="callback", callback=push_option, type="string", metavar="NEIGHBOURS|DEGREE|DEGREE|FILE", help="get the assortativity coefficient. Scalar properties are also accepted in place of DEGREE (not yet)")
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")
clustering = parser.add_option_group("Clustering")
clustering.add_option("--local-clustering-coefficient", action="callback", callback=push_option, type="string", metavar="FILE", help="get the local clustering coefficient")
......@@ -148,17 +148,6 @@ def degree(name):
deg = Degree.Total
return deg
def neighbour(name):
"this will retrieve the neighbour type from string"
nei = None
if name == "in-neighbours" or name == "in":
nei = Neighbours.In
if name == "out-neighbours" or name == "out":
nei = Neighbours.Out
if name == "all-neighbours" or name == "all":
nei = Neighbours.All
return nei
class OptionError(Exception):
def __init__(self, option, error):
self.what = "error parsing option %s: %s" % (option,error)
......@@ -296,28 +285,21 @@ def parse_option(opt, just_file=False):
return (graph.GetVertexDegreeScalarCorrelationHistogram(deg,values[1]),values[2])
elif opt.name == "average-nearest-neighbours-degree":
values = parse_values(opt.value)
if len(values) != 4:
if len(values) != 3:
raise OptionError(opt.name, "invalid value '%s'" % opt.value)
nei = neighbour(values[0])
if nei == None:
raise OptionError(opt.name, "invalid neighbour type '%s'" % values[0])
deg1 = degree(values[1])
deg2 = degree(values[2])
deg1 = degree(values[0])
deg2 = degree(values[1])
if just_file:
return values[3]
return (graph.GetAverageNearestNeighboursDegree(nei,deg1,deg2), values[3])
return values[2]
return (graph.GetAverageNearestNeighboursDegree(deg1,deg2), values[2])
elif opt.name == "assortativity-coefficient":
values = parse_values(opt.value)
if len(values) != 4:
if len(values) != 2:
raise OptionError(opt.name, "invalid value '%s'" % opt.value)
nei = neighbour(values[0])
if nei == None:
raise OptionError(opt.name, "invalid neighbour type '%s'" % values[0])
deg1 = degree(values[1])
deg2 = degree(values[2])
deg = degree(values[0])
if just_file:
return values[3]
return (graph.GetAssortativityCoefficient(nei,deg1,deg2), values[3])
return values[1]
return (graph.GetAssortativityCoefficient(deg), values[1])
elif opt.name == "local-clustering-coefficient":
hist = graph.GetLocalClusteringHistogram()
avg,count = 0.0,0.0
......
......@@ -84,8 +84,8 @@ public:
hist2d_t GetDegreeCorrelationHistogram(deg_t degree1, deg_t degree2) const;
hist3d_t GetEdgeDegreeCorrelationHistogram(deg_t deg1, std::string scalar, deg_t deg2) const;
hist2d_t GetVertexDegreeScalarCorrelationHistogram(deg_t deg, std::string scalar) const;
avg_corr_t GetAverageNearestNeighboursDegree(neighbours_t neighbours, deg_t origin_degree, deg_t neighbour_degree) const;
double GetAssortativityCoefficient(neighbours_t neighbours, deg_t deg1, deg_t deg2) const;
avg_corr_t GetAverageNearestNeighboursDegree(deg_t origin_degree, deg_t neighbour_degree) const;
double GetAssortativityCoefficient(deg_t deg) const;
//clustering
hist_t GetLocalClusteringHistogram() const;
......
......@@ -34,13 +34,13 @@ using namespace boost::lambda;
using namespace graph_tool;
//==============================================================================
// GetAssortativityCoefficient(neigh, deg1, deg2)
// GetAssortativityCoefficient(type)
//==============================================================================
template <class EdgeSelector, class DegreeSelector1, class DegreeSelector2>
template <class DegreeSelector>
struct get_assortativity_coefficient
{
get_assortativity_coefficient(DegreeSelector1& deg1, DegreeSelector2& deg2): _deg1(deg1), _deg2(deg2) {}
get_assortativity_coefficient(DegreeSelector& deg): _deg(deg) {}
template <class Graph>
void operator()(const Graph &g, double &a) const
......@@ -54,15 +54,15 @@ struct get_assortativity_coefficient
for(v = v_begin; v != v_end; ++v)
{
double k1, k2;
k1 = _deg1(*v,g);
k1 = _deg(*v,g);
n_k[k1]++;
n_vertices++;
typename EdgeSelector::template iterator<Graph>::type e, e_begin, e_end;
tie(e_begin, e_end) = _edges(*v,g);
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)
{
k2 = _deg2(_edges.target(*e,g),g);
k2 = _deg(target(*e,g),g);
if (k1 == k2)
e_kk[k1]++;
n_edges++;
......@@ -82,80 +82,45 @@ struct get_assortativity_coefficient
a = (t1 == 1.0)?1.0:(t1 - t2)/(1.0 - t2);
}
EdgeSelector _edges;
DegreeSelector1& _deg1;
DegreeSelector2& _deg2;
DegreeSelector& _deg;
};
template <class DegreeSelectors>
struct choose_assortativity_coefficient
{
choose_assortativity_coefficient(const GraphInterface &g, GraphInterface::neighbours_t neigh,
GraphInterface::deg_t deg1, GraphInterface::deg_t deg2, double &a)
: _g(g), _neigh(neigh), _a(a)
choose_assortativity_coefficient(const GraphInterface &g, GraphInterface::deg_t deg, double &a)
: _g(g), _a(a)
{
tie(_deg1, _deg_name1) = get_degree_type(deg1);
tie(_deg2, _deg_name2) = get_degree_type(deg2);
tie(_deg, _deg_name) = get_degree_type(deg);
}
template <class NeighbourSelector, class DegreeSelector1>
struct choose_degree_two
{
choose_degree_two(choose_assortativity_coefficient<DegreeSelectors> &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_assortativity_coefficient<NeighbourSelector,DegreeSelector1,DegreeSelector2>(deg1,deg2),
_1, var(_parent._a)),
reverse_check(),directed_check());
}
}
choose_assortativity_coefficient<DegreeSelectors> &_parent;
};
template <class NeighbourSelector>
struct choose_degree_one
{
choose_degree_one(choose_assortativity_coefficient<DegreeSelectors> &parent):_parent(parent) {}
template <class DegreeSelector1>
void operator()(DegreeSelector1)
template <class DegreeSelector>
void operator()(DegreeSelector)
{
if (mpl::at<degree_selector_index, DegreeSelector>::type::value == _deg)
{
if (mpl::at<degree_selector_index, DegreeSelector1>::type::value == _parent._deg1)
mpl::for_each<DegreeSelectors>(choose_degree_two<NeighbourSelector, DegreeSelector1>(_parent));
DegreeSelector deg(_deg_name, _g);
check_filter(_g, bind<void>(get_assortativity_coefficient<DegreeSelector>(deg), _1, var(_a)),
reverse_check(),directed_check());
}
choose_assortativity_coefficient<DegreeSelectors> &_parent;
};
template <class NeighbourSelector>
void operator()(NeighbourSelector)
{
if (mpl::at<edges_selector_index, NeighbourSelector>::type::value == _neigh)
mpl::for_each<DegreeSelectors>(choose_degree_one<NeighbourSelector>(*this));
}
const GraphInterface &_g;
GraphInterface::neighbours_t _neigh;
double &_a;
GraphInterface::degree_t _deg1;
string _deg_name1;
GraphInterface::degree_t _deg2;
string _deg_name2;
GraphInterface::degree_t _deg;
string _deg_name;
};
double
GraphInterface::GetAssortativityCoefficient(GraphInterface::neighbours_t neigh, GraphInterface::deg_t deg1, GraphInterface::deg_t deg2 ) const
GraphInterface::GetAssortativityCoefficient(GraphInterface::deg_t deg) const
{
double a;
try
{
typedef mpl::vector<out_edgeS, in_edgeS, any_edgeS> neighbours;
typedef mpl::vector<in_degreeS, out_degreeS, total_degreeS, scalarS> degrees;
mpl::for_each<neighbours>(choose_assortativity_coefficient<degrees>(*this, neigh, deg1, deg2, a));
mpl::for_each<degrees>(choose_assortativity_coefficient(*this, deg, a));
}
catch (dynamic_get_failure &e)
{
......
......@@ -38,7 +38,7 @@ using namespace graph_tool;
// return generalized average nearest neighbours degree
//==============================================================================
template <class EdgeSelector, class DegreeSelectorOrigin, class DegreeSelectorNeighbours>
template <class DegreeSelectorOrigin, class DegreeSelectorNeighbours>
struct get_average_nearest_neighbours_degree
{
get_average_nearest_neighbours_degree(DegreeSelectorOrigin& origin_deg, DegreeSelectorNeighbours& neighbours_deg)
......@@ -54,15 +54,15 @@ struct get_average_nearest_neighbours_degree
tie(v_begin,v_end) = vertices(g);
for(v = v_begin; v != v_end; ++v)
{
typename EdgeSelector::template iterator<Graph>::type e, e_begin, e_end;
tie(e_begin,e_end) = _edges(*v,g);
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)
{
if (neighbour_set.find(_edges.target(*e,g)) != neighbour_set.end())
if (neighbour_set.find(target(*e,g)) != neighbour_set.end())
continue;
else
neighbour_set.insert(_edges.target(*e,g));
typename AvgDeg::value_type::second_type::first_type deg = _neighbours_degree(_edges.target(*e,g),g);
neighbour_set.insert(target(*e,g));
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].second += deg*deg;
......@@ -83,61 +83,45 @@ struct get_average_nearest_neighbours_degree
}
DegreeSelectorOrigin& _origin_degree;
DegreeSelectorNeighbours& _neighbours_degree;
EdgeSelector _edges;
};
template <class DegreeSelectors>
struct choose_average_nearest_neighbours_degree
{
choose_average_nearest_neighbours_degree(const GraphInterface &g, GraphInterface::neighbours_t neigh,
GraphInterface::deg_t origin_deg, GraphInterface::deg_t neighbour_deg, GraphInterface::avg_corr_t &avg_deg)
: _g(g), _neigh(neigh), _avg_deg(avg_deg)
choose_average_nearest_neighbours_degree(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)
{
tie(_origin_deg, _origin_deg_name) = get_degree_type(origin_deg);
tie(_neighbour_deg, _neighbour_deg_name) = get_degree_type(neighbour_deg);
}
template <class EdgeSelector, class OriginDegreeSelector>
template <class OriginDegreeSelector>
struct choose_neighbour_degree
{
choose_neighbour_degree(choose_average_nearest_neighbours_degree<DegreeSelectors> &parent):_parent(parent) {}
choose_neighbour_degree(choose_average_nearest_neighbours_degree<DegreeSelectors>& parent):_parent(parent) {}
template <class DegreeSelector>
void operator()(DegreeSelector)
{
OriginDegreeSelector origin_deg(_parent._origin_deg_name, _parent._g);
DegreeSelector deg(_parent._neighbour_deg_name, _parent._g);
if ( mpl::at<degree_selector_index, DegreeSelector>::type::value == _parent._neighbour_deg)
check_filter(_parent._g, bind<void>(get_average_nearest_neighbours_degree<EdgeSelector,
OriginDegreeSelector,
DegreeSelector>(origin_deg, deg),
_1, var(_parent._avg_deg)),
{
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_degree<OriginDegreeSelector,DegreeSelector>(origin_deg, deg),
_1, var(_parent._avg_deg)),
reverse_check(),directed_check());
}
}
choose_average_nearest_neighbours_degree<DegreeSelectors> &_parent;
};
template <class EdgeSelector>
struct choose_origin_degree
{
choose_origin_degree(choose_average_nearest_neighbours_degree<DegreeSelectors> &parent):_parent(parent) {}
template <class DegreeSelector>
void operator()(DegreeSelector)
{
if ( mpl::at<degree_selector_index, DegreeSelector>::type::value == _parent._origin_deg)
mpl::for_each<DegreeSelectors>(choose_neighbour_degree<EdgeSelector,DegreeSelector>(_parent));
}
choose_average_nearest_neighbours_degree<DegreeSelectors> &_parent;
};
template <class EdgeSelector>
void operator()(EdgeSelector)
template <class DegreeSelector>
void operator()(DegreeSelector)
{
if (mpl::at<edges_selector_index, EdgeSelector>::type::value == _neigh)
mpl::for_each<DegreeSelectors>(choose_origin_degree<EdgeSelector>(*this));
if (mpl::at<degree_selector_index, DegreeSelector>::type::value == _origin_deg)
mpl::for_each<DegreeSelectors>(choose_neighbour_degree<DegreeSelector>(*this));
}
const GraphInterface &_g;
GraphInterface::neighbours_t _neigh;
GraphInterface::avg_corr_t &_avg_deg;
GraphInterface::degree_t _origin_deg;
string _origin_deg_name;
......@@ -149,15 +133,14 @@ struct choose_average_nearest_neighbours_degree
// GetAverageNearestNeighboursDegree(neigh, orign_deg, neighbours_deg)
//==============================================================================
GraphInterface::avg_corr_t
GraphInterface::GetAverageNearestNeighboursDegree(neighbours_t neigh, deg_t origin_deg, deg_t neighbours_deg ) const
GraphInterface::GetAverageNearestNeighboursDegree(deg_t origin_deg, deg_t neighbours_deg ) const
{
GraphInterface::avg_corr_t avg_corr;
try
{
typedef mpl::vector<in_degreeS,out_degreeS,total_degreeS,scalarS> degrees;
typedef mpl::vector<out_edgeS,in_edgeS,any_edgeS> edges;
mpl::for_each<edges>(choose_average_nearest_neighbours_degree<degrees>(*this, neigh, origin_deg, neighbours_deg, avg_corr));
mpl::for_each<degrees>(choose_average_nearest_neighbours_degree<degrees>(*this, origin_deg, neighbours_deg, avg_corr));
}
catch (dynamic_get_failure &e)
{
......
......@@ -81,7 +81,7 @@ struct in_degreeS
template <class Graph, class Vertex>
size_t get_in_degree(const Vertex& v, const Graph &g, boost::false_type) const
{
return 0;
return in_degree(v,g.OriginalGraph());
}
std::string name() {return "in_degree";}
......@@ -151,186 +151,6 @@ typedef boost::mpl::map< boost::mpl::pair<in_degreeS, boost::mpl::int_<GraphInte
boost::mpl::pair<total_degreeS, boost::mpl::int_<GraphInterface::TOTAL_DEGREE> >,
boost::mpl::pair<scalarS, boost::mpl::int_<GraphInterface::SCALAR> > > degree_selector_index;
struct out_edgeS
{
template <class Graph>
struct iterator
{
typedef typename boost::graph_traits<Graph>::out_edge_iterator type;
};
template <class Graph>
struct descriptor
{
typedef typename boost::graph_traits<Graph>::edge_descriptor type;
};
template <class Graph, class Vertex>
std::pair<typename iterator<Graph>::type, typename iterator<Graph>::type>
operator()(const Vertex& v, const Graph &g) const
{
return out_edges(v,g);
}
template <class Graph>
typename boost::graph_traits<Graph>::vertex_descriptor
target(const typename descriptor<Graph>::type& e, const Graph &g) const
{
return boost::target(e,g);
}
};
struct in_edgeS
{
template <class Graph, class IsDirected>
struct get_iterator
{
typedef typename boost::graph_traits<Graph>::in_edge_iterator type;
};
template <class Graph>
struct get_iterator<Graph,boost::false_type>
{
typedef typename boost::graph_traits<Graph>::out_edge_iterator type;
};
template <class Graph>
struct iterator
{
typedef typename boost::is_convertible<typename boost::graph_traits<Graph>::directed_category, boost::directed_tag>::type is_directed;
typedef typename get_iterator<Graph, is_directed>::type type;
};
template <class Graph>
struct descriptor
{
typedef typename boost::graph_traits<Graph>::edge_descriptor type;
};
template <class Graph, class Vertex>
std::pair<typename iterator<Graph>::type, typename iterator<Graph>::type>
operator()(const Vertex& v, const Graph &g) const
{
typedef typename boost::is_convertible<typename boost::graph_traits<Graph>::directed_category, boost::directed_tag>::type is_directed;
return get_in_edges(v, g, is_directed());
}
template <class Graph, class Vertex>
std::pair<typename iterator<Graph>::type, typename iterator<Graph>::type>
get_in_edges(const Vertex& v, const Graph &g, boost::true_type) const
{
return in_edges(v,g);
}
template <class Graph, class Vertex>
std::pair<typename iterator<Graph>::type, typename iterator<Graph>::type>
get_in_edges(const Vertex& v, const Graph &g, boost::false_type) const
{
typename iterator<Graph>::type end = out_edges(v,g).second;
return make_pair(end,end);
}
template <class Graph>
typename boost::graph_traits<Graph>::vertex_descriptor
target(const typename descriptor<Graph>::type& e, const Graph &g) const
{
return source(e,g);
}
};
struct any_edgeS
{
template <class Graph, class IsDirected>
struct get_iterator
{
typedef typename boost::graph_traits<boost::UndirectedAdaptor<Graph> >::out_edge_iterator type;
};
template <class Graph>
struct get_iterator<Graph,boost::false_type>
{
typedef typename boost::graph_traits<Graph>::out_edge_iterator type;
};
template <class Graph>
struct iterator
{
typedef typename boost::is_convertible<typename boost::graph_traits<Graph>::directed_category, boost::directed_tag>::type is_directed;
typedef typename get_iterator<Graph, is_directed>::type type;
};
template <class Graph, class IsDirected>
struct get_descriptor
{
typedef typename boost::graph_traits<boost::UndirectedAdaptor<Graph> >::edge_descriptor type;
};
template <class Graph>
struct get_descriptor<Graph,boost::false_type>
{
typedef typename boost::graph_traits<Graph>::edge_descriptor type;
};
template <class Graph>
struct descriptor
{
typedef typename boost::is_convertible<typename boost::graph_traits<Graph>::directed_category, boost::directed_tag>::type is_directed;
typedef typename get_descriptor<Graph, is_directed>::type type;
};
template <class Graph, class Vertex>
std::pair<typename iterator<Graph>::type, typename iterator<Graph>::type>
operator()(const Vertex& v, const Graph &g) const
{
typedef typename boost::is_convertible<typename boost::graph_traits<Graph>::directed_category, boost::directed_tag>::type is_directed;
return get_all_edges(v,g, is_directed());
}
template <class Graph, class Vertex>
std::pair<typename iterator<Graph>::type, typename iterator<Graph>::type>
get_all_edges(const Vertex& v, const Graph &g, boost::true_type) const
{
boost::UndirectedAdaptor<Graph> ug(g);
return out_edges(v,ug);
}
template <class Graph, class Vertex>
std::pair<typename iterator<Graph>::type, typename iterator<Graph>::type>
get_all_edges(const Vertex& v, const Graph &g, boost::false_type) const
{
return out_edges(v,g);
}
template <class Graph>
typename boost::graph_traits<Graph>::vertex_descriptor
target(const typename descriptor<Graph>::type& e, const Graph &g) const
{
typedef typename boost::is_convertible<typename boost::graph_traits<Graph>::directed_category, boost::directed_tag>::type is_directed;
return get_target(e,g,is_directed());
}
template <class Graph>
typename boost::graph_traits<Graph>::vertex_descriptor
get_target(const typename descriptor<Graph>::type& e, const Graph &g, boost::true_type) const
{
boost::UndirectedAdaptor<Graph> ug(g);
return boost::target(e,ug);
}
template <class Graph>
typename boost::graph_traits<Graph>::vertex_descriptor
get_target(const typename descriptor<Graph>::type& e, const Graph &g, boost::false_type) const
{
return boost::target(e,g);
}
};
typedef boost::mpl::map< boost::mpl::pair<out_edgeS, boost::mpl::int_<GraphInterface::OUT_NEIGHBOURS> >,
boost::mpl::pair<in_edgeS, boost::mpl::int_<GraphInterface::IN_NEIGHBOURS> >,
boost::mpl::pair<any_edgeS, boost::mpl::int_<GraphInterface::ALL_NEIGHBOURS> > >::type edges_selector_index;
} //namespace graph_tool
......
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