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 +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:
|