igraph 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +3 -0
- data/License.txt +504 -0
- data/Manifest.txt +24 -0
- data/README.txt +47 -0
- data/ext/cIGraph.c +160 -0
- data/ext/cIGraph.h +60 -0
- data/ext/cIGraph_add_delete.c +219 -0
- data/ext/cIGraph_basic_properties.c +34 -0
- data/ext/cIGraph_basic_query.c +260 -0
- data/ext/cIGraph_error_handlers.c +13 -0
- data/ext/cIGraph_iterators.c +135 -0
- data/ext/cIGraph_operators.c +9 -0
- data/ext/cIGraph_selectors.c +93 -0
- data/ext/cIGraph_shortest_paths.c +112 -0
- data/ext/cIGraph_utility.c +56 -0
- data/ext/extconf.rb +12 -0
- data/test/tc_add_delete.rb +49 -0
- data/test/tc_basic_properties.rb +10 -0
- data/test/tc_basic_query.rb +54 -0
- data/test/tc_create.rb +11 -0
- data/test/tc_error_handling.rb +10 -0
- data/test/tc_iterators.rb +44 -0
- data/test/tc_selectors.rb +14 -0
- data/test/tc_shortest_paths.rb +21 -0
- data/test/test_all.rb +12 -0
- metadata +75 -0
@@ -0,0 +1,34 @@
|
|
1
|
+
#include "igraph.h"
|
2
|
+
#include "ruby.h"
|
3
|
+
#include "cIGraph.h"
|
4
|
+
|
5
|
+
/* call-seq:
|
6
|
+
* graph.are_connected?(from,to) -> true/false
|
7
|
+
*
|
8
|
+
* Returns a boolean specifying whether the two vertices specified are
|
9
|
+
* connected by an edge.
|
10
|
+
*
|
11
|
+
* Example:
|
12
|
+
*
|
13
|
+
* IGraph.new([1,2,3,4],true)
|
14
|
+
* graph.are_connected?(1,2) #returns true
|
15
|
+
*
|
16
|
+
*/
|
17
|
+
|
18
|
+
VALUE cIGraph_are_connected(VALUE self, VALUE from, VALUE to){
|
19
|
+
|
20
|
+
igraph_t *graph;
|
21
|
+
igraph_integer_t from_i;
|
22
|
+
igraph_integer_t to_i;
|
23
|
+
igraph_bool_t res;
|
24
|
+
|
25
|
+
Data_Get_Struct(self, igraph_t, graph);
|
26
|
+
|
27
|
+
from_i = cIGraph_get_vertex_id(self,from);
|
28
|
+
to_i = cIGraph_get_vertex_id(self,to);
|
29
|
+
|
30
|
+
igraph_are_connected(graph,from_i,to_i,&res);
|
31
|
+
|
32
|
+
return res ? Qtrue : Qfalse;
|
33
|
+
|
34
|
+
}
|
@@ -0,0 +1,260 @@
|
|
1
|
+
#include "igraph.h"
|
2
|
+
#include "ruby.h"
|
3
|
+
#include "cIGraph.h"
|
4
|
+
|
5
|
+
/* call-seq:
|
6
|
+
* graph.vcount() -> Fixnum
|
7
|
+
*
|
8
|
+
* Returns the number of vertices in the IGraph object.
|
9
|
+
*
|
10
|
+
* Example:
|
11
|
+
*
|
12
|
+
* g = IGraph.new([1,2,3,4],true)
|
13
|
+
* g.vcount # returns 4
|
14
|
+
*
|
15
|
+
*/
|
16
|
+
|
17
|
+
VALUE cIGraph_vcount(VALUE self){
|
18
|
+
igraph_t *graph;
|
19
|
+
|
20
|
+
Data_Get_Struct(self, igraph_t, graph);
|
21
|
+
return INT2NUM(igraph_vcount(graph));
|
22
|
+
}
|
23
|
+
|
24
|
+
/* call-seq:
|
25
|
+
* graph.ecount() -> Fixnum
|
26
|
+
*
|
27
|
+
* Returns the number of edges in the IGraph object.
|
28
|
+
*
|
29
|
+
* Example:
|
30
|
+
*
|
31
|
+
* g = IGraph.new([1,2,3,4],true)
|
32
|
+
* g.ecount # returns 2
|
33
|
+
*
|
34
|
+
*/
|
35
|
+
|
36
|
+
VALUE cIGraph_ecount(VALUE self){
|
37
|
+
igraph_t *graph;
|
38
|
+
|
39
|
+
Data_Get_Struct(self, igraph_t, graph);
|
40
|
+
return INT2NUM(igraph_ecount(graph));
|
41
|
+
}
|
42
|
+
|
43
|
+
/* call-seq:
|
44
|
+
* graph.edge(eid) -> [from,to]
|
45
|
+
*
|
46
|
+
* Returns an Array comprising the vertices making up the edge represented
|
47
|
+
* by the edge id eid. You can find the id of an edge using IGraph#get_eid.
|
48
|
+
*
|
49
|
+
* Example:
|
50
|
+
*
|
51
|
+
* g = IGraph.new([1,2,3,4],true)
|
52
|
+
* g.edge(1) # returns [1,2]
|
53
|
+
*
|
54
|
+
*/
|
55
|
+
|
56
|
+
VALUE cIGraph_edge(VALUE self, VALUE eid){
|
57
|
+
igraph_t *graph;
|
58
|
+
igraph_integer_t from = 0;
|
59
|
+
igraph_integer_t to = 0;
|
60
|
+
VALUE from_r;
|
61
|
+
VALUE to_r;
|
62
|
+
|
63
|
+
Data_Get_Struct(self, igraph_t, graph);
|
64
|
+
|
65
|
+
igraph_edge(graph,NUM2INT(eid),&from,&to);
|
66
|
+
|
67
|
+
from_r = cIGraph_get_vertex_object(self,from);
|
68
|
+
to_r = cIGraph_get_vertex_object(self,to);
|
69
|
+
|
70
|
+
return rb_ary_new3(2, from_r, to_r);
|
71
|
+
|
72
|
+
}
|
73
|
+
|
74
|
+
/* call-seq:
|
75
|
+
* graph.get_eid(from,to,directed) -> Fixnum
|
76
|
+
*
|
77
|
+
* Returns the edge id of the edge connecting the vertices from and to.
|
78
|
+
* directed is a boolean specifying whether to search for directed edges
|
79
|
+
* in a directed graph.
|
80
|
+
*
|
81
|
+
* Example:
|
82
|
+
*
|
83
|
+
* g = IGraph.new([1,2,3,4],true)
|
84
|
+
* g.get_eid(1,2,true) # returns 1
|
85
|
+
*
|
86
|
+
*/
|
87
|
+
VALUE cIGraph_get_eid(VALUE self, VALUE from, VALUE to, VALUE directed){
|
88
|
+
igraph_t *graph;
|
89
|
+
igraph_integer_t eid = 0;
|
90
|
+
int from_i;
|
91
|
+
int to_i;
|
92
|
+
igraph_bool_t directed_b = 0;
|
93
|
+
|
94
|
+
Data_Get_Struct(self, igraph_t, graph);
|
95
|
+
|
96
|
+
from_i = cIGraph_get_vertex_id(self,from);
|
97
|
+
to_i = cIGraph_get_vertex_id(self,to);
|
98
|
+
|
99
|
+
if(directed)
|
100
|
+
directed_b = 1;
|
101
|
+
|
102
|
+
igraph_get_eid(graph,&eid,from_i,to_i,directed_b);
|
103
|
+
|
104
|
+
return INT2NUM(eid);
|
105
|
+
|
106
|
+
}
|
107
|
+
|
108
|
+
/* call-seq:
|
109
|
+
* graph.neighbours(vertex,mode) -> Array
|
110
|
+
*
|
111
|
+
* Returns an Array of the neighbouring vertices to vertex. mode defines
|
112
|
+
* the way adjacent vertices are searched for directed graphs. It can have
|
113
|
+
* the following values: IGraph::OUT, vertices reachable by an edge from the
|
114
|
+
* specified vertex are searched, IGraph::IN, vertices from which the
|
115
|
+
* specified vertex is reachable are searched. IGraph::ALL, both kind of
|
116
|
+
* vertices are searched. This parameter is ignored for undirected graphs.
|
117
|
+
*
|
118
|
+
* Example:
|
119
|
+
*
|
120
|
+
* g = IGraph.new([1,2,3,4],true)
|
121
|
+
* g.neighbours(1,IGraph::ALL) # returns [2]
|
122
|
+
*
|
123
|
+
*/
|
124
|
+
VALUE cIGraph_neighbors(VALUE self, VALUE v, VALUE mode){
|
125
|
+
|
126
|
+
igraph_t *graph;
|
127
|
+
igraph_integer_t pnode;
|
128
|
+
igraph_neimode_t pmode = NUM2INT(mode);
|
129
|
+
igraph_vector_t neis;
|
130
|
+
int i;
|
131
|
+
VALUE neighbors = rb_ary_new();
|
132
|
+
|
133
|
+
igraph_vector_init_int(&neis,0);
|
134
|
+
|
135
|
+
Data_Get_Struct(self, igraph_t, graph);
|
136
|
+
|
137
|
+
pnode = cIGraph_get_vertex_id(self,v);
|
138
|
+
|
139
|
+
igraph_neighbors(graph,&neis,pnode,pmode);
|
140
|
+
|
141
|
+
for(i=0;i<igraph_vector_size(&neis);i++){
|
142
|
+
rb_ary_push(neighbors,cIGraph_get_vertex_object(self,VECTOR(neis)[i]));
|
143
|
+
}
|
144
|
+
|
145
|
+
igraph_vector_destroy(&neis);
|
146
|
+
|
147
|
+
return neighbors;
|
148
|
+
|
149
|
+
}
|
150
|
+
|
151
|
+
/* call-seq:
|
152
|
+
* graph.adjacent(vertex,mode) -> Array
|
153
|
+
*
|
154
|
+
* Returns an Array of the adjacent edge ids to vertex. mode defines
|
155
|
+
* the way adjacent edges are searched for directed graphs. It can have
|
156
|
+
* the following values: IGraph::OUT means only outgoing edges, IGraph::IN
|
157
|
+
* only incoming edges, IGraph::ALL both. This parameter is ignored for
|
158
|
+
* undirected graphs.
|
159
|
+
*
|
160
|
+
* Example:
|
161
|
+
*
|
162
|
+
* g = IGraph.new([1,2,3,4],true)
|
163
|
+
* g.adjacent(1,IGraph::ALL) # returns [1]
|
164
|
+
*
|
165
|
+
*/
|
166
|
+
VALUE cIGraph_adjacent(VALUE self, VALUE v, VALUE mode){
|
167
|
+
|
168
|
+
igraph_t *graph;
|
169
|
+
igraph_integer_t pnode;
|
170
|
+
igraph_neimode_t pmode = NUM2INT(mode);
|
171
|
+
igraph_vector_t eids;
|
172
|
+
int i;
|
173
|
+
VALUE eids_r = rb_ary_new();
|
174
|
+
|
175
|
+
igraph_vector_init_int(&eids,0);
|
176
|
+
|
177
|
+
Data_Get_Struct(self, igraph_t, graph);
|
178
|
+
|
179
|
+
pnode = cIGraph_get_vertex_id(self,v);
|
180
|
+
|
181
|
+
igraph_adjacent(graph,&eids,pnode,pmode);
|
182
|
+
|
183
|
+
for(i=0;i<igraph_vector_size(&eids);i++){
|
184
|
+
rb_ary_push(eids_r,INT2NUM(VECTOR(eids)[i]));
|
185
|
+
}
|
186
|
+
|
187
|
+
igraph_vector_destroy(&eids);
|
188
|
+
|
189
|
+
return eids_r;
|
190
|
+
|
191
|
+
}
|
192
|
+
|
193
|
+
/* call-seq:
|
194
|
+
* graph.is_directed?() -> true/false
|
195
|
+
*
|
196
|
+
* Returns a boolean specifying whether the graph is directed or not.
|
197
|
+
*
|
198
|
+
* Example:
|
199
|
+
*
|
200
|
+
* g = IGraph.new([1,2,3,4],true)
|
201
|
+
* g.is_directed? #returns true
|
202
|
+
*
|
203
|
+
*/
|
204
|
+
VALUE cIGraph_is_directed(VALUE self){
|
205
|
+
igraph_t *graph;
|
206
|
+
|
207
|
+
Data_Get_Struct(self, igraph_t, graph);
|
208
|
+
|
209
|
+
return igraph_is_directed(graph) ? Qtrue : Qfalse;
|
210
|
+
|
211
|
+
}
|
212
|
+
|
213
|
+
/* call-seq:
|
214
|
+
* graph.degree(vs,mode,loops) -> Array
|
215
|
+
*
|
216
|
+
* Returns an Array of Integers specifying the degree of each of the
|
217
|
+
* vertices specified in the vs Array. mode defines the type of the degree.
|
218
|
+
* IGraph::OUT, out-degree, IGraph::IN, in-degree, IGraph::ALL, total degree
|
219
|
+
* (sum of the in- and out-degree). This parameter is ignored for undirected
|
220
|
+
* graphs.
|
221
|
+
*
|
222
|
+
* Example:
|
223
|
+
*
|
224
|
+
* g = IGraph.new([1,2,3,4],true)
|
225
|
+
* g.is_directed? #returns true
|
226
|
+
*
|
227
|
+
*/
|
228
|
+
VALUE cIGraph_degree(VALUE self, VALUE v, VALUE mode, VALUE loops){
|
229
|
+
igraph_t *graph;
|
230
|
+
igraph_vs_t vids;
|
231
|
+
igraph_vector_t vidv;
|
232
|
+
igraph_neimode_t pmode = NUM2INT(mode);
|
233
|
+
igraph_bool_t loop_mode = loops ? 1 : 0;
|
234
|
+
igraph_vector_t res;
|
235
|
+
int i;
|
236
|
+
VALUE degree_r = rb_ary_new();
|
237
|
+
|
238
|
+
//vector to hold the results of the degree calculations
|
239
|
+
igraph_vector_init_int(&res,0);
|
240
|
+
|
241
|
+
Data_Get_Struct(self, igraph_t, graph);
|
242
|
+
|
243
|
+
//Convert an array of vertices to a vector of vertex ids
|
244
|
+
cIGraph_vertex_arr_to_id_vec(self,v,&vidv);
|
245
|
+
//create vertex selector from the vecotr of ids
|
246
|
+
igraph_vs_vector(&vids,&vidv);
|
247
|
+
|
248
|
+
igraph_degree(graph,&res,vids,pmode,loop_mode);
|
249
|
+
|
250
|
+
for(i=0;i<igraph_vector_size(&res);i++){
|
251
|
+
rb_ary_push(degree_r,INT2NUM(VECTOR(res)[i]));
|
252
|
+
}
|
253
|
+
|
254
|
+
igraph_vector_destroy(&vidv);
|
255
|
+
igraph_vector_destroy(&res);
|
256
|
+
igraph_vs_destroy(&vids);
|
257
|
+
|
258
|
+
return degree_r;
|
259
|
+
|
260
|
+
}
|
@@ -0,0 +1,13 @@
|
|
1
|
+
#include "igraph.h"
|
2
|
+
#include "ruby.h"
|
3
|
+
#include "cIGraph.h"
|
4
|
+
|
5
|
+
void cIGraph_error_handler(const char *reason, const char *file,
|
6
|
+
int line, int igraph_errno) {
|
7
|
+
rb_raise(cIGraphError, reason);
|
8
|
+
}
|
9
|
+
|
10
|
+
void cIGraph_warning_handler(const char *reason, const char *file,
|
11
|
+
int line, int igraph_errno) {
|
12
|
+
rb_warning(reason);
|
13
|
+
}
|
@@ -0,0 +1,135 @@
|
|
1
|
+
#include "igraph.h"
|
2
|
+
#include "ruby.h"
|
3
|
+
#include "cIGraph.h"
|
4
|
+
|
5
|
+
/* call-seq:
|
6
|
+
* graph.each_vertex{|v| } -> nil
|
7
|
+
*
|
8
|
+
* Iterates through all the vertices in the graph. Also accessible via
|
9
|
+
* IGraph#each which is used by Enumerable to provide other methods.
|
10
|
+
*
|
11
|
+
* Example:
|
12
|
+
*
|
13
|
+
* g = IGraph.new([1,2,3,4],true)
|
14
|
+
* g.each do |v|
|
15
|
+
* puts v
|
16
|
+
* end
|
17
|
+
* g.find_all{|v| v > 2} #returns [3,4]
|
18
|
+
*
|
19
|
+
*/
|
20
|
+
|
21
|
+
VALUE cIGraph_each_vertex(VALUE self){
|
22
|
+
|
23
|
+
igraph_t *graph;
|
24
|
+
igraph_vs_t vs;
|
25
|
+
igraph_vit_t vit;
|
26
|
+
|
27
|
+
Data_Get_Struct(self, igraph_t, graph);
|
28
|
+
|
29
|
+
igraph_vs_all(&vs);
|
30
|
+
igraph_vit_create(graph, vs, &vit);
|
31
|
+
|
32
|
+
while(!IGRAPH_VIT_END(vit)) {
|
33
|
+
rb_yield(cIGraph_get_vertex_object(self,IGRAPH_VIT_GET(vit)));
|
34
|
+
IGRAPH_VIT_NEXT(vit);
|
35
|
+
}
|
36
|
+
|
37
|
+
igraph_vit_destroy(&vit);
|
38
|
+
igraph_vs_destroy(&vs);
|
39
|
+
|
40
|
+
return Qnil;
|
41
|
+
|
42
|
+
}
|
43
|
+
/* call-seq:
|
44
|
+
* graph.each_edge(mode){|v,w| } -> nil
|
45
|
+
*
|
46
|
+
* Iterates through all the edges in the graph. mode specifies the order the
|
47
|
+
* edges are returned: IGRAPH_EDGEORDER_ID, edge id order.
|
48
|
+
* IGRAPH_EDGEORDER_FROM, vertex id order, the id of the source vertex
|
49
|
+
* counts for directed graphs. The order of the adjacent edges of a given
|
50
|
+
* vertex is arbitrary. IGRAPH_EDGEORDER_TO, vertex id order, the id of the
|
51
|
+
* target vertex counts for directed graphs. The order of the adjacent edges
|
52
|
+
* of a given vertex is arbitrary. For undirected graph the latter two are
|
53
|
+
* the same.
|
54
|
+
*
|
55
|
+
* Example:
|
56
|
+
*
|
57
|
+
* g = IGraph.new([1,2,3,4],true)
|
58
|
+
* g.each_edge(IGraph::EDGORDER_ID) do |v,w|
|
59
|
+
* puts "#{v} -> #{w}"
|
60
|
+
* end
|
61
|
+
*
|
62
|
+
*/
|
63
|
+
VALUE cIGraph_each_edge(VALUE self, VALUE order){
|
64
|
+
|
65
|
+
igraph_t *graph;
|
66
|
+
igraph_es_t es;
|
67
|
+
igraph_eit_t eit;
|
68
|
+
igraph_edgeorder_type_t order_t = NUM2INT(order);
|
69
|
+
|
70
|
+
igraph_integer_t from;
|
71
|
+
igraph_integer_t to;
|
72
|
+
|
73
|
+
Data_Get_Struct(self, igraph_t, graph);
|
74
|
+
|
75
|
+
igraph_es_all(&es,order_t);
|
76
|
+
igraph_eit_create(graph, es, &eit);
|
77
|
+
|
78
|
+
while(!IGRAPH_EIT_END(eit)) {
|
79
|
+
igraph_edge(graph,IGRAPH_EIT_GET(eit),&from,&to);
|
80
|
+
rb_yield(rb_ary_new3(2,
|
81
|
+
cIGraph_get_vertex_object(self, from),
|
82
|
+
cIGraph_get_vertex_object(self, to)));
|
83
|
+
IGRAPH_EIT_NEXT(eit);
|
84
|
+
}
|
85
|
+
|
86
|
+
igraph_eit_destroy(&eit);
|
87
|
+
igraph_es_destroy(&es);
|
88
|
+
|
89
|
+
return Qnil;
|
90
|
+
|
91
|
+
}
|
92
|
+
|
93
|
+
/* call-seq:
|
94
|
+
* graph.each_edge_eid(mode){|id| } -> nil
|
95
|
+
*
|
96
|
+
* Iterates through all the edges in the graph. mode specifies the order the
|
97
|
+
* edges are returned: IGRAPH_EDGEORDER_ID, edge id order.
|
98
|
+
* IGRAPH_EDGEORDER_FROM, vertex id order, the id of the source vertex
|
99
|
+
* counts for directed graphs. The order of the adjacent edges of a given
|
100
|
+
* vertex is arbitrary. IGRAPH_EDGEORDER_TO, vertex id order, the id of the
|
101
|
+
* target vertex counts for directed graphs. The order of the adjacent edges
|
102
|
+
* of a given vertex is arbitrary. For undirected graph the latter two are
|
103
|
+
* the same.
|
104
|
+
*
|
105
|
+
* Example:
|
106
|
+
*
|
107
|
+
* g = IGraph.new([1,2,3,4],true)
|
108
|
+
* g.each_edge(IGraph::EDGORDER_ID) do |id|
|
109
|
+
* puts id
|
110
|
+
* end
|
111
|
+
*
|
112
|
+
*/
|
113
|
+
VALUE cIGraph_each_edge_eid(VALUE self, VALUE order){
|
114
|
+
|
115
|
+
igraph_t *graph;
|
116
|
+
igraph_es_t es;
|
117
|
+
igraph_eit_t eit;
|
118
|
+
igraph_edgeorder_type_t order_t = NUM2INT(order);
|
119
|
+
|
120
|
+
Data_Get_Struct(self, igraph_t, graph);
|
121
|
+
|
122
|
+
igraph_es_all(&es,order_t);
|
123
|
+
igraph_eit_create(graph, es, &eit);
|
124
|
+
|
125
|
+
while(!IGRAPH_EIT_END(eit)) {
|
126
|
+
rb_yield(INT2NUM(IGRAPH_EIT_GET(eit)));
|
127
|
+
IGRAPH_EIT_NEXT(eit);
|
128
|
+
}
|
129
|
+
|
130
|
+
igraph_eit_destroy(&eit);
|
131
|
+
igraph_es_destroy(&es);
|
132
|
+
|
133
|
+
return Qnil;
|
134
|
+
|
135
|
+
}
|