graph_bind.cc 13.1 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
// 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
16
17
// along with this program. If not, see <http://www.gnu.org/licenses/>.

Tiago Peixoto's avatar
Tiago Peixoto committed
18
19
20
21

#include <boost/python.hpp>
#include <boost/tuple/tuple.hpp>
#include "graph.hh"
22
#include "graph_python_interface.hh"
Tiago Peixoto's avatar
Tiago Peixoto committed
23
24
25
26
27
28
29
30
31
32
33
34
35

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)
    {
36
37
        boost::python::tuple t = boost::python::make_tuple(p.first,p.second);
        return incref(t.ptr());
Tiago Peixoto's avatar
Tiago Peixoto committed
38
39
40
41
42
43
44
45
    }
};

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


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

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

75
    static void construct(PyObject* obj_ptr,
76
                          converter::rvalue_from_python_stage1_data* data)
77
    {
78
79
80
81
82
83
        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]);
84
        void* storage =
85
86
            ((boost::python::converter::rvalue_from_python_storage
              <boost::tuple<T1,T2,T3> >*) data)->storage.bytes;
87
88
        new (storage) boost::tuple<T1,T2,T3>(value);
        data->convertible = storage;
Tiago Peixoto's avatar
Tiago Peixoto committed
89
90
91
92
93
94
95
96
    }
};

template <class T1, class T2>
struct pair_from_tuple
{
    pair_from_tuple()
    {
97
        converter::registry::push_back(&convertible, &construct,
98
                                       boost::python::type_id<pair<T1,T2> >());
Tiago Peixoto's avatar
Tiago Peixoto committed
99
100
101
102
    }

    static void* convertible(PyObject* obj_ptr)
    {
103
104
105
106
        handle<> x(borrowed(obj_ptr));
        object o(x);
        extract<T1> first(o[0]);
        extract<T2> second(o[1]);
107
        if (!first.check() || !second.check())
108
109
            return 0;
        return obj_ptr;
Tiago Peixoto's avatar
Tiago Peixoto committed
110
111
    }

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

128
template <class ValueType>
Tiago Peixoto's avatar
Tiago Peixoto committed
129
130
131
132
struct variant_from_python
{
    variant_from_python()
    {
133
        converter::registry::push_back
134
            (&convertible, &construct,
135
             boost::python::type_id<GraphInterface::deg_t>());
Tiago Peixoto's avatar
Tiago Peixoto committed
136
137
138
139
    }

    static void* convertible(PyObject* obj_ptr)
    {
140
141
142
143
144
145
        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
146
147
    }

148
    static void construct(PyObject* obj_ptr,
149
                          converter::rvalue_from_python_stage1_data* data)
150
    {
151
152
153
154
        handle<> x(borrowed(obj_ptr));
        object o(x);
        ValueType value = extract<ValueType>(o);
        GraphInterface::deg_t deg = value;
155
        void* storage =
156
157
            ( (boost::python::converter::rvalue_from_python_storage
               <GraphInterface::deg_t>*) data)->storage.bytes;
158
159
        new (storage) GraphInterface::deg_t(deg);
        data->convertible = storage;
Tiago Peixoto's avatar
Tiago Peixoto committed
160
161
162
163
164
165
166
167
168
169
    }
};



template <class Hist>
struct hist_to_dict
{
    static PyObject* convert(const Hist& h)
    {
170
171
172
173
        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
174
175
176
    }
};

177
178
179
180
181
182
183
184
185
186
187
188
189
struct pos_t_to_tuple
{
    static PyObject* convert(const pos_t& p)
    {
        boost::python::tuple t = boost::python::make_tuple(p.x,p.y);
        return incref(t.ptr());
    }
};

struct pos_t_from_tuple
{
    pos_t_from_tuple()
    {
190
        converter::registry::push_back(&convertible, &construct,
191
                                       boost::python::type_id<pos_t>());
192
193
194
195
196
197
198
199
    }

    static void* convertible(PyObject* obj_ptr)
    {
        handle<> x(borrowed(obj_ptr));
        object o(x);
        extract<double> first(o[0]);
        extract<double> second(o[1]);
200
        if (!first.check() || !second.check())
201
202
203
204
            return 0;
        return obj_ptr;
    }

205
    static void construct(PyObject* obj_ptr,
206
                          converter::rvalue_from_python_stage1_data* data)
207
    {
208
209
210
211
212
        handle<> x(borrowed(obj_ptr));
        object o(x);
        pos_t value;
        value.x = extract<double>(o[0]);
        value.y = extract<double>(o[1]);
213
        void* storage =
214
215
            ( (boost::python::converter::rvalue_from_python_storage
               <pos_t>*) data)->storage.bytes;
216
217
218
219
220
        new (storage) pos_t(value);
        data->convertible = storage;
    }
};

Tiago Peixoto's avatar
Tiago Peixoto committed
221
222
223
224
225
struct LibInfo
{
    string GetName()      const {return PACKAGE_NAME;}
    string GetAuthor()    const {return AUTHOR;}
    string GetCopyright() const {return COPYRIGHT;}
226
    string GetVersion()   const {return VERSION " (commit " GIT_COMMIT ", " GIT_COMMIT_DATE ")";}
227
    string GetLicense()   const {return "GPL version 3 or above";}
Tiago Peixoto's avatar
Tiago Peixoto committed
228
229
};

Tiago Peixoto's avatar
Tiago Peixoto committed
230
// overloads
231
232
233
234
235
236
237
238
void  (GraphInterface::*ReadFromFile1) (string) =
    &GraphInterface::ReadFromFile;
void  (GraphInterface::*ReadFromFile2) (string, string) =
    &GraphInterface::ReadFromFile;
void  (GraphInterface::*WriteToFile1)  (string) =
    &GraphInterface::WriteToFile;
void  (GraphInterface::*WriteToFile2)  (string, string)  =
    &GraphInterface::WriteToFile;
Tiago Peixoto's avatar
Tiago Peixoto committed
239

Tiago Peixoto's avatar
Tiago Peixoto committed
240
241
BOOST_PYTHON_MODULE(libgraph_tool)
{
242
243
244
245
246
247
248
249
250
251
252
    GraphInterface().ExportPythonInterface();

    class_<GraphInterface>("GraphInterface")
        .def("GenerateCorrelatedConfigurationalModel",
             &GraphInterface::GenerateCorrelatedConfigurationalModel)
        .def("GetNumberOfVertices", &GraphInterface::GetNumberOfVertices)
        .def("GetNumberOfEdges", &GraphInterface::GetNumberOfEdges)
        .def("GetVertexHistogram", &GraphInterface::GetVertexHistogram)
        .def("GetEdgeHistogram", &GraphInterface::GetEdgeHistogram)
        .def("LabelComponents", &GraphInterface::LabelComponents)
        .def("LabelParallelEdges", &GraphInterface::LabelParallelEdges)
253
        .def("GetCombinedVertexHistogram",
254
255
256
257
258
259
260
261
262
263
264
265
266
267
             &GraphInterface::GetCombinedVertexHistogram)
        .def("GetAverageCombinedVertexCorrelation",
             &GraphInterface::GetAverageCombinedVertexCorrelation)
        .def("GetVertexCorrelationHistogram",
             &GraphInterface::GetVertexCorrelationHistogram)
        .def("GetEdgeVertexCorrelationHistogram",
             &GraphInterface::GetEdgeVertexCorrelationHistogram)
        .def("GetAverageNearestNeighboursCorrelation",
             &GraphInterface::GetAverageNearestNeighboursCorrelation)
        .def("GetAssortativityCoefficient",
             &GraphInterface::GetAssortativityCoefficient)
        .def("GetScalarAssortativityCoefficient",
             &GraphInterface::GetScalarAssortativityCoefficient)
        .def("GetGlobalClustering", &GraphInterface::GetGlobalClustering)
268
        .def("SetLocalClusteringToProperty",
269
             &GraphInterface::SetLocalClusteringToProperty)
270
        .def("SetExtendedClusteringToProperty",
271
272
273
274
275
276
277
278
279
280
281
             &GraphInterface::SetExtendedClusteringToProperty)
        .def("GetDistanceHistogram", &GraphInterface::GetDistanceHistogram)
        .def("GetSampledDistanceHistogram",
             &GraphInterface::GetSampledDistanceHistogram)
        .def("GetReciprocity", &GraphInterface::GetReciprocity)
        .def("GetMinimumSpanningTree",
             &GraphInterface::GetMinimumSpanningTree)
        .def("GetLineGraph", &GraphInterface::GetLineGraph)
        .def("GetBetweenness", &GraphInterface::GetBetweenness)
        .def("GetCentralPointDominance",
             &GraphInterface::GetCentralPointDominance)
282
        .def("GetCommunityStructure",
283
284
285
             &GraphInterface::GetCommunityStructure)
        .def("GetCommunityNetwork", &GraphInterface::GetCommunityNetwork)
        .def("GetModularity", &GraphInterface::GetModularity)
Tiago Peixoto's avatar
Tiago Peixoto committed
286
        .def("RandomRewire", &GraphInterface::RandomRewire)
287
288
289
290
291
292
293
294
        .def("SetDirected", &GraphInterface::SetDirected)
        .def("GetDirected", &GraphInterface::GetDirected)
        .def("SetReversed", &GraphInterface::SetReversed)
        .def("GetReversed", &GraphInterface::GetReversed)
        .def("SetVertexFilterProperty",
             &GraphInterface::SetVertexFilterProperty)
        .def("SetVertexFilterRange", &GraphInterface::SetVertexFilterRange)
        .def("IsVertexFilterActive", &GraphInterface::IsVertexFilterActive)
295
        .def("SetEdgeFilterProperty",
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
             &GraphInterface::SetEdgeFilterProperty)
        .def("SetEdgeFilterRange", &GraphInterface::SetEdgeFilterRange)
        .def("IsEdgeFilterActive", &GraphInterface::IsEdgeFilterActive)
        .def("EditEdgeProperty",  &GraphInterface::EditEdgeProperty)
        .def("EditVertexProperty",  &GraphInterface::EditVertexProperty)
        .def("EditGraphProperty",  &GraphInterface::EditGraphProperty)
        .def("RemoveEdgeProperty",  &GraphInterface::RemoveEdgeProperty)
        .def("RemoveVertexProperty",  &GraphInterface::RemoveVertexProperty)
        .def("RemoveGraphProperty",  &GraphInterface::RemoveGraphProperty)
        .def("PurgeVertices",  &GraphInterface::PurgeVertices)
        .def("PurgeEdges",  &GraphInterface::PurgeEdges)
        .def("InsertEdgeIndexProperty",
             &GraphInterface::InsertEdgeIndexProperty)
        .def("InsertVertexIndexProperty",
             &GraphInterface::InsertVertexIndexProperty)
        .def("ComputeGraphLayoutGursoy",
             &GraphInterface::ComputeGraphLayoutGursoy)
        .def("ComputeGraphLayoutSpringBlock",
             &GraphInterface::ComputeGraphLayoutSpringBlock)
315
316
317
318
        .def("WriteToFile", WriteToFile1)
        .def("WriteToFile", WriteToFile2)
        .def("ReadFromFile", ReadFromFile1)
        .def("ReadFromFile", ReadFromFile2)
319
320
321
322
323
324
325
326
327
        .def("Vertices", &GraphInterface::Vertices)
        .def("Edges", &GraphInterface::Edges)
        .def("AddVertex", &GraphInterface::AddVertex)
        .def("AddEdge", &GraphInterface::AddEdge)
        .def("RemoveVertex", &GraphInterface::RemoveVertex)
        .def("RemoveEdge", &GraphInterface::RemoveEdge)
        .def("GetVertexProperties", &GraphInterface::GetVertexProperties)
        .def("GetEdgeProperties", &GraphInterface::GetEdgeProperties)
        .def("GetGraphProperties", &GraphInterface::GetGraphProperties)
328
329
330
331
332
333
        .def("InitSignalHandling", &GraphInterface::InitSignalHandling);

    enum_<GraphInterface::degree_t>("Degree")
        .value("In", GraphInterface::IN_DEGREE)
        .value("Out", GraphInterface::OUT_DEGREE)
        .value("Total", GraphInterface::TOTAL_DEGREE);
Tiago Peixoto's avatar
Tiago Peixoto committed
334

335
336
337
338
    enum_<GraphInterface::comm_corr_t>("CommCorr")
        .value("ErdosReyni", GraphInterface::ERDOS_REYNI)
        .value("Uncorrelated", GraphInterface::UNCORRELATED)
        .value("Correlated", GraphInterface::CORRELATED);
Tiago Peixoto's avatar
Tiago Peixoto committed
339

Tiago Peixoto's avatar
Tiago Peixoto committed
340
    variant_from_python<string>();
341
    variant_from_python<GraphInterface::degree_t>();
Tiago Peixoto's avatar
Tiago Peixoto committed
342
343
    to_python_converter<pair<double,double>, pair_to_tuple<double,double> >();
    pair_from_tuple<double,double>();
344
    to_python_converter<boost::tuple<double,double,double>,
345
                        tuple_to_tuple<double,double,double> >();
Tiago Peixoto's avatar
Tiago Peixoto committed
346
    tuple_from_tuple<double,double,double>();
347
348
    to_python_converter<pos_t, pos_t_to_tuple>();
    pos_t_from_tuple();
349
    pair_from_tuple<bool,bool>();
350
351
352
353
    to_python_converter<hist_t,hist_to_dict<hist_t> >();
    to_python_converter<hist2d_t,hist_to_dict<hist2d_t> >();
    to_python_converter<hist3d_t,hist_to_dict<hist3d_t> >();
    to_python_converter<avg_corr_t,hist_to_dict<avg_corr_t> >();
Tiago Peixoto's avatar
Tiago Peixoto committed
354
355

    class_<LibInfo>("mod_info")
356
357
358
        .add_property("name", &LibInfo::GetName)
        .add_property("author", &LibInfo::GetAuthor)
        .add_property("copyright", &LibInfo::GetCopyright)
359
360
        .add_property("version", &LibInfo::GetVersion)
        .add_property("license", &LibInfo::GetLicense);
Tiago Peixoto's avatar
Tiago Peixoto committed
361
}