igraph 0.1.1 → 0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,15 @@
1
- = 0.1 2007-06-29
1
+ = 0.3 2007-08-16
2
2
 
3
- * First version
3
+ * Over-hauled attribute code
4
+ * Some file read/write support
5
+
6
+ = 0.2 2007-07-31
7
+
8
+ * First public (announced) release
9
+ * Updated functions and documentation
10
+
11
+ = 0.1 2007-07-16
12
+
13
+ * First private release
14
+ * Graph generation and manipulation functions implemented
15
+ * Selection of basic querying functions implemented
@@ -5,20 +5,37 @@ README.txt
5
5
  ext/cIGraph.c
6
6
  ext/cIGraph.h
7
7
  ext/cIGraph_add_delete.c
8
+ ext/cIGraph_attribute_handler.c
8
9
  ext/cIGraph_basic_properties.c
9
10
  ext/cIGraph_basic_query.c
11
+ ext/cIGraph_centrality.c
12
+ ext/cIGraph_components.c
10
13
  ext/cIGraph_error_handlers.c
14
+ ext/cIGraph_file.c
11
15
  ext/cIGraph_iterators.c
16
+ ext/cIGraph_layout.c
17
+ ext/cIGraph_matrix.c
12
18
  ext/cIGraph_operators.c
13
19
  ext/cIGraph_selectors.c
14
20
  ext/cIGraph_shortest_paths.c
21
+ ext/cIGraph_topological_sort.c
15
22
  ext/cIGraph_utility.c
23
+ ext/cIGraph_vertex_neighbourhood.c
16
24
  test/tc_add_delete.rb
25
+ test/tc_attributes.rb
17
26
  test/tc_basic_properties.rb
18
27
  test/tc_basic_query.rb
28
+ test/tc_centrality.rb
29
+ test/tc_components.rb
30
+ test/tc_copy.rb
19
31
  test/tc_create.rb
20
32
  test/tc_error_handling.rb
33
+ test/tc_file_read_write.rb
21
34
  test/tc_iterators.rb
35
+ test/tc_layout.rb
36
+ test/tc_matrix.rb
22
37
  test/tc_selectors.rb
23
38
  test/tc_shortest_paths.rb
39
+ test/tc_topological_sort.rb
40
+ test/tc_vertex_neighbourhood.rb
24
41
  test/test_all.rb
data/README.txt CHANGED
@@ -1,33 +1,38 @@
1
1
  == Introduction
2
2
 
3
- IGraph
3
+ 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.
4
4
 
5
- IGraph
5
+ IGraph is currently in alpha status and although the basic graph creation and manipulation functions are implemented the API should be considered subject to change. The main documentation can be found at http://igraph.rubyforge.org/igraph/.
6
6
 
7
- IGraph
7
+ All bug reports, feature requests and patches are welcome. Please email alexg (at) kuicr.kyoto-u.ac.jp or use the rubyforge forums: http://rubyforge.org/forum/?group_id=3943
8
8
 
9
9
  == Installation
10
10
 
11
- A working igraph library installation is required.
11
+ A working igraph library installation is required. Please see the igraph homepage (http://cneurocvs.rmki.kfki.hu/igraph/) for details on installing igraph.
12
12
 
13
- An IGraph gem is available as well as a package using setup.rb. In each case the installation requires the location of your igraph library to compile the extension. If you download the setup.rb package use these incantations:
13
+ IGraph is only available as a gem. The installation requires the location of your igraph headers and library to compile the extension. For example, under Ubuntu linux the following command succesfully compiles and installs (you may need to be root):
14
14
 
15
- ruby setup.rb config -- --with-igraph-dir=$R_HOME
16
- ruby setup.rb setup
17
- ruby setup.rb install
15
+ gem install igraph -- --with-igraph-include=/usr/local/include/igraph
18
16
 
19
- Using gems it is almost the same:
17
+ == Documentation
20
18
 
21
- gem install igraph -- --with-igraph-dir=$R_HOME
19
+ Graph objects are represented in the IGraph class. See the IGraph class documentation for a list of available methods available to build and query graph objects. Any object can be used as a vertex and any edge can be annotated with any kind of object.
22
20
 
23
- == Documentation
21
+ Note that many functions require 'mode' constants to tell igraph how you want certain calculations to be made. The constants are listed under the IGraph documentation and should also be made explicit in each methods documentation.
24
22
 
25
23
  Here is a very quick and simple example:
26
24
 
27
25
  require 'igraph'
28
26
 
27
+ #Create an empty directed graph
29
28
  graph = IGraph.new([],true)
30
29
 
30
+ #Add two edges (unannotated)
31
+ graph.add_edges([1,2,3,4])
32
+
33
+ #Count the number of vertices
34
+ graph.vcount # returns 4
35
+
31
36
  == License
32
37
 
33
38
  Copyright (C) 2006 Alex Gutteridge
@@ -2,22 +2,58 @@
2
2
  #include "ruby.h"
3
3
  #include "cIGraph.h"
4
4
 
5
+ //Classes
6
+ VALUE cIGraph;
7
+ VALUE cIGraphError;
8
+
5
9
  void cIGraph_free(void *p){
6
10
  igraph_destroy(p);
7
11
  }
8
12
 
13
+ void cIGraph_mark(void *p){
14
+ rb_gc_mark(((VALUE*)((igraph_t*)p)->attr)[0]);
15
+ rb_gc_mark(((VALUE*)((igraph_t*)p)->attr)[1]);
16
+ rb_gc_mark(((VALUE*)((igraph_t*)p)->attr)[2]);
17
+ }
18
+
9
19
  VALUE cIGraph_alloc(VALUE klass){
10
20
 
11
21
  igraph_t *graph = malloc(sizeof(igraph_t));
12
22
  VALUE obj;
13
23
 
14
24
  igraph_empty(graph, 0, 1);
15
- obj = Data_Wrap_Struct(klass, 0, cIGraph_free, graph);
25
+
26
+ obj = Data_Wrap_Struct(klass, cIGraph_mark, cIGraph_free, graph);
16
27
 
17
28
  return obj;
18
29
 
19
30
  }
20
31
 
32
+ /* Document-method: initialize_copy
33
+ *
34
+ * Internal method for copying IGraph objects.
35
+ */
36
+ VALUE cIGraph_init_copy(VALUE copy, VALUE orig){
37
+
38
+ igraph_t *orig_graph;
39
+ igraph_t *copy_graph;
40
+
41
+ if (copy == orig)
42
+ return copy;
43
+
44
+ if(TYPE(orig) != T_DATA || RDATA(orig)->dfree != (RUBY_DATA_FUNC)cIGraph_free){
45
+ rb_raise(rb_eTypeError, "Wrong argument type.");
46
+ }
47
+
48
+ Data_Get_Struct(copy, igraph_t, copy_graph);
49
+ Data_Get_Struct(orig, igraph_t, orig_graph);
50
+
51
+ igraph_copy(copy_graph,orig_graph);
52
+
53
+ return copy;
54
+
55
+ }
56
+
21
57
  /* call-seq:
22
58
  * IGraph.new(edges,directed) -> IGraph
23
59
  *
@@ -38,53 +74,84 @@ VALUE cIGraph_alloc(VALUE klass){
38
74
  * Vertex 3 is connected to vertex 4.
39
75
  */
40
76
 
41
- VALUE cIGraph_initialize(VALUE self, VALUE edges, VALUE directed){
77
+ VALUE cIGraph_initialize(int argc, VALUE *argv, VALUE self){
42
78
 
43
79
  igraph_t *graph;
44
80
  igraph_vector_t edge_v;
45
81
  VALUE vertex;
46
- VALUE object_h;
47
- VALUE id_h;
82
+ VALUE directed;
83
+ VALUE edges;
84
+ VALUE attrs;
85
+ VALUE v_ary;
48
86
  int vertex_n = 0;
49
87
  int current_vertex_id;
88
+ int i;
50
89
 
51
- igraph_set_error_handler(cIGraph_error_handler);
52
- igraph_set_warning_handler(cIGraph_warning_handler);
90
+ igraph_vector_ptr_t vertex_attr;
91
+ igraph_vector_ptr_t edge_attr;
92
+
93
+ igraph_i_attribute_record_t v_attr_rec;
94
+ v_attr_rec.name = "__RUBY__";
95
+ v_attr_rec.type = IGRAPH_ATTRIBUTE_PY_OBJECT;
96
+ v_attr_rec.value = (void*)rb_ary_new();
97
+
98
+ igraph_i_attribute_record_t e_attr_rec;
99
+ e_attr_rec.name = "__RUBY__";
100
+ e_attr_rec.type = IGRAPH_ATTRIBUTE_PY_OBJECT;
101
+ e_attr_rec.value = (void*)rb_ary_new();
53
102
 
54
- //New hash for mapping vertex objects to floats used by iGraph
55
- object_h = rb_iv_set(self,"@object_ids",rb_hash_new());
56
- id_h = rb_iv_set(self,"@id_objects",rb_hash_new());
103
+ rb_scan_args(argc,argv,"12", &edges, &directed, &attrs);
57
104
 
58
105
  //Initialize edge vector
59
106
  igraph_vector_init_int(&edge_v,0);
60
107
 
108
+ igraph_vector_ptr_init(&vertex_attr,0);
109
+ igraph_vector_ptr_init(&edge_attr,0);
110
+
61
111
  Data_Get_Struct(self, igraph_t, graph);
112
+
113
+ v_ary = rb_ary_new();
114
+
62
115
  if(!directed)
63
116
  igraph_to_undirected(graph,IGRAPH_TO_UNDIRECTED_COLLAPSE);
64
117
 
65
118
  //Loop through objects in edge Array
66
- vertex = rb_ary_shift(edges);
67
- while(vertex != Qnil){
68
- if(rb_funcall(object_h,rb_intern("has_key?"),1,vertex)){
119
+ for (i=0; i<RARRAY(edges)->len; i++) {
120
+ vertex = RARRAY(edges)->ptr[i];
121
+ if(rb_ary_includes(v_ary,vertex)){
69
122
  //If @vertices includes this vertex then look up the vertex number
70
- current_vertex_id = NUM2INT(rb_hash_aref(object_h,vertex));
123
+ current_vertex_id = NUM2INT(rb_funcall(v_ary,rb_intern("index"),1,vertex));
71
124
  } else {
72
- //otherwise add a new entry to Hash
73
- rb_hash_aset(object_h,vertex,INT2NUM(vertex_n));
74
- rb_hash_aset(id_h, INT2NUM(vertex_n),vertex);
125
+ //Otherwise add to the list of vertices
126
+ rb_ary_push(v_ary,vertex);
75
127
  current_vertex_id = vertex_n;
76
128
  vertex_n++;
129
+
130
+ //Add object to list of vertex attributes
131
+ rb_ary_push((VALUE)v_attr_rec.value,vertex);
132
+
77
133
  }
78
134
  igraph_vector_push_back(&edge_v,current_vertex_id);
79
- vertex = rb_ary_shift(edges);
135
+ if (i % 2){
136
+ if (attrs != Qnil){
137
+ rb_ary_push((VALUE)e_attr_rec.value,RARRAY(attrs)->ptr[i/2]);
138
+ } else {
139
+ rb_ary_push((VALUE)e_attr_rec.value,Qnil);
140
+ }
141
+ }
80
142
  }
81
143
 
144
+ igraph_vector_ptr_push_back(&vertex_attr, &v_attr_rec);
145
+ igraph_vector_ptr_push_back(&edge_attr, &e_attr_rec);
146
+
82
147
  if(igraph_vector_size(&edge_v) > 0){
83
- igraph_add_vertices(graph,vertex_n,0);
84
- igraph_add_edges(graph,&edge_v,0);
148
+ igraph_add_vertices(graph,vertex_n,&vertex_attr);
149
+ igraph_add_edges(graph,&edge_v,&edge_attr);
85
150
  }
86
151
 
87
152
  igraph_vector_destroy(&edge_v);
153
+ igraph_vector_ptr_destroy(&vertex_attr);
154
+ igraph_vector_ptr_destroy(&edge_attr);
88
155
 
89
156
  return self;
90
157
 
@@ -96,65 +163,134 @@ VALUE cIGraph_initialize(VALUE self, VALUE edges, VALUE directed){
96
163
  */
97
164
 
98
165
  void Init_igraph(){
99
- cIGraph = rb_define_class("IGraph", rb_cObject);
166
+
167
+ igraph_i_set_attribute_table(&cIGraph_attribute_table);
168
+ igraph_set_error_handler(cIGraph_error_handler);
169
+ igraph_set_warning_handler(cIGraph_warning_handler);
170
+
171
+ cIGraph = rb_define_class("IGraph", rb_cObject);
100
172
  cIGraphError = rb_define_class("IGraphError", rb_eRuntimeError);
101
173
 
102
174
  rb_define_alloc_func(cIGraph, cIGraph_alloc);
103
- rb_define_method(cIGraph, "initialize", cIGraph_initialize, 2);
175
+ rb_define_method(cIGraph, "initialize", cIGraph_initialize, -1);
176
+ rb_define_method(cIGraph, "initialize_copy", cIGraph_init_copy, 1);
104
177
 
105
- rb_define_method(cIGraph, "each_vertex", cIGraph_each_vertex, 0); /* in cIGraph_iterators.c */
106
- rb_define_method(cIGraph, "each_edge", cIGraph_each_edge, 1); /* in cIGraph_iterators.c */
107
- rb_define_method(cIGraph, "each_edge_eid", cIGraph_each_edge_eid,1); /* in cIGraph_iterators.c */
178
+ rb_include_module(cIGraph, rb_mEnumerable);
179
+
180
+ rb_define_const(cIGraph, "VERSION", rb_str_new2("0.3"));
108
181
 
109
182
  rb_define_const(cIGraph, "EDGEORDER_ID", INT2NUM(1));
110
183
  rb_define_const(cIGraph, "EDGEORDER_FROM", INT2NUM(2));
111
184
  rb_define_const(cIGraph, "EDGEORDER_TO", INT2NUM(3));
112
185
 
113
- rb_define_method(cIGraph, "each", cIGraph_each_vertex, 0);
114
- rb_include_module(cIGraph, rb_mEnumerable);
115
-
116
- rb_define_method(cIGraph, "include?", cIGraph_include, 1);
117
-
118
- rb_define_method(cIGraph, "all_vertices", cIGraph_all_v, 0);
119
- rb_define_method(cIGraph, "vertices", cIGraph_all_v, 0); /* in cIGraph_selectors.c */
120
- rb_define_method(cIGraph, "adjacent_vertices", cIGraph_adj_v, 2); /* in cIGraph_selectors.c */
121
- rb_define_method(cIGraph, "nonadjacent_vertices", cIGraph_nonadj_v, 2); /* in cIGraph_selectors.c */
122
-
123
- rb_define_method(cIGraph, "all_edges", cIGraph_all_e, 1);
124
- rb_define_method(cIGraph, "edges", cIGraph_all_e, 1);
125
- rb_define_method(cIGraph, "adjacent_edges", cIGraph_adj_e, 2);
126
- rb_define_method(cIGraph, "nonadjacent_edges", cIGraph_nonadj_e, 2);
127
-
128
- rb_define_method(cIGraph, "vcount", cIGraph_vcount, 0); /* in cIGraph_basic_query.c */
129
- rb_define_method(cIGraph, "ecount", cIGraph_ecount, 0); /* in cIGraph_basic_query.c */
130
-
131
- rb_define_method(cIGraph, "edge", cIGraph_edge, 1); /* in cIGraph_basic_query.c */
132
- rb_define_method(cIGraph, "get_eid", cIGraph_get_eid, 2); /* in cIGraph_basic_query.c */
133
-
134
- rb_define_method(cIGraph, "neighbors", cIGraph_neighbors,2);
135
- rb_define_method(cIGraph, "neighbours", cIGraph_neighbors,2); /* in cIGraph_basic_query.c */
136
- rb_define_method(cIGraph, "adjacent", cIGraph_adjacent,2); /* in cIGraph_basic_query.c */
137
-
138
186
  rb_define_const(cIGraph, "OUT", INT2NUM(1));
139
187
  rb_define_const(cIGraph, "IN", INT2NUM(2));
140
188
  rb_define_const(cIGraph, "ALL", INT2NUM(3));
141
189
  rb_define_const(cIGraph, "TOTAL", INT2NUM(4));
142
-
143
- rb_define_method(cIGraph, "is_directed", cIGraph_is_directed,0);
144
- rb_define_method(cIGraph, "is_directed?", cIGraph_is_directed,0); /* in cIGraph_basic_query.c */
145
190
 
146
- rb_define_method(cIGraph, "degree", cIGraph_degree,3); /* in cIGraph_basic_query.c */
191
+ rb_define_const(cIGraph, "WEAK", INT2NUM(1));
192
+ rb_define_const(cIGraph, "STRONG", INT2NUM(2));
147
193
 
148
- rb_define_method(cIGraph, "add_edges", cIGraph_add_edges, 1); /* in cIGraph_add_delete.c */
149
- rb_define_method(cIGraph, "add_vertices", cIGraph_add_vertices, 1); /* in cIGraph_add_delete.c */
194
+ rb_define_method(cIGraph, "[]", cIGraph_get_edge_attr, 2); /* in cIGraph_attribute_handler.c */
195
+ rb_define_method(cIGraph, "[]=", cIGraph_set_edge_attr, 3); /* in cIGraph_attribute_handler.c */
196
+ rb_define_alias (cIGraph, "get_edge_attr", "[]");
197
+ rb_define_alias (cIGraph, "set_edge_attr", "[]=");
150
198
 
151
- rb_define_method(cIGraph, "add_edge", cIGraph_add_edge, 2); /* in cIGraph_add_delete.c */
152
- rb_define_method(cIGraph, "add_vertex", cIGraph_add_vertex, 1); /* in cIGraph_add_delete.c */
199
+ rb_define_method(cIGraph, "attributes", cIGraph_graph_attributes, 0); /* in cIGraph_attribute_handler.c */
153
200
 
154
- rb_define_method(cIGraph, "are_connected", cIGraph_are_connected,2);
155
- rb_define_method(cIGraph, "are_connected?", cIGraph_are_connected,2); /* in cIGraph_basic_properties.c */
201
+ rb_define_method(cIGraph, "each_vertex", cIGraph_each_vertex, 0); /* in cIGraph_iterators.c */
202
+ rb_define_method(cIGraph, "each_edge", cIGraph_each_edge, 1); /* in cIGraph_iterators.c */
203
+ rb_define_method(cIGraph, "each_edge_eid", cIGraph_each_edge_eid,1); /* in cIGraph_iterators.c */
204
+ rb_define_alias (cIGraph, "each", "each_vertex");
156
205
 
157
- rb_define_method(cIGraph, "shortest_paths", cIGraph_shortest_paths,2);
158
- rb_define_method(cIGraph, "get_shortest_paths", cIGraph_get_shortest_paths,3);
206
+ rb_define_method(cIGraph, "vertices", cIGraph_all_v, 0); /* in cIGraph_selectors.c */
207
+ rb_define_method(cIGraph, "adjacent_vertices", cIGraph_adj_v, 2); /* in cIGraph_selectors.c */
208
+ rb_define_method(cIGraph, "nonadjacent_vertices", cIGraph_nonadj_v, 2); /* in cIGraph_selectors.c */
209
+ rb_define_alias (cIGraph, "all_vertices", "vertices");
210
+
211
+ rb_define_method(cIGraph, "edges", cIGraph_all_e, 1); /* in cIGraph_selectors.c */
212
+ rb_define_method(cIGraph, "adjacent_edges", cIGraph_adj_e, 2); /* in cIGraph_selectors.c */
213
+ rb_define_alias (cIGraph, "all_edges", "edges");
214
+
215
+ rb_define_method(cIGraph, "vcount", cIGraph_vcount, 0); /* in cIGraph_basic_query.c */
216
+ rb_define_method(cIGraph, "ecount", cIGraph_ecount, 0); /* in cIGraph_basic_query.c */
217
+ rb_define_method(cIGraph, "edge", cIGraph_edge, 1); /* in cIGraph_basic_query.c */
218
+ rb_define_method(cIGraph, "get_eid", cIGraph_get_eid, 2); /* in cIGraph_basic_query.c */
219
+ rb_define_method(cIGraph, "neighbours", cIGraph_neighbors, 2); /* in cIGraph_basic_query.c */
220
+ rb_define_method(cIGraph, "adjacent", cIGraph_adjacent, 2); /* in cIGraph_basic_query.c */
221
+ rb_define_method(cIGraph, "degree", cIGraph_degree, 3); /* in cIGraph_basic_query.c */
222
+ rb_define_method(cIGraph, "is_directed?", cIGraph_is_directed, 0); /* in cIGraph_basic_query.c */
223
+ rb_define_alias (cIGraph, "is_directed", "is_directed?");
224
+ rb_define_alias (cIGraph, "neighbors", "neighbours");
225
+
226
+ rb_define_method(cIGraph, "add_edges", cIGraph_add_edges, -1); /* in cIGraph_add_delete.c */
227
+ rb_define_method(cIGraph, "add_vertices", cIGraph_add_vertices, 1); /* in cIGraph_add_delete.c */
228
+ rb_define_method(cIGraph, "add_edge", cIGraph_add_edge, -1); /* in cIGraph_add_delete.c */
229
+ rb_define_method(cIGraph, "add_vertex", cIGraph_add_vertex, 1); /* in cIGraph_add_delete.c */
230
+ rb_define_method(cIGraph, "delete_edge", cIGraph_delete_edge, 2); /* in cIGraph_add_delete.c */
231
+ rb_define_method(cIGraph, "delete_vertex", cIGraph_delete_vertex, 1); /* in cIGraph_add_delete.c */
232
+
233
+ rb_define_method(cIGraph, "are_connected", cIGraph_are_connected,2); /* in cIGraph_basic_properties.c */
234
+ rb_define_alias (cIGraph, "are_connected?", "are_connected");
235
+
236
+ rb_define_method(cIGraph, "shortest_paths", cIGraph_shortest_paths, 2); /* in cIGraph_shortest_paths.c */
237
+ rb_define_method(cIGraph, "get_shortest_paths", cIGraph_get_shortest_paths, 3); /* in cIGraph_shortest_paths.c */
238
+ rb_define_method(cIGraph, "get_all_shortest_paths", cIGraph_get_all_shortest_paths, 3); /* in cIGraph_shortest_paths.c */
239
+ rb_define_method(cIGraph, "average_path_length", cIGraph_average_path_length, 2); /* in cIGraph_shortest_paths.c */
240
+ rb_define_method(cIGraph, "diameter", cIGraph_diameter, 2); /* in cIGraph_shortest_paths.c */
241
+ rb_define_method(cIGraph, "girth", cIGraph_girth, 0); /* in cIGraph_shortest_paths.c */
242
+
243
+ rb_define_method(cIGraph, "neighbourhood_size", cIGraph_neighborhood_size, 3); /* in cIGraph_vertex_neighbourhood.c */
244
+ rb_define_method(cIGraph, "neighbourhood", cIGraph_neighborhood, 3); /* in cIGraph_vertex_neighbourhood.c */
245
+ rb_define_method(cIGraph, "neighbourhood_graphs", cIGraph_neighborhood_graphs, 3); /* in cIGraph_vertex_neighbourhood.c */
246
+ rb_define_alias (cIGraph, "neighborhood_size", "neighbourhood_size");
247
+ rb_define_alias (cIGraph, "neighborhood", "neighbourhood");
248
+ rb_define_alias (cIGraph, "neighborhood_graphs", "neighbourhood_graphs");
249
+
250
+ rb_define_method(cIGraph, "subcomponent", cIGraph_subcomponent, 2); /* in cIGraph_components.c */
251
+ rb_define_method(cIGraph, "subgraph", cIGraph_subgraph, 1); /* in cIGraph_components.c */
252
+ rb_define_method(cIGraph, "clusters", cIGraph_clusters, 1); /* in cIGraph_components.c */
253
+ rb_define_method(cIGraph, "decompose", cIGraph_decompose, -1); /* in cIGraph_components.c */
254
+
255
+ rb_define_method(cIGraph, "closeness", cIGraph_closeness, 2); /* in cIGraph_centrality.c */
256
+ rb_define_method(cIGraph, "betweenness", cIGraph_betweenness, 2); /* in cIGraph_centrality.c */
257
+ rb_define_method(cIGraph, "edge_betweenness", cIGraph_edge_betweenness, 1); /* in cIGraph_centrality.c */
258
+ rb_define_method(cIGraph, "pagerank", cIGraph_pagerank, 5); /* in cIGraph_centrality.c */
259
+ rb_define_method(cIGraph, "constraint", cIGraph_constraint, -1); /* in cIGraph_centrality.c */
260
+ rb_define_method(cIGraph, "maxdegree", cIGraph_maxdegree, 3); /* in cIGraph_centrality.c */
261
+
262
+ rb_define_method(cIGraph, "topological_sorting", cIGraph_topological_sorting, 1); /* in cIGraph_topological_sort.c */
263
+
264
+ rb_define_singleton_method(cIGraph, "read_graph_edgelist", cIGraph_read_graph_edgelist, 2); /* in cIGraph_file.c */
265
+ rb_define_singleton_method(cIGraph, "read_graph_graphml", cIGraph_read_graph_graphml, 2); /* in cIGraph_file.c */
266
+ rb_define_singleton_method(cIGraph, "read_graph_pajek", cIGraph_read_graph_pajek, 2); /* in cIGraph_file.c */
267
+ rb_define_method(cIGraph, "write_graph_edgelist", cIGraph_write_graph_edgelist, 1); /* in cIGraph_file.c */
268
+ rb_define_method(cIGraph, "write_graph_graphml", cIGraph_write_graph_graphml, 1); /* in cIGraph_file.c */
269
+ rb_define_method(cIGraph, "write_graph_pajek", cIGraph_write_graph_pajek, 1); /* in cIGraph_file.c */
270
+
271
+ rb_define_method(cIGraph, "layout_random", cIGraph_layout_random, 0); /* in cIGraph_layout.c */
272
+ rb_define_method(cIGraph, "layout_circle", cIGraph_layout_circle, 0); /* in cIGraph_layout.c */
273
+ rb_define_method(cIGraph, "layout_fruchterman_reingold", cIGraph_layout_fruchterman_reingold, 6); /* in cIGraph_layout.c */
274
+
275
+ //Matrix class
276
+ cIGraphMatrix = rb_define_class("IGraphMatrix", rb_cObject);
277
+
278
+ rb_define_alloc_func(cIGraphMatrix, cIGraph_matrix_alloc);
279
+ rb_define_method(cIGraphMatrix, "initialize", cIGraph_matrix_initialize, -1); /* in cIGraph_matrix.c */
280
+ rb_define_method(cIGraphMatrix, "initialize_copy", cIGraph_matrix_init_copy, 1); /* in cIGraph_matrix.c */
281
+ //rb_define_singleton_method(cIGraphMatrix, "[]", cIGraph_matrix_initialize, -1);
282
+ rb_include_module(cIGraphMatrix, rb_mEnumerable);
283
+ rb_define_method (cIGraphMatrix, "each", cIGraph_matrix_each,0); /* in cIGraph_matrix.c */
284
+
285
+ rb_define_method(cIGraphMatrix, "[]", cIGraph_matrix_get, 2); /* in cIGraph_matrix.c */
286
+ rb_define_method(cIGraphMatrix, "[]=", cIGraph_matrix_set, 3); /* in cIGraph_matrix.c */
287
+ rb_define_method(cIGraphMatrix, "size", cIGraph_matrix_size, 0); /* in cIGraph_matrix.c */
288
+ rb_define_method(cIGraphMatrix, "nrow", cIGraph_matrix_nrow, 0); /* in cIGraph_matrix.c */
289
+ rb_define_method(cIGraphMatrix, "ncol", cIGraph_matrix_ncol, 0); /* in cIGraph_matrix.c */
290
+ rb_define_method(cIGraphMatrix, "max", cIGraph_matrix_max, 0); /* in cIGraph_matrix.c */
291
+
292
+ rb_define_method(cIGraphMatrix, "*", cIGraph_matrix_multiply, 1); /* in cIGraph_matrix.c */
293
+
294
+ rb_define_method(cIGraphMatrix, "to_a", cIGraph_matrix_toa, 0); /* in cIGraph_matrix.c */
159
295
 
160
296
  }
@@ -1,6 +1,14 @@
1
+ #include "math.h"
2
+ #include "ruby.h"
3
+ #include "igraph.h"
4
+
5
+ //#define DEBUG
6
+
1
7
  //Classes
2
- VALUE cIGraph;
3
- VALUE cIGraphError;
8
+ extern VALUE cIGraph;
9
+ extern VALUE cIGraphError;
10
+ extern VALUE cIGraphMatrix;
11
+ extern igraph_attribute_table_t cIGraph_attribute_table;
4
12
 
5
13
  //Error and warning handling functions
6
14
  void cIGraph_error_handler(const char *reason, const char *file,
@@ -17,8 +25,17 @@ VALUE cIGraph_include(VALUE self, VALUE v);
17
25
  //IGraph allocation, destruction and intialization
18
26
  void Init_igraph(void);
19
27
  void cIGraph_free(void *p);
28
+ void cIGraph_mark(void *p);
20
29
  VALUE cIGraph_alloc(VALUE klass);
21
- VALUE cIGraph_initialize(VALUE self, VALUE edges, VALUE directed);
30
+ VALUE cIGraph_initialize(int argc, VALUE *argv, VALUE self);
31
+ VALUE cIGraph_init_copy(VALUE copy, VALUE orig);
32
+
33
+ //Attribute accessors
34
+ int replace_i(VALUE key, VALUE val, VALUE hash);
35
+ VALUE cIGraph_get_edge_attr(VALUE self, VALUE from, VALUE to);
36
+ VALUE cIGraph_set_edge_attr(VALUE self, VALUE from, VALUE to, VALUE attr);
37
+ VALUE cIGraph_graph_attributes(VALUE self);
38
+ igraph_i_attribute_record_t cIGraph_create_record(VALUE v);
22
39
 
23
40
  //Iterators
24
41
  VALUE cIGraph_each_vertex (VALUE self);
@@ -32,7 +49,6 @@ VALUE cIGraph_nonadj_v(VALUE self, VALUE v, VALUE mode);
32
49
 
33
50
  VALUE cIGraph_all_e (VALUE self, VALUE mode);
34
51
  VALUE cIGraph_adj_e (VALUE self, VALUE v, VALUE mode);
35
- VALUE cIGraph_nonadj_e(VALUE self, VALUE v, VALUE mode);
36
52
 
37
53
  //Basic query operations
38
54
  VALUE cIGraph_vcount (VALUE self);
@@ -45,16 +61,147 @@ VALUE cIGraph_is_directed(VALUE self);
45
61
  VALUE cIGraph_degree (VALUE self, VALUE v, VALUE mode, VALUE loops);
46
62
 
47
63
  //Adding and eleting vertices and edges
48
- VALUE cIGraph_add_edges (VALUE self, VALUE edges);
64
+ VALUE cIGraph_add_edges (int argc, VALUE *argv, VALUE self);
65
+ VALUE cIGraph_add_edge (int argc, VALUE *argv, VALUE self);
49
66
  VALUE cIGraph_add_vertices (VALUE self, VALUE vs);
67
+ VALUE cIGraph_delete_edge (VALUE self, VALUE from, VALUE to);
50
68
  VALUE cIGraph_delete_edges (VALUE self, VALUE edges);
51
69
  VALUE cIGraph_delete_vertices(VALUE self, VALUE vs);
52
- VALUE cIGraph_add_edge (VALUE self, VALUE from, VALUE to);
70
+ VALUE cIGraph_delete_vertex (VALUE self, VALUE v);
53
71
  VALUE cIGraph_add_vertex (VALUE self, VALUE v);
54
72
 
55
73
  //Basic properties
56
74
  VALUE cIGraph_are_connected(VALUE self, VALUE from, VALUE to);
57
75
 
58
76
  //Shortest Path Related Functions
59
- VALUE cIGraph_shortest_paths (VALUE self, VALUE from, VALUE mode);
60
- VALUE cIGraph_get_shortest_paths(VALUE self, VALUE from, VALUE to, VALUE mode);
77
+ VALUE cIGraph_shortest_paths (VALUE self, VALUE from, VALUE mode);
78
+ VALUE cIGraph_get_shortest_paths (VALUE self, VALUE from, VALUE to, VALUE mode);
79
+ VALUE cIGraph_get_all_shortest_paths(VALUE self, VALUE from, VALUE to, VALUE mode);
80
+ VALUE cIGraph_average_path_length (VALUE self, VALUE directed, VALUE unconn);
81
+ VALUE cIGraph_diameter (VALUE self, VALUE directed, VALUE unconn);
82
+ VALUE cIGraph_girth (VALUE self);
83
+
84
+ //Vertex neighbourhood functions
85
+ VALUE cIGraph_neighborhood_size (VALUE self, VALUE from, VALUE order, VALUE mode);
86
+ VALUE cIGraph_neighborhood (VALUE self, VALUE from, VALUE order, VALUE mode);
87
+ VALUE cIGraph_neighborhood_graphs(VALUE self, VALUE from, VALUE order, VALUE mode);
88
+
89
+ //Component functions
90
+ VALUE cIGraph_subcomponent(VALUE self, VALUE v, VALUE mode);
91
+ VALUE cIGraph_subgraph (VALUE self, VALUE vs);
92
+ VALUE cIGraph_clusters (VALUE self, VALUE mode);
93
+ VALUE cIGraph_decompose (int argc, VALUE *argv, VALUE self);
94
+
95
+ //Centrality measures
96
+ VALUE cIGraph_closeness (VALUE self, VALUE vs, VALUE mode);
97
+ VALUE cIGraph_betweenness (VALUE self, VALUE vs, VALUE directed);
98
+ VALUE cIGraph_edge_betweenness(VALUE self, VALUE directed);
99
+ VALUE cIGraph_pagerank (VALUE self, VALUE vs, VALUE directed, VALUE niter, VALUE eps, VALUE damping);
100
+ VALUE cIGraph_constraint (int argc, VALUE *argv, VALUE self);
101
+ VALUE cIGraph_maxdegree (VALUE self, VALUE vs, VALUE mode, VALUE loops);
102
+
103
+ //Topological sorting
104
+ VALUE cIGraph_topological_sorting(VALUE self, VALUE mode);
105
+
106
+ //File handling
107
+ VALUE cIGraph_read_graph_edgelist (VALUE self, VALUE file, VALUE mode);
108
+ VALUE cIGraph_write_graph_edgelist(VALUE self, VALUE file);
109
+ VALUE cIGraph_read_graph_graphml (VALUE self, VALUE file, VALUE index);
110
+ VALUE cIGraph_write_graph_graphml (VALUE self, VALUE file);
111
+ VALUE cIGraph_read_graph_pajek (VALUE self, VALUE file);
112
+ VALUE cIGraph_write_graph_pajek (VALUE self, VALUE file);
113
+
114
+ //Layouts
115
+ VALUE cIGraph_layout_random(VALUE self);
116
+ VALUE cIGraph_layout_circle(VALUE self);
117
+ VALUE cIGraph_layout_fruchterman_reingold(VALUE self,
118
+ VALUE niter,
119
+ VALUE maxdelta,
120
+ VALUE area,
121
+ VALUE coolexp,
122
+ VALUE repulserad,
123
+ VALUE use_seed);
124
+
125
+ //Attributes
126
+ int cIGraph_attribute_init(igraph_t *graph,
127
+ igraph_vector_ptr_t *attr);
128
+ void cIGraph_attribute_destroy(igraph_t *graph);
129
+ int cIGraph_attribute_copy(igraph_t *to,
130
+ const igraph_t *from);
131
+ int cIGraph_attribute_add_vertices(igraph_t *graph,
132
+ long int nv,
133
+ igraph_vector_ptr_t *attr);
134
+ void cIGraph_attribute_delete_edges(igraph_t *graph,
135
+ const igraph_vector_t *idx);
136
+ void cIGraph_attribute_delete_vertices(igraph_t *graph,
137
+ const igraph_vector_t *eidx,
138
+ const igraph_vector_t *vidx);
139
+ int cIGraph_attribute_add_edges(igraph_t *graph,
140
+ const igraph_vector_t *edges,
141
+ igraph_vector_ptr_t *attr);
142
+ void cIGraph_attribute_delete_edges(igraph_t *graph,
143
+ const igraph_vector_t *idx);
144
+ int cIGraph_attribute_permute_edges(igraph_t *graph,
145
+ const igraph_vector_t *idx);
146
+ int cIGraph_attribute_get_info(const igraph_t *graph,
147
+ igraph_strvector_t *gnames,
148
+ igraph_vector_t *gtypes,
149
+ igraph_strvector_t *vnames,
150
+ igraph_vector_t *vtypes,
151
+ igraph_strvector_t *enames,
152
+ igraph_vector_t *etypes);
153
+ igraph_bool_t cIGraph_attribute_has_attr(const igraph_t *graph,
154
+ igraph_attribute_elemtype_t type,
155
+ const char* name);
156
+ int cIGraph_attribute_get_type(const igraph_t *graph,
157
+ igraph_attribute_type_t *type,
158
+ igraph_attribute_elemtype_t elemtype,
159
+ const char *name);
160
+ int cIGraph_get_numeric_graph_attr(const igraph_t *graph,
161
+ const char *name,
162
+ igraph_vector_t *value);
163
+ int cIGraph_get_string_graph_attr(const igraph_t *graph,
164
+ const char *name,
165
+ igraph_strvector_t *value);
166
+ int cIGraph_get_numeric_vertex_attr(const igraph_t *graph,
167
+ const char *name,
168
+ igraph_vs_t vs,
169
+ igraph_vector_t *value);
170
+ int cIGraph_get_string_vertex_attr(const igraph_t *graph,
171
+ const char *name,
172
+ igraph_vs_t vs,
173
+ igraph_strvector_t *value);
174
+ int cIGraph_get_numeric_edge_attr(const igraph_t *graph,
175
+ const char *name,
176
+ igraph_es_t es,
177
+ igraph_vector_t *value);
178
+ int cIGraph_get_string_edge_attr(const igraph_t *graph,
179
+ const char *name,
180
+ igraph_es_t es,
181
+ igraph_strvector_t *value);
182
+
183
+
184
+ //Matrix functions
185
+ void cIGraph_matrix_free(void *p);
186
+ VALUE cIGraph_matrix_alloc(VALUE klass);
187
+ VALUE cIGraph_matrix_init_copy(VALUE copy, VALUE orig);
188
+ VALUE cIGraph_matrix_initialize(int argc, VALUE *argv, VALUE self);
189
+ void Init_igraphmatrix();
190
+
191
+ VALUE cIGraph_matrix_each(VALUE self);
192
+
193
+ VALUE cIGraph_matrix_get (VALUE self, VALUE i, VALUE j);
194
+ VALUE cIGraph_matrix_set (VALUE self, VALUE i, VALUE j, VALUE x);
195
+ VALUE cIGraph_matrix_size(VALUE self);
196
+ VALUE cIGraph_matrix_nrow(VALUE self);
197
+ VALUE cIGraph_matrix_ncol(VALUE self);
198
+ VALUE cIGraph_matrix_max (VALUE self);
199
+
200
+ VALUE cIGraph_matrix_multiply(VALUE self, VALUE x);
201
+
202
+ VALUE cIGraph_matrix_toa(VALUE self);
203
+
204
+ //Not implemented yet
205
+ //VALUE cIGraph_add_rows(VALUE self, VALUE n);
206
+ //VALUE cIGraph_add_cols(VALUE self, VALUE n);
207
+ //VALUE cIGraph_matrix_resize(VALUE self, VALUE nrow, VALUE ncol);