graph_rewiring.cc 5.09 KB
Newer Older
Tiago Peixoto's avatar
 
Tiago Peixoto committed
1
2
// graph-tool -- a general graph modification and manipulation thingy
//
Tiago Peixoto's avatar
Tiago Peixoto committed
3
// Copyright (C) 2007-2012 Tiago de Paula Peixoto <tiago@skewed.de>
Tiago Peixoto's avatar
 
Tiago Peixoto committed
4
5
6
7
8
9
10
11
12
13
14
15
//
// 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
Tiago Peixoto's avatar
Tiago Peixoto committed
16
// along with this program. If not, see <http://www.gnu.org/licenses/>.
Tiago Peixoto's avatar
 
Tiago Peixoto committed
17

18
#include "graph_python_interface.hh"
Tiago Peixoto's avatar
 
Tiago Peixoto committed
19
20
#include "graph.hh"
#include "graph_filtering.hh"
21

22
#include <boost/bind.hpp>
23
#include <boost/python.hpp>
24

25
26
#include "graph_rewiring.hh"

27
using namespace graph_tool;
Tiago Peixoto's avatar
 
Tiago Peixoto committed
28
29
using namespace boost;

30

31
32
33
34
35
class PythonFuncWrap
{
public:
    PythonFuncWrap(python::object o): _o(o) {}

36
37
    double operator()(pair<size_t, size_t> deg1, pair<size_t, size_t> deg2)
        const
38
    {
39
40
        python::object ret = _o(python::make_tuple(deg1.first, deg1.second),
                                python::make_tuple(deg2.first, deg2.second));
41
42
43
        return python::extract<double>(ret);
    }

44
45
46
    template <class Type>
    double operator()(const Type& deg1, const Type& deg2) const
    {
47
        python::object ret = _o(python::object(deg1), python::object(deg2));
48
49
50
        return python::extract<double>(ret);
    }

51
52
53
54
private:
    python::object _o;
};

55
56
57
58
59
60

struct graph_rewire_block
{
    template <class Graph, class EdgeIndexMap, class CorrProb, class BlockProp>
    void operator()(Graph& g, EdgeIndexMap edge_index, CorrProb corr_prob,
                    pair<bool, bool> rest, BlockProp block_prop,
61
62
63
                    pair<size_t, bool> iter_sweep,
                    pair<bool, bool> cache_verbose, size_t& pcount, rng_t& rng)
        const
64
65
66
    {
        graph_rewire<ProbabilisticRewireStrategy>()
            (g, edge_index, corr_prob, rest.first, rest.second, iter_sweep,
67
             cache_verbose, pcount, rng, PropertyBlock<BlockProp>(block_prop));
68
69
70
71
    }
};


72
73
size_t random_rewire(GraphInterface& gi, string strat, size_t niter,
                     bool no_sweep, bool self_loops, bool parallel_edges,
74
                     python::object corr_prob, boost::any block,
75
                     bool cache, rng_t& rng, bool verbose)
Tiago Peixoto's avatar
 
Tiago Peixoto committed
76
{
77
    PythonFuncWrap corr(corr_prob);
78
    size_t pcount = 0;
Tiago Peixoto's avatar
 
Tiago Peixoto committed
79

80
81
    if (strat == "erdos")
        run_action<graph_tool::detail::never_reversed>()
82
83
            (gi, boost::bind<void>(graph_rewire<ErdosRewireStrategy>(),
                                   _1, gi.GetEdgeIndex(), boost::ref(corr),
84
                                   self_loops, parallel_edges,
85
86
                                   make_pair(niter, no_sweep),
                                   make_pair(cache, verbose),
87
                                   boost::ref(pcount), boost::ref(rng)))();
88
    else if (strat == "uncorrelated")
89
        run_action<graph_tool::detail::never_reversed>()
90
91
            (gi, boost::bind<void>(graph_rewire<RandomRewireStrategy>(),
                                   _1, gi.GetEdgeIndex(), boost::ref(corr),
92
                                   self_loops, parallel_edges,
93
94
                                   make_pair(niter, no_sweep),
                                   make_pair(cache, verbose),
95
                                   boost::ref(pcount), boost::ref(rng)))();
Tiago Peixoto's avatar
Tiago Peixoto committed
96
    else if (strat == "correlated")
97
        run_action<graph_tool::detail::never_reversed>()
98
99
            (gi, boost::bind<void>(graph_rewire<CorrelatedRewireStrategy>(),
                                   _1, gi.GetEdgeIndex(), boost::ref(corr),
100
                                   self_loops, parallel_edges,
101
102
                                   make_pair(niter, no_sweep),
                                   make_pair(cache, verbose),
103
                                   boost::ref(pcount), boost::ref(rng)))();
104
105
    else if (strat == "probabilistic")
        run_action<>()
106
107
            (gi, boost::bind<void>(graph_rewire<ProbabilisticRewireStrategy>(),
                                   _1, gi.GetEdgeIndex(), boost::ref(corr),
108
                                   self_loops, parallel_edges,
109
110
                                   make_pair(niter, no_sweep),
                                   make_pair(cache, verbose),
111
                                   boost::ref(pcount), boost::ref(rng)))();
112
113
114
115
116
    else if (strat == "blockmodel")
        run_action<>()
            (gi, boost::bind<void>(graph_rewire_block(),
                                   _1, gi.GetEdgeIndex(), boost::ref(corr),
                                   make_pair(self_loops, parallel_edges), _2,
117
118
                                   make_pair(niter, no_sweep),
                                   make_pair(cache, verbose),
119
120
                                   boost::ref(pcount), boost::ref(rng)),
             vertex_properties())(block);
Tiago Peixoto's avatar
Tiago Peixoto committed
121
    else
Tiago Peixoto's avatar
Tiago Peixoto committed
122
        throw ValueException("invalid random rewire strategy: " + strat);
123
    return pcount;
Tiago Peixoto's avatar
 
Tiago Peixoto committed
124
}