graph.hh 11.8 KB
Newer Older
1

Tiago Peixoto's avatar
Tiago Peixoto committed
2
3
// graph-tool -- a general graph modification and manipulation thingy
//
Tiago Peixoto's avatar
Tiago Peixoto committed
4
// Copyright (C) 2007  Tiago de Paula Peixoto <tiago@forked.de>
Tiago Peixoto's avatar
Tiago Peixoto committed
5
6
7
//
// 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
8
// as published by the Free Software Foundation; either version 3
Tiago Peixoto's avatar
Tiago Peixoto committed
9
10
11
12
13
14
15
16
// 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
17
// along with this program. If not, see <http://www.gnu.org/licenses/>.
Tiago Peixoto's avatar
Tiago Peixoto committed
18
19
20
21
22
23
24
25
26
27

#ifndef GRAPH_HH
#define GRAPH_HH

#include <boost/graph/graph_traits.hpp>
#include <boost/graph/adjacency_list.hpp>
#include <boost/vector_property_map.hpp>
#include <boost/dynamic_property_map.hpp>
#include <boost/variant.hpp>
#include <boost/python/object.hpp>
28
#include <boost/python/dict.hpp>
29
#include <boost/lambda/lambda.hpp>
Tiago Peixoto's avatar
Tiago Peixoto committed
30
31
#include "histogram.hh"
#include "config.h"
32
#include "graph_properties.hh"
Tiago Peixoto's avatar
Tiago Peixoto committed
33
34
35

namespace graph_tool
{
36
37
using namespace std;
using namespace boost;
Tiago Peixoto's avatar
Tiago Peixoto committed
38
39

// GraphInterface
40
41
42
// this class is the main interface to the internally kept graph. This is how
// the external world will manipulate the graph. All the algorithms should be
// registered here. This class will be exported to python in graph_bind.hh
Tiago Peixoto's avatar
Tiago Peixoto committed
43
44
45
46

class GraphInterface
{
public:
47
    GraphInterface();
Tiago Peixoto's avatar
Tiago Peixoto committed
48
49
    ~GraphInterface();

50
    // this enum specifies all the different types of degree
Tiago Peixoto's avatar
Tiago Peixoto committed
51
52
    enum degree_t
    {
53
54
        IN_DEGREE,
        OUT_DEGREE,
55
56
        TOTAL_DEGREE, // in + out
        SCALAR        // scalar vertex property
Tiago Peixoto's avatar
Tiago Peixoto committed
57
58
    };

59
60
    typedef variant<degree_t,string> deg_t; // useful when function also expects
                                            // a scalar vertex property
Tiago Peixoto's avatar
Tiago Peixoto committed
61

62
63
64
    //
    // Basic manipulation
    //
Tiago Peixoto's avatar
Tiago Peixoto committed
65
66
67

    size_t GetNumberOfVertices() const;
    size_t GetNumberOfEdges() const;
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
    void SetDirected(bool directed) {_directed = directed;}
    bool GetDirected() const {return _directed;}
    void SetReversed(bool reversed) {_reversed = reversed;}
    bool GetReversed() const {return _reversed;}


    // graph filtering
    void SetVertexFilterProperty(string property);
    void SetVertexFilterRange(pair<double,double> allowed_range,
                              pair<bool,bool> include, bool invert);
    bool IsVertexFilterActive() const;

    void SetEdgeFilterProperty(string property);
    void SetEdgeFilterRange(pair<double,double> allowed_range,
                            pair<bool,bool> include, bool invert);
    bool IsEdgeFilterActive() const;


    // graph modification
    void RemoveVertexProperty(string property);
    void RemoveEdgeProperty(string property);
    void RemoveGraphProperty(string property);
    void InsertEdgeIndexProperty(string property);
    void InsertVertexIndexProperty(string property);
    void EditVertexProperty(string property, string type, python::object op,
                            python::object g);
    void EditEdgeProperty(string property, string type, python::object op,
                          python::object g);
    void EditGraphProperty(string property, string type, python::object op,
                           python::object g);
    void ReIndexEdges();
    void PurgeVertices(); // removes filtered vertices
    void PurgeEdges();    // removes filtered edges
    void RandomRewire(std::string strat, bool self_loops, bool parallel_edges,
                      size_t seed);

    // i/o
    void WriteToFile(string s);
    void WriteToFile(string s, string format);
    void ReadFromFile(string s);
    void ReadFromFile(string s, string format);

    //
    // Algorithms
    // Below are all the algorithms that operate somehow on the graph
    //

    // basic statistics
116
    hist_t GetVertexHistogram(deg_t degree) const;
117
    hist_t GetEdgeHistogram(string property) const;
Tiago Peixoto's avatar
Tiago Peixoto committed
118

119
    // correlations
120
    hist2d_t   GetCombinedVertexHistogram(deg_t degree1, deg_t degree2) const;
121
122
123
124
125
126
127
128
129
    avg_corr_t GetAverageCombinedVertexCorrelation(deg_t degree1,
                                                   deg_t degree2)const;
    hist2d_t   GetVertexCorrelationHistogram(deg_t degree1, deg_t degree2,
                                             string weight) const;
    hist3d_t   GetEdgeVertexCorrelationHistogram(deg_t deg1, string scalar,
                                                 deg_t deg2) const;
    avg_corr_t GetAverageNearestNeighboursCorrelation(deg_t origin_degree,
                                                      deg_t neighbour_degree,
                                                      string weight) const;
130

131
    // vertex mixing
132
133
    pair<double,double> GetAssortativityCoefficient(deg_t deg) const;
    pair<double,double> GetScalarAssortativityCoefficient(deg_t deg) const;
Tiago Peixoto's avatar
Tiago Peixoto committed
134

135
    // clustering
136
137
138
139
    void SetLocalClusteringToProperty(string property);
    pair<double,double> GetGlobalClustering();
    void SetExtendedClusteringToProperty(string property_prefix,
                                         size_t max_depth);
Tiago Peixoto's avatar
Tiago Peixoto committed
140
141

    // other
142
143
144
145
146
    void   LabelComponents(string property);
    void   LabelParallelEdges(string property);
    hist_t GetDistanceHistogram(string weight) const;
    hist_t GetSampledDistanceHistogram(string weight, size_t samples,
                                       size_t seed) const;
147
    double GetReciprocity() const;
148
149
150
151
152
    void   GetMinimumSpanningTree(string weight, string property);
    void   GetLineGraph(string out_file, string format);
    void   GetBetweenness(string weight, string edge_betweenness,
                          string vertex_betweenness);
    double GetCentralPointDominance(string vertex_betweenness);
153

Tiago Peixoto's avatar
Tiago Peixoto committed
154
    // community structure
155
    enum comm_corr_t // null model correlation type
Tiago Peixoto's avatar
Tiago Peixoto committed
156
    {
157
158
159
        ERDOS_REYNI,
        UNCORRELATED,
        CORRELATED
Tiago Peixoto's avatar
Tiago Peixoto committed
160
161
    };

162
163
164
165
166
    void   GetCommunityStructure(double gamma, comm_corr_t corr, size_t n_iter,
                                 double Tmin, double Tmax, size_t Nseeds,
                                 size_t seed, bool verbose, string history_file,
                                 string weight, string property);
    double GetModularity(string weight, string property);
167
    // TODO: this should return a GraphInterface type
168
169
    void   GetCommunityNetwork(string property, string size_property,
                               string out_file, string format) const;
Tiago Peixoto's avatar
Tiago Peixoto committed
170

171
172
173
174
175
176
177
    // Graph generation
    void GenerateCorrelatedConfigurationalModel
        (size_t N, python::object ppjk, python::object pceil_pjk,
         python::object pinv_ceil_pjk, double ceil_pjk_bound,
         python::object pcorr, python::object pceil_corr,
         python::object pinv_ceil_corr, double ceil_corr_bound,
         bool undirected_corr, size_t seed, bool verbose);
Tiago Peixoto's avatar
Tiago Peixoto committed
178

179
    // graph layout
180
181
182
183
    void ComputeGraphLayoutGursoy(string prop, string weight, string topology,
                                  size_t iter = 0, size_t seed = 4357);
    void ComputeGraphLayoutSpringBlock(string prop, string weight, string type,
                                       size_t iter = 0, size_t seed = 4357);
Tiago Peixoto's avatar
Tiago Peixoto committed
184

185
186
187
188
    // python interface
    python::object Vertices() const;
    python::object Edges() const;

189
190
191
192
193
194
195
196
197
198
199
200
    python::object AddVertex();
    void RemoveVertex(python::object v);
    python::object AddEdge(python::object s, python::object t);
    void RemoveEdge(python::object e);

    python::dict GetVertexProperties() const;
    python::dict GetEdgeProperties() const;
    python::dict GetGraphProperties() const;

    // used for graph properties
    graph_property_tag GetDescriptor() const { return graph_property_tag(); }

201
202
    void ExportPythonInterface() const;

Tiago Peixoto's avatar
Tiago Peixoto committed
203
204
205
    // signal handling
    void InitSignalHandling();

206
207
208
209
210
211
212
213
214
    // arbitrary code execution, for run-time code integration
    template <class Action, class Args>
    void RunAction(const Action &a, const Args& args)
    {
        using namespace boost::lambda;
        run_action(*this, bind<void>(a, boost::lambda::_1, _vertex_index,
                                     _edge_index, var(_properties), var(args)));
    }

215
216
217
218
    //
    // Internal types
    //

Tiago Peixoto's avatar
Tiago Peixoto committed
219
    // the following defines the edges' internal properties
220
    typedef property<edge_index_t, size_t> EdgeProperty;
Tiago Peixoto's avatar
Tiago Peixoto committed
221
222

    // this is the main graph type
223
224
225
226
227
228
229
    typedef adjacency_list <vecS, // edges
                            vecS, // vertices
                            bidirectionalS,
                            no_property,
                            EdgeProperty>  multigraph_t;
    typedef graph_traits<multigraph_t>::vertex_descriptor vertex_t;
    typedef graph_traits<multigraph_t>::edge_descriptor edge_t;
Tiago Peixoto's avatar
Tiago Peixoto committed
230
231

private:
232
233
234
235
236
237
238
239
240
241
242
243

    // The following function is very central to the implementation of the above
    // member functions. Most of the algorithms are implemented as template
    // functors, which must be run on the correct version of the graph, i.e.,
    // filtered, unfiltered, directed, undirected, etc. The functor in question
    // must be fed to the function below as the "a" variable, which will take
    // care of business, selection the correct implementation. The ReverseCheck
    // and DirectedCheck below are utility types which allow for limiting the
    // implementation generation when you want it to be confined for only
    // specific graph types. See graph_filtering.hh for details.

    template <class GraphInterfaceType, class Action, class ReverseCheck,
244
              class DirectedCheck>
245
    friend void run_action(GraphInterfaceType &g, Action a,
246
247
248
249
                           ReverseCheck, DirectedCheck, bool run_all=false);

    // useful overload for common case where all graph types should be probed
    template <class GraphInterfaceType, class Action>
250
    friend void run_action(GraphInterfaceType &g, Action a);
251

Tiago Peixoto's avatar
Tiago Peixoto committed
252
253
    friend class scalarS;

254
    // this is the main graph
Tiago Peixoto's avatar
Tiago Peixoto committed
255
256
    multigraph_t _mg;

257
    // reverse and directed states
Tiago Peixoto's avatar
Tiago Peixoto committed
258
259
260
261
    bool _reversed;
    bool _directed;

    // vertex index map
262
    typedef property_map<multigraph_t,vertex_index_t>::type vertex_index_map_t;
Tiago Peixoto's avatar
Tiago Peixoto committed
263
264
265
    vertex_index_map_t _vertex_index;

    // edge index map
266
    typedef property_map<multigraph_t,edge_index_t>::type edge_index_map_t;
Tiago Peixoto's avatar
Tiago Peixoto committed
267
268
269
    edge_index_map_t _edge_index;

    // graph properties
270
    dynamic_properties _properties;
Tiago Peixoto's avatar
Tiago Peixoto committed
271
272

    // vertex filter
273
274
275
276
277
278
279
280
    string _vertex_filter_property;
    typedef variant<vector_property_map<double,vertex_index_map_t>,
                    HashedDescriptorMap<vertex_index_map_t,double>,
                    vector_property_map<size_t,vertex_index_map_t>,
                    HashedDescriptorMap<vertex_index_map_t,size_t>,
                    vertex_index_map_t,
                    DynamicPropertyMapWrap<double,vertex_t> >
        vertex_filter_map_t;
Tiago Peixoto's avatar
Tiago Peixoto committed
281
    vertex_filter_map_t _vertex_filter_map;
282
283
    pair<double,double> _vertex_range;
    pair<bool,bool> _vertex_range_include;
Tiago Peixoto's avatar
   
Tiago Peixoto committed
284
    bool _vertex_range_invert;
Tiago Peixoto's avatar
Tiago Peixoto committed
285
286

    // edge filter
287
288
289
290
291
292
293
294
    string _edge_filter_property;
    typedef variant<vector_property_map<double, edge_index_map_t>,
                    HashedDescriptorMap<edge_index_map_t, double>,
                    vector_property_map<size_t, edge_index_map_t>,
                    HashedDescriptorMap<edge_index_map_t, size_t>,
                    edge_index_map_t,
                    DynamicPropertyMapWrap<double,edge_t> >
        edge_filter_map_t;
Tiago Peixoto's avatar
Tiago Peixoto committed
295
    edge_filter_map_t _edge_filter_map;
296
297
    pair<double,double> _edge_range;
    pair<bool,bool> _edge_range_include;
Tiago Peixoto's avatar
   
Tiago Peixoto committed
298
    bool _edge_range_invert;
299

Tiago Peixoto's avatar
Tiago Peixoto committed
300
301
};

302
303
pair<GraphInterface::degree_t,string>
get_degree_type(GraphInterface::deg_t degree);
Tiago Peixoto's avatar
Tiago Peixoto committed
304

305
306
// This is the main exception which will be thrown the outside world, when
// things go wrong
Tiago Peixoto's avatar
Tiago Peixoto committed
307

308
class GraphException : public exception
Tiago Peixoto's avatar
Tiago Peixoto committed
309
{
310
    string _error;
Tiago Peixoto's avatar
Tiago Peixoto committed
311
public:
312
    GraphException(string error) {_error = error;}
Tiago Peixoto's avatar
Tiago Peixoto committed
313
314
315
316
317
318
319
320
321
322
    virtual ~GraphException() throw () {}
    virtual const char * what () const throw () {return _error.c_str();}
};

} //namespace graph_tool

#endif