Commit 6957f8ec authored by Tiago Peixoto's avatar Tiago Peixoto
Browse files

Implement PropertyMap.set_value()

parent bc126545
......@@ -400,6 +400,10 @@ void perfect_ehash(GraphInterface& gi, boost::any prop, boost::any hprop,
boost::any& dict);
void perfect_vhash(GraphInterface& gi, boost::any prop, boost::any hprop,
boost::any& dict);
void set_vertex_property(GraphInterface& gi, boost::any prop,
boost::python::object val);
void set_edge_property(GraphInterface& gi, boost::any prop,
boost::python::object val);
void export_python_interface();
......@@ -527,6 +531,8 @@ BOOST_PYTHON_MODULE(libgraph_tool_core)
def("mark_edges", &mark_edges);
def("perfect_ehash", &perfect_ehash);
def("perfect_vhash", &perfect_vhash);
def("set_vertex_property", &set_vertex_property);
def("set_edge_property", &set_edge_property);
class_<LibInfo>("mod_info")
.add_property("name", &LibInfo::GetName)
......
......@@ -176,36 +176,37 @@ struct do_infect_vertex_property
}
}
unchecked_vector_property_map<uint8_t, IndexMap>
unchecked_vector_property_map<bool, IndexMap>
marked(index, num_vertices(g));
PropertyMap temp(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);
auto 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)
for (auto a : adjacent_vertices_range(v, g))
{
if (prop[*a] == prop[v])
if (prop[a] == prop[v])
continue;
{
#pragma omp critical
marked[*a] = true;
marked[a] = true;
temp[a] = prop[v];
}
prop[*a] = prop[v];
}
#pragma omp parallel for default(shared) private(i)
for (i = 0; i < N; ++i)
{
auto v = vertex(i, g);
if (v == graph_traits<Graph>::null_vertex())
continue;
if (marked[v])
prop[v] = temp[v];
}
}
};
......@@ -332,3 +333,46 @@ void perfect_ehash(GraphInterface& gi, boost::any prop, boost::any hprop,
edge_properties(), writable_edge_scalar_properties())
(prop, hprop);
}
struct do_set_vertex_property
{
template <class Graph, class PropertyMap>
void operator()(Graph& g, PropertyMap prop, boost::python::object oval) const
{
typedef typename property_traits<PropertyMap>::value_type val_t;
val_t val = boost::python::extract<val_t>(oval);
for (auto v : vertices_range(g))
prop[v] = val;
}
};
void set_vertex_property(GraphInterface& gi, boost::any prop,
boost::python::object val)
{
run_action<>()(gi, std::bind(do_set_vertex_property(), std::placeholders::_1,
std::placeholders::_2, val),
writable_vertex_properties())(prop);
}
struct do_set_edge_property
{
template <class Graph, class PropertyMap>
void operator()(Graph& g, PropertyMap prop, boost::python::object oval) const
{
typedef typename property_traits<PropertyMap>::value_type val_t;
val_t val = boost::python::extract<val_t>(oval);
for (auto e : edges_range(g))
prop[e] = val;
}
};
void set_edge_property(GraphInterface& gi, boost::any prop,
boost::python::object val)
{
run_action<>()(gi, std::bind(do_set_edge_property(), std::placeholders::_1,
std::placeholders::_2, val),
writable_edge_properties())(prop);
}
......@@ -799,6 +799,17 @@ class PropertyMap(object):
"""Return True if the property is writable."""
return self.__map.is_writable()
def set_value(self, val):
"""Sets all values in the property map to ``val``."""
g = self.get_graph()
if self.key_type() == "v":
libcore.set_vertex_property(g._Graph__graph, self.__map.get_map(), val)
elif self.key_type() == "e":
libcore.set_edge_property(g._Graph__graph, self.__map.get_map(), val)
else:
self[g] = val
def __call__(self, a):
p = self.copy()
p.fa = a
......@@ -2084,26 +2095,30 @@ class Graph(object):
return self.new_graph_property(value_type, vals)
raise ValueError("unknown key type: " + key_type)
def new_vertex_property(self, value_type, vals=None):
"""Create a new (uninitialized) vertex property map of type ``value_type``,
and return it. If provided, the values will be initialized by ``vals``,
which should be either a sequence or a single value."""
def new_vertex_property(self, value_type, vals=None, val=None):
"""Create a new vertex property map of type ``value_type``, and return it. If
provided, the values will be initialized by ``vals``, which should be
sequence or by ``val`` which should be a single value.
"""
prop = PropertyMap(new_vertex_property(_type_alias(value_type),
self.__graph.GetVertexIndex(),
libcore.any()),
self, "v")
if vals is not None:
try:
prop.a = vals
prop.fa = vals
except ValueError:
for v, x in zip(self.vertices(), vals):
prop[v] = x
elif val is not None:
prop.set_value(val)
return prop
def new_edge_property(self, value_type, vals=None):
"""Create a new (uninitialized) edge property map of type
``value_type``, and return it. If provided, the values will be
initialized by ``vals``, which should be a sequence or a single value."""
def new_edge_property(self, value_type, vals=None, val=None):
"""Create a new edge property map of type ``value_type``, and return it. If
provided, the values will be initialized by ``vals``, which should be
sequence or by ``val`` which should be a single value.
"""
prop = PropertyMap(new_edge_property(_type_alias(value_type),
self.__graph.GetEdgeIndex(),
libcore.any()),
......@@ -2114,6 +2129,8 @@ class Graph(object):
except ValueError:
for e, x in zip(self.edges(), vals):
prop[e] = x
elif val is not None:
prop.set_value(val)
return prop
def new_graph_property(self, value_type, val=None):
......@@ -2131,11 +2148,12 @@ class Graph(object):
@_require("src", PropertyMap)
@_require("tgt", (PropertyMap, type(None)))
def copy_property(self, src, tgt=None, value_type=None, g=None):
"""Copy contents of ``src`` property to ``tgt`` property. If ``tgt`` is
None, then a new property map of the same type (or with the type given
by the optional ``value_type`` parameter) is created, and returned. The
optional parameter g specifies the (identical) source graph to copy
properties from (defaults to self).
"""Copy contents of ``src`` property to ``tgt`` property. If ``tgt`` is None,
then a new property map of the same type (or with the type given by the
optional ``value_type`` parameter) is created, and returned. The
optional parameter ``g`` specifies the source graph to copy properties
from (defaults to self).
"""
if tgt is None:
tgt = self.new_property(src.key_type(),
......@@ -2159,13 +2177,29 @@ class Graph(object):
g.set_edge_filter(None)
g.set_vertex_filter(None)
if src.key_type() == "v":
if g.num_vertices() > self.num_vertices():
raise ValueError("graphs with incompatible sizes (%d, %d)" %
(g.num_vertices(), self.num_vertices()))
try:
self.__graph.CopyVertexProperty(g.__graph,
_prop("v", g, src),
_prop("v", self, tgt))
except ValueError:
raise ValueError("property maps with the following types are"
" not convertible: %s, %s" %
(src.value_type(), tgt.value_type()))
elif src.key_type() == "e":
if g.num_edges() > self.num_edges():
raise ValueError("graphs with incompatible sizes (%d, %d)" %
(g.num_edges(), self.num_edges()))
try:
self.__graph.CopyEdgeProperty(g.__graph,
_prop("e", g, src),
_prop("e", self, tgt))
except ValueError:
raise ValueError("property maps with the following types are"
" not convertible: %s, %s" %
(src.value_type(), tgt.value_type()))
else:
tgt[self] = src[g]
finally:
......
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