igraph 0.3 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
data/Manifest.txt CHANGED
@@ -2,6 +2,7 @@ History.txt
2
2
  License.txt
3
3
  Manifest.txt
4
4
  README.txt
5
+ Rakefile.rb
5
6
  ext/cIGraph.c
6
7
  ext/cIGraph.h
7
8
  ext/cIGraph_add_delete.c
@@ -10,17 +11,23 @@ ext/cIGraph_basic_properties.c
10
11
  ext/cIGraph_basic_query.c
11
12
  ext/cIGraph_centrality.c
12
13
  ext/cIGraph_components.c
14
+ ext/cIGraph_direction.c
13
15
  ext/cIGraph_error_handlers.c
14
16
  ext/cIGraph_file.c
15
17
  ext/cIGraph_iterators.c
18
+ ext/cIGraph_kcores.c
16
19
  ext/cIGraph_layout.c
17
20
  ext/cIGraph_matrix.c
18
21
  ext/cIGraph_operators.c
19
22
  ext/cIGraph_selectors.c
20
23
  ext/cIGraph_shortest_paths.c
24
+ ext/cIGraph_spanning.c
25
+ ext/cIGraph_spectral.c
21
26
  ext/cIGraph_topological_sort.c
27
+ ext/cIGraph_transitivity.c
22
28
  ext/cIGraph_utility.c
23
29
  ext/cIGraph_vertex_neighbourhood.c
30
+ ext/extconf.rb
24
31
  test/tc_add_delete.rb
25
32
  test/tc_attributes.rb
26
33
  test/tc_basic_properties.rb
@@ -28,7 +35,9 @@ test/tc_basic_query.rb
28
35
  test/tc_centrality.rb
29
36
  test/tc_components.rb
30
37
  test/tc_copy.rb
38
+ test/tc_cores.rb
31
39
  test/tc_create.rb
40
+ test/tc_directedness.rb
32
41
  test/tc_error_handling.rb
33
42
  test/tc_file_read_write.rb
34
43
  test/tc_iterators.rb
@@ -36,6 +45,10 @@ test/tc_layout.rb
36
45
  test/tc_matrix.rb
37
46
  test/tc_selectors.rb
38
47
  test/tc_shortest_paths.rb
48
+ test/tc_spanning.rb
49
+ test/tc_spectral.rb
50
+ test/tc_thrash.rb
39
51
  test/tc_topological_sort.rb
52
+ test/tc_transitivity.rb
40
53
  test/tc_vertex_neighbourhood.rb
41
54
  test/test_all.rb
data/Rakefile.rb ADDED
@@ -0,0 +1,52 @@
1
+ require 'hoe'
2
+
3
+ $LOAD_PATH.unshift("./ext")
4
+
5
+ class IGraph
6
+ VERSION = "0.0"
7
+ end
8
+
9
+ begin
10
+ require 'igraph'
11
+ rescue RuntimeError
12
+ end
13
+
14
+ hoe = Hoe.new("igraph",IGraph::VERSION) do |p|
15
+
16
+ p.author = "Alex Gutteridge"
17
+ p.email = "alexg@kuicr.kyoto-u.ac.jp"
18
+ p.url = "http://igraph.rubyforge.org/"
19
+
20
+ p.description = p.paragraphs_of("README.txt",1..3)[0]
21
+ p.summary = p.paragraphs_of("README.txt",1)[0]
22
+ p.changes = p.paragraphs_of("History.txt",0..1).join("\n\n")
23
+
24
+ p.clean_globs = ["ext/*.o","ext/*.so","ext/Makefile","ext/mkmf.log","**/*~","email.txt","manual.{aux,log,out,toc,pdf}"]
25
+
26
+ p.rdoc_pattern = /(^ext\/.*\.c$|^README|^History|^License)/
27
+
28
+ p.spec_extras = {
29
+ :extensions => ['ext/extconf.rb'],
30
+ :require_paths => ['test'],
31
+ :has_rdoc => true,
32
+ :extra_rdoc_files => ["README.txt","History.txt","License.txt"],
33
+ :rdoc_options => ["--exclude", "test/*", "--main", "README.txt", "--inline-source"]
34
+ }
35
+
36
+ end
37
+
38
+ hoe.spec.dependencies.delete_if{|dep| dep.name == "hoe"}
39
+
40
+ IGRAPH = '/usr/local/include/igraph'
41
+
42
+ desc "Uses extconf.rb and make to build the extension"
43
+ task :build_extension => ['ext/igraph.so']
44
+ SRC = FileList['ext/*.c'] + FileList['ext/*.h']
45
+ file 'ext/igraph.so' => SRC do
46
+ Dir.chdir('ext')
47
+ system("ruby extconf.rb --with-igraph-include=#{IGRAPH}")
48
+ system("make")
49
+ Dir.chdir('..')
50
+ end
51
+
52
+ task :test => [:build_extension]
data/ext/cIGraph.c CHANGED
@@ -8,6 +8,7 @@ VALUE cIGraphError;
8
8
 
9
9
  void cIGraph_free(void *p){
10
10
  igraph_destroy(p);
11
+ free(p);
11
12
  }
12
13
 
13
14
  void cIGraph_mark(void *p){
@@ -48,7 +49,7 @@ VALUE cIGraph_init_copy(VALUE copy, VALUE orig){
48
49
  Data_Get_Struct(copy, igraph_t, copy_graph);
49
50
  Data_Get_Struct(orig, igraph_t, orig_graph);
50
51
 
51
- igraph_copy(copy_graph,orig_graph);
52
+ IGRAPH_CHECK(igraph_copy(copy_graph,orig_graph));
52
53
 
53
54
  return copy;
54
55
 
@@ -103,17 +104,21 @@ VALUE cIGraph_initialize(int argc, VALUE *argv, VALUE self){
103
104
  rb_scan_args(argc,argv,"12", &edges, &directed, &attrs);
104
105
 
105
106
  //Initialize edge vector
106
- igraph_vector_init_int(&edge_v,0);
107
+ IGRAPH_FINALLY(igraph_vector_destroy,&edge_v);
108
+ IGRAPH_FINALLY(igraph_vector_ptr_destroy,&vertex_attr);
109
+ IGRAPH_FINALLY(igraph_vector_ptr_destroy,&edge_attr);
107
110
 
108
- igraph_vector_ptr_init(&vertex_attr,0);
109
- igraph_vector_ptr_init(&edge_attr,0);
111
+ IGRAPH_CHECK(igraph_vector_init_int(&edge_v,0));
112
+
113
+ IGRAPH_CHECK(igraph_vector_ptr_init(&vertex_attr,0));
114
+ IGRAPH_CHECK(igraph_vector_ptr_init(&edge_attr,0));
110
115
 
111
116
  Data_Get_Struct(self, igraph_t, graph);
112
117
 
113
118
  v_ary = rb_ary_new();
114
119
 
115
120
  if(!directed)
116
- igraph_to_undirected(graph,IGRAPH_TO_UNDIRECTED_COLLAPSE);
121
+ IGRAPH_CHECK(igraph_to_undirected(graph,IGRAPH_TO_UNDIRECTED_COLLAPSE));
117
122
 
118
123
  //Loop through objects in edge Array
119
124
  for (i=0; i<RARRAY(edges)->len; i++) {
@@ -131,7 +136,7 @@ VALUE cIGraph_initialize(int argc, VALUE *argv, VALUE self){
131
136
  rb_ary_push((VALUE)v_attr_rec.value,vertex);
132
137
 
133
138
  }
134
- igraph_vector_push_back(&edge_v,current_vertex_id);
139
+ IGRAPH_CHECK(igraph_vector_push_back(&edge_v,current_vertex_id));
135
140
  if (i % 2){
136
141
  if (attrs != Qnil){
137
142
  rb_ary_push((VALUE)e_attr_rec.value,RARRAY(attrs)->ptr[i/2]);
@@ -141,18 +146,20 @@ VALUE cIGraph_initialize(int argc, VALUE *argv, VALUE self){
141
146
  }
142
147
  }
143
148
 
144
- igraph_vector_ptr_push_back(&vertex_attr, &v_attr_rec);
145
- igraph_vector_ptr_push_back(&edge_attr, &e_attr_rec);
149
+ IGRAPH_CHECK(igraph_vector_ptr_push_back(&vertex_attr, &v_attr_rec));
150
+ IGRAPH_CHECK(igraph_vector_ptr_push_back(&edge_attr, &e_attr_rec));
146
151
 
147
152
  if(igraph_vector_size(&edge_v) > 0){
148
- igraph_add_vertices(graph,vertex_n,&vertex_attr);
149
- igraph_add_edges(graph,&edge_v,&edge_attr);
153
+ IGRAPH_CHECK(igraph_add_vertices(graph,vertex_n,&vertex_attr));
154
+ IGRAPH_CHECK(igraph_add_edges(graph,&edge_v,&edge_attr));
150
155
  }
151
156
 
152
157
  igraph_vector_destroy(&edge_v);
153
158
  igraph_vector_ptr_destroy(&vertex_attr);
154
159
  igraph_vector_ptr_destroy(&edge_attr);
155
160
 
161
+ IGRAPH_FINALLY_CLEAN(3);
162
+
156
163
  return self;
157
164
 
158
165
  }
@@ -177,7 +184,7 @@ void Init_igraph(){
177
184
 
178
185
  rb_include_module(cIGraph, rb_mEnumerable);
179
186
 
180
- rb_define_const(cIGraph, "VERSION", rb_str_new2("0.3"));
187
+ rb_define_const(cIGraph, "VERSION", rb_str_new2("0.3.1"));
181
188
 
182
189
  rb_define_const(cIGraph, "EDGEORDER_ID", INT2NUM(1));
183
190
  rb_define_const(cIGraph, "EDGEORDER_FROM", INT2NUM(2));
@@ -191,6 +198,11 @@ void Init_igraph(){
191
198
  rb_define_const(cIGraph, "WEAK", INT2NUM(1));
192
199
  rb_define_const(cIGraph, "STRONG", INT2NUM(2));
193
200
 
201
+ rb_define_const(cIGraph, "ARBITRARY", INT2NUM(0));
202
+ rb_define_const(cIGraph, "MUTUAL", INT2NUM(1));
203
+ rb_define_const(cIGraph, "EACH", INT2NUM(0));
204
+ rb_define_const(cIGraph, "COLLAPSE", INT2NUM(1));
205
+
194
206
  rb_define_method(cIGraph, "[]", cIGraph_get_edge_attr, 2); /* in cIGraph_attribute_handler.c */
195
207
  rb_define_method(cIGraph, "[]=", cIGraph_set_edge_attr, 3); /* in cIGraph_attribute_handler.c */
196
208
  rb_define_alias (cIGraph, "get_edge_attr", "[]");
@@ -259,6 +271,20 @@ void Init_igraph(){
259
271
  rb_define_method(cIGraph, "constraint", cIGraph_constraint, -1); /* in cIGraph_centrality.c */
260
272
  rb_define_method(cIGraph, "maxdegree", cIGraph_maxdegree, 3); /* in cIGraph_centrality.c */
261
273
 
274
+ rb_define_method(cIGraph, "minimum_spanning_tree_unweighted", cIGraph_minimum_spanning_tree_unweighted, 0); /* in cIGraph_spanning.c */
275
+ rb_define_method(cIGraph, "minimum_spanning_tree_prim", cIGraph_minimum_spanning_tree_prim, 1); /* in cIGraph_spanning.c */
276
+
277
+ rb_define_method(cIGraph, "transitivity", cIGraph_transitivity, 0); /* in cIGraph_transitivity.c */
278
+ rb_define_method(cIGraph, "transitivity_local", cIGraph_transitivity_local, 1); /* in cIGraph_transitivity.c */
279
+ rb_define_method(cIGraph, "transitivity_avglocal", cIGraph_transitivity_avglocal, 0); /* in cIGraph_transitivity.c */
280
+
281
+ rb_define_method(cIGraph, "to_directed", cIGraph_to_directed, 1); /* in cIGraph_direction.c */
282
+ rb_define_method(cIGraph, "to_undirected", cIGraph_to_undirected, 1); /* in cIGraph_direction.c */
283
+
284
+ rb_define_method(cIGraph, "laplacian", cIGraph_laplacian, 1); /* in cIGraph_spectral.c */
285
+
286
+ rb_define_method(cIGraph, "coreness", cIGraph_coreness, 1); /* in cIGraph_kcores.c */
287
+
262
288
  rb_define_method(cIGraph, "topological_sorting", cIGraph_topological_sorting, 1); /* in cIGraph_topological_sort.c */
263
289
 
264
290
  rb_define_singleton_method(cIGraph, "read_graph_edgelist", cIGraph_read_graph_edgelist, 2); /* in cIGraph_file.c */
data/ext/cIGraph.h CHANGED
@@ -100,6 +100,25 @@ VALUE cIGraph_pagerank (VALUE self, VALUE vs, VALUE directed, VALUE niter
100
100
  VALUE cIGraph_constraint (int argc, VALUE *argv, VALUE self);
101
101
  VALUE cIGraph_maxdegree (VALUE self, VALUE vs, VALUE mode, VALUE loops);
102
102
 
103
+ //Spanning trees
104
+ VALUE cIGraph_minimum_spanning_tree_prim (VALUE self, VALUE weights);
105
+ VALUE cIGraph_minimum_spanning_tree_unweighted(VALUE self);
106
+
107
+ //Transitivity
108
+ VALUE cIGraph_transitivity (VALUE self);
109
+ VALUE cIGraph_transitivity_local (VALUE self, VALUE vs);
110
+ VALUE cIGraph_transitivity_avglocal(VALUE self);
111
+
112
+ //Directedness conversion
113
+ VALUE cIGraph_to_directed (VALUE self, VALUE mode);
114
+ VALUE cIGraph_to_undirected(VALUE self, VALUE mode);
115
+
116
+ //Spectral properties
117
+ VALUE cIGraph_laplacian(VALUE self, VALUE mode);
118
+
119
+ //K-Cores
120
+ VALUE cIGraph_coreness(VALUE self, VALUE mode);
121
+
103
122
  //Topological sorting
104
123
  VALUE cIGraph_topological_sorting(VALUE self, VALUE mode);
105
124
 
@@ -40,8 +40,10 @@ VALUE cIGraph_add_edges(int argc, VALUE *argv, VALUE self){
40
40
  rb_scan_args(argc, argv, "11", &edges, &attrs);
41
41
 
42
42
  //Initialize edge vector
43
- igraph_vector_init_int(&edge_v,0);
44
- igraph_vector_ptr_init(&edge_attr,0);
43
+ IGRAPH_FINALLY(igraph_vector_destroy,&edge_v);
44
+ IGRAPH_FINALLY(igraph_vector_ptr_destroy,&edge_attr);
45
+ IGRAPH_CHECK(igraph_vector_init_int(&edge_v,0));
46
+ IGRAPH_CHECK(igraph_vector_ptr_init(&edge_attr,0));
45
47
 
46
48
  Data_Get_Struct(self, igraph_t, graph);
47
49
 
@@ -55,7 +57,7 @@ VALUE cIGraph_add_edges(int argc, VALUE *argv, VALUE self){
55
57
  } else {
56
58
  rb_raise(cIGraphError, "Unknown vertex in edge array. Use add_vertices first");
57
59
  }
58
- igraph_vector_push_back(&edge_v,vid);
60
+ IGRAPH_CHECK(igraph_vector_push_back(&edge_v,vid));
59
61
  if (i % 2){
60
62
  if (attrs != Qnil){
61
63
  rb_ary_push((VALUE)e_attr_rec.value,RARRAY(attrs)->ptr[i/2]);
@@ -65,15 +67,17 @@ VALUE cIGraph_add_edges(int argc, VALUE *argv, VALUE self){
65
67
  }
66
68
  }
67
69
 
68
- igraph_vector_ptr_push_back(&edge_attr, &e_attr_rec);
70
+ IGRAPH_CHECK(igraph_vector_ptr_push_back(&edge_attr, &e_attr_rec));
69
71
 
70
72
  if(igraph_vector_size(&edge_v) > 0){
71
- code = igraph_add_edges(graph,&edge_v,&edge_attr);
73
+ IGRAPH_CHECK(code = igraph_add_edges(graph,&edge_v,&edge_attr));
72
74
  }
73
75
 
74
76
  igraph_vector_destroy(&edge_v);
75
77
  igraph_vector_ptr_destroy(&edge_attr);
76
78
 
79
+ IGRAPH_FINALLY_CLEAN(2);
80
+
77
81
  return INT2NUM(code);
78
82
 
79
83
  }
@@ -108,7 +112,8 @@ VALUE cIGraph_add_vertices(VALUE self, VALUE vs){
108
112
  v_attr_rec.type = IGRAPH_ATTRIBUTE_PY_OBJECT;
109
113
  v_attr_rec.value = (void*)rb_ary_new();
110
114
 
111
- igraph_vector_ptr_init(&vertex_attr,0);
115
+ IGRAPH_CHECK(igraph_vector_ptr_init(&vertex_attr,0));
116
+ IGRAPH_FINALLY(igraph_vector_ptr_destroy,&vertex_attr);
112
117
 
113
118
  Data_Get_Struct(self, igraph_t, graph);
114
119
  v_ary = ((VALUE*)graph->attr)[0];
@@ -127,9 +132,12 @@ VALUE cIGraph_add_vertices(VALUE self, VALUE vs){
127
132
  }
128
133
  }
129
134
 
130
- igraph_vector_ptr_push_back(&vertex_attr,&v_attr_rec);
135
+ IGRAPH_CHECK(igraph_vector_ptr_push_back(&vertex_attr,&v_attr_rec));
136
+
137
+ IGRAPH_CHECK(code = igraph_add_vertices(graph,to_add,&vertex_attr));
131
138
 
132
- code = igraph_add_vertices(graph,to_add,&vertex_attr);
139
+ igraph_vector_ptr_destroy(&vertex_attr);
140
+ IGRAPH_FINALLY_CLEAN(1);
133
141
 
134
142
  return INT2NUM(code);
135
143
 
@@ -172,8 +180,10 @@ VALUE cIGraph_add_edge(int argc, VALUE *argv, VALUE self){
172
180
  rb_scan_args(argc, argv, "21", &from, &to, &attr);
173
181
 
174
182
  //Initialize edge vector
175
- igraph_vector_init_int(&edge_v,0);
176
- igraph_vector_ptr_init(&edge_attr,0);
183
+ IGRAPH_FINALLY(igraph_vector_destroy,&edge_v);
184
+ IGRAPH_FINALLY(igraph_vector_ptr_destroy,&edge_attr);
185
+ IGRAPH_CHECK(igraph_vector_init_int(&edge_v,0));
186
+ IGRAPH_CHECK(igraph_vector_ptr_init(&edge_attr,0));
177
187
 
178
188
  Data_Get_Struct(self, igraph_t, graph);
179
189
 
@@ -181,20 +191,21 @@ VALUE cIGraph_add_edge(int argc, VALUE *argv, VALUE self){
181
191
 
182
192
  if(rb_ary_includes(v_ary,from) && rb_ary_includes(v_ary,to)){
183
193
  //If graph includes this vertex then look up the vertex number
184
- igraph_vector_push_back(&edge_v,cIGraph_get_vertex_id(self, from));
185
- igraph_vector_push_back(&edge_v,cIGraph_get_vertex_id(self, to));
194
+ IGRAPH_CHECK(igraph_vector_push_back(&edge_v,cIGraph_get_vertex_id(self, from)));
195
+ IGRAPH_CHECK(igraph_vector_push_back(&edge_v,cIGraph_get_vertex_id(self, to)));
186
196
  rb_ary_push((VALUE)e_attr_rec.value,attr);
187
197
  } else {
188
198
  rb_raise(cIGraphError, "Unknown vertex in edge array. Use add_vertices");
189
199
  }
190
200
 
191
- igraph_vector_ptr_push_back(&edge_attr,&e_attr_rec);
192
-
193
- code = igraph_add_edges(graph,&edge_v,&edge_attr);
201
+ IGRAPH_CHECK(igraph_vector_ptr_push_back(&edge_attr,&e_attr_rec));
202
+ IGRAPH_CHECK(code = igraph_add_edges(graph,&edge_v,&edge_attr));
194
203
 
195
204
  igraph_vector_ptr_destroy(&edge_attr);
196
205
  igraph_vector_destroy(&edge_v);
197
206
 
207
+ IGRAPH_FINALLY_CLEAN(2);
208
+
198
209
  return INT2NUM(code);
199
210
 
200
211
  }
@@ -229,23 +240,28 @@ VALUE cIGraph_add_vertex(VALUE self, VALUE v){
229
240
  v_attr_rec.type = IGRAPH_ATTRIBUTE_PY_OBJECT;
230
241
  v_attr_rec.value = (void*)rb_ary_new();
231
242
 
232
- igraph_vector_ptr_init(&vertex_attr,0);
243
+ IGRAPH_CHECK(igraph_vector_ptr_init(&vertex_attr,0));
244
+ IGRAPH_FINALLY(igraph_vector_ptr_destroy,&vertex_attr);
233
245
 
234
246
  Data_Get_Struct(self, igraph_t, graph);
235
247
 
236
248
  v_ary = ((VALUE*)graph->attr)[0];
237
-
249
+
238
250
  //Loop through objects in vertex array
239
251
  if(rb_ary_includes(v_ary,v)){
240
252
  //rb_raise(cIGraphError, "Vertex already added to graph");
253
+ igraph_vector_ptr_destroy(&vertex_attr);
254
+ IGRAPH_FINALLY_CLEAN(1);
241
255
  return code;
242
256
  } else {
243
257
  rb_ary_push((VALUE)v_attr_rec.value,v);
244
258
  }
245
259
 
246
- igraph_vector_ptr_push_back(&vertex_attr,&v_attr_rec);
260
+ IGRAPH_CHECK(igraph_vector_ptr_push_back(&vertex_attr,&v_attr_rec));
261
+ IGRAPH_CHECK(code = igraph_add_vertices(graph,1,&vertex_attr));
247
262
 
248
- code = igraph_add_vertices(graph,1,&vertex_attr);
263
+ igraph_vector_ptr_destroy(&vertex_attr);
264
+ IGRAPH_FINALLY_CLEAN(1);
249
265
 
250
266
  return INT2NUM(code);
251
267
 
@@ -90,7 +90,7 @@ int cIGraph_attribute_init(igraph_t *graph, igraph_vector_ptr_t *attr) {
90
90
  VALUE key;
91
91
  VALUE value;
92
92
 
93
- attrs = ALLOC_N(VALUE, 3);
93
+ attrs = (VALUE*)calloc(3, sizeof(VALUE));
94
94
 
95
95
  if(!attrs)
96
96
  IGRAPH_ERROR("Error allocating Arrays\n", IGRAPH_ENOMEM);
@@ -132,7 +132,8 @@ int cIGraph_attribute_init(igraph_t *graph, igraph_vector_ptr_t *attr) {
132
132
 
133
133
  /* Destruction */
134
134
  void cIGraph_attribute_destroy(igraph_t *graph) {
135
- free(graph->attr);
135
+ VALUE *attrs = (VALUE*)graph->attr;
136
+ free(attrs);
136
137
  return;
137
138
  }
138
139
 
@@ -85,10 +85,11 @@ VALUE cIGraph_edge(VALUE self, VALUE eid){
85
85
  *
86
86
  */
87
87
  VALUE cIGraph_get_eid(VALUE self, VALUE from, VALUE to, VALUE directed){
88
+
88
89
  igraph_t *graph;
89
90
  igraph_integer_t eid = 0;
90
- int from_i;
91
- int to_i;
91
+ int from_i = 0;
92
+ int to_i = 0;
92
93
  igraph_bool_t directed_b = 0;
93
94
 
94
95
  Data_Get_Struct(self, igraph_t, graph);
@@ -241,6 +242,7 @@ VALUE cIGraph_degree(VALUE self, VALUE v, VALUE mode, VALUE loops){
241
242
  Data_Get_Struct(self, igraph_t, graph);
242
243
 
243
244
  //Convert an array of vertices to a vector of vertex ids
245
+ igraph_vector_init_int(&vidv,0);
244
246
  cIGraph_vertex_arr_to_id_vec(self,v,&vidv);
245
247
  //create vertex selector from the vecotr of ids
246
248
  igraph_vs_vector(&vids,&vidv);
@@ -25,6 +25,7 @@ VALUE cIGraph_closeness(VALUE self, VALUE vs, VALUE mode){
25
25
  Data_Get_Struct(self, igraph_t, graph);
26
26
 
27
27
  //Convert an array of vertices to a vector of vertex ids
28
+ igraph_vector_init_int(&vidv,0);
28
29
  cIGraph_vertex_arr_to_id_vec(self,vs,&vidv);
29
30
  //create vertex selector from the vecotr of ids
30
31
  igraph_vs_vector(&vids,&vidv);
@@ -64,25 +65,32 @@ VALUE cIGraph_betweenness(VALUE self, VALUE vs, VALUE directed){
64
65
  dir = 1;
65
66
 
66
67
  //vector to hold the results of the degree calculations
67
- igraph_vector_init_int(&res,0);
68
+ IGRAPH_FINALLY(igraph_vector_destroy, &res);
69
+ IGRAPH_FINALLY(igraph_vector_destroy, &vidv);
70
+ IGRAPH_FINALLY(igraph_vs_destroy,&vids);
71
+
72
+ IGRAPH_CHECK(igraph_vector_init(&res,0));
68
73
 
69
74
  Data_Get_Struct(self, igraph_t, graph);
70
75
 
71
76
  //Convert an array of vertices to a vector of vertex ids
77
+ IGRAPH_CHECK(igraph_vector_init_int(&vidv,0));
72
78
  cIGraph_vertex_arr_to_id_vec(self,vs,&vidv);
73
79
  //create vertex selector from the vecotr of ids
74
- igraph_vs_vector(&vids,&vidv);
80
+ IGRAPH_CHECK(igraph_vs_vector(&vids,&vidv));
75
81
 
76
- igraph_betweenness(graph,&res,vids,dir);
82
+ IGRAPH_CHECK(igraph_betweenness(graph,&res,vids,dir));
77
83
 
78
84
  for(i=0;i<igraph_vector_size(&res);i++){
79
- rb_ary_push(betweenness,INT2NUM((int)VECTOR(res)[i]));
85
+ rb_ary_push(betweenness,rb_float_new((float)VECTOR(res)[i]));
80
86
  }
81
87
 
82
88
  igraph_vector_destroy(&vidv);
83
89
  igraph_vector_destroy(&res);
84
90
  igraph_vs_destroy(&vids);
85
91
 
92
+ IGRAPH_FINALLY_CLEAN(3);
93
+
86
94
  return betweenness;
87
95
 
88
96
  }
@@ -148,6 +156,7 @@ VALUE cIGraph_pagerank(VALUE self, VALUE vs, VALUE directed, VALUE niter, VALUE
148
156
  Data_Get_Struct(self, igraph_t, graph);
149
157
 
150
158
  //Convert an array of vertices to a vector of vertex ids
159
+ igraph_vector_init_int(&vidv,0);
151
160
  cIGraph_vertex_arr_to_id_vec(self,vs,&vidv);
152
161
  //create vertex selector from the vecotr of ids
153
162
  igraph_vs_vector(&vids,&vidv);
@@ -179,7 +188,7 @@ VALUE cIGraph_constraint(int argc, VALUE *argv, VALUE self){
179
188
  igraph_vs_t vids;
180
189
  igraph_vector_t vidv;
181
190
  igraph_vector_t res;
182
- igraph_vector_t *wght = malloc(sizeof(igraph_vector_t));
191
+ igraph_vector_t wght;
183
192
  int i;
184
193
  VALUE constraints = rb_ary_new();
185
194
  VALUE vs, weights;
@@ -187,38 +196,39 @@ VALUE cIGraph_constraint(int argc, VALUE *argv, VALUE self){
187
196
  rb_scan_args(argc,argv,"11",&vs, &weights);
188
197
 
189
198
  //vector to hold the results of the degree calculations
190
- igraph_vector_init(&res,0);
191
- igraph_vector_init(wght,0);
199
+ IGRAPH_FINALLY(igraph_vector_destroy, &res);
200
+ IGRAPH_FINALLY(igraph_vector_destroy, &wght);
201
+ IGRAPH_FINALLY(igraph_vector_destroy, &vidv);
202
+ IGRAPH_CHECK(igraph_vector_init(&res,0));
203
+ IGRAPH_CHECK(igraph_vector_init(&wght,0));
192
204
 
193
205
  Data_Get_Struct(self, igraph_t, graph);
194
206
 
195
207
  //Convert an array of vertices to a vector of vertex ids
208
+ IGRAPH_CHECK(igraph_vector_init_int(&vidv,0));
196
209
  cIGraph_vertex_arr_to_id_vec(self,vs,&vidv);
197
210
  //create vertex selector from the vecotr of ids
198
211
  igraph_vs_vector(&vids,&vidv);
199
212
 
200
213
  if(weights == Qnil){
201
- igraph_vector_destroy(wght);
202
- wght = NULL;
214
+ IGRAPH_CHECK(igraph_constraint(graph,&res,vids,NULL));
203
215
  } else {
204
216
  for(i=0;i<RARRAY(weights)->len;i++){
205
- igraph_vector_push_back(wght,NUM2DBL(RARRAY(weights)->ptr[i]));
217
+ IGRAPH_CHECK(igraph_vector_push_back(&wght,NUM2DBL(RARRAY(weights)->ptr[i])));
206
218
  }
219
+ IGRAPH_CHECK(igraph_constraint(graph,&res,vids,&wght));
207
220
  }
208
221
 
209
- igraph_constraint(graph,&res,vids,wght);
210
-
211
222
  for(i=0;i<igraph_vector_size(&res);i++){
212
223
  rb_ary_push(constraints,rb_float_new(VECTOR(res)[i]));
213
224
  }
214
225
 
215
226
  igraph_vector_destroy(&vidv);
216
227
  igraph_vector_destroy(&res);
217
- if(wght != NULL)
218
- igraph_vector_destroy(wght);
228
+ igraph_vector_destroy(&wght);
219
229
  igraph_vs_destroy(&vids);
220
230
 
221
- free(wght);
231
+ IGRAPH_FINALLY_CLEAN(3);
222
232
 
223
233
  return constraints;
224
234
 
@@ -250,6 +260,7 @@ VALUE cIGraph_maxdegree(VALUE self, VALUE vs, VALUE mode, VALUE loops){
250
260
  Data_Get_Struct(self, igraph_t, graph);
251
261
 
252
262
  //Convert an array of vertices to a vector of vertex ids
263
+ igraph_vector_init_int(&vidv,0);
253
264
  cIGraph_vertex_arr_to_id_vec(self,vs,&vidv);
254
265
  //create vertex selector from the vecotr of ids
255
266
  igraph_vs_vector(&vids,&vidv);
@@ -53,6 +53,7 @@ VALUE cIGraph_subgraph(VALUE self, VALUE vs){
53
53
  Data_Get_Struct(self, igraph_t, graph);
54
54
 
55
55
  //Convert an array of vertices to a vector of vertex ids
56
+ igraph_vector_init_int(&vidv,0);
56
57
  cIGraph_vertex_arr_to_id_vec(self,vs,&vidv);
57
58
  //create vertex selector from the vecotr of ids
58
59
  igraph_vs_vector(&vids,&vidv);
@@ -0,0 +1,39 @@
1
+ #include "igraph.h"
2
+ #include "ruby.h"
3
+ #include "cIGraph.h"
4
+
5
+ /* call-seq:
6
+ * graph.to_directed(mode)
7
+ *
8
+ * Converts the graph to a directed graph.
9
+ */
10
+ VALUE cIGraph_to_directed(VALUE self, VALUE mode){
11
+
12
+ igraph_t *graph;
13
+ igraph_neimode_t pmode = NUM2INT(mode);
14
+ int ret;
15
+
16
+ Data_Get_Struct(self, igraph_t, graph);
17
+ IGRAPH_CHECK(ret = igraph_to_directed(graph,pmode));
18
+
19
+ return INT2NUM(ret);
20
+
21
+ }
22
+
23
+ /* call-seq:
24
+ * graph.to_undirected(mode)
25
+ *
26
+ * Converts the graph to a directed graph.
27
+ */
28
+ VALUE cIGraph_to_undirected(VALUE self, VALUE mode){
29
+
30
+ igraph_t *graph;
31
+ igraph_neimode_t pmode = NUM2INT(mode);
32
+ int ret;
33
+
34
+ Data_Get_Struct(self, igraph_t, graph);
35
+ IGRAPH_CHECK(ret = igraph_to_undirected(graph,pmode));
36
+
37
+ return INT2NUM(ret);
38
+
39
+ }
@@ -4,6 +4,7 @@
4
4
 
5
5
  void cIGraph_error_handler(const char *reason, const char *file,
6
6
  int line, int igraph_errno) {
7
+ IGRAPH_FINALLY_FREE();
7
8
  rb_raise(cIGraphError, reason);
8
9
  }
9
10
 
data/ext/cIGraph_file.c CHANGED
@@ -177,7 +177,7 @@ VALUE cIGraph_read_graph_pajek(VALUE self, VALUE file){
177
177
  string = rb_funcall(file, rb_intern("read"), 0);
178
178
  stream = fmemopen(RSTRING(string)->ptr,RSTRING(string)->len, "r");
179
179
 
180
- igraph_read_graph_pajek(graph, stream);
180
+ IGRAPH_CHECK(igraph_read_graph_pajek(graph, stream));
181
181
 
182
182
  fclose(stream);
183
183
 
@@ -0,0 +1,39 @@
1
+ #include "igraph.h"
2
+ #include "ruby.h"
3
+ #include "cIGraph.h"
4
+
5
+ /* call-seq:
6
+ * graph.coreness(mode) -> Array
7
+ *
8
+ * Finding the coreness of the vertices in a network. The k-core of a
9
+ * graph is a maximal subgraph in which each vertex has at least degree k.
10
+ * (Degree here means the degree in the subgraph of course.). The coreness
11
+ * of a vertex is the highest order of a k-core containing the vertex.
12
+ *
13
+ * This function implements the algorithm presented in Vladimir Batagelj,
14
+ * Matjaz Zaversnik: An O(m) Algorithm for Cores Decomposition of Networks.
15
+ */
16
+ VALUE cIGraph_coreness(VALUE self, VALUE mode){
17
+
18
+ igraph_t *graph;
19
+ igraph_neimode_t pmode = NUM2INT(mode);
20
+ igraph_vector_t cores;
21
+ int i;
22
+ VALUE result = rb_ary_new();
23
+
24
+ Data_Get_Struct(self, igraph_t, graph);
25
+
26
+ //vector to hold the results of the calculations
27
+ igraph_vector_init(&cores,0);
28
+
29
+ igraph_coreness(graph,&cores,pmode);
30
+
31
+ for(i=0; i< igraph_vector_size(&cores); i++){
32
+ rb_ary_push(result,VECTOR(cores)[i]);
33
+ }
34
+
35
+ igraph_vector_destroy(&cores);
36
+
37
+ return result;
38
+
39
+ }
@@ -37,6 +37,7 @@ VALUE cIGraph_shortest_paths(VALUE self, VALUE from, VALUE mode){
37
37
  igraph_matrix_init(&res,n_row,n_col);
38
38
 
39
39
  //Convert an array of vertices to a vector of vertex ids
40
+ igraph_vector_init_int(&vidv,0);
40
41
  cIGraph_vertex_arr_to_id_vec(self,from,&vidv);
41
42
  //create vertex selector from the vecotr of ids
42
43
  igraph_vs_vector(&vids,&vidv);
@@ -103,6 +104,7 @@ VALUE cIGraph_get_shortest_paths(VALUE self, VALUE from, VALUE to, VALUE mode){
103
104
  }
104
105
 
105
106
  //Convert an array of vertices to a vector of vertex ids
107
+ igraph_vector_init_int(&to_vidv,0);
106
108
  cIGraph_vertex_arr_to_id_vec(self,to,&to_vidv);
107
109
  //create vertex selector from the vecotr of ids
108
110
  igraph_vs_vector(&to_vids,&to_vidv);
@@ -123,6 +125,7 @@ VALUE cIGraph_get_shortest_paths(VALUE self, VALUE from, VALUE to, VALUE mode){
123
125
 
124
126
  for(i=0;i<n_paths;i++){
125
127
  igraph_vector_destroy(VECTOR(res)[i]);
128
+ free(VECTOR(res)[i]);
126
129
  }
127
130
 
128
131
  igraph_vector_destroy(&to_vidv);
@@ -166,17 +169,19 @@ VALUE cIGraph_get_all_shortest_paths(VALUE self, VALUE from, VALUE to, VALUE mod
166
169
  Data_Get_Struct(self, igraph_t, graph);
167
170
 
168
171
  //vector to hold the results of the calculations
169
- igraph_vector_ptr_init(&res,0);
172
+ IGRAPH_FINALLY(igraph_vector_ptr_destroy,&res);
173
+ IGRAPH_CHECK(igraph_vector_ptr_init(&res,0));
170
174
 
171
175
  //The id of the vertex from where we are counting
172
176
  from_vid = cIGraph_get_vertex_id(self, from);
173
177
 
174
178
  //Convert an array of vertices to a vector of vertex ids
179
+ igraph_vector_init_int(&to_vidv,0);
175
180
  cIGraph_vertex_arr_to_id_vec(self,to,&to_vidv);
176
181
  //create vertex selector from the vecotr of ids
177
- igraph_vs_vector(&to_vids,&to_vidv);
182
+ IGRAPH_CHECK(igraph_vs_vector(&to_vids,&to_vidv));
178
183
 
179
- igraph_get_all_shortest_paths(graph,&res,NULL,from_vid,to_vids,pmode);
184
+ IGRAPH_CHECK(igraph_get_all_shortest_paths(graph,&res,NULL,from_vid,to_vids,pmode));
180
185
 
181
186
  for(i=0; i< igraph_vector_ptr_size(&res); i++){
182
187
  path = rb_ary_new();
@@ -189,9 +194,13 @@ VALUE cIGraph_get_all_shortest_paths(VALUE self, VALUE from, VALUE to, VALUE mod
189
194
 
190
195
  for(i=0;i<igraph_vector_ptr_size(&res);i++){
191
196
  igraph_vector_destroy(VECTOR(res)[i]);
197
+ free(VECTOR(res)[i]);
192
198
  }
193
199
 
194
200
  igraph_vector_ptr_destroy(&res);
201
+ igraph_vector_destroy(&to_vidv);
202
+
203
+ IGRAPH_FINALLY_CLEAN(1);
195
204
 
196
205
  return matrix;
197
206
 
@@ -285,15 +294,17 @@ VALUE cIGraph_girth(VALUE self){
285
294
 
286
295
  igraph_t *graph;
287
296
  igraph_vector_t res;
297
+ igraph_integer_t girth = 0;
288
298
  int i;
289
299
  VALUE path = rb_ary_new();
290
300
 
291
301
  Data_Get_Struct(self, igraph_t, graph);
292
302
 
293
303
  //vector to hold the results of the calculations
294
- igraph_vector_init(&res,0);
304
+ IGRAPH_FINALLY(igraph_vector_destroy,&res);
305
+ IGRAPH_CHECK(igraph_vector_init(&res,0));
295
306
 
296
- igraph_girth(graph,NULL,&res);
307
+ IGRAPH_CHECK(igraph_girth(graph,&girth,&res));
297
308
 
298
309
  for(i=0; i<igraph_vector_size(&res); i++){
299
310
  rb_ary_push(path,cIGraph_get_vertex_object(self,VECTOR(res)[i]));
@@ -301,6 +312,8 @@ VALUE cIGraph_girth(VALUE self){
301
312
 
302
313
  igraph_vector_destroy(&res);
303
314
 
315
+ IGRAPH_FINALLY_CLEAN(1);
316
+
304
317
  return path;
305
318
 
306
319
  }
@@ -0,0 +1,78 @@
1
+ #include "igraph.h"
2
+ #include "ruby.h"
3
+ #include "cIGraph.h"
4
+
5
+ /* call-seq:
6
+ * graph.minimum_spanning_tree_unweighted() -> IGraph
7
+ *
8
+ * Calculates one minimum spanning tree of an unweighted graph.
9
+ *
10
+ * If the graph has more minimum spanning trees (this is always the case,
11
+ * except if it is a forest) this implementation returns only the same one.
12
+ *
13
+ * Directed graphs are considered as undirected for this computation.
14
+ *
15
+ * If the graph is not connected then its minimum spanning forest is returned.
16
+ * This is the set of the minimum spanning trees of each component.
17
+ */
18
+ VALUE cIGraph_minimum_spanning_tree_unweighted(VALUE self){
19
+
20
+ igraph_t *graph;
21
+ igraph_t *n_graph = malloc(sizeof(igraph_t));
22
+ VALUE n_graph_obj;
23
+
24
+ Data_Get_Struct(self, igraph_t, graph);
25
+
26
+ igraph_minimum_spanning_tree_unweighted(graph,n_graph);
27
+
28
+ n_graph_obj = Data_Wrap_Struct(cIGraph, cIGraph_mark, cIGraph_free, n_graph);
29
+
30
+ return n_graph_obj;
31
+
32
+ }
33
+
34
+ /* call-seq:
35
+ * graph.minimum_spanning_tree_prim(weights) -> IGraph
36
+ *
37
+ * Calculates one minimum spanning tree of a weighted graph.
38
+ *
39
+ * This function uses Prim's method for carrying out the computation, see
40
+ * Prim, R.C.: Shortest connection networks and some generalizations, Bell
41
+ * System Technical Journal, Vol. 36, 1957, 1389--1401.
42
+ *
43
+ * If the graph has more than one minimum spanning tree, the current
44
+ * implementation returns always the same one.
45
+ *
46
+ * Directed graphs are considered as undirected for this computation.
47
+ *
48
+ * If the graph is not connected then its minimum spanning forest is returned.
49
+ * This is the set of the minimum spanning trees of each component.
50
+ *
51
+ * The weights Array must contain the weights of the the edges. in the same
52
+ * order as the simple edge iterator visits them.
53
+ */
54
+ VALUE cIGraph_minimum_spanning_tree_prim(VALUE self, VALUE weights){
55
+
56
+ igraph_t *graph;
57
+ igraph_t *n_graph = malloc(sizeof(igraph_t));
58
+ VALUE n_graph_obj;
59
+ igraph_vector_t weights_vec;
60
+ int i;
61
+
62
+ igraph_vector_init(&weights_vec,RARRAY(weights)->len);
63
+
64
+ Data_Get_Struct(self, igraph_t, graph);
65
+
66
+ for(i=0;i<RARRAY(weights)->len;i++){
67
+ VECTOR(weights_vec)[i] = NUM2DBL(RARRAY(weights)->ptr[i]);
68
+ }
69
+
70
+ igraph_minimum_spanning_tree_prim(graph,n_graph,&weights_vec);
71
+
72
+ n_graph_obj = Data_Wrap_Struct(cIGraph, cIGraph_mark, cIGraph_free, n_graph);
73
+
74
+ igraph_vector_destroy(&weights_vec);
75
+
76
+ return n_graph_obj;
77
+
78
+ }
@@ -0,0 +1,57 @@
1
+ #include "igraph.h"
2
+ #include "ruby.h"
3
+ #include "cIGraph.h"
4
+
5
+ /* call-seq:
6
+ * graph.laplacian(mode) -> Array
7
+ *
8
+ * Returns the Laplacian matrix of a graph
9
+ *
10
+ * The graph Laplacian matrix is similar to an adjacency matrix but
11
+ * contains -1's instead of 1's and the vertex degrees are included
12
+ * in the diagonal. So the result for edge i--j is -1 if i!=j and is
13
+ * equal to the degree of vertex i if i==j. igraph_laplacian will work
14
+ * on a directed graph (although this does not seem to make much sense)
15
+ * and ignores loops.
16
+ *
17
+ * Mode is a boolean specifying whether the normalized version should be used
18
+ * The normalised Laplacian matrix has 1 in the diagonal
19
+ * and -1/sqrt(d[i]d[j]) if there is an edge from i to j.
20
+ *
21
+ * The first version of this function was written by Vincent Matossian.
22
+ */
23
+ VALUE cIGraph_laplacian(VALUE self, VALUE mode){
24
+
25
+ igraph_t *graph;
26
+ igraph_bool_t pmode = 0;
27
+ igraph_matrix_t res;
28
+ int i;
29
+ int j;
30
+ VALUE row;
31
+ VALUE val;
32
+ VALUE matrix = rb_ary_new();
33
+
34
+ if(mode = Qtrue)
35
+ pmode = 1;
36
+
37
+ Data_Get_Struct(self, igraph_t, graph);
38
+
39
+ //matrix to hold the results of the calculations
40
+ igraph_matrix_init(&res,igraph_vcount(graph),igraph_vcount(graph));
41
+
42
+ IGRAPH_CHECK(igraph_laplacian(graph,&res,pmode));
43
+
44
+ for(i=0; i<igraph_matrix_nrow(&res); i++){
45
+ row = rb_ary_new();
46
+ rb_ary_push(matrix,row);
47
+ for(j=0; j<igraph_matrix_ncol(&res); j++){
48
+ val = rb_float_new(MATRIX(res,i,j));
49
+ rb_ary_push(row,val);
50
+ }
51
+ }
52
+
53
+ igraph_matrix_destroy(&res);
54
+
55
+ return matrix;
56
+
57
+ }
@@ -0,0 +1,97 @@
1
+ #include "igraph.h"
2
+ #include "ruby.h"
3
+ #include "cIGraph.h"
4
+
5
+ /* call-seq:
6
+ * graph.transitivity() -> Float
7
+ *
8
+ * Calculates the transitivity (clustering coefficient) of a graph.
9
+ *
10
+ * The transitivity measures the probability that two neighbors of a vertex
11
+ * are connected. More precisely this is the ratio of the triangles and
12
+ * connected triples in the graph, the result is a single real number or
13
+ * NaN (0/0) if there are no connected triples in the graph. Directed graphs
14
+ * are considered as undirected ones.
15
+ */
16
+ VALUE cIGraph_transitivity(VALUE self){
17
+
18
+ igraph_t *graph;
19
+ igraph_real_t res;
20
+
21
+ Data_Get_Struct(self, igraph_t, graph);
22
+
23
+ igraph_transitivity_undirected(graph,&res);
24
+
25
+ return rb_float_new(res);
26
+
27
+ }
28
+
29
+ /* call-seq:
30
+ * graph.transitivity() -> Float
31
+ *
32
+ * Calculates the transitivity (clustering coefficient) of a graph.
33
+ *
34
+ * The transitivity measures the probability that two neighbors of a vertex
35
+ * are connected. More precisely this is the ratio of the triangles and
36
+ * connected triples in the graph, the result is a single real number or
37
+ * NaN (0/0) if there are no connected triples in the graph. Directed graphs
38
+ * are considered as undirected ones.
39
+ */
40
+ VALUE cIGraph_transitivity_local(VALUE self, VALUE vs){
41
+
42
+ igraph_t *graph;
43
+ igraph_vs_t vids;
44
+ igraph_vector_t vidv;
45
+ igraph_vector_t res;
46
+ VALUE trans = rb_ary_new();
47
+ int i;
48
+
49
+ //vector to hold the results of the calculations
50
+ igraph_vector_init_int(&res,0);
51
+
52
+ //Convert an array of vertices to a vector of vertex ids
53
+ igraph_vector_init_int(&vidv,0);
54
+ cIGraph_vertex_arr_to_id_vec(self,vs,&vidv);
55
+ //create vertex selector from the vecotr of ids
56
+ igraph_vs_vector(&vids,&vidv);
57
+
58
+ Data_Get_Struct(self, igraph_t, graph);
59
+
60
+ igraph_transitivity_local_undirected(graph,&res,vids);
61
+
62
+ for(i=0;i<igraph_vector_size(&res);i++){
63
+ rb_ary_push(trans,rb_float_new(VECTOR(res)[i]));
64
+ }
65
+
66
+ igraph_vector_destroy(&vidv);
67
+ igraph_vector_destroy(&res);
68
+ igraph_vs_destroy(&vids);
69
+
70
+ return trans;
71
+
72
+ }
73
+
74
+ /* call-seq:
75
+ * graph.transitivity_avglocal() -> Float
76
+ *
77
+ * Calculates the transitivity (clustering coefficient) of a graph.
78
+ *
79
+ * The transitivity measures the probability that two neighbors of a vertex
80
+ * are connected. More precisely this is the ratio of the triangles and
81
+ * connected triples in the graph, the result is a single real number or
82
+ * NaN (0/0) if there are no connected triples in the graph. Directed graphs
83
+ * are considered as undirected ones.
84
+ */
85
+ VALUE cIGraph_transitivity_avglocal(VALUE self){
86
+
87
+ igraph_t *graph;
88
+ igraph_real_t res;
89
+
90
+ Data_Get_Struct(self, igraph_t, graph);
91
+
92
+ igraph_transitivity_avglocal_undirected(graph,&res);
93
+
94
+ return rb_float_new(res);
95
+
96
+ }
97
+
@@ -49,7 +49,7 @@ int cIGraph_vertex_arr_to_id_vec(VALUE graph, VALUE va, igraph_vector_t *nv){
49
49
  rb_raise(cIGraphError, "Array expected\n");
50
50
 
51
51
  //Initialize edge vector
52
- igraph_vector_init_int(nv,0);
52
+ //igraph_vector_init_int(nv,0);
53
53
  for (i=0; i<RARRAY(va)->len; i++) {
54
54
  vertex = RARRAY(va)->ptr[i];
55
55
  igraph_vector_push_back(nv,cIGraph_get_vertex_id(graph, vertex));
@@ -29,6 +29,7 @@ VALUE cIGraph_neighborhood_size(VALUE self, VALUE from, VALUE order, VALUE mode)
29
29
  igraph_vector_init(&res,0);
30
30
 
31
31
  //Convert an array of vertices to a vector of vertex ids
32
+ igraph_vector_init_int(&vidv,0);
32
33
  cIGraph_vertex_arr_to_id_vec(self,from,&vidv);
33
34
  //create vertex selector from the vecotr of ids
34
35
  igraph_vs_vector(&vids,&vidv);
@@ -74,14 +75,18 @@ VALUE cIGraph_neighborhood(VALUE self, VALUE from, VALUE order, VALUE mode){
74
75
 
75
76
  Data_Get_Struct(self, igraph_t, graph);
76
77
 
77
- igraph_vector_ptr_init(&res,0);
78
+ IGRAPH_FINALLY(igraph_vector_ptr_destroy,&res);
79
+ IGRAPH_CHECK(igraph_vector_ptr_init(&res,0));
78
80
 
79
81
  //Convert an array of vertices to a vector of vertex ids
82
+ IGRAPH_FINALLY(igraph_vector_destroy,&vidv);
83
+ igraph_vector_init_int(&vidv,0);
80
84
  cIGraph_vertex_arr_to_id_vec(self,from,&vidv);
81
85
  //create vertex selector from the vecotr of ids
82
- igraph_vs_vector(&vids,&vidv);
86
+ IGRAPH_FINALLY(igraph_vs_destroy,&vids);
87
+ IGRAPH_CHECK(igraph_vs_vector(&vids,&vidv));
83
88
 
84
- igraph_neighborhood(graph,&res,vids,NUM2INT(order),pmode);
89
+ IGRAPH_CHECK(igraph_neighborhood(graph,&res,vids,NUM2INT(order),pmode));
85
90
 
86
91
  for(i=0; i<igraph_vector_ptr_size(&res); i++){
87
92
  neighbourhood = rb_ary_new();
@@ -94,12 +99,15 @@ VALUE cIGraph_neighborhood(VALUE self, VALUE from, VALUE order, VALUE mode){
94
99
 
95
100
  for(i=0;i<igraph_vector_ptr_size(&res);i++){
96
101
  igraph_vector_destroy(VECTOR(res)[i]);
102
+ free(VECTOR(res)[i]);
97
103
  }
98
104
 
99
105
  igraph_vector_destroy(&vidv);
100
106
  igraph_vector_ptr_destroy(&res);
101
107
  igraph_vs_destroy(&vids);
102
108
 
109
+ IGRAPH_FINALLY_CLEAN(3);
110
+
103
111
  return matrix;
104
112
 
105
113
  }
@@ -133,6 +141,7 @@ VALUE cIGraph_neighborhood_graphs(VALUE self, VALUE from, VALUE order, VALUE mod
133
141
  igraph_vector_ptr_init(&res,0);
134
142
 
135
143
  //Convert an array of vertices to a vector of vertex ids
144
+ igraph_vector_init_int(&vidv,0);
136
145
  cIGraph_vertex_arr_to_id_vec(self,from,&vidv);
137
146
  //create vertex selector from the vecotr of ids
138
147
  igraph_vs_vector(&vids,&vidv);
data/test/tc_cores.rb ADDED
@@ -0,0 +1,10 @@
1
+ require 'test/unit'
2
+ require 'igraph'
3
+
4
+ class TestGraph < Test::Unit::TestCase
5
+ def test_coreness
6
+ g = IGraph.new(['A','B','C','D'],true)
7
+ c = g.coreness(IGraph::ALL)
8
+ assert_equal c.length, g.vcount
9
+ end
10
+ end
@@ -0,0 +1,31 @@
1
+ require 'test/unit'
2
+ require 'igraph'
3
+
4
+ class TestGraph < Test::Unit::TestCase
5
+ def test_directed_conv
6
+
7
+ g = IGraph.new(['A','B','B','C','C','D'],false)
8
+
9
+ g.to_directed(IGraph::ARBITRARY)
10
+ assert g.are_connected?('A','B') || g.are_connected?('B','A')
11
+ assert !(g.are_connected?('A','B') && g.are_connected?('B','A'))
12
+
13
+ g = IGraph.new(['A','B','B','C','C','D'],false)
14
+
15
+ g.to_directed(IGraph::MUTUAL)
16
+ assert g.are_connected?('A','B') && g.are_connected?('B','A')
17
+
18
+ end
19
+ def test_undirected
20
+ g = IGraph.new(['A','B','B','A','B','C','C','D'],true)
21
+
22
+ g.to_undirected(IGraph::EACH)
23
+ assert_equal 4, g.ecount
24
+
25
+ g = IGraph.new(['A','B','B','A','B','C','C','D'],true)
26
+
27
+ g.to_undirected(IGraph::COLLAPSE)
28
+ assert_equal 3, g.ecount
29
+
30
+ end
31
+ end
@@ -34,9 +34,9 @@ class TestGraph < Test::Unit::TestCase
34
34
  graph = IGraph.new(['A','B','A','C','B','D'],true)
35
35
  m = graph.diameter(true,true)
36
36
  assert_equal 3, m.length
37
- assert_raises IGraphError do
38
- graph.girth
39
- end
37
+ #assert_raises IGraphError do
38
+ # graph.girth
39
+ #end
40
40
  graph = IGraph.new(['A','B','A','C','B','D','C','D'],true)
41
41
  assert_equal 4, graph.girth.length
42
42
  end
@@ -0,0 +1,24 @@
1
+ require 'test/unit'
2
+ require 'igraph'
3
+
4
+ class TestGraph < Test::Unit::TestCase
5
+ def test_minimum_span_tree
6
+ g = IGraph.new(['A','B','B','C','C','D','A','D'],true)
7
+ st = g.minimum_spanning_tree_unweighted()
8
+ assert_kind_of IGraph, st
9
+ assert_equal ['A','B','C','D'], st.to_a.sort
10
+ end
11
+ def test_minimum_span_tree_prim
12
+ g = IGraph.new(['A','B','B','C','C','D','A','D'],true)
13
+ st = g.minimum_spanning_tree_prim([1,1,5,1])
14
+ assert_kind_of IGraph, st
15
+ assert_equal ['A','B','C','D'], st.to_a.sort
16
+ assert st.are_connected?('A','D')
17
+ assert !st.are_connected?('C','D')
18
+ st = g.minimum_spanning_tree_prim([1,1,1,5])
19
+ assert_kind_of IGraph, st
20
+ assert_equal ['A','B','C','D'], st.to_a.sort
21
+ assert !st.are_connected?('A','D')
22
+ assert st.are_connected?('C','D')
23
+ end
24
+ end
@@ -0,0 +1,12 @@
1
+ require 'test/unit'
2
+ require 'igraph'
3
+
4
+ class TestGraph < Test::Unit::TestCase
5
+ def test_laplacian
6
+ g = IGraph.new(['A','B','C','D'],false)
7
+ m = g.laplacian(false)
8
+ assert_equal m.length, g.vcount
9
+ m = g.laplacian(true)
10
+ assert_equal m.length, g.vcount
11
+ end
12
+ end
data/test/tc_thrash.rb ADDED
@@ -0,0 +1,41 @@
1
+ require 'test/unit'
2
+ require 'igraph'
3
+
4
+ class Array
5
+ def mean
6
+ total = 0.0
7
+ self.each do |i|
8
+ total += i
9
+ end
10
+ total / self.length.to_f
11
+ end
12
+ end
13
+
14
+ class TestGraph < Test::Unit::TestCase
15
+ def test_thrash
16
+ g = IGraph.new([],true)
17
+ v = 100
18
+ v.times do |x|
19
+ g.add_vertex(x)
20
+ end
21
+ 200.times do |x|
22
+ g.add_edge(rand(v/2),rand(v/2))
23
+ end
24
+ 200.times do |x|
25
+ g.add_edge(rand(v/2)+v/2,rand(v/2)+v/2)
26
+ end
27
+ assert_equal v, g.vcount
28
+ h,i = g.decompose(IGraph::WEAK,-1,2)
29
+
30
+ p h.vcount
31
+ p i.vcount
32
+
33
+ p h.degree(h.to_a[20..30],IGraph::ALL,false).mean
34
+ p h.degree(h.to_a[10..20],IGraph::ALL,false).mean
35
+
36
+ p h.betweenness(h.to_a[20..30],true).mean
37
+ p h.betweenness(h.to_a[10..20],true).mean
38
+
39
+ end
40
+ end
41
+
@@ -0,0 +1,17 @@
1
+ require 'test/unit'
2
+ require 'igraph'
3
+
4
+ class TestGraph < Test::Unit::TestCase
5
+ def test_trans
6
+ g = IGraph.new(['A','B','A','C','A','D','B','C'],true)
7
+ assert_equal 0.6, g.transitivity
8
+ end
9
+ def test_trans_local
10
+ g = IGraph.new(['A','B','A','C','A','D','B','C'],true)
11
+ assert_in_delta 0.33, g.transitivity_local(['A'])[0], 0.01
12
+ end
13
+ def test_trans_avr_local
14
+ g = IGraph.new(['A','B','A','C','A','D','B','C'],true)
15
+ assert_equal 0.6, g.transitivity
16
+ end
17
+ end
data/test/test_all.rb CHANGED
@@ -12,10 +12,15 @@ require 'tc_basic_properties'
12
12
  require 'tc_centrality'
13
13
  require 'tc_components'
14
14
  require 'tc_copy'
15
+ require 'tc_cores'
16
+ require 'tc_directedness'
15
17
  require 'tc_error_handling'
16
18
  require 'tc_file_read_write'
17
19
  require 'tc_layout'
18
20
  require 'tc_matrix'
19
21
  require 'tc_shortest_paths'
22
+ require 'tc_spanning'
23
+ require 'tc_spectral'
20
24
  require 'tc_topological_sort'
25
+ require 'tc_transitivity'
21
26
  require 'tc_vertex_neighbourhood'
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.2
3
3
  specification_version: 1
4
4
  name: igraph
5
5
  version: !ruby/object:Gem::Version
6
- version: "0.3"
7
- date: 2007-08-16 00:00:00 +09:00
6
+ version: 0.3.1
7
+ date: 2007-08-31 00:00:00 +09:00
8
8
  summary: IGraph is a Ruby extension for interfacing with the C igraph library (http://cneurocvs.rmki.kfki.hu/igraph/). igraph is a library for creating and manipulating graphs with a particular emphasis on network analysis functions.
9
9
  require_paths:
10
10
  - test
@@ -33,6 +33,7 @@ files:
33
33
  - License.txt
34
34
  - Manifest.txt
35
35
  - README.txt
36
+ - Rakefile.rb
36
37
  - ext/cIGraph.c
37
38
  - ext/cIGraph.h
38
39
  - ext/cIGraph_add_delete.c
@@ -41,17 +42,23 @@ files:
41
42
  - ext/cIGraph_basic_query.c
42
43
  - ext/cIGraph_centrality.c
43
44
  - ext/cIGraph_components.c
45
+ - ext/cIGraph_direction.c
44
46
  - ext/cIGraph_error_handlers.c
45
47
  - ext/cIGraph_file.c
46
48
  - ext/cIGraph_iterators.c
49
+ - ext/cIGraph_kcores.c
47
50
  - ext/cIGraph_layout.c
48
51
  - ext/cIGraph_matrix.c
49
52
  - ext/cIGraph_operators.c
50
53
  - ext/cIGraph_selectors.c
51
54
  - ext/cIGraph_shortest_paths.c
55
+ - ext/cIGraph_spanning.c
56
+ - ext/cIGraph_spectral.c
52
57
  - ext/cIGraph_topological_sort.c
58
+ - ext/cIGraph_transitivity.c
53
59
  - ext/cIGraph_utility.c
54
60
  - ext/cIGraph_vertex_neighbourhood.c
61
+ - ext/extconf.rb
55
62
  - test/tc_add_delete.rb
56
63
  - test/tc_attributes.rb
57
64
  - test/tc_basic_properties.rb
@@ -59,7 +66,9 @@ files:
59
66
  - test/tc_centrality.rb
60
67
  - test/tc_components.rb
61
68
  - test/tc_copy.rb
69
+ - test/tc_cores.rb
62
70
  - test/tc_create.rb
71
+ - test/tc_directedness.rb
63
72
  - test/tc_error_handling.rb
64
73
  - test/tc_file_read_write.rb
65
74
  - test/tc_iterators.rb
@@ -67,7 +76,11 @@ files:
67
76
  - test/tc_matrix.rb
68
77
  - test/tc_selectors.rb
69
78
  - test/tc_shortest_paths.rb
79
+ - test/tc_spanning.rb
80
+ - test/tc_spectral.rb
81
+ - test/tc_thrash.rb
70
82
  - test/tc_topological_sort.rb
83
+ - test/tc_transitivity.rb
71
84
  - test/tc_vertex_neighbourhood.rb
72
85
  - test/test_all.rb
73
86
  test_files: