Commit 0595e4f3 authored by Tiago Peixoto's avatar Tiago Peixoto
Browse files

Implement infect_vertex_property()

parent d7e364cf
...@@ -318,6 +318,8 @@ void ungroup_vector_property(GraphInterface& g, boost::any vector_prop, ...@@ -318,6 +318,8 @@ void ungroup_vector_property(GraphInterface& g, boost::any vector_prop,
boost::any prop, size_t pos, bool edge); boost::any prop, size_t pos, bool edge);
void group_vector_property(GraphInterface& g, boost::any vector_prop, void group_vector_property(GraphInterface& g, boost::any vector_prop,
boost::any prop, size_t pos, bool edge); boost::any prop, size_t pos, bool edge);
void infect_vertex_property(GraphInterface& gi, boost::any prop,
python::object val);
void export_python_interface(); void export_python_interface();
BOOST_PYTHON_MODULE(libgraph_tool_core) BOOST_PYTHON_MODULE(libgraph_tool_core)
...@@ -405,6 +407,7 @@ BOOST_PYTHON_MODULE(libgraph_tool_core) ...@@ -405,6 +407,7 @@ BOOST_PYTHON_MODULE(libgraph_tool_core)
def("group_vector_property", &group_vector_property); def("group_vector_property", &group_vector_property);
def("ungroup_vector_property", &ungroup_vector_property); def("ungroup_vector_property", &ungroup_vector_property);
def("infect_vertex_property", &infect_vertex_property);
class_<LibInfo>("mod_info") class_<LibInfo>("mod_info")
.add_property("name", &LibInfo::GetName) .add_property("name", &LibInfo::GetName)
......
...@@ -21,6 +21,12 @@ ...@@ -21,6 +21,12 @@
#include "graph_selectors.hh" #include "graph_selectors.hh"
#include "graph_util.hh" #include "graph_util.hh"
#if (GCC_VERSION >= 40400)
# include <tr1/unordered_set>
#else
# include <boost/tr1/unordered_set.hpp>
#endif
#include <boost/mpl/for_each.hpp> #include <boost/mpl/for_each.hpp>
#include <boost/python/extract.hpp> #include <boost/python/extract.hpp>
...@@ -68,4 +74,71 @@ void GraphInterface::ShiftVertexProperty(boost::any prop, size_t index) const ...@@ -68,4 +74,71 @@ void GraphInterface::ShiftVertexProperty(boost::any prop, size_t index) const
throw GraphException("invalid writable property map"); throw GraphException("invalid writable property map");
} }
} // graph_tool namespace } // graph_tool namespace
struct do_infect_vertex_property
{
template <class Graph, class IndexMap, class PropertyMap>
void operator()(Graph& g, IndexMap index, PropertyMap prop,
python::object oval) const
{
typedef typename property_traits<PropertyMap>::value_type val_t;
bool all = false;
tr1::unordered_set<val_t, boost::hash<val_t> > vals;
if (oval == python::object())
{
all = true;
}
else
{
for (int i = 0; i < len(oval); ++i)
{
val_t val = python::extract<val_t>(oval[i]);
vals.insert(val);
}
}
unchecked_vector_property_map<uint8_t, IndexMap>
marked(index, num_vertices(g));
int i, N = num_vertices(g);
#pragma omp parallel for default(shared) private(i)
for (i = 0; i < N; ++i)
{
typename graph_traits<Graph>::vertex_descriptor v = vertex(i, g);
if (v == graph_traits<Graph>::null_vertex())
continue;
bool skip;
{
#pragma omp critical
skip = marked[v];
}
if (skip)
continue;
if (!all && vals.find(prop[v]) == vals.end())
continue;
typename graph_traits<Graph>::adjacency_iterator a, a_end;
for (tie(a, a_end) = adjacent_vertices(v, g); a != a_end; ++a)
{
if (prop[*a] == prop[v])
continue;
{
#pragma omp critical
marked[*a] = true;
}
prop[*a] = prop[v];
}
}
}
};
void infect_vertex_property(GraphInterface& gi, boost::any prop,
python::object val)
{
run_action<>()(gi, bind<void>(do_infect_vertex_property(), _1,
gi.GetVertexIndex(), _2, val),
writable_vertex_properties())(prop);
}
...@@ -113,6 +113,7 @@ __all__ = ["Graph", "GraphView", "Vertex", "Edge", "Vector_bool", ...@@ -113,6 +113,7 @@ __all__ = ["Graph", "GraphView", "Vertex", "Edge", "Vector_bool",
"PropertyMap", "group_vector_property", "ungroup_vector_property", "PropertyMap", "group_vector_property", "ungroup_vector_property",
"show_config", "PropertyArray", "__author__", "__copyright__", "show_config", "PropertyArray", "__author__", "__copyright__",
"__URL__", "__version__"] "__URL__", "__version__"]
"infect_vertex_property", "edge_difference", "show_config",
# this is rather pointless, but it works around a sphinx bug # this is rather pointless, but it works around a sphinx bug
graph_tool = sys.modules[__name__] graph_tool = sys.modules[__name__]
...@@ -755,6 +756,35 @@ def ungroup_vector_property(vprop, pos, props=None): ...@@ -755,6 +756,35 @@ def ungroup_vector_property(vprop, pos, props=None):
return props return props
def infect_vertex_property(g, prop, vals=None):
"""Propagate the `prop` values of vertices with value `val` to all their
out-neighbours.
Parameters
----------
prop : :class:`~graph_tool.PropertyMap`
Property map to be modified.
vals : list (optional, default: `None`)
List of values to be propagated. If not provided, all values
will be propagated.
Returns
-------
None
Examples
--------
>>> from numpy.random import seed
>>> seed(42)
>>> g = gt.random_graph(100, lambda: (3, 3))
>>> prop = g.copy_property(g.vertex_index)
>>> gt.infect_vertex_property(g, prop, [10])
>>> print sum(prop.a == 10)
3
"""
libcore.infect_vertex_property(g._Graph__graph, _prop("v", g, prop),
vals)
class PropertyDict(dict): class PropertyDict(dict):
"""Wrapper for the dict of vertex, graph or edge properties, which sets the """Wrapper for the dict of vertex, graph or edge properties, which sets the
value on the property map when changed in the dict.""" value on the property map when changed in the dict."""
......
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