Commit f4234551 authored by Tiago Peixoto's avatar Tiago Peixoto

Unify all random number generators into a single module-wise instance

The object may be globally reset via the seed_rng() function.
parent 2e0b08d3
......@@ -32,6 +32,7 @@ libgraph_tool_core_la_SOURCES = \
graph_python_interface_export.cc \
graph_selectors.cc \
graphml.cpp \
random.cc \
read_graphviz_new.cpp
libgraph_tool_core_la_includedir = $(pythondir)/graph_tool/include
......@@ -52,6 +53,7 @@ libgraph_tool_core_la_include_HEADERS = \
histogram.hh \
mpl_nested_loop.hh \
numpy_bind.hh \
random.hh \
str_repr.hh \
shared_map.hh
......
......@@ -23,6 +23,8 @@
#include "graph_clustering.hh"
#include "random.hh"
#include <boost/python.hpp>
using namespace std;
......@@ -55,7 +57,7 @@ using namespace boost::python;
void extended_clustering(GraphInterface& g, python::list props);
void get_motifs(GraphInterface& g, size_t k, python::list subgraph_list,
python::list hist, python::list p, bool comp_iso,
bool fill_list, size_t seed);
bool fill_list, rng_t& rng);
BOOST_PYTHON_MODULE(libgraph_tool_clustering)
{
......
......@@ -67,10 +67,8 @@ struct retrieve_from_list
void get_motifs(GraphInterface& g, size_t k, python::list subgraph_list,
python::list hist, python::list p, bool comp_iso,
bool fill_list, size_t seed)
bool fill_list, rng_t& rng)
{
rng_t rng(static_cast<rng_t::result_type>(seed));
boost::any list;
if (g.GetDirected())
list = vector<d_graph_t>();
......@@ -144,4 +142,3 @@ void get_motifs(GraphInterface& g, size_t k, python::list subgraph_list,
subgraph_list.reverse();
}
}
......@@ -29,11 +29,11 @@
#include <boost/functional/hash.hpp>
#include <algorithm>
#include "random.hh"
namespace graph_tool
{
typedef tr1::mt19937 rng_t;
template <class Value>
void insert_sorted(vector<Value>& v, const Value& val)
{
......
......@@ -25,8 +25,6 @@ using namespace std;
using namespace boost;
using namespace graph_tool;
typedef tr1::mt19937 rng_t;
class PythonFuncWrap
{
public:
......@@ -50,7 +48,7 @@ private:
void generate_graph(GraphInterface& gi, size_t N, python::object deg_sample,
bool uncorrelated, bool no_parallel, bool no_self_loops,
bool undirected, size_t seed, bool verbose, bool verify)
bool undirected, rng_t& rng, bool verbose, bool verify)
{
typedef graph_tool::detail::get_all_graph_views::apply<
graph_tool::detail::scalar_pairs, mpl::bool_<false>,
......@@ -66,7 +64,7 @@ void generate_graph(GraphInterface& gi, size_t N, python::object deg_sample,
(gi, bind<void>(gen_graph(), _1, N,
PythonFuncWrap(deg_sample),
no_parallel, no_self_loops,
seed, verbose, verify))();
ref(rng), verbose, verify))();
}
else
{
......@@ -74,7 +72,7 @@ void generate_graph(GraphInterface& gi, size_t N, python::object deg_sample,
(gi, bind<void>(gen_graph(), _1, N,
PythonFuncWrap(deg_sample),
no_parallel, no_self_loops,
seed, verbose, verify))();
ref(rng), verbose, verify))();
}
gi.ReIndexEdges();
}
......@@ -82,7 +80,7 @@ void generate_graph(GraphInterface& gi, size_t N, python::object deg_sample,
size_t random_rewire(GraphInterface& gi, string strat, size_t niter,
bool no_sweep, bool self_loops, bool parallel_edges,
python::object corr_prob, boost::any block,
bool cache, size_t seed, bool verbose);
bool cache, rng_t& rng, bool verbose);
void predecessor_graph(GraphInterface& gi, GraphInterface& gpi,
boost::any pred_map);
void line_graph(GraphInterface& gi, GraphInterface& lgi,
......@@ -101,7 +99,7 @@ void lattice(GraphInterface& gi, python::object oshape, bool periodic);
void geometric(GraphInterface& gi, python::object opoints, double r,
python::object orange, bool periodic, boost::any pos);
void price(GraphInterface& gi, size_t N, double gamma, double c, size_t m,
size_t seed);
rng_t& rng);
using namespace boost::python;
......
......@@ -20,11 +20,9 @@
#if (GCC_VERSION >= 40400)
# include <tr1/unordered_map>
# include <tr1/random>
# include <tr1/tuple>
#else
# include <boost/tr1/unordered_map.hpp>
# include <boost/tr1/random.hpp>
# include <boost/tr1/tuple.hpp>
#endif
#include <boost/functional/hash.hpp>
......@@ -33,14 +31,13 @@
#include <iostream>
#include "graph_util.hh"
#include "random.hh"
namespace graph_tool
{
using namespace std;
using namespace boost;
typedef tr1::mt19937 rng_t;
// desired vertex type, with desired j,k values and the index in the real graph
struct dvertex_t
{
......@@ -443,10 +440,9 @@ struct gen_graph
{
template <class Graph, class DegSample>
void operator()(Graph& g, size_t N, DegSample& deg_sample, bool no_parallel,
bool no_self_loops, size_t seed, bool verbose, bool verify)
bool no_self_loops, rng_t& rng, bool verbose, bool verify)
const
{
rng_t rng(static_cast<rng_t::result_type>(seed));
typename property_map<Graph,vertex_index_t>::type vertex_index =
get(vertex_index_t(), g);
......
......@@ -26,8 +26,8 @@ using namespace graph_tool;
void price(GraphInterface& gi, size_t N, double gamma, double c, size_t m,
size_t seed)
rng_t& rng)
{
run_action<>()(gi, bind<void>(get_price(), _1, N, gamma, c, m, seed))();
run_action<>()(gi, bind<void>(get_price(), _1, N, gamma, c, m, ref(rng)))();
gi.ReIndexEdges();
}
......@@ -21,12 +21,11 @@
#include <iostream>
#include <boost/functional/hash.hpp>
#include "graph_util.hh"
#include "random.hh"
#if (GCC_VERSION >= 40400)
# include <tr1/random>
# include <tr1/unordered_set>
#else
# include <boost/tr1/random.hpp>
# include <boost/tr1/unordered_set.hpp>
#endif
......@@ -38,16 +37,12 @@ namespace graph_tool
using namespace std;
using namespace boost;
typedef tr1::mt19937 rng_t;
struct get_price
{
template <class Graph>
void operator()(Graph& g, size_t N, double gamma, double c, size_t m,
size_t seed) const
rng_t& rng) const
{
rng_t rng(static_cast<rng_t::result_type>(seed));
typedef typename mpl::if_<typename is_directed::apply<Graph>::type,
in_degreeS, out_degreeS>::type DegSelector;
......
......@@ -19,12 +19,6 @@
#include "graph.hh"
#include "graph_filtering.hh"
#if (GCC_VERSION >= 40400)
# include <tr1/random>
#else
# include <boost/tr1/random.hpp>
#endif
#include <boost/bind.hpp>
#include <boost/python.hpp>
......@@ -78,9 +72,8 @@ struct graph_rewire_block
size_t random_rewire(GraphInterface& gi, string strat, size_t niter,
bool no_sweep, bool self_loops, bool parallel_edges,
python::object corr_prob, boost::any block,
bool cache, size_t seed, bool verbose)
bool cache, rng_t& rng, bool verbose)
{
rng_t rng(static_cast<rng_t::result_type>(seed));
PythonFuncWrap corr(corr_prob);
size_t pcount = 0;
......
......@@ -20,10 +20,8 @@
#if (GCC_VERSION >= 40400)
# include <tr1/unordered_set>
# include <tr1/random>
#else
# include <boost/tr1/unordered_set.hpp>
# include <boost/tr1/random.hpp>
#endif
#include <boost/functional/hash.hpp>
......@@ -34,6 +32,8 @@
#include "graph_util.hh"
#include "sampler.hh"
#include "random.hh"
namespace graph_tool
{
using namespace std;
......
......@@ -25,11 +25,9 @@
#if (GCC_VERSION >= 40400)
# include <tr1/unordered_set>
# include <tr1/random>
# include <tr1/tuple>
#else
# include <boost/tr1/unordered_set.hpp>
# include <boost/tr1/random.hpp>
# include <boost/tr1/tuple.hpp>
#endif
#include <boost/functional/hash.hpp>
......
......@@ -18,11 +18,7 @@
#ifndef SAMPLER_HH
#define SAMPLER_HH
#if (GCC_VERSION >= 40400)
# include <tr1/random>
#else
# include <boost/tr1/random.hpp>
#endif
#include "random.hh"
#include <iostream>
namespace graph_tool
......@@ -30,8 +26,6 @@ namespace graph_tool
using namespace std;
using namespace boost;
typedef tr1::mt19937 rng_t;
// utility class to sample uniformly from a collection of values
template <class ValueType>
class Sampler
......@@ -232,7 +226,7 @@ public:
}
_rebuild = false;
}
ValueType operator()(rng_t& rng, bool remove = false)
{
......
......@@ -338,6 +338,10 @@ BOOST_PYTHON_MODULE(libgraph_tool_core)
do_import_array();
export_python_interface();
// random numbers
class_<rng_t>("rng_t");
def("get_rng", get_rng);
register_exception_translator<GraphException>
(graph_exception_translator<GraphException>);
register_exception_translator<IOException>
......
......@@ -29,12 +29,12 @@
#include <boost/lambda/bind.hpp>
#include "graph_sfdp.hh"
#include "random.hh"
using namespace std;
using namespace boost;
using namespace graph_tool;
typedef tr1::mt19937 rng_t;
void sfdp_layout(GraphInterface& g, boost::any pos, boost::any vweight,
boost::any eweight, boost::any pin, python::object spring_parms,
......@@ -149,10 +149,8 @@ struct get_pointers
void propagate_pos(GraphInterface& gi, GraphInterface& cgi, boost::any vmap,
boost::any cvmap, boost::any pos, boost::any cpos,
double delta, size_t seed)
double delta, rng_t& rng)
{
rng_t rng(static_cast<rng_t::result_type>(seed));
typedef mpl::vector<property_map_type::apply
<int32_t,
GraphInterface::vertex_index_map_t>::type>::type
......@@ -226,10 +224,8 @@ struct do_propagate_pos_mivs
void propagate_pos_mivs(GraphInterface& gi, boost::any mivs, boost::any pos,
double delta, size_t seed)
double delta, rng_t& rng)
{
rng_t rng(static_cast<rng_t::result_type>(seed));
run_action<>()
(gi, bind<void>(do_propagate_pos_mivs(),
_1, _2, _3, delta, ref(rng)),
......
// graph-tool -- a general graph modification and manipulation thingy
//
// Copyright (C) 2007-2012 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 "random.hh"
rng_t get_rng(size_t seed)
{
return rng_t(static_cast<rng_t::result_type>(seed));
}
// graph-tool -- a general graph modification and manipulation thingy
//
// Copyright (C) 2007-2012 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 RANDOM_HH
#define RANDOM_HH
#include "graph.hh"
#if (GCC_VERSION >= 40400)
# include <tr1/random>
#else
# include <boost/tr1/random.hpp>
#endif
typedef std::tr1::mt19937 rng_t;
rng_t get_rng(size_t seed);
#endif
......@@ -22,7 +22,7 @@
#include "graph_distance_sampled.hh"
typedef std::tr1::mt19937 rng_t;
#include "random.hh"
using namespace std;
using namespace boost;
......@@ -32,10 +32,8 @@ typedef Histogram<size_t, size_t, 1> hist_t;
python::object sampled_distance_histogram(GraphInterface& gi, boost::any weight,
const vector<long double>& bins,
size_t n_samples, size_t seed)
size_t n_samples, rng_t& rng)
{
rng_t rng(static_cast<rng_t::result_type>(seed));
python::object ret;
if (weight.empty())
......
......@@ -25,12 +25,6 @@
#include <boost/python/list.hpp>
#include <boost/python/extract.hpp>
#if (GCC_VERSION >= 40400)
# include <tr1/random>
#else
# include <boost/tr1/random.hpp>
#endif
#include "histogram.hh"
#include "numpy_bind.hh"
......
......@@ -19,20 +19,14 @@
#include "graph_selectors.hh"
#include "graph_util.hh"
#include <boost/python.hpp>
#include "random.hh"
#if (GCC_VERSION >= 40400)
# include <tr1/random>
#else
# include <boost/tr1/random.hpp>
#endif
#include <boost/python.hpp>
using namespace std;
using namespace boost;
using namespace graph_tool;
typedef tr1::mt19937 rng_t;
struct do_maximal_vertex_set
{
template <class Graph, class VertexIndex, class VertexSet,
......@@ -174,10 +168,8 @@ struct do_maximal_vertex_set
};
void maximal_vertex_set(GraphInterface& gi, boost::any mvs, bool high_deg,
size_t seed)
rng_t& rng)
{
rng_t rng(static_cast<rng_t::result_type>(seed));
run_action<>()
(gi, bind<void>(do_maximal_vertex_set(), _1, gi.GetVertexIndex(),
_2, high_deg, ref(rng)),
......
......@@ -19,20 +19,15 @@
#include "graph_selectors.hh"
#include "graph_util.hh"
#include "random.hh"
#include <boost/python.hpp>
#if (GCC_VERSION >= 40400)
# include <tr1/random>
#else
# include <boost/tr1/random.hpp>
#endif
using namespace std;
using namespace boost;
using namespace graph_tool;
typedef tr1::mt19937 rng_t;
struct do_random_matching
{
template <class Graph, class VertexIndex, class WeightMap, class MatchMap,
......@@ -94,9 +89,8 @@ struct do_random_matching
};
void random_matching(GraphInterface& gi, boost::any weight, boost::any match,
bool minimize, size_t seed)
bool minimize, rng_t& rng)
{
rng_t rng(static_cast<rng_t::result_type>(seed));
typedef ConstantPropertyMap<int32_t,GraphInterface::edge_t> weight_map_t;
typedef mpl::push_back<edge_scalar_properties, weight_map_t>::type
edge_props_t;
......
......@@ -19,20 +19,14 @@
#include "graph.hh"
#include "graph_properties.hh"
#include <boost/graph/random_spanning_tree.hpp>
#include "random.hh"
#if (GCC_VERSION >= 40400)
# include <tr1/random>
#else
# include <boost/tr1/random.hpp>
#endif
#include <boost/graph/random_spanning_tree.hpp>
using namespace std;
using namespace boost;
using namespace graph_tool;
typedef tr1::mt19937 rng_t;
struct get_random_span_tree
{
template <class Graph, class IndexMap, class WeightMap, class TreeMap,
......@@ -89,10 +83,8 @@ typedef property_map_types::apply<mpl::vector<uint8_t>,
void get_random_spanning_tree(GraphInterface& gi, size_t root,
boost::any weight_map, boost::any tree_map,
size_t seed)
rng_t& rng)
{
rng_t rng(static_cast<rng_t::result_type>(seed));
typedef ConstantPropertyMap<size_t,GraphInterface::edge_t> cweight_t;
if (weight_map.empty())
......
......@@ -18,6 +18,8 @@
#include "graph.hh"
#include "graph_filtering.hh"
#include "random.hh"
#include <graph_subgraph_isomorphism.hh>
#include <graph_python_interface.hh>
......@@ -65,16 +67,15 @@ struct get_subgraphs
VertexLabel vertex_label1, boost::any vertex_label2,
EdgeLabel edge_label1, boost::any edge_label2,
vector<vector<pair<size_t, size_t> > >& F,
vector<size_t>& vlist, pair<size_t,size_t> sn) const
vector<size_t>& vlist, pair<reference_wrapper<rng_t>,size_t> sn) const
{
typedef PropLabelling<Graph1,Graph2,VertexLabel,VertexLabel>
vlabelling_t;
typedef PropLabelling<Graph1,Graph2,EdgeLabel,EdgeLabel>
elabelling_t;
size_t seed = sn.first;
rng_t& rng = sn.first;
size_t max_n = sn.second;
rng_t rng(static_cast<rng_t::result_type>(seed));
vlist.resize(num_vertices(*g));
int i, N = num_vertices(*g);
for (i = 0; i < N; ++i)
......@@ -166,7 +167,7 @@ void subgraph_isomorphism(GraphInterface& gi1, GraphInterface& gi2,
boost::any vertex_label1, boost::any vertex_label2,
boost::any edge_label1, boost::any edge_label2,
python::list vmapping, python::list emapping,
size_t max_n, size_t seed)
size_t max_n, rng_t& rng)
{
if (gi1.GetDirected() != gi2.GetDirected())
return;
......@@ -191,7 +192,7 @@ void subgraph_isomorphism(GraphInterface& gi1, GraphInterface& gi2,
run_action<graph_tool::detail::always_directed>()
(gi1, bind<void>(get_subgraphs(),
_1, _2, _3, vertex_label2, _4, edge_label2,
ref(F), ref(vlist), make_pair(seed, max_n)),
ref(F), ref(vlist), make_pair(ref(rng), max_n)),
directed_graph_view_pointers(), vertex_props_t(),
edge_props_t())
(gi2.GetGraphView(), vertex_label1, edge_label1);
......@@ -201,7 +202,7 @@ void subgraph_isomorphism(GraphInterface& gi1, GraphInterface& gi2,
run_action<graph_tool::detail::never_directed>()
(gi1, bind<void>(get_subgraphs(),
_1, _2, _3, vertex_label2, _4, edge_label2,
ref(F), ref(vlist), make_pair(seed, max_n)),
ref(F), ref(vlist), make_pair(ref(rng), max_n)),
undirected_graph_view_pointers(), vertex_props_t(),
edge_props_t())
(gi2.GetGraphView(), vertex_label1, edge_label1);
......
......@@ -22,17 +22,14 @@
#include <utility>
#if (GCC_VERSION >= 40400)
# include <tr1/unordered_set>
# include <tr1/random>
#else
# include <boost/tr1/unordered_set.hpp>
# include <boost/tr1/random.hpp>
#endif
namespace boost
{
using namespace std;
typedef tr1::mt19937 rng_t;
namespace detail {