Commit 300589cb authored by Tiago Peixoto's avatar Tiago Peixoto

Add vertex and edge average calculation

This adds vertex_average() and edge_average() to the stats module.
parent 8cd70848
## Process this file with automake to produce Makefile.in
AM_CPPFLAGS =\
-I$(srcdir)/.. \
-I$(srcdir)/../../boost-workaround \
-DHAVE_CONFIG_H
AM_CPPFLAGS = $(MOD_CPPFLAGS)
AM_CFLAGS=$(AM_CXXFLAGS)
AM_CXXFLAGS = $(CXXFLAGS)
libgraph_tool_statsdir = $(pythondir)/graph_tool/stats
......@@ -16,27 +13,16 @@ libgraph_tool_stats_la_includedir = $(pythondir)/graph_tool/include
libgraph_tool_stats_la_SOURCES = \
graph_components.cc \
graph_histograms.cc \
graph_average.cc \
graph_parallel.cc \
graph_stats_bind.cc
libgraph_tool_stats_la_include_HEADERS = \
graph_components.hh \
graph_parallel.hh \
graph_histograms.hh
libgraph_tool_stats_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_stats_la_LDFLAGS = \
-module \
-avoid-version \
-export-dynamic \
-no-undefined \
-Wl,-E
graph_histograms.hh \
graph_average.hh
libgraph_tool_stats_la_LIBADD = $(MOD_LIBADD)
libgraph_tool_stats_la_LDFLAGS = $(MOD_LDFLAGS)
// 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_average.hh"
#include <boost/python.hpp>
using namespace std;
using namespace boost;
using namespace graph_tool;
// this will return the vertex average of degrees or scalar properties
python::object
get_vertex_average(const GraphInterface& gi, GraphInterface::deg_t deg)
{
long double a, dev;
run_action<>()(gi, get_average<VertexAverageTraverse>(a,dev),
all_selectors())(degree_selector(deg));
return python::make_tuple(a,dev);
}
// this will return the edge average of scalar properties
python::object
get_edge_average(GraphInterface& gi, boost::any prop)
{
long double a, dev;
bool directed = gi.GetDirected();
gi.SetDirected(true);
run_action<graph_tool::detail::always_directed>()
(gi, get_average<EdgeAverageTraverse>(a, dev),
edge_scalar_properties())(prop);
gi.SetDirected(directed);
return python::make_tuple(a, dev);
}
using namespace boost::python;
void export_average()
{
def("get_vertex_average", &get_vertex_average);
def("get_edge_average", &get_edge_average);
}
// 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_AVERAGE_HH
#define GRAPH_AVERAGE_HH
#include <algorithm>
#include <boost/numeric/conversion/bounds.hpp>
#include <boost/numeric/conversion/cast.hpp>
namespace graph_tool
{
using namespace std;
using namespace boost;
class VertexAverageTraverse
{
public:
template <class Graph, class DegreeSelector, class ValueType>
void operator()(Graph& g, typename graph_traits<Graph>::vertex_descriptor v,
DegreeSelector& deg, ValueType& a, ValueType& aa,
size_t& count)
{
ValueType x = deg(v, g);
a += x;
aa += x*x;
count++;
}
};
class EdgeAverageTraverse
{
public:
template <class Graph, class EdgeProperty, class ValueType>
void operator()(Graph& g, typename graph_traits<Graph>::vertex_descriptor v,
EdgeProperty& eprop, ValueType& a, ValueType& aa,
size_t& count)
{
typename graph_traits<Graph>::out_edge_iterator e, e_begin, e_end;
tie(e_begin,e_end) = out_edges(v,g);
for(e = e_begin; e != e_end; ++e)
{
ValueType x = eprop[*e];
a += x;
aa += x*x;
count++;
}
}
};
// generalized functor to obtain average of different types of "degrees"
template <class AverageTraverse>
struct get_average
{
get_average(long double& a, long double& dev)
: _a(a), _dev(dev) {}
template <class Graph, class DegreeSelector>
void operator()(Graph* gp, DegreeSelector deg) const
{
Graph& g = *gp;
typedef typename DegreeSelector::value_type value_type;
long double a, aa;
size_t count;
AverageTraverse traverse;
int i, N = num_vertices(g);
#pragma omp parallel for default(shared) private(i) \
reduction(+:a,aa,count) 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;
traverse(g, v, deg, a, aa, count);
}
_a = a/count;
_dev = sqrt((aa/count - _a*_a))/sqrt(count);
}
long double& _a;
long double& _dev;
};
} // graph_tool namespace
#endif // GRAPH_AVERAGE_HH
......@@ -20,10 +20,12 @@ using namespace boost;
void export_components();
void export_parallel();
void export_histograms();
void export_average();
BOOST_PYTHON_MODULE(libgraph_tool_stats)
{
export_components();
export_parallel();
export_histograms();
export_average();
}
......@@ -22,8 +22,8 @@ dl_import("import libgraph_tool_stats")
from .. core import _degree, _prop
from numpy import *
__all__ = ["vertex_hist", "edge_hist", "label_components",
"label_parallel_edges", "label_self_loops"]
__all__ = ["vertex_hist", "edge_hist", "vertex_average", "edge_average",
"label_components", "label_parallel_edges", "label_self_loops"]
def vertex_hist(g, deg, bins=[1], float_count=True):
ret = libgraph_tool_stats.\
......@@ -35,6 +35,16 @@ def edge_hist(g, eprop, bins=[1], float_count=True):
get_edge_histogram(g._Graph__graph, _prop("e", g, eprop), bins)
return [array(ret[0], dtype="float64") if float_count else ret[0], ret[1]]
def vertex_average(g, deg):
ret = libgraph_tool_stats.\
get_vertex_average(g._Graph__graph, _degree(g, deg))
return ret
def edge_average(g, eprop):
ret = libgraph_tool_stats.\
get_edge_average(g._Graph__graph, _prop("e", g, eprop))
return ret
def label_components(g, vprop=None):
if vprop == None:
vprop = g.new_vertex_property("int32_t")
......
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