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 +13 -0
- data/Rakefile.rb +52 -0
- data/ext/cIGraph.c +37 -11
- data/ext/cIGraph.h +19 -0
- data/ext/cIGraph_add_delete.c +35 -19
- data/ext/cIGraph_attribute_handler.c +3 -2
- data/ext/cIGraph_basic_query.c +4 -2
- data/ext/cIGraph_centrality.c +26 -15
- data/ext/cIGraph_components.c +1 -0
- data/ext/cIGraph_direction.c +39 -0
- data/ext/cIGraph_error_handlers.c +1 -0
- data/ext/cIGraph_file.c +1 -1
- data/ext/cIGraph_kcores.c +39 -0
- data/ext/cIGraph_shortest_paths.c +18 -5
- data/ext/cIGraph_spanning.c +78 -0
- data/ext/cIGraph_spectral.c +57 -0
- data/ext/cIGraph_transitivity.c +97 -0
- data/ext/cIGraph_utility.c +1 -1
- data/ext/cIGraph_vertex_neighbourhood.c +12 -3
- data/test/tc_cores.rb +10 -0
- data/test/tc_directedness.rb +31 -0
- data/test/tc_shortest_paths.rb +3 -3
- data/test/tc_spanning.rb +24 -0
- data/test/tc_spectral.rb +12 -0
- data/test/tc_thrash.rb +41 -0
- data/test/tc_transitivity.rb +17 -0
- data/test/test_all.rb +5 -0
- metadata +15 -2
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
|
-
|
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
|
-
|
109
|
-
|
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
|
|
data/ext/cIGraph_add_delete.c
CHANGED
@@ -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
|
-
|
44
|
-
|
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
|
-
|
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
|
-
|
176
|
-
|
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
|
-
|
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 =
|
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
|
-
|
135
|
+
VALUE *attrs = (VALUE*)graph->attr;
|
136
|
+
free(attrs);
|
136
137
|
return;
|
137
138
|
}
|
138
139
|
|
data/ext/cIGraph_basic_query.c
CHANGED
@@ -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);
|
data/ext/cIGraph_centrality.c
CHANGED
@@ -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
|
-
|
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,
|
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
|
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
|
-
|
191
|
-
|
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
|
-
|
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
|
-
|
218
|
-
igraph_vector_destroy(wght);
|
228
|
+
igraph_vector_destroy(&wght);
|
219
229
|
igraph_vs_destroy(&vids);
|
220
230
|
|
221
|
-
|
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);
|
data/ext/cIGraph_components.c
CHANGED
@@ -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
|
+
}
|
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
|
-
|
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
|
-
|
304
|
+
IGRAPH_FINALLY(igraph_vector_destroy,&res);
|
305
|
+
IGRAPH_CHECK(igraph_vector_init(&res,0));
|
295
306
|
|
296
|
-
igraph_girth(graph
|
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
|
+
|
data/ext/cIGraph_utility.c
CHANGED
@@ -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
|
-
|
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
|
-
|
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,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
|
data/test/tc_shortest_paths.rb
CHANGED
@@ -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
|
-
|
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
|
data/test/tc_spanning.rb
ADDED
@@ -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
|
data/test/tc_spectral.rb
ADDED
@@ -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:
|
7
|
-
date: 2007-08-
|
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:
|