Commit 126f2179 authored by Tiago Peixoto's avatar Tiago Peixoto
Browse files

Implement incident_edges_sum()

parent 010afe9b
......@@ -27,6 +27,7 @@ libgraph_tool_core_la_SOURCES = \
graph_openmp.cc \
graph_properties.cc \
graph_properties_imp1.cc \
graph_properties_imp2.cc \
graph_properties_copy.cc \
graph_properties_group.cc \
graph_properties_ungroup.cc \
......
......@@ -392,6 +392,8 @@ void infect_vertex_property(GraphInterface& gi, boost::any prop,
boost::python::object val);
void edge_endpoint(GraphInterface& gi, boost::any prop,
boost::any eprop, std::string endpoint);
void out_edges_sum(GraphInterface& gi, boost::any eprop, boost::any vprop);
void mark_edges(GraphInterface& gi, boost::any prop);
void perfect_ehash(GraphInterface& gi, boost::any prop, boost::any hprop,
......@@ -521,6 +523,7 @@ BOOST_PYTHON_MODULE(libgraph_tool_core)
def("ungroup_vector_property", &ungroup_vector_property);
def("infect_vertex_property", &infect_vertex_property);
def("edge_endpoint", &edge_endpoint);
def("out_edges_sum", &out_edges_sum);
def("mark_edges", &mark_edges);
def("perfect_ehash", &perfect_ehash);
def("perfect_vhash", &perfect_vhash);
......
......@@ -42,13 +42,13 @@ struct do_edge_endpoint
eprop.reserve(num_edges(g));
int i, N = num_vertices(g);
#pragma omp parallel for default(shared) private(i)
#pragma omp parallel for default(shared) private(i) \
schedule(runtime) if (N > 100)
for (i = 0; i < N; ++i)
{
typename graph_traits<Graph>::vertex_descriptor v = vertex(i, g);
if (v == graph_traits<Graph>::null_vertex())
continue;
typename graph_traits<Graph>::out_edge_iterator e, e_end;
for (auto e : out_edges_range(v, g))
{
auto s = v;
......@@ -68,11 +68,11 @@ void edge_endpoint(GraphInterface& gi, boost::any prop,
boost::any eprop, std::string endpoint)
{
if (endpoint == "source")
run_action<>()(gi, bind<void>(do_edge_endpoint<true>(), _1,
gi.GetEdgeIndex(), _2, eprop),
run_action<>()(gi, std::bind(do_edge_endpoint<true>(), placeholders::_1,
gi.GetEdgeIndex(), placeholders::_2, eprop),
vertex_properties())(prop);
else
run_action<>()(gi, bind<void>(do_edge_endpoint<false>(), _1,
gi.GetEdgeIndex(), _2, eprop),
run_action<>()(gi, std::bind(do_edge_endpoint<false>(), placeholders::_1,
gi.GetEdgeIndex(), placeholders::_2, eprop),
vertex_properties())(prop);
}
// graph-tool -- a general graph modification and manipulation thingy
//
// Copyright (C) 2006-2015 Tiago de Paula Peixoto <tiago@skewed.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 3
// 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, see <http://www.gnu.org/licenses/>.
#include "graph_python_interface.hh"
#include "graph.hh"
#include "graph_properties.hh"
#include "graph_filtering.hh"
#include "graph_selectors.hh"
#include "graph_util.hh"
using namespace std;
using namespace boost;
using namespace graph_tool;
template <class Val1, class Val2>
void operator+=(std::vector<Val1>& v1, const std::vector<Val2>& v2)
{
if (v2.size() > v1.size())
v1.resize(v2.size());
for (size_t i = 0; i < v2.size(); ++i)
v1[i] += v2[i];
}
struct do_out_edges_sum
{
template <class Graph, class EProp, class VProp>
void operator()(Graph& g, EProp eprop, VProp vprop) const
{
typedef typename property_traits<EProp>::value_type eval_t;
typedef typename property_traits<VProp>::value_type vval_t;
convert<vval_t, eval_t> conv;
int i, N = num_vertices(g);
#pragma omp parallel for default(shared) private(i) \
schedule(runtime) if (N > 100)
for (i = 0; i < N; ++i)
{
typename graph_traits<Graph>::vertex_descriptor v = vertex(i, g);
if (v == graph_traits<Graph>::null_vertex())
continue;
vprop[v] = vval_t();
for (auto e : out_edges_range(v, g))
vprop[v] += conv(eprop[e]);
}
}
};
void out_edges_sum(GraphInterface& gi, boost::any eprop, boost::any vprop)
{
run_action<>()(gi, std::bind(do_out_edges_sum(), placeholders::_1,
placeholders::_2, placeholders::_3),
edge_properties(), writable_vertex_properties())
(eprop, vprop);
}
......@@ -39,6 +39,7 @@ Summary
ungroup_vector_property
infect_vertex_property
edge_endpoint_property
incident_edges_sum
perfect_prop_hash
value_types
show_config
......@@ -124,10 +125,11 @@ __all__ = ["Graph", "GraphView", "Vertex", "Edge", "Vector_bool",
"Vector_size_t", "value_types", "load_graph", "PropertyMap",
"group_vector_property", "ungroup_vector_property",
"infect_vertex_property", "edge_endpoint_property",
"perfect_prop_hash", "seed_rng", "show_config", "PropertyArray",
"openmp_enabled", "openmp_get_num_threads", "openmp_set_num_threads",
"openmp_get_schedule", "openmp_set_schedule", "__author__",
"__copyright__", "__URL__", "__version__"]
"incident_edges_sum", "perfect_prop_hash", "seed_rng", "show_config",
"PropertyArray", "openmp_enabled", "openmp_get_num_threads",
"openmp_set_num_threads", "openmp_get_schedule",
"openmp_set_schedule", "__author__", "__copyright__", "__URL__",
"__version__"]
# this is rather pointless, but it works around a sphinx bug
graph_tool = sys.modules[__name__]
......@@ -1036,6 +1038,53 @@ def edge_endpoint_property(g, prop, endpoint, eprop=None):
_prop("e", g, eprop), endpoint)
return eprop
@_limit_args({"direction": ["in", "out"]})
def incident_edges_sum(g, direction, eprop, vprop=None):
"""Return a vertex property map corresponding to the sum of the edge property
`eprop` of incident edges on each vertex, following the direction given by
`direction`.
Parameters
----------
direction : `"in"` or `"out"`
Direction of the incident edges.
eprop : :class:`~graph_tool.PropertyMap`
Edge property map to be summed.
vprop : :class:`~graph_tool.PropertyMap` (optional, default: `None`)
If provided, the resulting vertex properties will be stored here.
Returns
-------
vprop : :class:`~graph_tool.PropertyMap`
Summed vertex property.
Examples
--------
>>> gt.seed_rng(42)
>>> g = gt.random_graph(100, lambda: (3, 3))
>>> vsum = gt.incident_edges_sum(g, "out", g.edge_index)
>>> print(vsum.a)
[ 3 237 246 255 219 264 273 282 210 291 300 453 201 687 309 696 192 705
669 318 183 714 723 732 174 327 660 741 165 750 336 759 156 651 768 345
147 777 786 642 138 354 795 804 129 813 363 633 120 822 831 372 111 840
624 849 102 381 858 867 93 615 390 876 84 885 894 399 75 606 678 597
66 408 588 579 57 570 417 561 48 552 543 426 39 534 525 516 30 435
507 498 21 489 444 480 12 471 462 228]
"""
val_t = eprop.value_type()
if val_t == "unsigned long":
val_t = "int64_t"
if vprop is None:
vprop = g.new_vertex_property(val_t)
if direction == "in" and not g.is_directed():
return vprop
if direction == "in":
g = GraphView(g, reversed=True, skip_properties=True)
libcore.out_edges_sum(g._Graph__graph, _prop("e", g, eprop),
_prop("v", g, vprop))
return vprop
@_limit_args({"htype": ["int8_t", "int32_t", "int64_t"]})
def perfect_prop_hash(props, htype="int32_t"):
"""Given a list of property maps `props` of the same type, a derived list of
......
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