igraph 0.1.1 → 0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,77 @@
1
+ #include "igraph.h"
2
+ #include "ruby.h"
3
+ #include "cIGraph.h"
4
+
5
+ /* call-seq:
6
+ * graph.layout_random -> IGraphMatrix
7
+ *
8
+ * Returns a random layout
9
+ */
10
+ VALUE cIGraph_layout_random(VALUE self){
11
+
12
+ igraph_t *graph;
13
+ igraph_matrix_t *res = malloc(sizeof(igraph_matrix_t));
14
+
15
+ Data_Get_Struct(self, igraph_t, graph);
16
+
17
+ igraph_matrix_init(res,0,0);
18
+ igraph_layout_random(graph,res);
19
+
20
+ return Data_Wrap_Struct(cIGraphMatrix, 0, cIGraph_matrix_free, res);
21
+
22
+ }
23
+
24
+ /* call-seq:
25
+ * graph.layout_random -> IGraphMatrix
26
+ *
27
+ * Returns a layout with nodes laid out around a circle.
28
+ */
29
+ VALUE cIGraph_layout_circle(VALUE self){
30
+
31
+ igraph_t *graph;
32
+ igraph_matrix_t *res = malloc(sizeof(igraph_matrix_t));
33
+
34
+ Data_Get_Struct(self, igraph_t, graph);
35
+
36
+ igraph_matrix_init(res,0,0);
37
+ igraph_layout_circle(graph,res);
38
+
39
+ return Data_Wrap_Struct(cIGraphMatrix, 0, cIGraph_matrix_free, res);
40
+
41
+ }
42
+
43
+ /* call-seq:
44
+ * graph.layout_random -> IGraphMatrix
45
+ *
46
+ * Places the vertices on a plane according to the Fruchterman-Reingold
47
+ * algorithm.
48
+ *
49
+ * This is a force-directed layout, see Fruchterman, T.M.J. and Reingold,
50
+ * E.M.: Graph Drawing by Force-directed Placement. Software -- Practice and
51
+ * Experience, 21/11, 1129--1164, 1991.
52
+ */
53
+ VALUE cIGraph_layout_fruchterman_reingold(VALUE self,
54
+ VALUE niter,
55
+ VALUE maxdelta,
56
+ VALUE area,
57
+ VALUE coolexp,
58
+ VALUE repulserad,
59
+ VALUE use_seed){
60
+
61
+ igraph_t *graph;
62
+ igraph_matrix_t *res = malloc(sizeof(igraph_matrix_t));
63
+
64
+ Data_Get_Struct(self, igraph_t, graph);
65
+
66
+ igraph_matrix_init(res,0,0);
67
+ igraph_layout_fruchterman_reingold(graph,res,
68
+ NUM2INT(niter),
69
+ NUM2DBL(maxdelta),
70
+ NUM2DBL(area),
71
+ NUM2DBL(coolexp),
72
+ NUM2DBL(repulserad),
73
+ use_seed == Qtrue ? 1: 0);
74
+
75
+ return Data_Wrap_Struct(cIGraphMatrix, 0, cIGraph_matrix_free, res);
76
+
77
+ }
@@ -0,0 +1,241 @@
1
+ #include "igraph.h"
2
+ #include "ruby.h"
3
+ #include "cIGraph.h"
4
+
5
+ //Classes
6
+ VALUE cIGraphMatrix;
7
+
8
+ void cIGraph_matrix_free(void *p){
9
+ igraph_matrix_destroy(p);
10
+ }
11
+
12
+ VALUE cIGraph_matrix_alloc(VALUE klass){
13
+
14
+ igraph_matrix_t *m = malloc(sizeof(igraph_matrix_t));
15
+ VALUE obj;
16
+
17
+ igraph_matrix_init(m, 0, 0);
18
+
19
+ obj = Data_Wrap_Struct(klass, 0, cIGraph_matrix_free, m);
20
+
21
+ return obj;
22
+
23
+ }
24
+
25
+ /* Document-method: initialize_copy
26
+ *
27
+ * Internal method for copying IGraph objects.
28
+ */
29
+ VALUE cIGraph_matrix_init_copy(VALUE copy, VALUE orig){
30
+
31
+ igraph_matrix_t *orig_m;
32
+ igraph_matrix_t *copy_m;
33
+
34
+ if (copy == orig)
35
+ return copy;
36
+
37
+ if(TYPE(orig) != T_DATA || RDATA(orig)->dfree != (RUBY_DATA_FUNC)cIGraph_free){
38
+ rb_raise(rb_eTypeError, "Wrong argument type.");
39
+ }
40
+
41
+ Data_Get_Struct(copy, igraph_matrix_t, copy_m);
42
+ Data_Get_Struct(orig, igraph_matrix_t, orig_m);
43
+
44
+ igraph_matrix_copy(copy_m,orig_m);
45
+
46
+ return copy;
47
+
48
+ }
49
+
50
+ /* call-seq:
51
+ * IGraphMatrix.new([[x,y,...],...]) -> IGraphMatrix
52
+ *
53
+ * Creates a new IGraphMatrix object. The argument should be an Array of
54
+ * Arrays which each contain the data for a row of the matrix.
55
+ */
56
+ VALUE cIGraph_matrix_initialize(int argc, VALUE *argv, VALUE self){
57
+
58
+ igraph_matrix_t *m;
59
+ VALUE rows;
60
+ int nrows;
61
+ int ncols;
62
+ int i;
63
+ int j;
64
+
65
+ rb_scan_args(argc,argv,"0*", &rows);
66
+
67
+ Data_Get_Struct(self, igraph_matrix_t, m);
68
+
69
+ nrows = RARRAY(rows)->len;
70
+ ncols = RARRAY(RARRAY(rows)->ptr[0])->len;
71
+
72
+ igraph_matrix_resize(m, nrows, ncols);
73
+
74
+ //Loop through rows
75
+ for (i=0; i<nrows; i++) {
76
+ for (j=0; j<ncols; j++){
77
+ MATRIX(*m,i,j) = NUM2DBL(RARRAY(RARRAY(rows)->ptr[i])->ptr[j]);
78
+ }
79
+ }
80
+
81
+ return self;
82
+
83
+ }
84
+
85
+ /* call-seq:
86
+ * matrix[i,j] -> Float
87
+ *
88
+ * Returns the value stored at row i and column j.
89
+ */
90
+ VALUE cIGraph_matrix_get(VALUE self, VALUE i, VALUE j){
91
+
92
+ igraph_matrix_t *m;
93
+
94
+ Data_Get_Struct(self, igraph_matrix_t, m);
95
+ return rb_float_new(MATRIX(*m,NUM2INT(i),NUM2INT(j)));
96
+
97
+ }
98
+
99
+ /* call-seq:
100
+ * matrix[i,j]= -> Float
101
+ *
102
+ * Sets the value stored at row i and column j.
103
+ */
104
+ VALUE cIGraph_matrix_set(VALUE self, VALUE i, VALUE j, VALUE x){
105
+
106
+ igraph_matrix_t *m;
107
+
108
+ Data_Get_Struct(self, igraph_matrix_t, m);
109
+ MATRIX(*m,NUM2INT(i),NUM2INT(j)) = NUM2DBL(x);
110
+ return x;
111
+
112
+ }
113
+
114
+ /* call-seq:
115
+ * matrix.each{|v| } -> nil
116
+ *
117
+ * Iterates through each value in the matrix.
118
+ */
119
+ VALUE cIGraph_matrix_each(VALUE self){
120
+
121
+ igraph_matrix_t *m;
122
+ int i;
123
+ int j;
124
+
125
+ Data_Get_Struct(self, igraph_matrix_t, m);
126
+
127
+ for(i=0;i < m->nrow;i++){
128
+ for(j=0;j < m->ncol;j++){
129
+ rb_yield(rb_float_new(MATRIX(*m,i,j)));
130
+ }
131
+ }
132
+
133
+ return Qnil;
134
+
135
+ }
136
+
137
+ /* call-seq:
138
+ * matrix.size -> Integer
139
+ *
140
+ * Returns the number of elements in the matrix.
141
+ */
142
+ VALUE cIGraph_matrix_size(VALUE self){
143
+
144
+ igraph_matrix_t *m;
145
+
146
+ Data_Get_Struct(self, igraph_matrix_t, m);
147
+ return LONG2FIX(igraph_matrix_size(m));
148
+
149
+ }
150
+
151
+ /* call-seq:
152
+ * matrix.nrow -> Integer
153
+ *
154
+ * Returns the number of rows in the matrix.
155
+ */
156
+ VALUE cIGraph_matrix_nrow(VALUE self){
157
+
158
+ igraph_matrix_t *m;
159
+
160
+ Data_Get_Struct(self, igraph_matrix_t, m);
161
+ return LONG2FIX(igraph_matrix_nrow(m));
162
+
163
+ }
164
+
165
+ /* call-seq:
166
+ * matrix.ncol -> Integer
167
+ *
168
+ * Returns the number of columns in the matrix.
169
+ */
170
+ VALUE cIGraph_matrix_ncol(VALUE self){
171
+
172
+ igraph_matrix_t *m;
173
+
174
+ Data_Get_Struct(self, igraph_matrix_t, m);
175
+ return LONG2FIX(igraph_matrix_ncol(m));
176
+
177
+ }
178
+
179
+ /* call-seq:
180
+ * matrix.max -> Float
181
+ *
182
+ * Returns the value of the maximum element in the matrix.
183
+ */
184
+ VALUE cIGraph_matrix_max(VALUE self){
185
+
186
+ igraph_matrix_t *m;
187
+
188
+ Data_Get_Struct(self, igraph_matrix_t, m);
189
+ return rb_float_new(igraph_matrix_max(m));
190
+
191
+ }
192
+
193
+ /* call-seq:
194
+ * matrix * matrix -> IGraphMatrix
195
+ *
196
+ * Multiples two IGraphMatrix objects together
197
+ */
198
+ VALUE cIGraph_matrix_multiply(VALUE self, VALUE x){
199
+
200
+ igraph_matrix_t *m;
201
+ igraph_matrix_t *n = malloc(sizeof(igraph_matrix_t));
202
+ VALUE nobj;
203
+
204
+ Data_Get_Struct(self, igraph_matrix_t, m);
205
+
206
+ igraph_matrix_copy(n,m);
207
+ igraph_matrix_multiply(n, NUM2DBL(x));
208
+
209
+ nobj = Data_Wrap_Struct(cIGraphMatrix, 0, cIGraph_matrix_free, n);
210
+
211
+ return nobj;
212
+
213
+ }
214
+
215
+ /* call-seq:
216
+ * matrix.to_a -> Array
217
+ *
218
+ * Returns the matrix represented as an Array of Arrays.
219
+ */
220
+ VALUE cIGraph_matrix_toa(VALUE self){
221
+
222
+ igraph_matrix_t *m;
223
+ int i;
224
+ int j;
225
+ VALUE a = rb_ary_new();
226
+ VALUE row;
227
+
228
+ Data_Get_Struct(self, igraph_matrix_t, m);
229
+
230
+ for(i=0;i < m->nrow;i++){
231
+ row = rb_ary_new();
232
+ for(j=0;j < m->ncol;j++){
233
+ rb_ary_push(row,rb_float_new(MATRIX(*m,i,j)));
234
+ }
235
+ rb_ary_push(a,row);
236
+ }
237
+
238
+ return a;
239
+
240
+ }
241
+
@@ -18,7 +18,7 @@ VALUE cIGraph_all_v(VALUE self){
18
18
  igraph_t *graph;
19
19
 
20
20
  Data_Get_Struct(self, igraph_t, graph);
21
- return rb_funcall(rb_iv_get(self,"@object_ids"),rb_intern("keys"),0);
21
+ return ((VALUE*)graph->attr)[0];
22
22
 
23
23
  }
24
24
 
@@ -67,27 +67,115 @@ VALUE cIGraph_adj_v(VALUE self, VALUE v, VALUE mode){
67
67
 
68
68
  }
69
69
 
70
+ /* call-seq:
71
+ * graph.noadjacent_vertices(v,mode) -> Array
72
+ *
73
+ * Returns all non-neighboring vertices of a given vertex (v). The mode
74
+ * argument controls the type of neighboring vertics not to select. Possible
75
+ * values: IGRAPH_OUT, all vertices will be selected except those to which
76
+ * there is a directed edge from vid. IGRAPH_IN, all vertices will be
77
+ * selected except those from which there is a directed edge to vid.
78
+ * IGRAPH_ALL, all vertices will be selected except those from or to which
79
+ * there is a directed edge to or from vid.
80
+ */
81
+
70
82
  VALUE cIGraph_nonadj_v(VALUE self, VALUE v, VALUE mode){
71
83
 
72
- return Qnil;
84
+ igraph_t *graph;
85
+ igraph_integer_t pnode;
86
+ VALUE nonadjacent = rb_ary_new();
87
+ igraph_neimode_t pmode = NUM2INT(mode);
88
+ igraph_vs_t vs;
89
+ igraph_vit_t vit;
90
+
91
+ Data_Get_Struct(self, igraph_t, graph);
92
+
93
+ pnode = cIGraph_get_vertex_id(self,v);
94
+
95
+ igraph_vs_nonadj(&vs,pnode,pmode);
96
+ igraph_vit_create(graph, vs, &vit);
97
+
98
+ while(!IGRAPH_VIT_END(vit)) {
99
+ rb_ary_push(nonadjacent,cIGraph_get_vertex_object(self,IGRAPH_VIT_GET(vit)));
100
+ IGRAPH_VIT_NEXT(vit);
101
+ }
102
+
103
+ igraph_vit_destroy(&vit);
104
+ igraph_vs_destroy(&vs);
105
+
106
+ return nonadjacent;
73
107
 
74
108
  }
75
109
 
110
+ /* call-seq:
111
+ * graph.edges(mode) -> Array
112
+ *
113
+ * Returns an Array of all edge ids in the graph. The mode argument specifies
114
+ * the order the eids are returned. Possible values: IGRAPH_EDGEORDER_ID,
115
+ * edge id order. IGRAPH_EDGEORDER_FROM, vertex id order, the id of the
116
+ * source vertex counts for directed graphs. The order of the adjacent edges
117
+ * of a given vertex is arbitrary. IGRAPH_EDGEORDER_TO, vertex id order, the
118
+ * id of the target vertex counts for directed graphs. The order of the
119
+ * adjacent edges of a given vertex is arbitrary. For undirected graph the
120
+ * latter two is the same.
121
+ */
76
122
  VALUE cIGraph_all_e(VALUE self, VALUE mode){
77
123
 
78
- return Qnil;
124
+ igraph_t *graph;
125
+ igraph_es_t es;
126
+ igraph_eit_t eit;
127
+ igraph_edgeorder_type_t pmode = NUM2INT(mode);
128
+ VALUE edge_ids = rb_ary_new();
129
+
130
+ Data_Get_Struct(self, igraph_t, graph);
131
+
132
+ igraph_es_all(&es,pmode);
133
+ igraph_eit_create(graph, es, &eit);
134
+
135
+ while(!IGRAPH_EIT_END(eit)) {
136
+ rb_ary_push(edge_ids,INT2NUM(IGRAPH_EIT_GET(eit)));
137
+ IGRAPH_EIT_NEXT(eit);
138
+ }
139
+
140
+ igraph_eit_destroy(&eit);
141
+ igraph_es_destroy(&es);
142
+
143
+ return edge_ids;
144
+
79
145
 
80
146
  }
81
147
 
148
+ /* call-seq:
149
+ * graph.adjacent_edges(v,mode) -> Array
150
+ *
151
+ * Returns an Array of the eids of the adjacent edges of a vertex (v). The
152
+ * mode argument gives the type of edges to select. Possible values:
153
+ * IGRAPH_OUT, outgoing edges IGRAPH_IN, incoming edges IGRAPH_ALL, all edges
154
+ */
82
155
  VALUE cIGraph_adj_e(VALUE self, VALUE v, VALUE mode){
83
156
 
84
- return Qnil;
157
+ igraph_t *graph;
158
+ igraph_es_t es;
159
+ igraph_eit_t eit;
85
160
 
86
- }
161
+ VALUE adjacent = rb_ary_new();
87
162
 
88
- VALUE cIGraph_nonadj_e(VALUE self, VALUE v, VALUE mode){
163
+ Data_Get_Struct(self, igraph_t, graph);
89
164
 
90
- return Qnil;
165
+ igraph_es_none(&es);
166
+ igraph_es_adj(&es,cIGraph_get_vertex_id(self,v),NUM2INT(mode));
167
+ igraph_eit_create(graph, es, &eit);
168
+
169
+ while(!IGRAPH_EIT_END(eit)) {
170
+ rb_ary_push(adjacent,INT2NUM(IGRAPH_EIT_GET(eit)));
171
+ IGRAPH_EIT_NEXT(eit);
172
+ }
173
+
174
+ igraph_eit_destroy(&eit);
175
+ igraph_es_destroy(&es);
176
+
177
+ return adjacent;
91
178
 
92
179
  }
93
180
 
181
+
@@ -2,6 +2,17 @@
2
2
  #include "ruby.h"
3
3
  #include "cIGraph.h"
4
4
 
5
+ /* call-seq:
6
+ * graph.shortest_paths(varray,mode) -> Array
7
+ *
8
+ * Calculates the length of the shortest paths from each of the vertices in
9
+ * the varray Array to all of the other vertices in the graph. The result
10
+ * is returned as an Array of Array. Each top-level Array contains the results
11
+ * for a vertex in the varray Array. Each entry in the Array is the path length
12
+ * to another vertex in the graph in vertex order (the order the vertices were
13
+ * added to the graph. (This should probalby be changed to give a Hash of Hash
14
+ * to allow easier look up.)
15
+ */
5
16
  VALUE cIGraph_shortest_paths(VALUE self, VALUE from, VALUE mode){
6
17
 
7
18
  igraph_t *graph;
@@ -49,6 +60,17 @@ VALUE cIGraph_shortest_paths(VALUE self, VALUE from, VALUE mode){
49
60
 
50
61
  }
51
62
 
63
+ /* call-seq:
64
+ * graph.get_shortest_paths(from,to_array,mode) -> Array
65
+ *
66
+ * Calculates the paths from the vertex specified as from to each vertex in the
67
+ * to_array Array. Returns an Array of Arrays. Each top level Array represents
68
+ * a path and each entry in each Array is a vertex on the path. mode
69
+ * represents the type of shortest paths to be calculated: IGraph::OUT
70
+ * the outgoing paths are calculated. IGraph::IN the incoming paths are
71
+ * calculated. IGraph::ALL the directed graph is considered as an undirected
72
+ * one for the computation.
73
+ */
52
74
  VALUE cIGraph_get_shortest_paths(VALUE self, VALUE from, VALUE to, VALUE mode){
53
75
 
54
76
  igraph_t *graph;
@@ -70,7 +92,7 @@ VALUE cIGraph_get_shortest_paths(VALUE self, VALUE from, VALUE to, VALUE mode){
70
92
 
71
93
  Data_Get_Struct(self, igraph_t, graph);
72
94
 
73
- n_paths = NUM2INT(rb_funcall(to,rb_intern("length"),0));
95
+ n_paths = RARRAY(to)->len;
74
96
 
75
97
  //vector to hold the results of the calculations
76
98
  igraph_vector_ptr_init(&res,0);
@@ -93,8 +115,8 @@ VALUE cIGraph_get_shortest_paths(VALUE self, VALUE from, VALUE to, VALUE mode){
93
115
  for(i=0; i<n_paths; i++){
94
116
  path = rb_ary_new();
95
117
  rb_ary_push(matrix,path);
118
+ path_v = VECTOR(res)[i];
96
119
  for(j=0; j<igraph_vector_size(VECTOR(res)[i]); j++){
97
- path_v = VECTOR(res)[i];
98
120
  rb_ary_push(path,cIGraph_get_vertex_object(self,VECTOR(*path_v)[j]));
99
121
  }
100
122
  }
@@ -110,3 +132,175 @@ VALUE cIGraph_get_shortest_paths(VALUE self, VALUE from, VALUE to, VALUE mode){
110
132
  return matrix;
111
133
 
112
134
  }
135
+
136
+ /* call-seq:
137
+ * graph.get_all_shortest_paths(from,mode) -> Array
138
+ *
139
+ * Calculates the paths from the vertex specified as from to each vertex
140
+ * in the to_array Arrayevery other. Returns an Array of Arrays. Each top
141
+ * level Array represents a path and each entry in each Array is a vertex on
142
+ * the path. mode represents the type of shortest paths to be calculated:
143
+ * IGraph::OUT the outgoing paths are calculated. IGraph::IN the incoming
144
+ * paths are calculated. IGraph::ALL the directed graph is considered as an
145
+ * undirected one for the computation. In contrast to
146
+ * IGraph#get_shortest_paths all possible shortest paths are reported here.
147
+ */
148
+ VALUE cIGraph_get_all_shortest_paths(VALUE self, VALUE from, VALUE to, VALUE mode){
149
+
150
+ igraph_t *graph;
151
+
152
+ igraph_integer_t from_vid;
153
+ igraph_neimode_t pmode = NUM2INT(mode);
154
+
155
+ igraph_vs_t to_vids;
156
+ igraph_vector_t to_vidv;
157
+
158
+ igraph_vector_ptr_t res;
159
+ igraph_vector_t *path_v;
160
+
161
+ int i;
162
+ int j;
163
+ VALUE path;
164
+ VALUE matrix = rb_ary_new();
165
+
166
+ Data_Get_Struct(self, igraph_t, graph);
167
+
168
+ //vector to hold the results of the calculations
169
+ igraph_vector_ptr_init(&res,0);
170
+
171
+ //The id of the vertex from where we are counting
172
+ from_vid = cIGraph_get_vertex_id(self, from);
173
+
174
+ //Convert an array of vertices to a vector of vertex ids
175
+ cIGraph_vertex_arr_to_id_vec(self,to,&to_vidv);
176
+ //create vertex selector from the vecotr of ids
177
+ igraph_vs_vector(&to_vids,&to_vidv);
178
+
179
+ igraph_get_all_shortest_paths(graph,&res,NULL,from_vid,to_vids,pmode);
180
+
181
+ for(i=0; i< igraph_vector_ptr_size(&res); i++){
182
+ path = rb_ary_new();
183
+ rb_ary_push(matrix,path);
184
+ for(j=0; j<igraph_vector_size(VECTOR(res)[i]); j++){
185
+ path_v = VECTOR(res)[i];
186
+ rb_ary_push(path,cIGraph_get_vertex_object(self,VECTOR(*path_v)[j]));
187
+ }
188
+ }
189
+
190
+ for(i=0;i<igraph_vector_ptr_size(&res);i++){
191
+ igraph_vector_destroy(VECTOR(res)[i]);
192
+ }
193
+
194
+ igraph_vector_ptr_destroy(&res);
195
+
196
+ return matrix;
197
+
198
+ }
199
+
200
+ /* call-seq:
201
+ * graph.average_path_length(directed,uncon) -> Float
202
+ *
203
+ * Calculates the average geodesic length in a graph. directed should be a
204
+ * boolean specifying whether to consider directed paths. unconn is another
205
+ * boolean specifying what to do about unconnected graphs. If TRUE the
206
+ * average of the geodesics within the components will be returned,
207
+ * otherwise the number of vertices is used for the length of non-existing
208
+ * geodesics. (The rationale behind this is that this is always longer than
209
+ * the longest possible geodesic in a graph.)
210
+ */
211
+ VALUE cIGraph_average_path_length(VALUE self, VALUE directed, VALUE unconn){
212
+
213
+ igraph_t *graph;
214
+ igraph_bool_t directed_b = 0;
215
+ igraph_bool_t unconn_b = 0;
216
+ igraph_real_t res;
217
+
218
+ if(directed)
219
+ directed_b = 1;
220
+ if(unconn)
221
+ unconn_b = 1;
222
+
223
+ Data_Get_Struct(self, igraph_t, graph);
224
+
225
+ igraph_average_path_length(graph,&res,directed_b,unconn_b);
226
+
227
+ return rb_float_new(res);
228
+
229
+ }
230
+
231
+ /* call-seq:
232
+ * graph.diameter(directed,uncon) -> Array
233
+ *
234
+ * Returns the longest path in the graph. directed should be a
235
+ * boolean specifying whether to consider directed paths. unconn is another
236
+ * boolean specifying what to do about unconnected graphs. If TRUE the
237
+ * average of the geodesics within the components will be returned,
238
+ * otherwise the number of vertices is used for the length of non-existing
239
+ * geodesics. (The rationale behind this is that this is always longer than
240
+ * the longest possible diamter in a graph.)
241
+ */
242
+ VALUE cIGraph_diameter(VALUE self, VALUE directed, VALUE unconn){
243
+
244
+ igraph_t *graph;
245
+ igraph_bool_t directed_b = 0;
246
+ igraph_bool_t unconn_b = 0;
247
+ igraph_vector_t res;
248
+ int i;
249
+ VALUE path = rb_ary_new();
250
+
251
+ if(directed)
252
+ directed_b = 1;
253
+ if(unconn)
254
+ unconn_b = 1;
255
+
256
+ Data_Get_Struct(self, igraph_t, graph);
257
+
258
+ //vector to hold the results of the calculations
259
+ igraph_vector_init(&res,0);
260
+
261
+ igraph_diameter(graph,NULL,NULL,NULL,&res,directed_b,unconn_b);
262
+
263
+ for(i=0; i<igraph_vector_size(&res); i++){
264
+ rb_ary_push(path,cIGraph_get_vertex_object(self,VECTOR(res)[i]));
265
+ }
266
+
267
+ igraph_vector_destroy(&res);
268
+
269
+ return path;
270
+
271
+ }
272
+
273
+ /* call-seq:
274
+ * graph.diameter(directed,uncon) -> Array
275
+ *
276
+ * Returns the shortest cycle in the graph. directed should be a
277
+ * boolean specifying whether to consider directed paths. unconn is another
278
+ * boolean specifying what to do about unconnected graphs. If TRUE the
279
+ * average of the geodesics within the components will be returned,
280
+ * otherwise the number of vertices is used for the length of non-existing
281
+ * geodesics. (The rationale behind this is that this is always longer than
282
+ * the longest possible diamter in a graph.)
283
+ */
284
+ VALUE cIGraph_girth(VALUE self){
285
+
286
+ igraph_t *graph;
287
+ igraph_vector_t res;
288
+ int i;
289
+ VALUE path = rb_ary_new();
290
+
291
+ Data_Get_Struct(self, igraph_t, graph);
292
+
293
+ //vector to hold the results of the calculations
294
+ igraph_vector_init(&res,0);
295
+
296
+ igraph_girth(graph,NULL,&res);
297
+
298
+ for(i=0; i<igraph_vector_size(&res); i++){
299
+ rb_ary_push(path,cIGraph_get_vertex_object(self,VECTOR(res)[i]));
300
+ }
301
+
302
+ igraph_vector_destroy(&res);
303
+
304
+ return path;
305
+
306
+ }