igraph 0.3.3 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -30,6 +30,17 @@ VALUE cIGraph_alloc(VALUE klass);
30
30
  VALUE cIGraph_initialize(int argc, VALUE *argv, VALUE self);
31
31
  VALUE cIGraph_init_copy(VALUE copy, VALUE orig);
32
32
 
33
+ //Graph generators
34
+ VALUE cIGraph_adjacency(VALUE self, VALUE matrix, VALUE mode);
35
+ VALUE cIGraph_star (VALUE self, VALUE n, VALUE mode, VALUE center);
36
+ VALUE cIGraph_lattice (VALUE self, VALUE dim, VALUE directed, VALUE mutual, VALUE circular);
37
+ VALUE cIGraph_ring(VALUE self, VALUE n, VALUE directed, VALUE mutual, VALUE circular);
38
+ VALUE cIGraph_tree(VALUE self, VALUE n, VALUE children, VALUE type);
39
+ VALUE cIGraph_full(VALUE self, VALUE n, VALUE directed, VALUE loops);
40
+ VALUE cIGraph_atlas(VALUE self, VALUE n);
41
+ VALUE cIGraph_extended_chordal_ring(VALUE self, VALUE n, VALUE matrix);
42
+ VALUE cIGraph_connect_neighborhood(VALUE self, VALUE order, VALUE mode);
43
+
33
44
  //Random graph generators
34
45
  VALUE cIGraph_grg_game (VALUE self, VALUE nodes,
35
46
  VALUE radius, VALUE torus);
@@ -38,6 +49,21 @@ VALUE cIGraph_barabasi_game(VALUE self, VALUE nodes,
38
49
  VALUE cIGraph_nonlinear_barabasi_game(VALUE self, VALUE nodes, VALUE power,
39
50
  VALUE m, VALUE outpref, VALUE zeroappeal, VALUE directed);
40
51
  VALUE cIGraph_erdos_renyi_game (VALUE self, VALUE type, VALUE nodes, VALUE mp, VALUE directed, VALUE loops);
52
+ VALUE cIGraph_watts_strogatz_game(VALUE self, VALUE dim, VALUE size, VALUE nei, VALUE p);
53
+ VALUE cIGraph_degree_sequence_game(VALUE self, VALUE out_deg, VALUE in_deg);
54
+ VALUE cIGraph_growing_random_game(VALUE self, VALUE n, VALUE m, VALUE directed, VALUE citation);
55
+ VALUE cIGraph_callaway_traits_game(VALUE self, VALUE nodes, VALUE types, VALUE e_per_step, VALUE type_dist, VALUE pref_matrix, VALUE directed);
56
+ VALUE cIGraph_establishment_game(VALUE self, VALUE nodes, VALUE types, VALUE k, VALUE type_dist, VALUE pref_matrix, VALUE directed);
57
+ VALUE cIGraph_preference_game(VALUE self, VALUE nodes, VALUE types, VALUE type_dist, VALUE pref_matrix, VALUE directed, VALUE loops);
58
+ VALUE cIGraph_asymmetric_preference_game(VALUE self, VALUE nodes, VALUE types, VALUE type_dist_matrix, VALUE pref_matrix, VALUE loops);
59
+ VALUE cIGraph_recent_degree_game(VALUE self, VALUE n, VALUE power, VALUE window, VALUE m, VALUE outpref, VALUE zero_appeal, VALUE directed);
60
+ VALUE cIGraph_barabasi_aging_game(VALUE self, VALUE nodes, VALUE m, VALUE outpref, VALUE pa_exp, VALUE aging_exp, VALUE aging_bin, VALUE zero_deg_appeal, VALUE zero_age_appeal, VALUE deg_coef, VALUE age_coef, VALUE directed);
61
+ VALUE cIGraph_recent_degree_aging_game(VALUE self, VALUE nodes, VALUE m, VALUE outpref, VALUE pa_exp, VALUE aging_exp, VALUE aging_bin, VALUE time_window, VALUE zero_appeal, VALUE directed);
62
+ VALUE cIGraph_cited_type_game(VALUE self, VALUE nodes, VALUE types, VALUE pref, VALUE e_per_s, VALUE directed);
63
+ VALUE cIGraph_citing_cited_type_game(VALUE self, VALUE nodes, VALUE types, VALUE pref, VALUE e_per_s, VALUE directed);
64
+
65
+ VALUE cIGraph_rewire_edges(VALUE self, VALUE prop);
66
+ VALUE cIGraph_rewire(VALUE self, VALUE n);
41
67
 
42
68
  //Attribute accessors
43
69
  int replace_i(VALUE key, VALUE val, VALUE hash);
@@ -174,8 +200,17 @@ VALUE cIGraph_motifs_randesu_estimate(VALUE self, VALUE size, VALUE cuts,
174
200
  //File handling
175
201
  VALUE cIGraph_read_graph_edgelist (VALUE self, VALUE file, VALUE mode);
176
202
  VALUE cIGraph_write_graph_edgelist(VALUE self, VALUE file);
203
+ VALUE cIGraph_read_graph_ncol (VALUE self, VALUE file, VALUE predefnames, VALUE names, VALUE weights, VALUE directed);
204
+ VALUE cIGraph_write_graph_ncol (VALUE self, VALUE file, VALUE names, VALUE weights);
205
+ VALUE cIGraph_read_graph_lgl (VALUE self, VALUE file, VALUE names, VALUE weights);
206
+ VALUE cIGraph_write_graph_lgl (VALUE self, VALUE file, VALUE names, VALUE weights, VALUE isolates);
207
+ VALUE cIGraph_read_graph_dimacs (VALUE self, VALUE file, VALUE directed);
208
+ VALUE cIGraph_write_graph_dimacs (VALUE self, VALUE file, VALUE source, VALUE target, VALUE capacity);
209
+ VALUE cIGraph_read_graph_graphdb (VALUE self, VALUE file, VALUE directed);
177
210
  VALUE cIGraph_read_graph_graphml (VALUE self, VALUE file, VALUE index);
178
211
  VALUE cIGraph_write_graph_graphml (VALUE self, VALUE file);
212
+ VALUE cIGraph_read_graph_gml (VALUE self, VALUE file);
213
+ VALUE cIGraph_write_graph_gml (VALUE self, VALUE file);
179
214
  VALUE cIGraph_read_graph_pajek (VALUE self, VALUE file);
180
215
  VALUE cIGraph_write_graph_pajek (VALUE self, VALUE file);
181
216
 
@@ -216,6 +251,69 @@ VALUE cIGraph_layout_lgl(VALUE self,
216
251
  VALUE cellsize,
217
252
  VALUE proot);
218
253
 
254
+ VALUE cIGraph_layout_random_3d(VALUE self);
255
+ VALUE cIGraph_layout_sphere (VALUE self);
256
+ VALUE cIGraph_layout_fruchterman_reingold_3d(VALUE self,
257
+ VALUE niter,
258
+ VALUE maxdelta,
259
+ VALUE volume,
260
+ VALUE coolexp,
261
+ VALUE repulserad);
262
+ VALUE cIGraph_layout_kamada_kawai_3d (VALUE self,
263
+ VALUE niter,
264
+ VALUE sigma,
265
+ VALUE initemp,
266
+ VALUE coolexp,
267
+ VALUE kkconst);
268
+
269
+ VALUE cIGraph_layout_merge_dla(VALUE self, VALUE graphs, VALUE layouts);
270
+
271
+ //Min cuts
272
+ VALUE cIGraph_maxflow_value (VALUE self, VALUE source, VALUE target, VALUE capacity);
273
+ VALUE cIGraph_st_mincut_value(VALUE self, VALUE source, VALUE target, VALUE capacity);
274
+ VALUE cIGraph_mincut_value (VALUE self, VALUE capacity);
275
+ VALUE cIGraph_mincut (VALUE self, VALUE capacity);
276
+
277
+ //Connectivity
278
+ VALUE cIGraph_st_edge_connectivity (VALUE self, VALUE source, VALUE target);
279
+ VALUE cIGraph_edge_connectivity (VALUE self);
280
+ VALUE cIGraph_st_vertex_connectivity(VALUE self, VALUE source, VALUE target, VALUE neighbours);
281
+ VALUE cIGraph_vertex_connectivity (VALUE self);
282
+ VALUE cIGraph_edge_disjoint_paths (VALUE self, VALUE source, VALUE target);
283
+ VALUE cIGraph_vertex_disjoint_paths (VALUE self, VALUE source, VALUE target);
284
+ VALUE cIGraph_adhesion(VALUE self);
285
+ VALUE cIGraph_cohesion(VALUE self);
286
+
287
+ //Community
288
+ VALUE cIGraph_modularity (VALUE self, VALUE groups);
289
+ VALUE cIGraph_community_to_membership (VALUE self, VALUE merge,
290
+ VALUE steps);
291
+ VALUE cIGraph_community_spinglass (VALUE self, VALUE weights,
292
+ VALUE spins,
293
+ VALUE parupdate,
294
+ VALUE starttemp,
295
+ VALUE stoptemp,
296
+ VALUE coolfact,
297
+ VALUE update_rule,
298
+ VALUE gamma);
299
+ VALUE cIGraph_community_spinglass_single (VALUE self, VALUE weights,
300
+ VALUE vertex,
301
+ VALUE spins,
302
+ VALUE update_rule,
303
+ VALUE gamma);
304
+ VALUE cIGraph_community_leading_eigenvector (VALUE self, VALUE steps);
305
+ VALUE cIGraph_community_leading_eigenvector_naive(VALUE self, VALUE steps);
306
+ VALUE cIGraph_community_leading_eigenvector_step (VALUE self,
307
+ VALUE membership,
308
+ VALUE steps);
309
+ VALUE cIGraph_community_walktrap (VALUE self,
310
+ VALUE weights,
311
+ VALUE steps);
312
+ VALUE cIGraph_community_edge_betweenness (VALUE self,
313
+ VALUE directed);
314
+ VALUE cIGraph_community_eb_get_merges (VALUE self,
315
+ VALUE edges);
316
+ VALUE cIGraph_community_fastgreedy (VALUE self);
219
317
 
220
318
  //Attributes
221
319
  int cIGraph_attribute_init(igraph_t *graph,
@@ -497,9 +497,9 @@ igraph_bool_t cIGraph_attribute_has_attr(const igraph_t *graph,
497
497
  VALUE obj;
498
498
 
499
499
  switch (type) {
500
- case IGRAPH_ATTRIBUTE_GRAPH: attrnum=0; break;
501
- case IGRAPH_ATTRIBUTE_VERTEX: attrnum=1; break;
502
- case IGRAPH_ATTRIBUTE_EDGE: attrnum=2; break;
500
+ case IGRAPH_ATTRIBUTE_GRAPH: attrnum = 2; break;
501
+ case IGRAPH_ATTRIBUTE_VERTEX: attrnum = 0; break;
502
+ case IGRAPH_ATTRIBUTE_EDGE: attrnum = 1; break;
503
503
  default: return 0; break;
504
504
  }
505
505
 
@@ -507,14 +507,14 @@ igraph_bool_t cIGraph_attribute_has_attr(const igraph_t *graph,
507
507
  if (attrnum != 2)
508
508
  obj = RARRAY(obj)->ptr[0];
509
509
 
510
- if(rb_funcall(obj,rb_intern("include?"), 1, rb_str_new2(name))){
510
+ if(TYPE(obj) == T_HASH && rb_funcall(obj,rb_intern("include?"), 1, rb_str_new2(name))){
511
511
  res = 1;
512
512
  }
513
513
 
514
514
  #ifdef DEBUG
515
515
  printf("Leaving cIGraph_attribute_has_attr\n");
516
516
  #endif
517
-
517
+
518
518
  return res;
519
519
  }
520
520
 
@@ -533,9 +533,9 @@ int cIGraph_attribute_get_type(const igraph_t *graph,
533
533
  VALUE val;
534
534
 
535
535
  switch (elemtype) {
536
- case IGRAPH_ATTRIBUTE_GRAPH: attrnum=0; break;
537
- case IGRAPH_ATTRIBUTE_VERTEX: attrnum=1; break;
538
- case IGRAPH_ATTRIBUTE_EDGE: attrnum=2; break;
536
+ case IGRAPH_ATTRIBUTE_GRAPH: attrnum = 2; break;
537
+ case IGRAPH_ATTRIBUTE_VERTEX: attrnum = 0; break;
538
+ case IGRAPH_ATTRIBUTE_EDGE: attrnum = 1; break;
539
539
  default: return 0; break;
540
540
  }
541
541
 
@@ -543,7 +543,9 @@ int cIGraph_attribute_get_type(const igraph_t *graph,
543
543
  if (attrnum != 2)
544
544
  obj = RARRAY(obj)->ptr[0];
545
545
 
546
- if(rb_funcall(obj,rb_intern("includes"), rb_str_new2(name))){
546
+ rb_funcall(obj,rb_intern("include?"), 1, rb_str_new2(name));
547
+
548
+ if(rb_funcall(obj,rb_intern("include?"), 1, rb_str_new2(name))){
547
549
  val = rb_hash_aref(obj,rb_str_new2(name));
548
550
  if (TYPE(val) == T_STRING){
549
551
  *type = IGRAPH_ATTRIBUTE_STRING;
@@ -552,7 +554,9 @@ int cIGraph_attribute_get_type(const igraph_t *graph,
552
554
  } else {
553
555
  *type = IGRAPH_ATTRIBUTE_PY_OBJECT;
554
556
  }
555
- }
557
+ } else {
558
+ *type = IGRAPH_ATTRIBUTE_PY_OBJECT;
559
+ }
556
560
 
557
561
  #ifdef DEBUG
558
562
  printf("Leaving cIGraph_attribute_get_type\n");
@@ -736,7 +740,7 @@ int cIGraph_get_string_edge_attr(const igraph_t *graph,
736
740
  #endif
737
741
 
738
742
  VALUE array = ((VALUE*)graph->attr)[1];
739
- VALUE val, vertex;
743
+ VALUE val, edge;
740
744
  igraph_eit_t it;
741
745
  int i=0;
742
746
 
@@ -745,10 +749,16 @@ int cIGraph_get_string_edge_attr(const igraph_t *graph,
745
749
  IGRAPH_CHECK(igraph_strvector_resize(value, IGRAPH_EIT_SIZE(it)));
746
750
 
747
751
  while(!IGRAPH_EIT_END(it)){
748
- vertex = RARRAY(array)->ptr[(int)IGRAPH_EIT_GET(it)];
749
- val = rb_hash_aref(vertex,rb_str_new2(name));
752
+ edge = RARRAY(array)->ptr[(int)IGRAPH_EIT_GET(it)];
753
+
754
+ val = rb_hash_aref(edge,rb_str_new2(name));
755
+
750
756
  if(val == Qnil)
751
757
  val = rb_str_new2("");
758
+
759
+ //Fix for floats when required by ncol write
760
+ val = rb_funcall(val,rb_intern("to_s"),0);
761
+
752
762
  igraph_strvector_set(value,i,RSTRING(val)->ptr);
753
763
  IGRAPH_EIT_NEXT(it);
754
764
  i++;
@@ -0,0 +1,654 @@
1
+ #include "igraph.h"
2
+ #include "ruby.h"
3
+ #include "cIGraph.h"
4
+
5
+ /* call-seq:
6
+ * graph.modularity(groups) -> Float
7
+ *
8
+ * Calculate the modularity of a graph with respect to some vertex types.
9
+ * The modularity of a graph with respect to some division (or vertex types)
10
+ * measures how good the division is, or how separated are the different
11
+ * vertex types from each other.
12
+ *
13
+ */
14
+
15
+ VALUE cIGraph_modularity(VALUE self, VALUE groups){
16
+
17
+ igraph_t *graph;
18
+ igraph_real_t value;
19
+ igraph_vector_t membership;
20
+
21
+ VALUE group;
22
+
23
+ int i,j;
24
+
25
+ Data_Get_Struct(self, igraph_t, graph);
26
+
27
+ igraph_vector_init(&membership,igraph_vcount(graph));
28
+
29
+ for(i=0;i<RARRAY(groups)->len;i++){
30
+ group = RARRAY(groups)->ptr[i];
31
+ for(j=0;j<RARRAY(group)->len;j++){
32
+ igraph_vector_set(&membership,
33
+ cIGraph_get_vertex_id(self,RARRAY(group)->ptr[j]),i);
34
+ }
35
+ }
36
+
37
+ igraph_modularity(graph,&membership,&value);
38
+
39
+ igraph_vector_destroy(&membership);
40
+
41
+ return rb_float_new(value);
42
+
43
+ }
44
+
45
+ /* call-seq:
46
+ * graph.community_to_membership(merge,steps) -> Array
47
+ *
48
+ * Create membership vector from community structure dendrogram This function
49
+ * creates a membership vector from a community structure dendrogram.
50
+ * A membership vector contains for each vertex the id of its graph
51
+ * component, the graph components are numbered from zero, see the same
52
+ * argument of igraph_clusters() for an example of a membership vector.
53
+ *
54
+ */
55
+
56
+ VALUE cIGraph_community_to_membership(VALUE self, VALUE merge, VALUE steps){
57
+
58
+ igraph_t *graph;
59
+ igraph_matrix_t *merges;
60
+
61
+ igraph_vector_t membership;
62
+
63
+ VALUE groups;
64
+
65
+ int i,groupid,max_groupid;
66
+
67
+ Data_Get_Struct(self, igraph_t, graph);
68
+ Data_Get_Struct(merge, igraph_matrix_t, merges);
69
+
70
+ igraph_vector_init(&membership,0);
71
+
72
+ igraph_community_to_membership(graph,merges,NUM2INT(steps),&membership,NULL);
73
+
74
+ max_groupid = 0;
75
+ for(i=0;i<igraph_vector_size(&membership);i++){
76
+ if(VECTOR(membership)[i] > max_groupid)
77
+ max_groupid = VECTOR(membership)[i];
78
+ }
79
+
80
+ groups = rb_ary_new();
81
+ for(i=0;i<max_groupid+1;i++){
82
+ rb_ary_push(groups,rb_ary_new());
83
+ }
84
+
85
+ for(i=0;i<igraph_vector_size(&membership);i++){
86
+ groupid = VECTOR(membership)[i];
87
+ if(RARRAY(groups)->ptr[groupid] == Qnil){
88
+ RARRAY(groups)->ptr[groupid] = rb_ary_new();
89
+ }
90
+ rb_ary_push(RARRAY(groups)->ptr[groupid],
91
+ cIGraph_get_vertex_object(self, i));
92
+ }
93
+
94
+ igraph_vector_destroy(&membership);
95
+
96
+ return groups;
97
+
98
+ }
99
+
100
+ /* call-seq:
101
+ * graph.community_spinglass(weights,spins,parupdate,starttemp,stoptemp,coolfact,update_rule,gamma) -> Array
102
+ *
103
+ * Community detection based on statistical mechanics This function
104
+ * implements the community structure detection algorithm proposed by Joerg
105
+ * Reichardt and Stefan Bornholdt. The algorithm is described in their
106
+ * paper: Statistical Mechanics of Community Detection.
107
+ *
108
+ */
109
+
110
+ VALUE cIGraph_community_spinglass(VALUE self, VALUE weights, VALUE spins, VALUE parupdate, VALUE starttemp, VALUE stoptemp, VALUE coolfact, VALUE update_rule, VALUE gamma){
111
+
112
+ igraph_t *graph;
113
+
114
+ igraph_vector_t weights_vec;
115
+ igraph_vector_t membership;
116
+ igraph_real_t temperature;
117
+ igraph_real_t modularity;
118
+ igraph_bool_t parupdate_b;
119
+
120
+ VALUE group;
121
+ VALUE groups;
122
+ VALUE res;
123
+
124
+ VALUE str;
125
+
126
+ int i,groupid,max_groupid;
127
+
128
+ if(parupdate)
129
+ parupdate_b = 1;
130
+
131
+ Data_Get_Struct(self, igraph_t, graph);
132
+
133
+ igraph_vector_init(&membership,0);
134
+
135
+ igraph_vector_init(&weights_vec,RARRAY(weights)->len);
136
+ for(i=0;i<RARRAY(weights)->len;i++){
137
+ VECTOR(weights_vec)[i] = NUM2DBL(RARRAY(weights)->ptr[i]);
138
+ }
139
+
140
+ igraph_community_spinglass(graph,
141
+ igraph_vector_size(&weights_vec) > 0 ? &weights_vec : NULL,
142
+ &modularity,&temperature,
143
+ &membership,NULL,NUM2INT(spins),parupdate_b,
144
+ NUM2DBL(starttemp),NUM2DBL(stoptemp),
145
+ NUM2DBL(coolfact),NUM2INT(update_rule),
146
+ NUM2DBL(gamma));
147
+
148
+ max_groupid = 0;
149
+ for(i=0;i<igraph_vector_size(&membership);i++){
150
+ if(VECTOR(membership)[i] > max_groupid)
151
+ max_groupid = VECTOR(membership)[i];
152
+ }
153
+
154
+ groups = rb_ary_new();
155
+ for(i=0;i<max_groupid+1;i++){
156
+ rb_ary_push(groups,rb_ary_new());
157
+ }
158
+
159
+ for(i=0;i<igraph_vector_size(&membership);i++){
160
+
161
+ groupid = VECTOR(membership)[i];
162
+
163
+ if(groupid == -1)
164
+ groupid = 0;
165
+
166
+ group = RARRAY(groups)->ptr[groupid];
167
+ rb_ary_push(group,cIGraph_get_vertex_object(self, i));
168
+ }
169
+
170
+ res = rb_ary_new3(3,groups,
171
+ rb_float_new(modularity),
172
+ rb_float_new(temperature));
173
+
174
+ igraph_vector_destroy(&membership);
175
+ igraph_vector_destroy(&weights_vec);
176
+
177
+ return res;
178
+
179
+ }
180
+
181
+ /* call-seq:
182
+ * graph.community_spinglass_single(weights,vertex,spins,update_rule,gamma) -> Array
183
+ *
184
+ * Community detection based on statistical mechanics This function
185
+ * implements the community structure detection algorithm proposed by Joerg
186
+ * Reichardt and Stefan Bornholdt. The algorithm is described in their
187
+ * paper: Statistical Mechanics of Community Detection.
188
+ *
189
+ */
190
+
191
+ VALUE cIGraph_community_spinglass_single(VALUE self, VALUE weights, VALUE vertex, VALUE spins, VALUE update_rule, VALUE gamma){
192
+
193
+ igraph_t *graph;
194
+
195
+ igraph_vector_t weights_vec;
196
+ igraph_vector_t community;
197
+ igraph_real_t cohesion;
198
+ igraph_real_t adhesion;
199
+
200
+ VALUE group;
201
+ VALUE res;
202
+
203
+ int i;
204
+
205
+ Data_Get_Struct(self, igraph_t, graph);
206
+
207
+ igraph_vector_init(&community,0);
208
+
209
+ igraph_vector_init(&weights_vec,RARRAY(weights)->len);
210
+ for(i=0;i<RARRAY(weights)->len;i++){
211
+ VECTOR(weights_vec)[i] = NUM2DBL(RARRAY(weights)->ptr[i]);
212
+ }
213
+
214
+ igraph_community_spinglass_single(graph,
215
+ igraph_vector_size(&weights_vec) > 0 ? &weights_vec : NULL,
216
+ cIGraph_get_vertex_id(self, vertex),
217
+ &community, &cohesion, &adhesion,
218
+ NULL, NULL,
219
+ NUM2INT(spins),NUM2INT(update_rule),
220
+ NUM2DBL(gamma));
221
+
222
+ group = rb_ary_new();
223
+
224
+ for(i=0;i<igraph_vector_size(&community);i++){
225
+ rb_ary_push(group,cIGraph_get_vertex_object(self, i));
226
+ }
227
+
228
+ res = rb_ary_new3(3,group,
229
+ rb_float_new(cohesion),
230
+ rb_float_new(adhesion));
231
+
232
+ igraph_vector_destroy(&community);
233
+ igraph_vector_destroy(&weights_vec);
234
+
235
+ return res;
236
+
237
+ }
238
+
239
+ /* call-seq:
240
+ * graph.community_leading_eigenvector(steps) -> Array
241
+ *
242
+ * Newman's leading eigenvector method for detecting community structure.
243
+ * This is the proper implementation of the recursive, divisive algorithm:
244
+ * each split is done by maximizing the modularity regarding the original
245
+ * network, see MEJ Newman: Finding community structure in networks using
246
+ * the eigenvectors of matrices, arXiv:physics/0605087.
247
+ *
248
+ */
249
+
250
+ VALUE cIGraph_community_leading_eigenvector(VALUE self, VALUE steps){
251
+
252
+ igraph_t *graph;
253
+
254
+ igraph_vector_t membership;
255
+ igraph_matrix_t *merges = malloc(sizeof(igraph_matrix_t));
256
+
257
+ int i,groupid,max_groupid;
258
+
259
+ VALUE groups, group, res;
260
+
261
+ Data_Get_Struct(self, igraph_t, graph);
262
+
263
+ igraph_matrix_init(merges,0,0);
264
+ igraph_vector_init(&membership,0);
265
+
266
+ igraph_community_leading_eigenvector(graph,merges,&membership,
267
+ NUM2INT(steps));
268
+
269
+ max_groupid = 0;
270
+ for(i=0;i<igraph_vector_size(&membership);i++){
271
+ if(VECTOR(membership)[i] > max_groupid)
272
+ max_groupid = VECTOR(membership)[i];
273
+ }
274
+
275
+ groups = rb_ary_new();
276
+ for(i=0;i<max_groupid+1;i++){
277
+ rb_ary_push(groups,rb_ary_new());
278
+ }
279
+
280
+ for(i=0;i<igraph_vector_size(&membership);i++){
281
+
282
+ groupid = VECTOR(membership)[i];
283
+
284
+ if(groupid == -1)
285
+ groupid = 0;
286
+
287
+ group = RARRAY(groups)->ptr[groupid];
288
+ rb_ary_push(group,cIGraph_get_vertex_object(self, i));
289
+ }
290
+
291
+ res = rb_ary_new3(2,groups,
292
+ Data_Wrap_Struct(cIGraphMatrix, 0,
293
+ cIGraph_matrix_free, merges));
294
+
295
+ igraph_vector_destroy(&membership);
296
+
297
+ return res;
298
+
299
+ }
300
+
301
+ /* call-seq:
302
+ * graph.community_leading_eigenvector_naive(steps) -> Array
303
+ *
304
+ * Newman's leading eigenvector method for detecting community structure.
305
+ * This is the proper implementation of the recursive, divisive algorithm:
306
+ * each split is done by maximizing the modularity regarding the original
307
+ * network, see MEJ Newman: Finding community structure in networks using
308
+ * the eigenvectors of matrices, arXiv:physics/0605087.
309
+ *
310
+ */
311
+
312
+ VALUE cIGraph_community_leading_eigenvector_naive(VALUE self, VALUE steps){
313
+
314
+ igraph_t *graph;
315
+
316
+ igraph_vector_t membership;
317
+ igraph_matrix_t *merges = malloc(sizeof(igraph_matrix_t));
318
+
319
+ int i,groupid,max_groupid;
320
+
321
+ VALUE groups, group, res;
322
+
323
+ Data_Get_Struct(self, igraph_t, graph);
324
+
325
+ igraph_matrix_init(merges,0,0);
326
+ igraph_vector_init(&membership,0);
327
+
328
+ igraph_community_leading_eigenvector_naive(graph,merges,&membership,
329
+ NUM2INT(steps));
330
+
331
+ max_groupid = 0;
332
+ for(i=0;i<igraph_vector_size(&membership);i++){
333
+ if(VECTOR(membership)[i] > max_groupid)
334
+ max_groupid = VECTOR(membership)[i];
335
+ }
336
+
337
+ groups = rb_ary_new();
338
+ for(i=0;i<max_groupid+1;i++){
339
+ rb_ary_push(groups,rb_ary_new());
340
+ }
341
+
342
+ for(i=0;i<igraph_vector_size(&membership);i++){
343
+
344
+ groupid = VECTOR(membership)[i];
345
+
346
+ if(groupid == -1)
347
+ groupid = 0;
348
+
349
+ group = RARRAY(groups)->ptr[groupid];
350
+ rb_ary_push(group,cIGraph_get_vertex_object(self, i));
351
+ }
352
+
353
+ res = rb_ary_new3(2,groups,
354
+ Data_Wrap_Struct(cIGraphMatrix, 0,
355
+ cIGraph_matrix_free, merges));
356
+
357
+ igraph_vector_destroy(&membership);
358
+
359
+ return res;
360
+
361
+ }
362
+
363
+ /* call-seq:
364
+ * graph.community_leading_eigenvector_step(membership,community) -> Array
365
+ *
366
+ * Do one split according to Mark Newman's leading eigenvector community
367
+ * detection method. See MEJ Newman: Finding community structure in networks
368
+ * using the eigenvectors of matrices, arXiv:phyisics/0605087 for the details.
369
+ *
370
+ */
371
+
372
+ VALUE cIGraph_community_leading_eigenvector_step(VALUE self, VALUE membership, VALUE community){
373
+
374
+ igraph_t *graph;
375
+
376
+ igraph_vector_t membership_vec;
377
+ igraph_vector_t eigenvector;
378
+ igraph_real_t eigenvalue;
379
+ igraph_bool_t split;
380
+
381
+ int i,j,groupid,max_groupid,vid;
382
+
383
+ VALUE groups, group, res, eigenvector_a, obj;
384
+
385
+ Data_Get_Struct(self, igraph_t, graph);
386
+
387
+ igraph_vector_init(&membership_vec,igraph_vcount(graph));
388
+ igraph_vector_init(&eigenvector,0);
389
+
390
+ for(i=0;i<RARRAY(membership)->len;i++){
391
+ group = RARRAY(membership)->ptr[i];
392
+
393
+ for(j=0;j<RARRAY(group)->len;j++){
394
+
395
+ obj = RARRAY(group)->ptr[j];
396
+ vid = cIGraph_get_vertex_id(self,obj);
397
+
398
+ VECTOR(membership_vec)[vid] = i;
399
+
400
+ }
401
+ }
402
+
403
+ igraph_community_leading_eigenvector_step(graph,&membership_vec,
404
+ NUM2INT(community),
405
+ &split,&eigenvector,&eigenvalue);
406
+
407
+ max_groupid = 0;
408
+ for(i=0;i<igraph_vector_size(&membership_vec);i++){
409
+ if(VECTOR(membership_vec)[i] > max_groupid)
410
+ max_groupid = VECTOR(membership_vec)[i];
411
+ }
412
+
413
+ groups = rb_ary_new();
414
+ for(i=0;i<max_groupid+1;i++){
415
+ rb_ary_push(groups,rb_ary_new());
416
+ }
417
+
418
+ for(i=0;i<igraph_vector_size(&membership_vec);i++){
419
+
420
+ groupid = VECTOR(membership_vec)[i];
421
+
422
+ if(groupid == -1)
423
+ groupid = 0;
424
+
425
+ group = RARRAY(groups)->ptr[groupid];
426
+ rb_ary_push(group,cIGraph_get_vertex_object(self, i));
427
+ }
428
+
429
+ eigenvector_a = rb_ary_new();
430
+ for(i=0;i<igraph_vector_size(&eigenvector);i++){
431
+ rb_ary_push(eigenvector_a,rb_float_new(VECTOR(eigenvector)[i]));
432
+ }
433
+
434
+ res = rb_ary_new3(4,groups,split==0 ? Qfalse : Qtrue,
435
+ eigenvector_a,rb_float_new(eigenvalue));
436
+
437
+
438
+ igraph_vector_destroy(&membership_vec);
439
+ igraph_vector_destroy(&eigenvector);
440
+
441
+ return res;
442
+
443
+ }
444
+
445
+ /* call-seq:
446
+ * graph.community_walktrap(weights,steps) -> Array
447
+ *
448
+ * This function is the implementation of the Walktrap community finding
449
+ * algorithm, see Pascal Pons, Matthieu Latapy: Computing communities in
450
+ * large networks using random walks, http://arxiv.org/abs/physics/0512106
451
+ *
452
+ */
453
+
454
+ VALUE cIGraph_community_walktrap(VALUE self, VALUE weights, VALUE steps){
455
+
456
+ igraph_t *graph;
457
+
458
+ igraph_vector_t weights_vec;
459
+ igraph_vector_t modularity;
460
+ igraph_matrix_t *merges = malloc(sizeof(igraph_matrix_t));
461
+
462
+ int i;
463
+
464
+ VALUE modularity_a, res;
465
+
466
+ Data_Get_Struct(self, igraph_t, graph);
467
+
468
+ igraph_matrix_init(merges,0,0);
469
+ igraph_vector_init(&weights_vec,0);
470
+ igraph_vector_init(&modularity,0);
471
+
472
+ for(i=0;i<RARRAY(weights)->len;i++){
473
+ VECTOR(weights_vec)[i] = NUM2DBL(RARRAY(weights)->ptr[i]);
474
+ }
475
+
476
+ igraph_community_walktrap(graph,
477
+ igraph_vector_size(&weights_vec) > 0 ? &weights_vec : NULL,
478
+ NUM2INT(steps),merges,&modularity);
479
+
480
+ modularity_a = rb_ary_new();
481
+ for(i=0;i<igraph_vector_size(&modularity);i++){
482
+ rb_ary_push(modularity_a,rb_float_new(VECTOR(modularity)[i]));
483
+ }
484
+
485
+ res = rb_ary_new3(2,
486
+ Data_Wrap_Struct(cIGraphMatrix, 0,
487
+ cIGraph_matrix_free, merges),
488
+ modularity_a);
489
+
490
+ igraph_vector_destroy(&weights_vec);
491
+ igraph_vector_destroy(&modularity);
492
+
493
+ return res;
494
+
495
+ }
496
+
497
+ /* call-seq:
498
+ * graph.community_edge_betweenness(directed) -> Array
499
+ *
500
+ * Community structure detection based on the betweenness of the edges in the
501
+ * network. The algorithm was invented by M. Girvan and M. Newman, see:
502
+ * M. Girvan and M. E. J. Newman: Community structure in social and
503
+ * biological networks, Proc. Nat. Acad. Sci. USA 99, 7821-7826 (2002).
504
+ *
505
+ */
506
+
507
+ VALUE cIGraph_community_edge_betweenness(VALUE self, VALUE directed){
508
+
509
+ igraph_t *graph;
510
+
511
+ igraph_vector_t result_vec;
512
+ igraph_vector_t edge_betw_vec;
513
+ igraph_vector_t bridges_vec;
514
+ igraph_matrix_t *merges = malloc(sizeof(igraph_matrix_t));
515
+ igraph_bool_t directed_b = 0;
516
+
517
+ int i;
518
+
519
+ VALUE result_a, edge_betw_a, bridges_a, res;
520
+
521
+ if(directed)
522
+ directed_b = 1;
523
+
524
+ Data_Get_Struct(self, igraph_t, graph);
525
+
526
+ igraph_matrix_init(merges,0,0);
527
+ igraph_vector_init(&result_vec,0);
528
+ igraph_vector_init(&edge_betw_vec,0);
529
+ igraph_vector_init(&bridges_vec,0);
530
+
531
+ igraph_community_edge_betweenness(graph,
532
+ &result_vec,&edge_betw_vec,
533
+ merges,&bridges_vec,directed_b);
534
+
535
+ result_a = rb_ary_new();
536
+ for(i=0;i<igraph_vector_size(&result_vec);i++){
537
+ rb_ary_push(result_a,INT2NUM(VECTOR(result_vec)[i]));
538
+ }
539
+ edge_betw_a = rb_ary_new();
540
+ for(i=0;i<igraph_vector_size(&edge_betw_vec);i++){
541
+ rb_ary_push(edge_betw_a,INT2NUM(VECTOR(edge_betw_vec)[i]));
542
+ }
543
+ bridges_a = rb_ary_new();
544
+ for(i=0;i<igraph_vector_size(&bridges_vec);i++){
545
+ rb_ary_push(bridges_a,INT2NUM(VECTOR(bridges_vec)[i]));
546
+ }
547
+
548
+ res = rb_ary_new3(4,
549
+ Data_Wrap_Struct(cIGraphMatrix, 0,
550
+ cIGraph_matrix_free, merges),
551
+ result_a, edge_betw_a, bridges_a);
552
+
553
+ igraph_vector_destroy(&result_vec);
554
+ igraph_vector_destroy(&edge_betw_vec);
555
+ igraph_vector_destroy(&bridges_vec);
556
+
557
+ return res;
558
+
559
+ }
560
+
561
+ /* call-seq:
562
+ * graph.community_eb_get_merges(edges) -> Array
563
+ *
564
+ * Calculating the merges, ie. the dendrogram for an edge betweenness
565
+ * community structure
566
+ *
567
+ */
568
+
569
+ VALUE cIGraph_community_eb_get_merges(VALUE self, VALUE edges){
570
+
571
+ igraph_t *graph;
572
+ igraph_matrix_t *res = malloc(sizeof(igraph_matrix_t));
573
+
574
+ igraph_vector_t edges_vec;
575
+ igraph_vector_t bridges_vec;
576
+
577
+ VALUE result,bridges_a;
578
+
579
+ int i;
580
+
581
+ Data_Get_Struct(self, igraph_t, graph);
582
+
583
+ igraph_matrix_init(res,0,0);
584
+ igraph_vector_init(&edges_vec,0);
585
+ igraph_vector_init(&bridges_vec,0);
586
+
587
+ for(i=0;i<RARRAY(edges)->len;i++){
588
+ igraph_vector_push_back(&edges_vec,NUM2INT(RARRAY(edges)->ptr[i]));
589
+ }
590
+
591
+ igraph_community_eb_get_merges(graph,&edges_vec,res,&bridges_vec);
592
+
593
+ bridges_a = rb_ary_new();
594
+ for(i=0;i<igraph_vector_size(&bridges_vec);i++){
595
+ rb_ary_push(bridges_a,INT2NUM(VECTOR(bridges_vec)[i]));
596
+ }
597
+
598
+ igraph_vector_destroy(&bridges_vec);
599
+ igraph_vector_destroy(&edges_vec);
600
+
601
+ result = rb_ary_new3(2,
602
+ Data_Wrap_Struct(cIGraphMatrix, 0,
603
+ cIGraph_matrix_free, res),
604
+ bridges_a);
605
+
606
+ return result;
607
+
608
+ }
609
+
610
+ /* call-seq:
611
+ * graph.community_fastgreedy() -> Array
612
+ *
613
+ * Finding community structure by greedy optimization of modularity.
614
+ * This function implements the fast greedy modularity optimization algorithm
615
+ * for finding community structure, see A Clauset, MEJ Newman, C Moore:
616
+ * Finding community structure in very large networks,
617
+ * http://www.arxiv.org/abs/cond-mat/0408187 for the details.
618
+ *
619
+ */
620
+
621
+ VALUE cIGraph_community_fastgreedy(VALUE self){
622
+
623
+ igraph_t *graph;
624
+
625
+ igraph_vector_t modularity;
626
+ igraph_matrix_t *merges = malloc(sizeof(igraph_matrix_t));
627
+
628
+ int i;
629
+
630
+ VALUE modularity_a, res;
631
+
632
+ Data_Get_Struct(self, igraph_t, graph);
633
+
634
+ igraph_matrix_init(merges,0,0);
635
+ igraph_vector_init(&modularity,0);
636
+
637
+ igraph_community_fastgreedy(graph,
638
+ merges,&modularity);
639
+
640
+ modularity_a = rb_ary_new();
641
+ for(i=0;i<igraph_vector_size(&modularity);i++){
642
+ rb_ary_push(modularity_a,rb_float_new(VECTOR(modularity)[i]));
643
+ }
644
+
645
+ res = rb_ary_new3(2,
646
+ Data_Wrap_Struct(cIGraphMatrix, 0,
647
+ cIGraph_matrix_free, merges),
648
+ modularity_a);
649
+
650
+ igraph_vector_destroy(&modularity);
651
+
652
+ return res;
653
+
654
+ }