Commit bc1feb23 authored by Tiago Peixoto's avatar Tiago Peixoto

Implement map_property_values()

parent 40aaa59c
......@@ -32,6 +32,7 @@ libgraph_tool_core_la_SOURCES = \
graph_properties_copy.cc \
graph_properties_group.cc \
graph_properties_ungroup.cc \
graph_properties_map_values.cc \
graph_python_interface.cc \
graph_python_interface_export.cc \
graph_selectors.cc \
......@@ -53,6 +54,7 @@ libgraph_tool_core_la_include_HEADERS = \
graph_io_binary.hh \
graph_properties.hh \
graph_properties_group.hh \
graph_properties_map_values.hh \
graph_python_interface.hh \
graph_selectors.hh \
graph_util.hh \
......
......@@ -385,6 +385,9 @@ 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 property_map_values(GraphInterface& g, boost::any src_prop,
boost::any tgt_prop, boost::python::object mapper,
bool edge);
void infect_vertex_property(GraphInterface& gi, boost::any prop,
boost::python::object val);
void edge_endpoint(GraphInterface& gi, boost::any prop,
......@@ -517,6 +520,7 @@ BOOST_PYTHON_MODULE(libgraph_tool_core)
def("group_vector_property", &group_vector_property);
def("ungroup_vector_property", &ungroup_vector_property);
def("property_map_values", &property_map_values);
def("infect_vertex_property", &infect_vertex_property);
def("edge_endpoint", &edge_endpoint);
def("out_edges_op", &out_edges_op);
......
// 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.hh"
#include "graph_properties.hh"
#include "graph_filtering.hh"
#include "graph_selectors.hh"
#include "graph_util.hh"
#include "graph_python_interface.hh"
#include "graph_properties_map_values.hh"
using namespace std;
using namespace boost;
using namespace graph_tool;
void property_map_values(GraphInterface& g, boost::any src_prop,
boost::any tgt_prop, boost::python::object mapper,
bool edge)
{
if (!edge)
{
run_action<graph_tool::detail::always_directed_never_reversed>()
(g, std::bind(do_map_values(), placeholders::_1, placeholders::_2,
placeholders::_3, std::ref(mapper)),
vertex_properties(), writable_vertex_properties())
(src_prop, tgt_prop);
}
else
{
run_action<graph_tool::detail::always_directed_never_reversed>()
(g, std::bind(do_map_values(), placeholders::_1, placeholders::_2,
placeholders::_3, std::ref(mapper)),
edge_properties(), writable_edge_properties())
(src_prop, tgt_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/>.
#ifndef GRAPH_PROPERTIES_MAP_VALUES_HH
#define GRAPH_PROPERTIES_MAP_VALUES_HH
#include <unordered_map>
#include <boost/python/extract.hpp>
namespace graph_tool
{
using namespace boost;
struct do_map_values
{
template <class Graph, class SrcProp, class TgtProp>
void operator()(Graph& g, SrcProp src, TgtProp tgt, python::object& mapper) const
{
typedef typename graph_traits<Graph>::vertex_descriptor vertex_t;
typedef typename property_traits<SrcProp>::key_type key_type;
typedef typename property_traits<SrcProp>::value_type src_value_type;
typedef typename property_traits<TgtProp>::value_type tgt_value_type;
std::unordered_map<src_value_type, tgt_value_type> value_map;
dispatch(g, src, tgt, value_map, mapper, std::is_same<key_type, vertex_t>());
}
template <class Graph, class SrcProp, class TgtProp, class ValueMap>
void dispatch(Graph& g, SrcProp& src, TgtProp& tgt, ValueMap& value_map,
python::object& mapper, std::true_type) const
{
dispatch_descriptor(src, tgt, value_map, mapper, vertices_range(g));
}
template <class Graph, class SrcProp, class TgtProp, class ValueMap>
void dispatch(Graph& g, SrcProp& src, TgtProp& tgt, ValueMap& value_map,
python::object& mapper, std::false_type) const
{
dispatch_descriptor(src, tgt, value_map, mapper, edges_range(g));
}
template <class SrcProp, class TgtProp, class ValueMap, class Range>
void dispatch_descriptor(SrcProp& src, TgtProp& tgt, ValueMap& value_map,
python::object& mapper, Range && range) const
{
typedef typename property_traits<TgtProp>::value_type tgt_value_type;
for (const auto& v : range)
{
const auto& k = src[v];
const auto& iter = value_map.find(k);
if (iter == value_map.end())
{
value_map[k] = tgt[v] =
boost::python::extract<tgt_value_type>(mapper(k));
}
else
{
tgt[v] = iter->second;
}
}
}
};
} // namespace graph_tool
#endif // GRAPH_PROPERTIES_MAP_VALUES_HH
......@@ -37,6 +37,7 @@ Summary
load_graph
group_vector_property
ungroup_vector_property
map_property_values
infect_vertex_property
edge_endpoint_property
incident_edges_op
......@@ -125,12 +126,12 @@ __all__ = ["Graph", "GraphView", "Vertex", "Edge", "Vector_bool",
"Vector_double", "Vector_long_double", "Vector_string",
"Vector_size_t", "value_types", "load_graph", "PropertyMap",
"group_vector_property", "ungroup_vector_property",
"infect_vertex_property", "edge_endpoint_property",
"incident_edges_op", "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__"]
"map_property_values", "infect_vertex_property",
"edge_endpoint_property", "incident_edges_op", "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 +1037,49 @@ def ungroup_vector_property(vprop, pos, props=None):
props[i][g] = vprop[g][pos[i]]
return props
def map_property_values(src_prop, tgt_prop, map_func):
"""Map the values of ``src_prop`` to ``tgt_prop`` according to the mapping
function ``map_func``.
Parameters
----------
src_prop : :class:`~graph_tool.PropertyMap`
Source property map.
tgt_prop : :class:`~graph_tool.PropertyMap`
Target property map.
map_func : function or callable object
Function mapping values of ``src_prop`` to values of ``tgt_prop``.
Returns
-------
None
Examples
--------
>>> g = gt.collection.data["lesmis"]
>>> label_len = g.new_vertex_property("int64_t")
>>> gt.map_property_values(g.vp.label, label_len,
... label x: len(x))
>>> print(label_len.a)
[ 6 8 14 11 12 8 12 8 5 6 7 7 10 6 7 7 9 9 7 11 9 6 7 7 13
10 7 6 12 10 8 8 11 6 5 12 6 10 11 9 12 7 7 6 14 7 9 9 8 12
6 16 12 11 14 6 9 6 8 10 9 7 10 7 7 4 9 14 9 5 10 12 9 6 6
6 12]
"""
if src_prop.key_type() != tgt_prop.key_type():
raise ValueError("src_prop and tgt_prop must be of the same key type")
g = src_prop.get_graph()
k = src_prop.key_type()
if k == "g":
tgt_prop[g] = map_func(src_prop[g])
return
u = GraphView(g, directed=True, reversed=g.is_reversed(),
skip_properties=True)
libcore.property_map_values(u._Graph__graph,
_prop(k, g, src_prop),
_prop(k, g, tgt_prop),
map_func, k == 'e')
def infect_vertex_property(g, prop, vals=None):
"""Propagate the `prop` values of vertices with value `val` to all their
......
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