Commit 7067c4fd authored by Tiago Peixoto's avatar Tiago Peixoto

global_clustering(): add `ret_counts` parameter

parent 65142f35
......@@ -43,17 +43,18 @@ boost::python::tuple global_clustering(GraphInterface& g, boost::any weight)
if(weight.empty())
weight = weight_map_t();
double c, c_err;
boost::python::tuple oret;
run_action<graph_tool::detail::never_directed>()
(g,
[&](auto&& graph, auto&& a2)
{
return get_global_clustering()
(std::forward<decltype(graph)>(graph),
std::forward<decltype(a2)>(a2), c, c_err);
auto ret = get_global_clustering(std::forward<decltype(graph)>(graph),
std::forward<decltype(a2)>(a2));
oret = boost::python::make_tuple(get<0>(ret), get<1>(ret),
get<2>(ret), get<3>(ret));
},
weight_props_t())(weight);
return boost::python::make_tuple(c, c_err);
return oret;
}
void local_clustering(GraphInterface& g, boost::any prop, boost::any weight)
......@@ -72,10 +73,9 @@ void local_clustering(GraphInterface& g, boost::any prop, boost::any weight)
(g,
[&](auto&& graph, auto&& a2, auto&& a3)
{
return set_clustering_to_property()
(std::forward<decltype(graph)>(graph),
std::forward<decltype(a2)>(a2),
std::forward<decltype(a3)>(a3));
set_clustering_to_property(std::forward<decltype(graph)>(graph),
std::forward<decltype(a2)>(a2),
std::forward<decltype(a3)>(a3));
},
weight_props_t(), writable_vertex_scalar_properties())(weight, prop);
}
......
......@@ -90,80 +90,65 @@ auto get_triangles(typename graph_traits<Graph>::vertex_descriptor v,
// retrieves the global clustering coefficient
struct get_global_clustering
template <class Graph, class EWeight>
auto get_global_clustering(const Graph& g, EWeight eweight)
{
template <class Graph, class EWeight>
void operator()(const Graph& g, EWeight eweight, double& c, double& c_err) const
{
typedef typename property_traits<EWeight>::value_type val_t;
val_t triangles = 0, n = 0;
vector<val_t> mask(num_vertices(g), 0);
vector<std::pair<val_t, val_t>> ret(num_vertices(g));
#pragma omp parallel if (num_vertices(g) > OPENMP_MIN_THRESH) \
firstprivate(mask) reduction(+:triangles, n)
parallel_vertex_loop_no_spawn
(g,
[&](auto v)
{
auto temp = get_triangles(v, eweight, mask, g);
triangles += temp.first;
n += temp.second;
ret[v] = temp;
});
c = double(triangles) / n;
// "jackknife" variance
c_err = 0.0;
double cerr = 0.0;
#pragma omp parallel if (num_vertices(g) > OPENMP_MIN_THRESH) \
reduction(+:cerr)
parallel_vertex_loop_no_spawn
(g,
[&](auto v)
{
auto cl = double(triangles - ret[v].first) /
(n - ret[v].second);
cerr += power(c - cl, 2);
});
c_err = sqrt(cerr);
}
};
typedef typename property_traits<EWeight>::value_type val_t;
val_t triangles = 0, n = 0;
vector<val_t> mask(num_vertices(g), 0);
vector<std::pair<val_t, val_t>> ret(num_vertices(g));
// sets the local clustering coefficient to a property
struct set_clustering_to_property
{
template <class Graph, class EWeight, class ClustMap>
void operator()(const Graph& g, EWeight eweight, ClustMap clust_map) const
{
typedef typename property_traits<EWeight>::value_type val_t;
vector<val_t> mask(num_vertices(g), false);
#pragma omp parallel if (num_vertices(g) > OPENMP_MIN_THRESH) \
firstprivate(mask) reduction(+:triangles, n)
parallel_vertex_loop_no_spawn
(g,
[&](auto v)
{
auto temp = get_triangles(v, eweight, mask, g);
triangles += temp.first;
n += temp.second;
ret[v] = temp;
});
double c = double(triangles) / n;
#pragma omp parallel if (num_vertices(g) > OPENMP_MIN_THRESH) \
firstprivate(mask)
parallel_vertex_loop_no_spawn
// "jackknife" variance
double c_err = 0.0;
#pragma omp parallel if (num_vertices(g) > OPENMP_MIN_THRESH) \
reduction(+:c_err)
parallel_vertex_loop_no_spawn
(g,
[&](auto v)
{
auto triangles = get_triangles(v, eweight, mask, g);
double clustering = (triangles.second > 0) ?
double(triangles.first)/triangles.second :
0.0;
clust_map[v] = clustering;
auto cl = double(triangles - ret[v].first) /
(n - ret[v].second);
c_err += power(c - cl, 2);
});
}
template <class Graph>
struct get_undirected_graph
{
typedef typename mpl::if_
<std::is_convertible<typename graph_traits<Graph>::directed_category,
directed_tag>,
const undirected_adaptor<Graph>,
const Graph& >::type type;
};
};
c_err = sqrt(c_err);
return std::make_tuple(c, c_err, triangles/3, n);
}
// sets the local clustering coefficient to a property
template <class Graph, class EWeight, class ClustMap>
void set_clustering_to_property(const Graph& g, EWeight eweight,
ClustMap clust_map)
{
typedef typename property_traits<EWeight>::value_type val_t;
vector<val_t> mask(num_vertices(g), false);
#pragma omp parallel if (num_vertices(g) > OPENMP_MIN_THRESH) \
firstprivate(mask)
parallel_vertex_loop_no_spawn
(g,
[&](auto v)
{
auto triangles = get_triangles(v, eweight, mask, g);
double clustering = (triangles.second > 0) ?
double(triangles.first)/triangles.second :
0.0;
clust_map[v] = clustering;
});
}
} //graph-tool namespace
......
......@@ -131,7 +131,7 @@ def local_clustering(g, weight=None, prop=None, undirected=True):
return prop
def global_clustering(g, weight=None):
def global_clustering(g, weight=None, ret_counts=False):
r"""Return the global clustering coefficient.
Parameters
......@@ -140,11 +140,18 @@ def global_clustering(g, weight=None):
Graph to be used.
weight : :class:`~graph_tool.EdgePropertyMap`, optional (default: None)
Edge weights. If omitted, a constant value of 1 will be used.
ret_counts : ``boolean`` (optional, default: ``False``)
If ``True`` the number of triangles and connected triples are also
returned.
Returns
-------
c : tuple of floats
Global clustering coefficient and standard deviation (jacknife method)
Global clustering coefficient and standard deviation (jackknife method)
triangles : `int` (if ``ret_counts is True``)
Number of triangles.
triples : `int` (if ``ret_counts is True``)
Number of connected triples.
See Also
--------
......@@ -192,7 +199,10 @@ def global_clustering(g, weight=None):
if g.is_directed():
g = GraphView(g, directed=False, skip_properties=True)
c = _gt.global_clustering(g._Graph__graph, _prop("e", g, weight))
return c
if ret_counts:
return c[:2], c[2], c[3]
else:
return c[:2]
def extended_clustering(g, props=None, max_depth=3, undirected=False):
......
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