...
 
Commits (32)
......@@ -20,7 +20,7 @@ website http://graph-tool.skewed.de.
graph-tool is free software, you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License, version 3 or
above. See LICENSE and LICENSE.LESSER for details.
above. See COPYING and COPYING.LESSER for details.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
......
......@@ -2,7 +2,7 @@ dnl Process this file with autoconf to produce a configure script.
dnl graph-tool package version number
m4_define(graph_tool_version_major, 2)
m4_define(graph_tool_version_minor, 33dev)
m4_define(graph_tool_version_minor, 34dev)
AC_INIT([graph-tool],
[graph_tool_version_major().graph_tool_version_minor()],
......
.. _planted_partition:
Assortative community structure
-------------------------------
Traditionally, `"community structure"
<https://en.wikipedia.org/wiki/Community_structure>`_ in the proper
sense refers to groups of nodes that are more connected to each other
than to nodes of other communities. The SBM is capable of representing
this kind of structure without any problems, but in some circumstances
it might make sense to search exclusively for assortative communities
[lizhi-statistical-2020]_. A version of the SBM that is constrained in
this way is called the "planted partition model", which can be inferred
with graph-tool using
:class:`~graph_tool.inference.planted_partition.PPBlockState`. This
class behaves just like
:class:`~graph_tool.inference.blockmodel.BlockState`, therefore all
algorithms described in this documentation work in the same way. Below
we show how this model can be inferred for the football network
considered previously
.. testsetup:: assortative
import os
try:
os.chdir("demos/inference")
except FileNotFoundError:
pass
gt.seed_rng(42)
.. testcode:: assortative
g = gt.collection.data["football"]
state = gt.PPBlockState(g)
# Now we run 1,000 sweeps of the MCMC with zero temperature.
state.multiflip_mcmc_sweep(beta=np.inf, niter=1000)
state.draw(pos=g.vp.pos, output="football-pp.svg")
.. figure:: football-pp.*
:align: center
:width: 350px
Best fit of the degree-corrected planted partition model to a
network of American college football teams.
It is possible to perform model comparison with other model variations
in the same manner as described in :ref:`sec_model_selection` below.
......@@ -161,16 +161,18 @@ figure.
.. note::
With the SBM no constraints are imposed on what `kind` of modular
With the SBM, no constraints are imposed on what `kind` of modular
structure is allowed, as the matrix of edge counts :math:`e` is
unconstrained. Hence, we can detect the putatively typical pattern of
`"community structure"
assortative `"community structure"
<https://en.wikipedia.org/wiki/Community_structure>`_, i.e. when
nodes are connected mostly to other nodes of the same group, if it
happens to be the most likely network description, but we can also
detect a large multiplicity of other patterns, such as `bipartiteness
<https://en.wikipedia.org/wiki/Bipartite_graph>`_, core-periphery,
and many others, all under the same inference framework.
and many others, all under the same inference framework. If you are
interested in searching exclusively for assortative structures, see
Sec. :ref:`planted_partition`.
Although quite general, the traditional model assumes that the edges are
......
......@@ -17,6 +17,7 @@ reader is referred to [peixoto-bayesian-2019]_.
.. include:: _model_class_selection.rst
.. include:: _edge_weights.rst
.. include:: _layers.rst
.. include:: _assortative.rst
.. include:: _reconstruction.rst
.. include:: _prediction.rst
......@@ -81,6 +82,9 @@ References
.. [peixoto-revealing-2020] Tiago P. Peixoto, "Revealing consensus and
dissensus between network partitions", :arxiv:`2005.13977`
.. [lizhi-statistical-2020] Lizhi Zhang, Tiago P. Peixoto, "Statistical
inference of assortative community structures", :arxiv:`2006.14493`
.. [peixoto-reconstructing-2018] Tiago P. Peixoto, "Reconstructing
networks with unknown and heterogeneous errors", Phys. Rev. X 8
041011 (2018). :doi:`10.1103/PhysRevX.8.041011`, :arxiv:`1806.07956`
......
......@@ -221,7 +221,7 @@ div.admonition p.admonition-title {
display: block;
/* color: #FFF; */
margin: -12px -12px 8px;
margin: 0px -12px 8px;
padding: 6px 12px;
}
......
......@@ -72,6 +72,10 @@
:no-undoc-members:
:show-inheritance:
.. automodule:: graph_tool.inference.planted_partition
:no-undoc-members:
:show-inheritance:
.. automodule:: graph_tool.inference.blockmodel_em
:no-undoc-members:
:show-inheritance:
......
......@@ -15,7 +15,6 @@ ARG REF
RUN git reset --hard $REF
ADD debian debian
RUN cp LICENSE debian/copyright
ADD git2debchangelog.sh .
RUN /bin/bash git2debchangelog.sh > debian/changelog
......
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: graph-tool
Upstream-Contact: Tiago de Paula Peixoto <tiago@skewed.de>
Source: https://graph-tool.skewed.de
Files: *
Copyright: 2006-2020 Tiago de Paula Peixoto
License: LGPL-3+
......@@ -144,27 +144,31 @@ void betweenness(GraphInterface& g, std::vector<size_t>& pivots,
if (!weight.empty())
{
run_action<>()
(g, std::bind<>(get_weighted_betweenness(),
std::placeholders::_1,
std::ref(pivots),
g.get_vertex_index(),
std::placeholders::_2,
std::placeholders::_3, weight,
g.get_edge_index_range()),
edge_floating_properties(),
vertex_floating_properties())
(edge_betweenness, vertex_betweenness);
(g,
[&](auto&& graph, auto&& a2, auto&& a3)
{
return get_weighted_betweenness()
(std::forward<decltype(graph)>(graph), pivots,
g.get_vertex_index(), std::forward<decltype(a2)>(a2),
std::forward<decltype(a3)>(a3), weight,
g.get_edge_index_range());
},
edge_floating_properties(), vertex_floating_properties())(
edge_betweenness, vertex_betweenness);
}
else
{
run_action<>()
(g, std::bind<void>(get_betweenness(), std::placeholders::_1,
std::ref(pivots),
g.get_vertex_index(), std::placeholders::_2,
std::placeholders::_3),
edge_floating_properties(),
vertex_floating_properties())
(edge_betweenness, vertex_betweenness);
(g,
[&](auto&& graph, auto&& a2, auto&& a3)
{
return get_betweenness()
(std::forward<decltype(graph)>(graph), pivots,
g.get_vertex_index(), std::forward<decltype(a2)>(a2),
std::forward<decltype(a3)>(a3));
},
edge_floating_properties(), vertex_floating_properties())(
edge_betweenness, vertex_betweenness);
}
}
......@@ -207,9 +211,14 @@ double central_point(GraphInterface& g,
{
double c = 0.0;
run_action<graph_tool::detail::never_reversed>()
(g, std::bind<>(get_central_point_dominance(), std::placeholders::_1,
std::placeholders::_2, std::ref(c)),
vertex_scalar_properties()) (vertex_betweenness);
(g,
[&](auto&& graph, auto&& a2)
{
return get_central_point_dominance()
(std::forward<decltype(graph)>(graph),
std::forward<decltype(a2)>(a2), c);
},
vertex_scalar_properties())(vertex_betweenness);
return c;
}
......
......@@ -22,7 +22,6 @@
#include "graph_closeness.hh"
#include <functional>
#include <boost/python.hpp>
using namespace std;
......@@ -33,20 +32,30 @@ void do_get_closeness(GraphInterface& gi, boost::any weight,
{
if (weight.empty())
{
run_action<>()(gi,
std::bind(get_closeness(), std::placeholders::_1,
gi.get_vertex_index(), no_weightS(),
std::placeholders::_2, harmonic, norm),
writable_vertex_scalar_properties())(closeness);
run_action<>()
(gi,
[&](auto&& graph, auto&& a2)
{
return get_closeness()
(std::forward<decltype(graph)>(graph),
gi.get_vertex_index(), no_weightS(),
std::forward<decltype(a2)>(a2), harmonic, norm);
},
writable_vertex_scalar_properties())(closeness);
}
else
{
run_action<>()(gi,
std::bind(get_closeness(), std::placeholders::_1,
gi.get_vertex_index(), std::placeholders::_2,
std::placeholders::_3, harmonic, norm),
edge_scalar_properties(),
writable_vertex_scalar_properties())(weight, closeness);
run_action<>()
(gi,
[&](auto&& graph, auto&& a2, auto&& a3)
{
return get_closeness()
(std::forward<decltype(graph)>(graph),
gi.get_vertex_index(), std::forward<decltype(a2)>(a2),
std::forward<decltype(a3)>(a3), harmonic, norm);
},
edge_scalar_properties(),
writable_vertex_scalar_properties())(weight, closeness);
}
}
......
......@@ -37,11 +37,15 @@ size_t eigentrust(GraphInterface& g, boost::any c, boost::any t,
size_t iter = 0;
run_action<>()
(g, bind(get_eigentrust(),
_1, g.get_vertex_index(), g.get_edge_index(), _2,
_3, epslon, max_iter, ref(iter)),
writable_edge_scalar_properties(),
vertex_floating_properties())(c,t);
(g,
[&](auto&& graph, auto&& a2, auto&& a3)
{
return get_eigentrust()
(std::forward<decltype(graph)>(graph), g.get_vertex_index(),
g.get_edge_index(), std::forward<decltype(a2)>(a2),
std::forward<decltype(a3)>(a3), epslon, max_iter, iter);
},
writable_edge_scalar_properties(), vertex_floating_properties())(c, t);
return iter;
}
......
......@@ -42,11 +42,15 @@ long double eigenvector(GraphInterface& g, boost::any w, boost::any c,
long double eig = 0;
run_action<>()
(g, std::bind(get_eigenvector(), std::placeholders::_1, g.get_vertex_index(),
std::placeholders::_2, std::placeholders::_3, epsilon, max_iter,
std::ref(eig)),
weight_props_t(),
vertex_floating_properties())(w, c);
(g,
[&](auto&& graph, auto&& a2, auto&& a3)
{
return get_eigenvector()
(std::forward<decltype(graph)>(graph), g.get_vertex_index(),
std::forward<decltype(a2)>(a2),
std::forward<decltype(a3)>(a3), epsilon, max_iter, eig);
},
weight_props_t(), vertex_floating_properties())(w, c);
return eig;
}
......
......@@ -68,11 +68,15 @@ long double hits(GraphInterface& g, boost::any w, boost::any x, boost::any y,
long double eig = 0;
run_action<>()
(g, std::bind(get_hits_dispatch(), std::placeholders::_1, g.get_vertex_index(),
std::placeholders::_2, std::placeholders::_3, y, epsilon, max_iter,
std::ref(eig)),
weight_props_t(),
vertex_floating_properties())(w, x);
(g,
[&](auto&& graph, auto&& a2, auto&& a3)
{
return get_hits_dispatch()
(std::forward<decltype(graph)>(graph), g.get_vertex_index(),
std::forward<decltype(a2)>(a2),
std::forward<decltype(a3)>(a3), y, epsilon, max_iter, eig);
},
weight_props_t(), vertex_floating_properties())(w, x);
return eig;
}
......
......@@ -53,12 +53,18 @@ void katz(GraphInterface& g, boost::any w, boost::any c, boost::any beta,
if(beta.empty())
beta = beta_map_t();
run_action<>()(g, std::bind(get_katz(), std::placeholders::_1, g.get_vertex_index(),
std::placeholders::_2, std::placeholders::_3,
std::placeholders::_4, alpha, epsilon, max_iter),
weight_props_t(),
vertex_floating_properties(),
beta_props_t())(w, c, beta);
run_action<>()
(g,
[&](auto&& graph, auto&& a2, auto&& a3, auto&& a4)
{
return get_katz()
(std::forward<decltype(graph)>(graph), g.get_vertex_index(),
std::forward<decltype(a2)>(a2),
std::forward<decltype(a3)>(a3),
std::forward<decltype(a4)>(a4), alpha, epsilon, max_iter);
},
weight_props_t(), vertex_floating_properties(),
beta_props_t())(w, c, beta);
}
void export_katz()
......
......@@ -18,7 +18,6 @@
#include "graph_filtering.hh"
#include <boost/python.hpp>
#include <boost/bind.hpp>
#include "graph.hh"
#include "graph_selectors.hh"
......@@ -56,12 +55,17 @@ size_t pagerank(GraphInterface& g, boost::any rank, boost::any pers,
size_t iter;
run_action<>()
(g, std::bind(get_pagerank(),
std::placeholders::_1, g.get_vertex_index(), std::placeholders::_2,
std::placeholders::_3, std::placeholders::_4, d,
epsilon, max_iter, std::ref(iter)),
vertex_floating_properties(),
pers_props_t(), weight_props_t())(rank, pers, weight);
(g,
[&](auto&& graph, auto&& a2, auto&& a3, auto&& a4)
{
return get_pagerank()
(std::forward<decltype(graph)>(graph), g.get_vertex_index(),
std::forward<decltype(a2)>(a2),
std::forward<decltype(a3)>(a3),
std::forward<decltype(a4)>(a4), d, epsilon, max_iter, iter);
},
vertex_floating_properties(), pers_props_t(),
weight_props_t())(rank, pers, weight);
return iter;
}
......
......@@ -36,11 +36,16 @@ void trust_transitivity(GraphInterface& g, int64_t source, int64_t target,
if (!belongs<vertex_floating_vector_properties>()(t))
throw ValueException("vertex property must be of floating point valued vector type");
run_action<>()(g,
bind<void>(get_trust_transitivity(), _1, g.get_vertex_index(),
source, target, _2, _3),
edge_floating_properties(),
vertex_floating_vector_properties())(c,t);
run_action<>()
(g,
[&](auto&& graph, auto&& a2, auto&& a3)
{
return get_trust_transitivity()
(std::forward<decltype(graph)>(graph), g.get_vertex_index(),
source, target, std::forward<decltype(a2)>(a2),
std::forward<decltype(a3)>(a3));
},
edge_floating_properties(), vertex_floating_vector_properties())(c, t);
}
void export_trust_transitivity()
......
......@@ -45,8 +45,13 @@ boost::python::tuple global_clustering(GraphInterface& g, boost::any weight)
double c, c_err;
run_action<graph_tool::detail::never_directed>()
(g, std::bind(get_global_clustering(), std::placeholders::_1,
std::placeholders::_2, std::ref(c), std::ref(c_err)),
(g,
[&](auto&& graph, auto&& a2)
{
return get_global_clustering()
(std::forward<decltype(graph)>(graph),
std::forward<decltype(a2)>(a2), c, c_err);
},
weight_props_t())(weight);
return boost::python::make_tuple(c, c_err);
}
......@@ -64,12 +69,15 @@ void local_clustering(GraphInterface& g, boost::any prop, boost::any weight)
weight = weight_map_t();
run_action<>()
(g, std::bind(set_clustering_to_property(),
std::placeholders::_1,
std::placeholders::_2,
std::placeholders::_3),
weight_props_t(),
writable_vertex_scalar_properties())(weight, prop);
(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));
},
weight_props_t(), writable_vertex_scalar_properties())(weight, prop);
}
using namespace boost::python;
......
......@@ -49,7 +49,7 @@ auto get_triangles(typename graph_traits<Graph>::vertex_descriptor v,
EWeight& eweight, VProp& mark, const Graph& g)
{
typedef typename property_traits<EWeight>::value_type val_t;
val_t triangles = 0, w1 = 0, w2 = 0, k = 0;
val_t triangles = 0, k = 0;
for (auto e : out_edges_range(v, g))
{
......@@ -66,15 +66,17 @@ auto get_triangles(typename graph_traits<Graph>::vertex_descriptor v,
auto n = target(e, g);
if (n == v)
continue;
w1 = eweight[e];
auto m = mark[n];
mark[n] = 0;
val_t t = 0;
for (auto e2 : out_edges_range(n, g))
{
auto n2 = target(e2, g);
if (n2 == n)
continue;
w2 = eweight[e2];
triangles += mark[n2] * w1 * w2;
if (mark[n2] > 0)
t += eweight[e2];
}
triangles += t * eweight[e];
mark[n] = m;
}
for (auto n : adjacent_vertices_range(v, g))
......@@ -96,6 +98,7 @@ struct get_global_clustering
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)
......@@ -106,23 +109,24 @@ struct get_global_clustering
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) \
firstprivate(mask) reduction(+:cerr)
#pragma omp parallel if (num_vertices(g) > OPENMP_MIN_THRESH) \
reduction(+:cerr)
parallel_vertex_loop_no_spawn
(g,
[&](auto v)
{
auto temp = get_triangles(v, eweight, mask, g);
double cl = double(triangles - temp.first) /
(n - temp.second);
auto cl = double(triangles - ret[v].first) /
(n - ret[v].second);
cerr += power(c - cl, 2);
});
c_err = sqrt(cerr);
}
};
......
......@@ -35,9 +35,13 @@ struct prop_vector
boost::any operator()(const vector<boost::any>& props, size_t size) const
{
boost::any prop_vec;
boost::mpl::for_each<PropertySequence>
(std::bind(get_prop_vector(), std::placeholders::_1, std::ref(props),
std::ref(prop_vec), size));
boost::mpl::for_each<PropertySequence>(
[&](auto&& graph)
{
return get_prop_vector()
(std::forward<decltype(graph)>(graph), props, prop_vec,
size);
});
return prop_vec;
}
......@@ -92,8 +96,14 @@ void extended_clustering(GraphInterface& g, boost::python::list props)
properties_vector;
run_action<>()
(g, std::bind<void>(get_extended_clustering(), std::placeholders::_1,
any_cast<GraphInterface::vertex_index_map_t>(g.get_vertex_index()),
std::placeholders::_2),
properties_vector()) (vprop);
(g,
[&](auto&& graph, auto&& a2)
{
return get_extended_clustering()
(std::forward<decltype(graph)>(graph),
any_cast<GraphInterface::vertex_index_map_t>(
g.get_vertex_index()),
std::forward<decltype(a2)>(a2));
},
properties_vector())(vprop);
}
......@@ -65,9 +65,13 @@ void get_motifs(GraphInterface& g, size_t k, boost::python::list subgraph_list,
{
GraphInterface& sub =
boost::python::extract<GraphInterface&>(subgraph_list[i]);
run_action<>()(sub, std::bind(append_to_list(),
std::placeholders::_1,
std::ref(list)))();
run_action<>()
(sub,
[&](auto&& graph)
{
return append_to_list()
(std::forward<decltype(graph)>(graph), list);
})();
}
std::vector<size_t> phist;
......@@ -91,11 +95,15 @@ void get_motifs(GraphInterface& g, size_t k, boost::python::list subgraph_list,
std::vector<std::vector<vmap_t> > vmaps;
run_action<>()
(g, std::bind(get_all_motifs(collect_vmaps, plist[0], comp_iso,
fill_list, rng),
std::placeholders::_1, k, std::ref(list), std::ref(phist),
std::ref(vmaps), std::placeholders::_2),
boost::mpl::vector<sample_all,sample_some>())(sampler);
(g,
[&](auto&& graph, auto&& a2)
{
return get_all_motifs(collect_vmaps, plist[0], comp_iso, fill_list,
rng)(std::forward<decltype(graph)>(graph), k,
list, phist, vmaps,
std::forward<decltype(a2)>(a2));
},
boost::mpl::vector<sample_all, sample_some>())(sampler);
for (size_t i = 0; i < phist.size(); ++i)
hist.append(phist[i]);
......@@ -125,8 +133,12 @@ void get_motifs(GraphInterface& g, size_t k, boost::python::list subgraph_list,
boost::mpl::bool_<false>, boost::mpl::bool_<true>,
boost::mpl::bool_<true> >::type gviews;
run_action<gviews>()
(sub, std::bind(retrieve_from_list(), std::placeholders::_1,
std::ref(list), std::ref(done)))();
(sub,
[&](auto&& graph)
{
return retrieve_from_list()
(std::forward<decltype(graph)>(graph), list, done);
})();
if (!done)
subgraph_list.append(sub);
}
......
......@@ -150,7 +150,8 @@ struct sample_some
void operator()(std::vector<val_type>& extend, size_t d)
{
typedef std::uniform_real_distribution<double> rdist_t;
auto random = std::bind(rdist_t(), std::ref(*_rng));
auto random = [this] { return rdist_t()(*_rng); };
double pd = (*_p)[d+1];
size_t nc = extend.size();
......@@ -177,8 +178,7 @@ struct sample_some
typedef std::uniform_int_distribution<size_t> idist_t;
for (size_t i = 0; i < n; ++i)
{
auto random_v = std::bind(idist_t(0, extend.size()-i-1),
std::ref(*_rng));
auto random_v = [this, &extend, i] { return idist_t(0, extend.size()-i-1)(*_rng); };
size_t j;
#pragma omp critical (random)
{
......@@ -331,8 +331,7 @@ struct get_all_motifs
hist.resize(subgraph_list.size());
typedef std::uniform_real_distribution<double> rdist_t;
auto random = std::bind(rdist_t(), std::ref(rng));
auto random = [this] { return rdist_t()(rng); };
// the set of vertices V to be sampled (filled only if p < 1)
std::vector<size_t> V;
if (p < 1)
......@@ -349,8 +348,7 @@ struct get_all_motifs
typedef std::uniform_int_distribution<size_t> idist_t;
for (size_t i = 0; i < n; ++i)
{
auto random_v = std::bind(idist_t(0, V.size()-i-1),
std::ref(rng));
auto random_v = [&V, i, this] { return idist_t(0, V.size()-i-1)(rng); };
size_t j = i + random_v();
std::swap(V[i], V[j]);
}
......
......@@ -94,12 +94,16 @@ assortativity_coefficient(GraphInterface& gi, GraphInterface::deg_t deg,
weight = weight_map_t();
double a = 0, a_err = 0;
run_action<>()(gi,std::bind(get_assortativity_coefficient(),
std::placeholders::_1, std::placeholders::_2,
std::placeholders::_3,
std::ref(a), std::ref(a_err)),
all_selectors(), weight_props_t())
(degree_selector(deg), weight);
run_action<>()
(gi,
[&](auto&& graph, auto&& a2, auto&& a3)
{
return get_assortativity_coefficient()
(std::forward<decltype(graph)>(graph),
std::forward<decltype(a2)>(a2),
std::forward<decltype(a3)>(a3), a, a_err);
},
all_selectors(), weight_props_t())(degree_selector(deg), weight);
return make_pair(a, a_err);
}
......@@ -118,12 +122,16 @@ scalar_assortativity_coefficient(GraphInterface& gi, GraphInterface::deg_t deg,
weight = weight_map_t();
double a = 0, a_err = 0;
run_action<>()(gi, std::bind(get_scalar_assortativity_coefficient(),
std::placeholders::_1, std::placeholders::_2,
std::placeholders::_3,
std::ref(a), std::ref(a_err)),
scalar_selectors(), weight_props_t())
(degree_selector(deg), weight);
run_action<>()
(gi,
[&](auto&& graph, auto&& a2, auto&& a3)
{
return get_scalar_assortativity_coefficient()
(std::forward<decltype(graph)>(graph),
std::forward<decltype(a2)>(a2),
std::forward<decltype(a3)>(a3), a, a_err);
},
scalar_selectors(), weight_props_t())(degree_selector(deg), weight);
return make_pair(a, a_err);
}
......
......@@ -1852,9 +1852,13 @@ boost::python::object cairo_draw(GraphInterface& gi,
populate_defaults(ovdefaults, vdefaults);
run_action<>()
(gi, std::bind(populate_edge_attrs(), std::placeholders::_1,
oeattrs, std::ref(eattrs), oedefaults,
std::ref(edefaults)))();
(gi,
[&](auto&& graph)
{
return populate_edge_attrs()
(std::forward<decltype(graph)>(graph), oeattrs, eattrs,
oedefaults, edefaults);
})();
typedef boost::mpl::push_back<vertex_scalar_properties, no_order>::type
vorder_t;
......@@ -1877,31 +1881,45 @@ boost::python::object cairo_draw(GraphInterface& gi,
if (nodesfirst)
run_action<>()
(gi, std::bind(do_cairo_draw_vertices(), std::placeholders::_1,
std::placeholders::_2, std::placeholders::_3,
std::ref(vattrs), std::ref(eattrs), std::ref(vdefaults),
std::ref(edefaults), mtime, dt, std::ref(count),
std::ref(cr), std::ref(yield)),
(gi,
[&](auto&& graph, auto&& a2, auto&& a3)
{
return do_cairo_draw_vertices()
(std::forward<decltype(graph)>(graph),
std::forward<decltype(a2)>(a2),
std::forward<decltype(a3)>(a3), vattrs, eattrs,
vdefaults, edefaults, mtime, dt, count, cr,
yield);
},
vertex_scalar_vector_properties(),
vorder_t())(pos, vorder);
run_action<>()
(gi, std::bind(do_cairo_draw_edges(), std::placeholders::_1,
std::placeholders::_2, std::placeholders::_3,
std::ref(vattrs), std::ref(eattrs),
std::ref(vdefaults), std::ref(edefaults), res,
mtime, dt, std::ref(count), std::ref(cr), std::ref(yield)),
vertex_scalar_vector_properties(),
eorder_t())(pos, eorder);
(gi,
[&](auto&& graph, auto&& a2, auto&& a3)
{
return do_cairo_draw_edges()
(std::forward<decltype(graph)>(graph),
std::forward<decltype(a2)>(a2),
std::forward<decltype(a3)>(a3), vattrs, eattrs,
vdefaults, edefaults, res, mtime, dt, count, cr,
yield);
},
vertex_scalar_vector_properties(), eorder_t())(pos, eorder);
if (!nodesfirst)
{
run_action<>()
(gi, std::bind(do_cairo_draw_vertices(), std::placeholders::_1,
std::placeholders::_2, std::placeholders::_3,
std::ref(vattrs), std::ref(eattrs), std::ref(vdefaults),
std::ref(edefaults), mtime, dt, std::ref(count),
std::ref(cr), std::ref(yield)),
(gi,
[&](auto&& graph, auto&& a2, auto&& a3)
{
return do_cairo_draw_vertices()
(std::forward<decltype(graph)>(graph),
std::forward<decltype(a2)>(a2),
std::forward<decltype(a3)>(a3), vattrs, eattrs,
vdefaults, edefaults, mtime, dt, count, cr,
yield);
},
vertex_scalar_vector_properties(),
vorder_t())(pos, vorder);
}
......@@ -1935,8 +1953,13 @@ void apply_transforms(GraphInterface& gi, boost::any pos, double xx, double yx,
{
Cairo::Matrix m(xx, yx, xy, yy, x0, y0);
run_action<>()
(gi, std::bind(do_apply_transforms(), std::placeholders::_1,
std::placeholders::_2, std::ref(m)),
(gi,
[&](auto&& graph, auto&& a2)
{
return do_apply_transforms()
(std::forward<decltype(graph)>(graph),
std::forward<decltype(a2)>(a2), m);
},
vertex_scalar_vector_properties())(pos);
}
......@@ -2082,8 +2105,13 @@ void put_parallel_splines(GraphInterface& gi, boost::any opos,
angle(loop_angle, vertex_scalar_properties());
run_action<>()
(gi, std::bind(do_put_parallel_splines(), std::placeholders::_1, pos, l,
std::placeholders::_2, angle, parallel_distance),
(gi,
[&](auto&& graph, auto&& a2)
{
return do_put_parallel_splines()
(std::forward<decltype(graph)>(graph), pos, l,
std::forward<decltype(a2)>(a2), angle, parallel_distance);
},
edge_scalar_vector_properties())(splines);
}
......
......@@ -245,10 +245,16 @@ void get_cts(GraphInterface& gi, GraphInterface& tgi, boost::any otpos,
beprop_t beta = boost::any_cast<beprop_t>(obeta);
gt_dispatch<>()
(std::bind(do_get_cts(), std::placeholders::_1, std::placeholders::_2,
std::placeholders::_3, beta, cts, is_tree, max_depth),
graph_tool::all_graph_views(),
graph_tool::always_directed(),
vertex_scalar_vector_properties())
(gi.get_graph_view(), tgi.get_graph_view(), otpos);
(
[&](auto&& graph, auto&& a2, auto&& a3)
{
return do_get_cts()
(std::forward<decltype(graph)>(graph),
std::forward<decltype(a2)>(a2),
std::forward<decltype(a3)>(a3), beta, cts, is_tree,
max_depth);
},
graph_tool::all_graph_views(), graph_tool::always_directed(),
vertex_scalar_vector_properties())(gi.get_graph_view(),
tgi.get_graph_view(), otpos);
}
......@@ -24,7 +24,6 @@
#include <boost/graph/edmonds_karp_max_flow.hpp>
#include <boost/bind.hpp>
using namespace graph_tool;
using namespace boost;
......@@ -69,10 +68,15 @@ void edmonds_karp_max_flow(GraphInterface& gi, size_t src, size_t sink,
boost::any capacity, boost::any res)
{
run_action<graph_tool::detail::always_directed>()
(gi, std::bind(get_edmonds_karp_max_flow(),
std::placeholders::_1, gi.get_vertex_index(), gi.get_edge_index(),
gi.get_edge_index_range(),
src, sink, std::placeholders::_2, std::placeholders::_3),
writable_edge_scalar_properties(), writable_edge_scalar_properties())
(capacity,res);
(gi,
[&](auto&& graph, auto&& a2, auto&& a3)
{
return get_edmonds_karp_max_flow()
(std::forward<decltype(graph)>(graph), gi.get_vertex_index(),
gi.get_edge_index(), gi.get_edge_index_range(), src, sink,
std::forward<decltype(a2)>(a2),
std::forward<decltype(a3)>(a3));
},
writable_edge_scalar_properties(),
writable_edge_scalar_properties())(capacity, res);
}
......@@ -44,7 +44,6 @@ min(const T1& v1, const T2& v2)
}
}
#include <boost/bind.hpp>
using namespace graph_tool;
using namespace boost;
......@@ -96,10 +95,15 @@ void kolmogorov_max_flow(GraphInterface& gi, size_t src, size_t sink,
boost::any capacity, boost::any res)
{
run_action<graph_tool::detail::always_directed, boost::mpl::true_>()
(gi, std::bind(get_kolmogorov_max_flow(),
std::placeholders::_1, gi.get_edge_index(), gi.get_edge_index_range(),
gi.get_vertex_index(), src, sink, std::placeholders::_2,
std::placeholders::_3),
writable_edge_scalar_properties(), writable_edge_scalar_properties())
(capacity,res);
(gi,
[&](auto&& graph, auto&& a2, auto&& a3)
{
return get_kolmogorov_max_flow()
(std::forward<decltype(graph)>(graph), gi.get_edge_index(),
gi.get_edge_index_range(), gi.get_vertex_index(), src, sink,
std::forward<decltype(a2)>(a2),
std::forward<decltype(a3)>(a3));
},
writable_edge_scalar_properties(),
writable_edge_scalar_properties())(capacity, res);
}
......@@ -56,8 +56,14 @@ double min_cut(GraphInterface& gi, boost::any weight, boost::any part_map)
weight_maps;
run_action<graph_tool::detail::never_directed>()
(gi, std::bind(get_min_cut(), std::placeholders::_1, std::placeholders::_2,
std::placeholders::_3, std::ref(mc)),
(gi,
[&](auto&& graph, auto&& a2, auto&& a3)
{
return get_min_cut()
(std::forward<decltype(graph)>(graph),
std::forward<decltype(a2)>(a2),
std::forward<decltype(a3)>(a3), mc);
},
weight_maps(), writable_vertex_scalar_properties())(weight, part_map);
return mc;
}
......@@ -79,7 +85,13 @@ void get_residual_graph(GraphInterface& gi, boost::any capacity,
typedef eprop_map_t<uint8_t>::type emap_t;
emap_t augment = boost::any_cast<emap_t>(oaugment);
run_action<>()
(gi, std::bind(do_get_residual_graph(), std::placeholders::_1,
std::placeholders::_2, std::placeholders::_3, augment),
(gi,
[&](auto&& graph, auto&& a2, auto&& a3)
{
return do_get_residual_graph()
(std::forward<decltype(graph)>(graph),
std::forward<decltype(a2)>(a2),
std::forward<decltype(a3)>(a3), augment);
},
edge_scalar_properties(), edge_scalar_properties())(capacity, res);
}
......@@ -46,7 +46,6 @@ min(const T1& v1, const T2& v2)
#include <boost/graph/push_relabel_max_flow.hpp>
#include <boost/bind.hpp>
using namespace graph_tool;
using namespace boost;
......@@ -86,10 +85,15 @@ void push_relabel_max_flow(GraphInterface& gi, size_t src, size_t sink,
boost::any capacity, boost::any res)
{
run_action<graph_tool::detail::always_directed, boost::mpl::true_>()
(gi, std::bind(get_push_relabel_max_flow(),
std::placeholders::_1, gi.get_vertex_index(), gi.get_edge_index(),
gi.get_edge_index_range(),
src, sink, std::placeholders::_2, std::placeholders::_3),
writable_edge_scalar_properties(), writable_edge_scalar_properties())
(capacity,res);
(gi,
[&](auto&& graph, auto&& a2, auto&& a3)
{
return get_push_relabel_max_flow()
(std::forward<decltype(graph)>(graph), gi.get_vertex_index(),
gi.get_edge_index(), gi.get_edge_index_range(), src, sink,
std::forward<decltype(a2)>(a2),
std::forward<decltype(a3)>(a3));
},
writable_edge_scalar_properties(),
writable_edge_scalar_properties())(capacity, res);
}
......@@ -19,7 +19,6 @@
#define DYNAMIC_SAMPLER_HH
#include "random.hh"
#include <functional>
#include <boost/mpl/if.hpp>
namespace graph_tool
......
......@@ -21,7 +21,6 @@
#include "graph_selectors.hh"
#include "graph_properties.hh"
#include <boost/bind.hpp>
#include <boost/bind/placeholders.hpp>
#include <boost/mpl/push_back.hpp>
#include <boost/python.hpp>
......@@ -100,12 +99,16 @@ void community_network(GraphInterface& gi, GraphInterface& cgi,
vweight = no_vweight_map_t();
run_action<>()
(gi, std::bind(get_community_network_vertices_dispatch(),
std::placeholders::_1, std::ref(cgi.get_graph()),
std::placeholders::_2, condensed_community_property,
std::placeholders::_3, vertex_count),
writable_vertex_properties(), vweight_properties())
(community_property, vweight);
(gi,
[&](auto&& graph, auto&& a2, auto&& a3)
{
return get_community_network_vertices_dispatch()
(std::forward<decltype(graph)>(graph), cgi.get_graph(),
std::forward<decltype(a2)>(a2), condensed_community_property,
std::forward<decltype(a3)>(a3), vertex_count);
},
writable_vertex_properties(),
vweight_properties())(community_property, vweight);
community_network_edges(gi, cgi, community_property,
condensed_community_property, edge_count,
......
......@@ -21,7 +21,6 @@
#include "graph_selectors.hh"
#include "graph_properties.hh"
#include <boost/bind.hpp>
#include <boost/bind/placeholders.hpp>
#include <boost/mpl/push_back.hpp>
#include <boost/python.hpp>
......@@ -86,11 +85,15 @@ void community_network_eavg(GraphInterface& gi, GraphInterface& cgi,
{
// compute weighted values to temp
run_action<>()
(gi, std::bind(get_weighted_edge_property_dispatch(),
std::placeholders::_1, std::placeholders::_2,
std::placeholders::_3, temp),
eweight_properties(), eprops_t())
(eweight, eprop);
(gi,
[&](auto&& graph, auto&& a2, auto&& a3)
{
return get_weighted_edge_property_dispatch()
(std::forward<decltype(graph)>(graph),
std::forward<decltype(a2)>(a2),
std::forward<decltype(a3)>(a3), temp);
},
eweight_properties(), eprops_t())(eweight, eprop);
// sum weighted values
sum_eprops(gi, cgi, community_property,
......
......@@ -21,7 +21,6 @@
#include "graph_selectors.hh"
#include "graph_properties.hh"
#include <boost/bind.hpp>
#include <boost/bind/placeholders.hpp>
#include <boost/mpl/push_back.hpp>
#include <boost/python.hpp>
......@@ -64,11 +63,14 @@ void sum_eprops(GraphInterface& gi, GraphInterface& cgi,
eprops_t;
run_action<>()
(gi, std::bind(get_edge_sum_dispatch(),
std::placeholders::_1, std::ref(cgi.get_graph()),
std::placeholders::_2,
condensed_community_property, std::placeholders::_3,
ceprop, self_loops, parallel_edges),
writable_vertex_properties(), eprops_t())
(community_property, eprop);
(gi,
[&](auto&& graph, auto&& a2, auto&& a3)
{
return get_edge_sum_dispatch()
(std::forward<decltype(graph)>(graph), cgi.get_graph(),
std::forward<decltype(a2)>(a2), condensed_community_property,
std::forward<decltype(a3)>(a3), ceprop, self_loops,
parallel_edges);
},
writable_vertex_properties(), eprops_t())(community_property, eprop);
}
......@@ -21,7 +21,6 @@
#include "graph_selectors.hh"
#include "graph_properties.hh"
#include <boost/bind.hpp>
#include <boost/bind/placeholders.hpp>
#include <boost/mpl/push_back.hpp>
#include <boost/python.hpp>
......@@ -75,10 +74,16 @@ void community_network_edges(GraphInterface& gi, GraphInterface& cgi,
eweight = no_eweight_map_t();
run_action<>()
(gi, std::bind(get_community_network_edges_dispatch(self_loops, parallel_edges),
std::placeholders::_1, std::ref(cgi.get_graph()), cgi.get_edge_index(),
std::placeholders::_2, condensed_community_property,
std::placeholders::_3, edge_count),
writable_vertex_properties(), eweight_properties())
(community_property, eweight);
(gi,
[&](auto&& graph, auto&& a2, auto&& a3)
{
return get_community_network_edges_dispatch(self_loops,
parallel_edges)(
std::forward<decltype(graph)>(graph), cgi.get_graph(),
cgi.get_edge_index(), std::forward<decltype(a2)>(a2),
condensed_community_property, std::forward<decltype(a3)>(a3),
edge_count);
},
writable_vertex_properties(),
eweight_properties())(community_property, eweight);
}
......@@ -21,7 +21,6 @@
#include "graph_selectors.hh"
#include "graph_properties.hh"
#include <boost/bind.hpp>
#include <boost/bind/placeholders.hpp>
#include <boost/mpl/push_back.hpp>
#include <boost/python.hpp>
......@@ -97,33 +96,45 @@ void community_network_vavg(GraphInterface& gi, GraphInterface& cgi,
{
// compute weighted values to temp
run_action<>()
(gi, std::bind(get_weighted_vertex_property_dispatch(),
std::placeholders::_1, std::placeholders::_2,
std::placeholders::_3, temp),
vweight_properties(), vprops_t())
(vweight, vprop);
(gi,
[&](auto&& graph, auto&& a2, auto&& a3)
{
return get_weighted_vertex_property_dispatch()
(std::forward<decltype(graph)>(graph),
std::forward<decltype(a2)>(a2),
std::forward<decltype(a3)>(a3), temp);
},
vweight_properties(), vprops_t())(vweight, vprop);
// sum weighted values
run_action<>()
(gi, std::bind(get_vertex_sum_dispatch(),
std::placeholders::_1, std::ref(cgi.get_graph()),
std::placeholders::_2,
condensed_community_property,
std::placeholders::_3, cvprop),
writable_vertex_properties(), vprops_t())
(community_property, temp);
(gi,
[&](auto&& graph, auto&& a2, auto&& a3)
{
return get_vertex_sum_dispatch()
(std::forward<decltype(graph)>(graph), cgi.get_graph(),
std::forward<decltype(a2)>(a2),
condensed_community_property,
std::forward<decltype(a3)>(a3), cvprop);
},
writable_vertex_properties(),
vprops_t())(community_property, temp);
}
else
{
// sum unweighted values
run_action<>()
(gi, std::bind(get_vertex_sum_dispatch(),
std::placeholders::_1, std::ref(cgi.get_graph()),
std::placeholders::_2,
condensed_community_property,
std::placeholders::_3, cvprop),
writable_vertex_properties(), vprops_t())
(community_property, vprop);
(gi,
[&](auto&& graph, auto&& a2, auto&& a3)
{
return get_vertex_sum_dispatch()
(std::forward<decltype(graph)>(graph), cgi.get_graph(),
std::forward<decltype(a2)>(a2),
condensed_community_property,
std::forward<decltype(a3)>(a3), cvprop);
},
writable_vertex_properties(),
vprops_t())(community_property, vprop);
}
}
}
......@@ -64,10 +64,14 @@ void generate_graph(GraphInterface& gi, size_t N,
gi.set_directed(false);
run_action<graph_views>()
(gi, std::bind(gen_graph(), std::placeholders::_1, N,
PythonFuncWrap(deg_sample),
no_parallel, no_self_loops,
std::ref(rng), verbose, verify))();
(gi,
[&](auto&& graph)
{
return gen_graph()
(std::forward<decltype(graph)>(graph), N,
PythonFuncWrap(deg_sample), no_parallel, no_self_loops, rng,
verbose, verify);
})();
}
void generate_sbm(GraphInterface& gi, boost::any ab, boost::python::object ors,
......
......@@ -433,7 +433,7 @@ bool update_deg(size_t t_i, const pair<size_t, size_t>& deg, Vset& vset,
struct gen_graph
{
template <class Graph, class DegSample>
void operator()(Graph& g, size_t N, DegSample& deg_sample, bool no_parallel,
void operator()(Graph& g, size_t N, DegSample const& deg_sample, bool no_parallel,
bool no_self_loops, rng_t& rng, bool verbose, bool verify)
const
{
......
......@@ -59,9 +59,13 @@ void geometric(GraphInterface& gi, python::object opoints, double r,
range[i].second = python::extract<double>(orange[i][1]);
}
run_action<graph_views>()(gi, std::bind(get_geometric(), std::placeholders::_1,
std::placeholders::_2, std::ref(points),
std::ref(range), r,
periodic),
prop_types())(pos);
run_action<graph_views>()
(gi,
[&](auto&& graph, auto&& a2)
{
return get_geometric()
(std::forward<decltype(graph)>(graph),
std::forward<decltype(a2)>(a2), points, range, r, periodic);
},
prop_types())(pos);
}
......@@ -92,9 +92,14 @@ void line_graph(GraphInterface& gi, GraphInterface& lgi,
boost::mpl::false_>::type
vertex_properties;
run_action<>()(gi, std::bind(get_line_graph(), std::placeholders::_1,
gi.get_vertex_index(),
std::ref(lgi.get_graph()), lgi.get_edge_index(),
std::placeholders::_2),
vertex_properties())(edge_index);
run_action<>()
(gi,
[&](auto&& graph, auto&& a2)
{
return get_line_graph()
(std::forward<decltype(graph)>(graph), gi.get_vertex_index(),
lgi.get_graph(), lgi.get_edge_index(),
std::forward<decltype(a2)>(a2));
},
vertex_properties())(edge_index);
}
......@@ -26,8 +26,13 @@ using namespace boost;
void predecessor_graph(GraphInterface& gi, GraphInterface& gpi,
boost::any pred_map)
{
run_action<>()(gi, std::bind(get_predecessor_graph(), std::placeholders::_1,
std::ref(gpi