Commit 4cfd772d authored by Tiago Peixoto's avatar Tiago Peixoto

Added util sub-module

This contains at the moment functions to perform basic vertex and edge
searches.
parent 7538d895
......@@ -250,6 +250,7 @@ src/graph/correlations/Makefile
src/graph/generation/Makefile
src/graph/stats/Makefile
src/graph/clustering/Makefile
src/graph/util/Makefile
src/graph_tool/Makefile
])
## Process this file with automake to produce Makefile.in
SUBDIRS = generation correlations stats clustering
SUBDIRS = generation correlations stats clustering util
AM_CPPFLAGS =\
-I$(srcdir)/.. \
......
## Process this file with automake to produce Makefile.in
AM_CPPFLAGS =\
-I$(srcdir) -I$(srcdir)/.. \
-I$(srcdir)/../boost-workaround \
-DHAVE_CONFIG_H
AM_CFLAGS=$(AM_CXXFLAGS)
libgraph_tool_utildir = $(pythondir)/graph_tool/util
libgraph_tool_util_LTLIBRARIES = libgraph_tool_util.la
libgraph_tool_util_la_includedir = $(pythondir)/graph_tool/include
libgraph_tool_util_la_SOURCES = \
graph_search.cc \
graph_util_bind.cc
libgraph_tool_util_la_include_HEADERS = \
graph_search.hh
libgraph_tool_util_la_LIBADD = \
$(PYTHON_LDFLAGS) \
$(BOOST_LDFLAGS) \
$(OPENMP_LDFLAGS) \
-lboost_python \
-lboost_iostreams \
-lexpat
# needed for typeinfo objects to work across DSO boundaries.
# see http://gcc.gnu.org/faq.html#dso
libgraph_tool_util_la_LDFLAGS = \
-module \
-avoid-version \
-export-dynamic \
-no-undefined \
-Wl,-E
// Copyright (C) 2008 Tiago de Paula Peixoto <tiago@forked.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_filtering.hh"
#include "graph_properties.hh"
#include "graph_search.hh"
#include <boost/python.hpp>
using namespace std;
using namespace boost;
using namespace graph_tool;
// find vertices which match a certain (inclusive) property range
python::list
find_vertex_range(const GraphInterface& gi, GraphInterface::deg_t deg,
python::tuple range)
{
python::list ret;
run_action<>()(gi, lambda::bind<void>(find_vertices(), lambda::_1,
lambda::var(gi), lambda::_2,
lambda::var(range), lambda::var(ret)),
all_selectors())(degree_selector(deg));
return ret;
}
// find vertices which match a certain (inclusive) property range
python::list
find_edge_range(GraphInterface& gi, boost::any eprop,
python::tuple range)
{
python::list ret;
typedef property_map_types::apply<value_types,
GraphInterface::edge_index_map_t,
mpl::bool_<true> >::type
all_edge_props;
GraphInterface::edge_index_map_t eindex =
any_cast<GraphInterface::edge_index_map_t>(gi.GetEdgeIndex());
run_action<>()(gi, lambda::bind<void>(find_edges(), lambda::_1,
lambda::var(gi), eindex,
lambda::_2, lambda::var(range),
lambda::var(ret)),
all_edge_props())(eprop);
return ret;
}
using namespace boost::python;
void export_search()
{
def("find_vertex_range", &find_vertex_range);
def("find_edge_range", &find_edge_range);
}
// Copyright (C) 2008 Tiago de Paula Peixoto <tiago@forked.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_SEARCH_HH
#define GRAPH_SEARCH_HH
#include "graph_python_interface.hh"
#include "graph_util.hh"
#include <tr1/unordered_set>
namespace graph_tool
{
using namespace std;
using namespace boost;
// less than or equal for vectors. Compare sizes, or distance from origin.
template <class ValueType>
bool operator<=(const vector<ValueType>& v1, const vector<ValueType>& v2)
{
if (v1.size() < v2.size())
return true;
if (v1.size() > v2.size())
return false;
long double d1, d2;
for (size_t i; i < v1.size(); ++i)
{
d1 += v1[i]*v1[i];
d2 += v2[i]*v2[i];
}
return (d1 <= d2);
}
// sort strings in alphabetical (ASCII) order
bool operator<=(const string s1, const string s2)
{
for (size_t i; i < s1.size(); ++i)
{
if (s1[i] != s1[i])
return (s1[i] < s1[i]);
}
return (s1.size() == s2.size());
}
// vector of strings. compare element by element
bool operator<=(const vector<string>& v1, const vector<string>& v2)
{
if (v1.size() < v2.size())
return true;
if (v1.size() > v2.size())
return false;
for (size_t i; i < v1.size(); ++i)
{
if (v1[i] > v2[i])
return false;
}
return true;
}
// find vertices which match a certain (inclusive) property range
struct find_vertices
{
template <class Graph, class DegreeSelector>
void operator()(Graph* gp, const GraphInterface& gi, DegreeSelector deg,
python::tuple& prange, python::list& ret) const
{
Graph& g = *gp;
typedef typename DegreeSelector::value_type value_type;
pair<value_type,value_type> range;
range.first = python::extract<value_type>(prange[0]);
range.second = python::extract<value_type>(prange[1]);
int i, N = num_vertices(g);
#pragma omp parallel for default(shared) private(i) \
firstprivate(s_vertices) schedule(dynamic)
for (i = 0; i < N; ++i)
{
typename graph_traits<Graph>::vertex_descriptor v = vertex(i, g);
if (v == graph_traits<Graph>::null_vertex())
continue;
value_type val = deg(v, g);
if (val >= range.first && val <= range.second)
{
#pragma omp atomic
ret.append(PythonVertex(gi, v));
}
}
}
};
// find edges which match a certain (inclusive) property range
struct find_edges
{
template <class Graph, class EdgeIndex, class EdgeProperty>
void operator()(Graph* gp, const GraphInterface& gi, EdgeIndex eindex,
EdgeProperty prop, python::tuple& prange, python::list& ret)
const
{
Graph& g = *gp;
typedef typename property_traits<EdgeProperty>::value_type value_type;
pair<value_type,value_type> range;
range.first = python::extract<value_type>(prange[0]);
range.second = python::extract<value_type>(prange[1]);
tr1::unordered_set<size_t> edge_set;
int i, N = num_vertices(g);
#pragma omp parallel for default(shared) private(i) \
firstprivate(s_vertices) schedule(dynamic)
for (i = 0; i < N; ++i)
{
typename graph_traits<Graph>::vertex_descriptor v = vertex(i, g);
if (v == graph_traits<Graph>::null_vertex())
continue;
typename graph_traits<Graph>::out_edge_iterator e, e_end;
for (tie(e, e_end) = out_edges(v, g); e != e_end; ++e)
{
if (!is_directed::apply<Graph>::type::value)
{
if (edge_set.find(eindex[*e]) == edge_set.end())
edge_set.insert(eindex[*e]);
else
continue;
}
value_type val = get(prop, *e);
if (val >= range.first && val <= range.second)
{
#pragma omp atomic
ret.append(PythonEdge<Graph>(gi, *e));
}
}
}
}
};
} // graph_tool namespace
#endif // GRAPH_SEARCH_HH
// Copyright (C) 2008 Tiago de Paula Peixoto <tiago@forked.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 <boost/python.hpp>
using namespace boost;
void export_search();
BOOST_PYTHON_MODULE(libgraph_tool_util)
{
export_search();
}
......@@ -4,7 +4,9 @@ graph_tool_PYTHON = \
__init__.py \
core.py \
decorators.py \
io.py
io.py \
all.py
graph_tooldir = $(pythondir)/graph_tool
graph_tool_run_action_PYTHON = \
......@@ -38,3 +40,7 @@ graph_tool_clusteringdir = $(pythondir)/graph_tool/clustering
graph_tool_draw_PYTHON = \
draw/__init__.py
graph_tool_drawdir = $(pythondir)/graph_tool/draw
graph_tool_util_PYTHON = \
util/__init__.py
graph_tool_utildir = $(pythondir)/graph_tool/util
#! /usr/bin/env python
# graph_tool.py -- a general graph manipulation python module
#
# Copyright (C) 2007 Tiago de Paula Peixoto <tiago@forked.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/>.
import sys
# RTLD_GLOBAL needs to be set in dlopen() if we want typeinfo and friends to
# work properly across DSO boundaries. See http://gcc.gnu.org/faq.html#dso
# The "except" is because the dl module raises a system error on ia64 and x86_64
# systems because "int" and addresses are different sizes.
try:
from dl import RTLD_LAZY, RTLD_NOW, RTLD_GLOBAL
except ImportError:
RTLD_LAZY = 1
RTLD_NOW = 2
RTLD_GLOBAL = 256
_orig_dlopen_flags = sys.getdlopenflags()
sys.setdlopenflags(RTLD_LAZY|RTLD_GLOBAL)
import libgraph_tool_util
sys.setdlopenflags(_orig_dlopen_flags) # reset it to normal case to avoid
# unnecessary symbol collision
from .. core import _degree, _prop
__all__ = ["find_vertex", "find_vertex_range", "find_edge", "find_edge_range"]
def find_vertex(g, deg, match):
ret = libgraph_tool_util.\
find_vertex_range(g._Graph__graph, _degree(deg), (match, match))
return ret
def find_vertex_range(g, deg, range):
ret = libgraph_tool_util.\
find_vertex_range(g._Graph__graph, _degree(deg), range)
return ret
def find_edge(g, prop, match):
ret = libgraph_tool_util.\
find_edge_range(g._Graph__graph, _prop(prop,"e"), (match, match))
return ret
def find_edge_range(g, prop, range):
ret = libgraph_tool_util.\
find_edge_range(g._Graph__graph, _prop(prop,"e"), range)
return ret
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