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,
boost::any prop, size_t pos, bool edge);
void group_vector_property(GraphInterface& g, boost::any vector_prop,
boost::any prop, size_t pos, bool edge);
void infect_vertex_property(GraphInterface& gi, boost::any prop,
python::object val);
void export_python_interface();
BOOST_PYTHON_MODULE(libgraph_tool_core)
......@@ -405,6 +407,7 @@ BOOST_PYTHON_MODULE(libgraph_tool_core)
def("group_vector_property", &group_vector_property);
def("ungroup_vector_property", &ungroup_vector_property);
def("infect_vertex_property", &infect_vertex_property);
class_<LibInfo>("mod_info")
.add_property("name", &LibInfo::GetName)
......
......@@ -21,6 +21,12 @@
#include "graph_selectors.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/python/extract.hpp>
......@@ -68,4 +74,71 @@ void GraphInterface::ShiftVertexProperty(boost::any prop, size_t index) const
throw GraphException("invalid writable property map");
}
} // 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",
"PropertyMap", "group_vector_property", "ungroup_vector_property",
"show_config", "PropertyArray", "__author__", "__copyright__",
"__URL__", "__version__"]
"infect_vertex_property", "edge_difference", "show_config",
# this is rather pointless, but it works around a sphinx bug
graph_tool = sys.modules[__name__]
......@@ -755,6 +756,35 @@ def ungroup_vector_property(vprop, pos, props=None):
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):
"""Wrapper for the dict of vertex, graph or edge properties, which sets the
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