igraph 0.3 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: