graph_bind.cc 13.2 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  Tiago de Paula Peixoto <tiago@forked.de>
Tiago Peixoto's avatar
Tiago Peixoto committed
4
5
6
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
Tiago Peixoto's avatar
Tiago Peixoto committed
7
// as published by the Free Software Foundation; either version 3
Tiago Peixoto's avatar
Tiago Peixoto committed
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// 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, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

#include <boost/python.hpp>
#include <boost/tuple/tuple.hpp>
#include "graph.hh"

using namespace std;
using namespace graph_tool;
using namespace boost;
using namespace boost::python;

// some conversions...

template <class T1, class T2>
struct pair_to_tuple
{
    static PyObject* convert(const pair<T1,T2>& p)
    {
35
36
        boost::python::tuple t = boost::python::make_tuple(p.first,p.second);
        return incref(t.ptr());
Tiago Peixoto's avatar
Tiago Peixoto committed
37
38
39
40
41
42
43
44
    }
};

template <class T1, class T2, class T3>
struct tuple_to_tuple
{
    static PyObject* convert(const boost::tuple<T1,T2,T3>& p)
    {
45
46
        boost::python::tuple t = boost::python::make_tuple(get<0>(p),get<1>(p),get<2>(p));
        return incref(t.ptr());
Tiago Peixoto's avatar
Tiago Peixoto committed
47
48
49
50
51
52
53
54
55
    }
};


template <class T1, class T2, class T3>
struct tuple_from_tuple
{
    tuple_from_tuple()
    {
56
        converter::registry::push_back(&convertible, &construct,  boost::python::type_id<boost::tuple<T1,T2,T3> >());
Tiago Peixoto's avatar
Tiago Peixoto committed
57
58
59
60
    }

    static void* convertible(PyObject* obj_ptr)
    {
61
62
63
64
65
66
67
68
        handle<> x(borrowed(obj_ptr));
        object o(x);
        extract<T1> first(o[0]);
        extract<T2> second(o[1]);
        extract<T2> third(o[3]);
        if (!first.check() || !second.check() || !third.check()) 
            return 0;
        return obj_ptr;
Tiago Peixoto's avatar
Tiago Peixoto committed
69
70
71
    }

    static void construct(PyObject* obj_ptr, converter::rvalue_from_python_stage1_data* data)
72
73
74
75
76
77
78
79
80
81
    {          
        handle<> x(borrowed(obj_ptr));
        object o(x);
        boost::tuple<T1,T2,T3> value;
        get<0>(value) = extract<T1>(o[0]);
        get<1>(value) = extract<T2>(o[1]);
        get<2>(value) = extract<T2>(o[2]);
        void* storage = ( (boost::python::converter::rvalue_from_python_storage<boost::tuple<T1,T2,T3> >*) data)->storage.bytes;
        new (storage) boost::tuple<T1,T2,T3>(value);
        data->convertible = storage;
Tiago Peixoto's avatar
Tiago Peixoto committed
82
83
84
85
86
87
88
89
    }
};

template <class T1, class T2>
struct pair_from_tuple
{
    pair_from_tuple()
    {
90
        converter::registry::push_back(&convertible, &construct,  boost::python::type_id<pair<T1,T2> >());
Tiago Peixoto's avatar
Tiago Peixoto committed
91
92
93
94
    }

    static void* convertible(PyObject* obj_ptr)
    {
95
96
97
98
99
100
101
        handle<> x(borrowed(obj_ptr));
        object o(x);
        extract<T1> first(o[0]);
        extract<T2> second(o[1]);
        if (!first.check() || !second.check()) 
            return 0;
        return obj_ptr;
Tiago Peixoto's avatar
Tiago Peixoto committed
102
103
104
    }

    static void construct(PyObject* obj_ptr, converter::rvalue_from_python_stage1_data* data)
105
106
107
108
109
110
111
112
113
    {          
        handle<> x(borrowed(obj_ptr));
        object o(x);
        pair<T1,T2> value;
        value.first = extract<T1>(o[0]);
        value.second = extract<T2>(o[1]);
        void* storage = ( (boost::python::converter::rvalue_from_python_storage<pair<T1,T2> >*) data)->storage.bytes;
        new (storage) pair<T1,T2>(value);
        data->convertible = storage;
Tiago Peixoto's avatar
Tiago Peixoto committed
114
115
116
117
118
119
120
121
    }
};

template <class ValueType> 
struct variant_from_python
{
    variant_from_python()
    {
122
        converter::registry::push_back(&convertible, &construct, boost::python::type_id<GraphInterface::deg_t>());
Tiago Peixoto's avatar
Tiago Peixoto committed
123
124
125
126
    }

    static void* convertible(PyObject* obj_ptr)
    {
127
128
129
130
131
132
        handle<> x(borrowed(obj_ptr));
        object o(x);
        extract<ValueType> str(o);
        if (!str.check())
            return 0;
        return obj_ptr;
Tiago Peixoto's avatar
Tiago Peixoto committed
133
134
135
    }

    static void construct(PyObject* obj_ptr, converter::rvalue_from_python_stage1_data* data)
136
137
138
139
140
141
142
143
    {          
        handle<> x(borrowed(obj_ptr));
        object o(x);
        ValueType value = extract<ValueType>(o);
        GraphInterface::deg_t deg = value;
        void* storage = ( (boost::python::converter::rvalue_from_python_storage<GraphInterface::deg_t>*) data)->storage.bytes;
        new (storage) GraphInterface::deg_t(deg);
        data->convertible = storage;
Tiago Peixoto's avatar
Tiago Peixoto committed
144
145
146
147
148
149
150
151
152
153
    }
};



template <class Hist>
struct hist_to_dict
{
    static PyObject* convert(const Hist& h)
    {
154
155
156
157
        dict hist;
        for(typeof(h.begin()) iter = h.begin(); iter != h.end(); ++iter)
            hist[iter->first] = iter->second;
        return incref(hist.ptr());
Tiago Peixoto's avatar
Tiago Peixoto committed
158
159
160
161
162
163
164
165
    }
};


class GraphInterfaceWrap: public GraphInterface
{
public:
    void GenerateCorrelatedConfigurationalModel(size_t N, object pjk, object ceil_pjk, object inv_ceil_pjk, double ceil_pjk_bound,
166
167
                                                object corr, object ceil_corr, object inv_ceil_corr, double ceil_corr_bound, bool undirected_corr, 
                                                size_t seed, bool verbose) 
Tiago Peixoto's avatar
Tiago Peixoto committed
168
    {
169
170
        GraphInterface& base = *this;
        base.GenerateCorrelatedConfigurationalModel(N, pjk_t(python_function(pjk)), pjk_t(python_function(ceil_pjk)), 
171
172
173
                                                    inv_ceil_t(python_function(inv_ceil_pjk)),
                                                    ceil_pjk_bound, corr_t(python_function(corr)), corr_t(python_function(ceil_corr)), 
                                                    inv_corr_t(python_function(inv_ceil_corr)), ceil_corr_bound, undirected_corr, seed, verbose);
Tiago Peixoto's avatar
Tiago Peixoto committed
174
175
176
177
    }

    struct python_function
    {
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
        python_function(object o): _o(o) {}
        double operator()(size_t j, size_t k)
        {
            return extract<double>(_o(j,k));
        }
        double operator()(size_t jl, size_t kl, size_t j, size_t k)
        {
            return extract<double>(_o(jl,kl,j,k));
        }
        pair<size_t,size_t> operator()(double r1, double r2)
        {
            object retval = _o(r1,r2);
            return make_pair(size_t(max(int(extract<int>(retval[0])),0)), size_t(max(int(extract<int>(retval[1])),0)));
        }
        pair<size_t,size_t> operator()(double r1, double r2, size_t j, size_t k)
        {
            object retval = _o(r1,r2,j,k);
            return make_pair(size_t(max(int(extract<int>(retval[0])),0)), size_t(max(int(extract<int>(retval[1])),0)));
        }
        object _o;
Tiago Peixoto's avatar
Tiago Peixoto committed
198
199
200
201
202
203
204
205
206
    };

};

struct LibInfo
{
    string GetName()      const {return PACKAGE_NAME;}
    string GetAuthor()    const {return AUTHOR;}
    string GetCopyright() const {return COPYRIGHT;}
207
    string GetVersion()   const {return VERSION " (r" SVN_REVISION ")";}
Tiago Peixoto's avatar
Tiago Peixoto committed
208
209
};

Tiago Peixoto's avatar
Tiago Peixoto committed
210
211
212
213
214
215
216
// overloads
void  (GraphInterfaceWrap::*ReadFromFile1) (string)          = &GraphInterfaceWrap::ReadFromFile;
void  (GraphInterfaceWrap::*ReadFromFile2) (string, string)  = &GraphInterfaceWrap::ReadFromFile;
void  (GraphInterfaceWrap::*WriteToFile1)  (string)          = &GraphInterfaceWrap::WriteToFile;
void  (GraphInterfaceWrap::*WriteToFile2)  (string, string)  = &GraphInterfaceWrap::WriteToFile;


Tiago Peixoto's avatar
Tiago Peixoto committed
217
218
219
BOOST_PYTHON_MODULE(libgraph_tool)
{
    class_<GraphInterfaceWrap>("GraphInterface")
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
        .def("GenerateCorrelatedConfigurationalModel", &GraphInterfaceWrap::GenerateCorrelatedConfigurationalModel)
        .def("GetNumberOfVertices", &GraphInterfaceWrap::GetNumberOfVertices)
        .def("GetNumberOfEdges", &GraphInterfaceWrap::GetNumberOfEdges)
        .def("GetVertexHistogram", &GraphInterfaceWrap::GetVertexHistogram)
        .def("GetEdgeHistogram", &GraphInterfaceWrap::GetEdgeHistogram)
        .def("LabelComponents", &GraphInterfaceWrap::LabelComponents)
        .def("LabelParallelEdges", &GraphInterfaceWrap::LabelParallelEdges)
        .def("GetCombinedVertexHistogram", &GraphInterfaceWrap::GetCombinedVertexHistogram)
        .def("GetAverageCombinedVertexCorrelation", &GraphInterfaceWrap::GetAverageCombinedVertexCorrelation)
        .def("GetVertexCorrelationHistogram", &GraphInterfaceWrap::GetVertexCorrelationHistogram)
        .def("GetEdgeVertexCorrelationHistogram", &GraphInterfaceWrap::GetEdgeVertexCorrelationHistogram)
        .def("GetAverageNearestNeighboursCorrelation", &GraphInterfaceWrap::GetAverageNearestNeighboursCorrelation)
        .def("GetAssortativityCoefficient", &GraphInterfaceWrap::GetAssortativityCoefficient)
        .def("GetScalarAssortativityCoefficient", &GraphInterfaceWrap::GetScalarAssortativityCoefficient)
        .def("GetGlobalClustering", &GraphInterfaceWrap::GetGlobalClustering)
        .def("SetLocalClusteringToProperty", &GraphInterfaceWrap::SetLocalClusteringToProperty)
        .def("SetExtendedClusteringToProperty", &GraphInterfaceWrap::SetExtendedClusteringToProperty)
        .def("GetDistanceHistogram", &GraphInterfaceWrap::GetDistanceHistogram)
        .def("GetSampledDistanceHistogram", &GraphInterfaceWrap::GetSampledDistanceHistogram)
        .def("GetReciprocity", &GraphInterfaceWrap::GetReciprocity)
        .def("GetMinimumSpanningTree", &GraphInterfaceWrap::GetMinimumSpanningTree)
        .def("GetLineGraph", &GraphInterfaceWrap::GetLineGraph)
242
        .def("GetBetweenness", &GraphInterfaceWrap::GetBetweenness)
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
        .def("GetCommunityStructure", &GraphInterfaceWrap::GetCommunityStructure)
        .def("GetCommunityNetwork", &GraphInterfaceWrap::GetCommunityNetwork)
        .def("GetModularity", &GraphInterfaceWrap::GetModularity)
        .def("SetDirected", &GraphInterfaceWrap::SetDirected)
        .def("GetDirected", &GraphInterfaceWrap::GetDirected)
        .def("SetReversed", &GraphInterfaceWrap::SetReversed)
        .def("GetReversed", &GraphInterfaceWrap::GetReversed)
        .def("SetVertexFilterProperty", &GraphInterfaceWrap::SetVertexFilterProperty)
        .def("GetVertexFilterProperty", &GraphInterfaceWrap::GetVertexFilterProperty)
        .def("SetVertexFilterRange", &GraphInterfaceWrap::SetVertexFilterRange)
        .def("GetVertexFilterRange", &GraphInterfaceWrap::GetVertexFilterRange)
        .def("IsVertexFilterActive", &GraphInterfaceWrap::IsVertexFilterActive)
        .def("SetGenericVertexFilter",  &GraphInterfaceWrap::SetGenericVertexFilter)
        .def("SetEdgeFilterProperty", &GraphInterfaceWrap::SetEdgeFilterProperty)
        .def("GetEdgeFilterProperty", &GraphInterfaceWrap::GetEdgeFilterProperty)
        .def("SetEdgeFilterRange", &GraphInterfaceWrap::SetEdgeFilterRange)
        .def("GetEdgeFilterRange", &GraphInterfaceWrap::GetEdgeFilterRange)
        .def("IsEdgeFilterActive", &GraphInterfaceWrap::IsEdgeFilterActive)
        .def("SetGenericEdgeFilter",  &GraphInterfaceWrap::SetGenericEdgeFilter)
        .def("EditEdgeProperty",  &GraphInterfaceWrap::EditEdgeProperty)
        .def("EditVertexProperty",  &GraphInterfaceWrap::EditVertexProperty)
Tiago Peixoto's avatar
Tiago Peixoto committed
264
        .def("EditGraphProperty",  &GraphInterfaceWrap::EditGraphProperty)
265
266
        .def("RemoveEdgeProperty",  &GraphInterfaceWrap::RemoveEdgeProperty)
        .def("RemoveVertexProperty",  &GraphInterfaceWrap::RemoveVertexProperty)
Tiago Peixoto's avatar
Tiago Peixoto committed
267
        .def("RemoveGraphProperty",  &GraphInterfaceWrap::RemoveGraphProperty)
268
        .def("ListProperties",  &GraphInterfaceWrap::ListProperties)
269
270
271
272
273
274
275
276
277
278
        .def("InsertEdgeIndexProperty",  &GraphInterfaceWrap::InsertEdgeIndexProperty)
        .def("InsertVertexIndexProperty",  &GraphInterfaceWrap::InsertVertexIndexProperty)
        .def("ComputeGraphLayoutGursoy", &GraphInterfaceWrap::ComputeGraphLayoutGursoy)
        .def("ComputeGraphLayoutSpringBlock", &GraphInterfaceWrap::ComputeGraphLayoutSpringBlock)
        .def("WriteToFile", WriteToFile1)
        .def("WriteToFile", WriteToFile2)
        .def("ReadFromFile", ReadFromFile1)
        .def("ReadFromFile", ReadFromFile2)
        .def("InitSignalHandling", &GraphInterfaceWrap::InitSignalHandling);
        
Tiago Peixoto's avatar
Tiago Peixoto committed
279
    enum_<GraphInterfaceWrap::degree_t>("Degree")
280
281
282
        .value("In", GraphInterfaceWrap::IN_DEGREE)
        .value("Out", GraphInterfaceWrap::OUT_DEGREE)
        .value("Total", GraphInterfaceWrap::TOTAL_DEGREE);
Tiago Peixoto's avatar
Tiago Peixoto committed
283

Tiago Peixoto's avatar
Tiago Peixoto committed
284
    enum_<GraphInterfaceWrap::comm_corr_t>("CommCorr")
285
286
287
        .value("ErdosReyni", GraphInterfaceWrap::ERDOS_REYNI)
        .value("Uncorrelated", GraphInterfaceWrap::UNCORRELATED)
        .value("Correlated", GraphInterfaceWrap::CORRELATED);
Tiago Peixoto's avatar
Tiago Peixoto committed
288

Tiago Peixoto's avatar
Tiago Peixoto committed
289
290
291
292
293
294
295
296
297
298
299
300
    variant_from_python<string>();
    variant_from_python<GraphInterfaceWrap::degree_t>();
    to_python_converter<pair<double,double>, pair_to_tuple<double,double> >();
    pair_from_tuple<double,double>();
    to_python_converter<boost::tuple<double,double,double>, tuple_to_tuple<double,double,double> >();
    tuple_from_tuple<double,double,double>();
    to_python_converter<GraphInterfaceWrap::hist_t, hist_to_dict<GraphInterfaceWrap::hist_t> >();
    to_python_converter<GraphInterfaceWrap::hist2d_t, hist_to_dict<GraphInterfaceWrap::hist2d_t> >();
    to_python_converter<GraphInterfaceWrap::hist3d_t, hist_to_dict<GraphInterfaceWrap::hist3d_t> >();
    to_python_converter<GraphInterfaceWrap::avg_corr_t, hist_to_dict<GraphInterfaceWrap::avg_corr_t> >();

    class_<LibInfo>("mod_info")
301
302
303
304
        .add_property("name", &LibInfo::GetName)
        .add_property("author", &LibInfo::GetAuthor)
        .add_property("copyright", &LibInfo::GetCopyright)
        .add_property("version", &LibInfo::GetVersion);
Tiago Peixoto's avatar
Tiago Peixoto committed
305
}