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

Propagate external property map usage to all algorithms

parent e984bf8e
......@@ -282,7 +282,7 @@ BOOST_PYTHON_MODULE(libgraph_tool_core)
def("raise_error", &raise_error);
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());
......
......@@ -15,26 +15,34 @@
// 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 <boost/lambda/bind.hpp>
#include <boost/variant/get.hpp>
#include "graph.hh"
#include "graph_selectors.hh"
using namespace graph_tool;
using namespace boost;
using namespace boost::lambda;
// retrieves the appropriate degree selector
boost::any graph_tool::degree_selector(GraphInterface::deg_t deg)
{
boost::any sel;
try
{
boost::any degS;
mpl::for_each<selectors>
(get_degree_selector(boost::get<GraphInterface::degree_t>(deg),
degS));
return degS;
(bind<void>(get_degree_selector(), _1,
boost::get<GraphInterface::degree_t>(deg),
var(sel)));
}
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
struct get_degree_selector
{
get_degree_selector(int deg_index, boost::any& deg)
: _index(deg_index), _deg(deg) {}
typedef boost::mpl::map
<boost::mpl::pair<in_degreeS,
boost::mpl::int_<GraphInterface::IN_DEGREE> >,
......@@ -148,14 +145,27 @@ struct get_degree_selector
degree_selector_index;
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)
_deg = Selector();
if (mpl::at<degree_selector_index, Selector>::type::value == deg_index)
deg = Selector();
}
};
int _index;
boost::any& _deg;
struct get_scalar_selector
{
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
......@@ -167,7 +177,6 @@ struct scalar_selector_type
};
};
struct selectors:
boost::mpl::vector<out_degreeS, in_degreeS, total_degreeS> {};
......
......@@ -48,16 +48,10 @@ get_edge_histogram(GraphInterface& gi, boost::any prop,
python::object ret_bins;
bool directed = gi.GetDirected();
gi.SetDirected(false);
typedef property_map_types::apply<scalar_types,
GraphInterface::edge_index_map_t,
mpl::bool_<true> >::type
edge_props;
gi.SetDirected(true);
run_action<graph_tool::detail::always_directed>()
(gi, get_histogram<EdgeHistogramFiller>(hist, bins, ret_bins),
edge_props())(prop);
edge_scalar_properties())(prop);
gi.SetDirected(directed);
return python::make_tuple(hist, ret_bins);
......
......@@ -48,18 +48,6 @@ from decorators import _wraps, _require, _attrs, _handle_exceptions, _limit_args
# 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):
"""Returns either a property map, or an internal vertex property map with a
given name"""
......@@ -72,7 +60,24 @@ def _prop(t, g, prop):
("edge" if t == "e" else "graph"),prop))
else:
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):
"""Parse a range in the form 'lower[*] upper[*]' (where an '*' indicates
......
......@@ -35,7 +35,7 @@ import libgraph_tool_correlations
sys.setdlopenflags(_orig_dlopen_flags) # reset it to normal case to avoid
# unnecessary symbol collision
from .. core import _degree
from .. core import _degree, _prop
from numpy import *
__all__ = ["assortativity", "scalar_assortativity",
......@@ -43,28 +43,30 @@ __all__ = ["assortativity", "scalar_assortativity",
def assortativity(g, deg):
return libgraph_tool_correlations.\
assortativity_coefficient(g.underlying_graph(), _degree(deg))
assortativity_coefficient(g.underlying_graph(), _degree(g, deg))
def scalar_assortativity(g, deg):
return libgraph_tool_correlations.\
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.\
vertex_correlation_histogram(g.underlying_graph(), _degree(deg1),
_degree(deg2), weight, bins[0], bins[1])
vertex_correlation_histogram(g.underlying_graph(), _degree(g, deg1),
_degree(g, deg2), _prop("e", g, weight),
bins[0], bins[1])
return [ret[0], [ret[1][0], ret[1][1]]]
def combined_corr_hist(g, deg1, deg2, bins=[[1],[1]]):
ret = libgraph_tool_correlations.\
vertex_combined_correlation_histogram(g.underlying_graph(),
_degree(deg1), _degree(deg2),
_degree(g, deg1),
_degree(g, deg2),
bins[0], bins[1])
return [ret[0], [ret[1][0], ret[1][1]]]
def avg_neighbour_corr(g, deg1, deg2, weight="", bins=[[1],[1]]):
ret = corr_hist(g, deg1, deg2, weight, bins)
def avg_neighbour_corr(g, deg1, deg2, bins=[[1],[1]], weight=None):
ret = corr_hist(g, deg1, deg2, bins, weight)
xbins = ret[1][0]
ybins = ret[1][1]
counts = ret[0]
......
......@@ -35,7 +35,7 @@ import libgraph_tool_stats
sys.setdlopenflags(_orig_dlopen_flags) # reset it to normal case to avoid
# unnecessary symbol collision
from .. core import _degree
from .. core import _degree, _prop
from numpy import *
__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]):
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]]
def edge_hist(g, eprop, bins=[1]):
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]]
def label_components(g, vprop):
if vprop not in g.vertex_properties:
g.add_vertex_property(vprop, "int32_t")
def label_components(g, vprop=None):
if vprop == None:
vprop = g.new_vertex_property("int32_t")
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):
if eprop not in g.edge_properties:
g.add_edge_property(eprop, "int32_t")
if eprop == None:
eprop = g.new_edge_property("int32_t")
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):
if eprop not in g.edge_properties:
g.add_edge_property(eprop, "int32_t")
if eprop == None:
eprop = g.new_edge_property("int32_t")
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