Commit 242bfff7 authored by Tiago Peixoto's avatar Tiago Peixoto
Browse files

Propagate external property map usage to all algorithms

parent e984bf8e
...@@ -282,7 +282,7 @@ BOOST_PYTHON_MODULE(libgraph_tool_core) ...@@ -282,7 +282,7 @@ BOOST_PYTHON_MODULE(libgraph_tool_core)
def("raise_error", &raise_error); def("raise_error", &raise_error);
def("get_property_types", &get_property_types); def("get_property_types", &get_property_types);
class_<boost::any>("any", no_init); class_<boost::any>("any");
mpl::for_each<mpl::push_back<scalar_types,string>::type>(export_vector_types()); mpl::for_each<mpl::push_back<scalar_types,string>::type>(export_vector_types());
......
...@@ -15,26 +15,34 @@ ...@@ -15,26 +15,34 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>. // along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <boost/lambda/bind.hpp>
#include <boost/variant/get.hpp> #include <boost/variant/get.hpp>
#include "graph.hh" #include "graph.hh"
#include "graph_selectors.hh" #include "graph_selectors.hh"
using namespace graph_tool; using namespace graph_tool;
using namespace boost; using namespace boost;
using namespace boost::lambda;
// retrieves the appropriate degree selector // retrieves the appropriate degree selector
boost::any graph_tool::degree_selector(GraphInterface::deg_t deg) boost::any graph_tool::degree_selector(GraphInterface::deg_t deg)
{ {
boost::any sel;
try try
{ {
boost::any degS;
mpl::for_each<selectors> mpl::for_each<selectors>
(get_degree_selector(boost::get<GraphInterface::degree_t>(deg), (bind<void>(get_degree_selector(), _1,
degS)); boost::get<GraphInterface::degree_t>(deg),
return degS; var(sel)));
} }
catch (bad_get) catch (bad_get)
{ {
return boost::get<boost::any>(deg); bool found = false;
mpl::for_each<vertex_scalar_properties>
(bind<void>(get_scalar_selector(), _1, boost::get<boost::any>(deg),
var(sel), var(found)));
if (!found)
throw GraphException("invalid degree selector");
} }
return sel;
} }
...@@ -135,9 +135,6 @@ struct scalarS ...@@ -135,9 +135,6 @@ struct scalarS
struct get_degree_selector struct get_degree_selector
{ {
get_degree_selector(int deg_index, boost::any& deg)
: _index(deg_index), _deg(deg) {}
typedef boost::mpl::map typedef boost::mpl::map
<boost::mpl::pair<in_degreeS, <boost::mpl::pair<in_degreeS,
boost::mpl::int_<GraphInterface::IN_DEGREE> >, boost::mpl::int_<GraphInterface::IN_DEGREE> >,
...@@ -148,14 +145,27 @@ struct get_degree_selector ...@@ -148,14 +145,27 @@ struct get_degree_selector
degree_selector_index; degree_selector_index;
template <class Selector> template <class Selector>
void operator()(Selector) const void operator()(Selector, int deg_index, boost::any& deg) const
{ {
if (mpl::at<degree_selector_index, Selector>::type::value == _index) if (mpl::at<degree_selector_index, Selector>::type::value == deg_index)
_deg = Selector(); deg = Selector();
} }
};
int _index; struct get_scalar_selector
boost::any& _deg; {
template <class PropertyMap>
void operator()(PropertyMap, boost::any prop, boost::any& sec, bool& found)
const
{
try
{
PropertyMap map = any_cast<PropertyMap>(prop);
sec = scalarS<PropertyMap>(map);
found = true;
}
catch (bad_any_cast&) {}
}
}; };
struct scalar_selector_type struct scalar_selector_type
...@@ -167,7 +177,6 @@ struct scalar_selector_type ...@@ -167,7 +177,6 @@ struct scalar_selector_type
}; };
}; };
struct selectors: struct selectors:
boost::mpl::vector<out_degreeS, in_degreeS, total_degreeS> {}; boost::mpl::vector<out_degreeS, in_degreeS, total_degreeS> {};
......
...@@ -48,16 +48,10 @@ get_edge_histogram(GraphInterface& gi, boost::any prop, ...@@ -48,16 +48,10 @@ get_edge_histogram(GraphInterface& gi, boost::any prop,
python::object ret_bins; python::object ret_bins;
bool directed = gi.GetDirected(); bool directed = gi.GetDirected();
gi.SetDirected(false); gi.SetDirected(true);
typedef property_map_types::apply<scalar_types,
GraphInterface::edge_index_map_t,
mpl::bool_<true> >::type
edge_props;
run_action<graph_tool::detail::always_directed>() run_action<graph_tool::detail::always_directed>()
(gi, get_histogram<EdgeHistogramFiller>(hist, bins, ret_bins), (gi, get_histogram<EdgeHistogramFiller>(hist, bins, ret_bins),
edge_props())(prop); edge_scalar_properties())(prop);
gi.SetDirected(directed); gi.SetDirected(directed);
return python::make_tuple(hist, ret_bins); return python::make_tuple(hist, ret_bins);
......
...@@ -48,18 +48,6 @@ from decorators import _wraps, _require, _attrs, _handle_exceptions, _limit_args ...@@ -48,18 +48,6 @@ from decorators import _wraps, _require, _attrs, _handle_exceptions, _limit_args
# Utility functions # Utility functions
################################################################################ ################################################################################
_require("name", str)
def _degree(name):
"""Retrieve the degree type from string"""
deg = name
if name == "in-degree" or name == "in":
deg = libcore.Degree.In
if name == "out-degree" or name == "out":
deg = libcore.Degree.Out
if name == "total-degree" or name == "total":
deg = libcore.Degree.Total
return deg
def _prop(t, g, prop): def _prop(t, g, prop):
"""Returns either a property map, or an internal vertex property map with a """Returns either a property map, or an internal vertex property map with a
given name""" given name"""
...@@ -72,7 +60,24 @@ def _prop(t, g, prop): ...@@ -72,7 +60,24 @@ def _prop(t, g, prop):
("edge" if t == "e" else "graph"),prop)) ("edge" if t == "e" else "graph"),prop))
else: else:
pmap = prop pmap = prop
return pmap._PropertyMap__map if pmap == None:
return libcore.any()
else:
return pmap._PropertyMap__map.get_map()
def _degree(g, name):
"""Retrieve the degree type from string, or returns the corresponding
property map"""
deg = name
if name == "in-degree" or name == "in":
deg = libcore.Degree.In
elif name == "out-degree" or name == "out":
deg = libcore.Degree.Out
elif name == "total-degree" or name == "total":
deg = libcore.Degree.Total
else:
deg = _prop("v", g, deg)
return deg
def _parse_range(range): def _parse_range(range):
"""Parse a range in the form 'lower[*] upper[*]' (where an '*' indicates """Parse a range in the form 'lower[*] upper[*]' (where an '*' indicates
......
...@@ -35,7 +35,7 @@ import libgraph_tool_correlations ...@@ -35,7 +35,7 @@ import libgraph_tool_correlations
sys.setdlopenflags(_orig_dlopen_flags) # reset it to normal case to avoid sys.setdlopenflags(_orig_dlopen_flags) # reset it to normal case to avoid
# unnecessary symbol collision # unnecessary symbol collision
from .. core import _degree from .. core import _degree, _prop
from numpy import * from numpy import *
__all__ = ["assortativity", "scalar_assortativity", __all__ = ["assortativity", "scalar_assortativity",
...@@ -43,28 +43,30 @@ __all__ = ["assortativity", "scalar_assortativity", ...@@ -43,28 +43,30 @@ __all__ = ["assortativity", "scalar_assortativity",
def assortativity(g, deg): def assortativity(g, deg):
return libgraph_tool_correlations.\ return libgraph_tool_correlations.\
assortativity_coefficient(g.underlying_graph(), _degree(deg)) assortativity_coefficient(g.underlying_graph(), _degree(g, deg))
def scalar_assortativity(g, deg): def scalar_assortativity(g, deg):
return libgraph_tool_correlations.\ return libgraph_tool_correlations.\
scalar_assortativity_coefficient(g.underlying_graph(), scalar_assortativity_coefficient(g.underlying_graph(),
_degree(deg)) _degree(g, deg))
def corr_hist(g, deg1, deg2, weight="", bins=[[1],[1]]): def corr_hist(g, deg1, deg2, bins=[[1],[1]], weight=None):
ret = libgraph_tool_correlations.\ ret = libgraph_tool_correlations.\
vertex_correlation_histogram(g.underlying_graph(), _degree(deg1), vertex_correlation_histogram(g.underlying_graph(), _degree(g, deg1),
_degree(deg2), weight, bins[0], bins[1]) _degree(g, deg2), _prop("e", g, weight),
bins[0], bins[1])
return [ret[0], [ret[1][0], ret[1][1]]] return [ret[0], [ret[1][0], ret[1][1]]]
def combined_corr_hist(g, deg1, deg2, bins=[[1],[1]]): def combined_corr_hist(g, deg1, deg2, bins=[[1],[1]]):
ret = libgraph_tool_correlations.\ ret = libgraph_tool_correlations.\
vertex_combined_correlation_histogram(g.underlying_graph(), vertex_combined_correlation_histogram(g.underlying_graph(),
_degree(deg1), _degree(deg2), _degree(g, deg1),
_degree(g, deg2),
bins[0], bins[1]) bins[0], bins[1])
return [ret[0], [ret[1][0], ret[1][1]]] return [ret[0], [ret[1][0], ret[1][1]]]
def avg_neighbour_corr(g, deg1, deg2, weight="", bins=[[1],[1]]): def avg_neighbour_corr(g, deg1, deg2, bins=[[1],[1]], weight=None):
ret = corr_hist(g, deg1, deg2, weight, bins) ret = corr_hist(g, deg1, deg2, bins, weight)
xbins = ret[1][0] xbins = ret[1][0]
ybins = ret[1][1] ybins = ret[1][1]
counts = ret[0] counts = ret[0]
......
...@@ -35,7 +35,7 @@ import libgraph_tool_stats ...@@ -35,7 +35,7 @@ import libgraph_tool_stats
sys.setdlopenflags(_orig_dlopen_flags) # reset it to normal case to avoid sys.setdlopenflags(_orig_dlopen_flags) # reset it to normal case to avoid
# unnecessary symbol collision # unnecessary symbol collision
from .. core import _degree from .. core import _degree, _prop
from numpy import * from numpy import *
__all__ = ["vertex_hist", "edge_hist", "label_components", __all__ = ["vertex_hist", "edge_hist", "label_components",
...@@ -43,28 +43,31 @@ __all__ = ["vertex_hist", "edge_hist", "label_components", ...@@ -43,28 +43,31 @@ __all__ = ["vertex_hist", "edge_hist", "label_components",
def vertex_hist(g, deg, bins=[1]): def vertex_hist(g, deg, bins=[1]):
ret = libgraph_tool_stats.\ ret = libgraph_tool_stats.\
get_vertex_histogram(g.underlying_graph(), _degree(deg), bins) get_vertex_histogram(g.underlying_graph(), _degree(g, deg), bins)
return [array(ret[0]), ret[1]] return [array(ret[0]), ret[1]]
def edge_hist(g, eprop, bins=[1]): def edge_hist(g, eprop, bins=[1]):
ret = libgraph_tool_stats.\ ret = libgraph_tool_stats.\
get_edge_histogram(g.underlying_graph(), eprop, bins) get_edge_histogram(g.underlying_graph(), _prop("e", g, eprop), bins)
return [array(ret[0]), ret[1]] return [array(ret[0]), ret[1]]
def label_components(g, vprop): def label_components(g, vprop=None):
if vprop not in g.vertex_properties: if vprop == None:
g.add_vertex_property(vprop, "int32_t") vprop = g.new_vertex_property("int32_t")
libgraph_tool_stats.\ libgraph_tool_stats.\
label_components(g.underlying_graph(), vprop) label_components(g.underlying_graph(), _prop("v", g, vprop))
return _prop("v", g, vprop)
def label_parallel_edges(g, eprop): def label_parallel_edges(g, eprop):
if eprop not in g.edge_properties: if eprop == None:
g.add_edge_property(eprop, "int32_t") eprop = g.new_edge_property("int32_t")
libgraph_tool_stats.\ libgraph_tool_stats.\
label_parallel_edges(g.underlying_graph(), eprop) label_parallel_edges(g.underlying_graph(), _prop("e", g, eprop))
return _prop("e", g, eprop)
def label_self_loops(g, eprop): def label_self_loops(g, eprop):
if eprop not in g.edge_properties: if eprop == None:
g.add_edge_property(eprop, "int32_t") eprop = g.new_edge_property("int32_t")
libgraph_tool_stats.\ libgraph_tool_stats.\
label_self_loops(g.underlying_graph(), eprop) label_self_loops(g.underlying_graph(), _prop("e", g, eprop))
return _prop("e", g, eprop)
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