igraph 0.1.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/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
|
+
}
|