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.
@@ -0,0 +1,93 @@
1
+ #include "igraph.h"
2
+ #include "ruby.h"
3
+ #include "cIGraph.h"
4
+
5
+ /* call-seq:
6
+ * graph.vertices -> Array
7
+ *
8
+ * Returns an Array containing all the vertices in the graph. Also aliased
9
+ * to IGraph#all_vertices
10
+ *
11
+ * Example:
12
+ *
13
+ * g = IGraph.new([1,2,3,4],true)
14
+ * g.vertices #returns [1,2,3,4]
15
+ *
16
+ */
17
+ VALUE cIGraph_all_v(VALUE self){
18
+ igraph_t *graph;
19
+
20
+ Data_Get_Struct(self, igraph_t, graph);
21
+ return rb_funcall(rb_iv_get(self,"@object_ids"),rb_intern("keys"),0);
22
+
23
+ }
24
+
25
+ /* call-seq:
26
+ * graph.adjacent_vertices(v,mode) -> Array
27
+ *
28
+ * Returns an Array containing all the vertices in the graph that are
29
+ * adjacent to vertex v. mode decides the type of the neighborhood for
30
+ * directed graphs. Possible values: IGRAPH_OUT, all vertices to which
31
+ * there is a directed edge from vid. IGRAPH_IN, all vertices from which
32
+ * there is a directed edge from vid. IGRAPH_ALL, all vertices to which
33
+ * or from which there is a directed edge from/to vid. This parameter is
34
+ * ignored for undirected graphs.
35
+ *
36
+ * Example:
37
+ *
38
+ * g = IGraph.new([1,2,3,4],true)
39
+ * g.adjacent_vertices(1,IGraph::ALL) #returns [2]
40
+ *
41
+ */
42
+ VALUE cIGraph_adj_v(VALUE self, VALUE v, VALUE mode){
43
+
44
+ igraph_t *graph;
45
+ igraph_integer_t pnode;
46
+ VALUE adjacent = rb_ary_new();
47
+ igraph_neimode_t pmode = NUM2INT(mode);
48
+ igraph_vs_t vs;
49
+ igraph_vit_t vit;
50
+
51
+ Data_Get_Struct(self, igraph_t, graph);
52
+
53
+ pnode = cIGraph_get_vertex_id(self,v);
54
+
55
+ igraph_vs_adj(&vs,pnode,pmode);
56
+ igraph_vit_create(graph, vs, &vit);
57
+
58
+ while(!IGRAPH_VIT_END(vit)) {
59
+ rb_ary_push(adjacent,cIGraph_get_vertex_object(self,IGRAPH_VIT_GET(vit)));
60
+ IGRAPH_VIT_NEXT(vit);
61
+ }
62
+
63
+ igraph_vit_destroy(&vit);
64
+ igraph_vs_destroy(&vs);
65
+
66
+ return adjacent;
67
+
68
+ }
69
+
70
+ VALUE cIGraph_nonadj_v(VALUE self, VALUE v, VALUE mode){
71
+
72
+ return Qnil;
73
+
74
+ }
75
+
76
+ VALUE cIGraph_all_e(VALUE self, VALUE mode){
77
+
78
+ return Qnil;
79
+
80
+ }
81
+
82
+ VALUE cIGraph_adj_e(VALUE self, VALUE v, VALUE mode){
83
+
84
+ return Qnil;
85
+
86
+ }
87
+
88
+ VALUE cIGraph_nonadj_e(VALUE self, VALUE v, VALUE mode){
89
+
90
+ return Qnil;
91
+
92
+ }
93
+
@@ -0,0 +1,112 @@
1
+ #include "igraph.h"
2
+ #include "ruby.h"
3
+ #include "cIGraph.h"
4
+
5
+ VALUE cIGraph_shortest_paths(VALUE self, VALUE from, VALUE mode){
6
+
7
+ igraph_t *graph;
8
+ igraph_vs_t vids;
9
+ igraph_vector_t vidv;
10
+ igraph_neimode_t pmode = NUM2INT(mode);
11
+ igraph_matrix_t res;
12
+ int i;
13
+ int j;
14
+ VALUE row;
15
+ VALUE path_length;
16
+ VALUE matrix = rb_ary_new();
17
+ int n_row;
18
+ int n_col;
19
+
20
+ Data_Get_Struct(self, igraph_t, graph);
21
+
22
+ n_row = NUM2INT(rb_funcall(from,rb_intern("length"),0));
23
+ n_col = igraph_vcount(graph);
24
+
25
+ //matrix to hold the results of the calculations
26
+ igraph_matrix_init(&res,n_row,n_col);
27
+
28
+ //Convert an array of vertices to a vector of vertex ids
29
+ cIGraph_vertex_arr_to_id_vec(self,from,&vidv);
30
+ //create vertex selector from the vecotr of ids
31
+ igraph_vs_vector(&vids,&vidv);
32
+
33
+ igraph_shortest_paths(graph,&res,vids,pmode);
34
+
35
+ for(i=0; i<igraph_matrix_nrow(&res); i++){
36
+ row = rb_ary_new();
37
+ rb_ary_push(matrix,row);
38
+ for(j=0; j<igraph_matrix_ncol(&res); j++){
39
+ path_length = MATRIX(res,i,j) == n_col ? Qnil : INT2NUM(MATRIX(res,i,j));
40
+ rb_ary_push(row,path_length);
41
+ }
42
+ }
43
+
44
+ igraph_vector_destroy(&vidv);
45
+ igraph_matrix_destroy(&res);
46
+ igraph_vs_destroy(&vids);
47
+
48
+ return matrix;
49
+
50
+ }
51
+
52
+ VALUE cIGraph_get_shortest_paths(VALUE self, VALUE from, VALUE to, VALUE mode){
53
+
54
+ igraph_t *graph;
55
+
56
+ igraph_integer_t from_vid;
57
+ igraph_vs_t to_vids;
58
+ igraph_vector_t to_vidv;
59
+
60
+ igraph_neimode_t pmode = NUM2INT(mode);
61
+
62
+ igraph_vector_ptr_t res;
63
+ igraph_vector_t *path_v;
64
+
65
+ int i;
66
+ int j;
67
+ VALUE path;
68
+ VALUE matrix = rb_ary_new();
69
+ int n_paths;
70
+
71
+ Data_Get_Struct(self, igraph_t, graph);
72
+
73
+ n_paths = NUM2INT(rb_funcall(to,rb_intern("length"),0));
74
+
75
+ //vector to hold the results of the calculations
76
+ igraph_vector_ptr_init(&res,0);
77
+ for(i=0;i<n_paths;i++){
78
+ path_v = malloc(sizeof(igraph_vector_t));
79
+ igraph_vector_init(path_v,0);
80
+ igraph_vector_ptr_push_back(&res,path_v);
81
+ }
82
+
83
+ //Convert an array of vertices to a vector of vertex ids
84
+ cIGraph_vertex_arr_to_id_vec(self,to,&to_vidv);
85
+ //create vertex selector from the vecotr of ids
86
+ igraph_vs_vector(&to_vids,&to_vidv);
87
+
88
+ //The id of the vertex from where we are counting
89
+ from_vid = cIGraph_get_vertex_id(self, from);
90
+
91
+ igraph_get_shortest_paths(graph,&res,from_vid,to_vids,pmode);
92
+
93
+ for(i=0; i<n_paths; i++){
94
+ path = rb_ary_new();
95
+ rb_ary_push(matrix,path);
96
+ for(j=0; j<igraph_vector_size(VECTOR(res)[i]); j++){
97
+ path_v = VECTOR(res)[i];
98
+ rb_ary_push(path,cIGraph_get_vertex_object(self,VECTOR(*path_v)[j]));
99
+ }
100
+ }
101
+
102
+ for(i=0;i<n_paths;i++){
103
+ igraph_vector_destroy(VECTOR(res)[i]);
104
+ }
105
+
106
+ igraph_vector_destroy(&to_vidv);
107
+ igraph_vector_ptr_destroy(&res);
108
+ igraph_vs_destroy(&to_vids);
109
+
110
+ return matrix;
111
+
112
+ }
@@ -0,0 +1,56 @@
1
+ #include "igraph.h"
2
+ #include "ruby.h"
3
+ #include "cIGraph.h"
4
+
5
+ igraph_integer_t cIGraph_get_vertex_id(VALUE graph, VALUE v){
6
+
7
+ VALUE vertex_h;
8
+
9
+ vertex_h = rb_iv_get(graph,"@object_ids");
10
+
11
+ if(rb_funcall(vertex_h,rb_intern("has_key?"),1,v))
12
+ return NUM2INT(rb_hash_aref(vertex_h,v));
13
+
14
+ return -1;
15
+
16
+ }
17
+
18
+ VALUE cIGraph_get_vertex_object(VALUE graph, igraph_integer_t n){
19
+
20
+ VALUE vertex_h;
21
+
22
+ vertex_h = rb_iv_get(graph,"@id_objects");
23
+
24
+ if(rb_funcall(vertex_h,rb_intern("has_key?"),1,INT2NUM(n)))
25
+ return rb_hash_aref(vertex_h,INT2NUM(n));
26
+
27
+ return Qnil;
28
+
29
+ }
30
+
31
+ int cIGraph_vertex_arr_to_id_vec(VALUE graph, VALUE va, igraph_vector_t *nv){
32
+
33
+ VALUE vertex;
34
+ VALUE tmp;
35
+
36
+ tmp = rb_check_array_type(va);
37
+
38
+ if(NIL_P(tmp))
39
+ rb_raise(cIGraphError, "Array expected\n");
40
+
41
+ //Initialize edge vector
42
+ igraph_vector_init_int(nv,0);
43
+ vertex = rb_ary_shift(va);
44
+ while(vertex != Qnil){
45
+ igraph_vector_push_back(nv,cIGraph_get_vertex_id(graph, vertex));
46
+ vertex = rb_ary_shift(va);
47
+ }
48
+
49
+ return 0;
50
+
51
+ }
52
+
53
+ VALUE cIGraph_include(VALUE self, VALUE v){
54
+ VALUE vertex_h = rb_iv_get(self,"@object_ids");
55
+ return rb_funcall(vertex_h,rb_intern("has_key?"),1,v);
56
+ }
data/ext/extconf.rb ADDED
@@ -0,0 +1,12 @@
1
+ require 'mkmf'
2
+ dir_config('igraph')
3
+ unless have_library("igraph")
4
+ $stderr.puts "\nERROR: Cannot find the iGraph library, aborting."
5
+ exit 1
6
+ end
7
+ unless have_header("igraph.h")
8
+ $stderr.puts "\nERROR: Cannot find the iGraph header, aborting."
9
+ exit 1
10
+ end
11
+
12
+ create_makefile("igraph")
@@ -0,0 +1,49 @@
1
+ require 'test/unit'
2
+ require 'igraph'
3
+
4
+ class TestGraph < Test::Unit::TestCase
5
+ def test_add_edges
6
+ graph = IGraph.new(['A','B','C','D'],true)
7
+ graph.add_edges(['A','C'])
8
+ assert_equal [2], graph.degree(['A'],IGraph::ALL,true)
9
+ end
10
+
11
+ def test_add_vertices
12
+ graph = IGraph.new(['A','B','C','D'],true)
13
+ assert_equal 4, graph.vcount
14
+ graph.add_vertices(['E','F','G','H'])
15
+ assert_equal 8, graph.vcount
16
+ assert_equal [0], graph.degree(['E'],IGraph::ALL,true)
17
+ assert_nothing_raised do
18
+ graph.add_vertices(['H','I'])
19
+ end
20
+ assert_equal 9, graph.vcount
21
+ end
22
+
23
+ def test_add_to_empty_graph
24
+ graph = IGraph.new([],true)
25
+ assert_equal 0, graph.vcount
26
+ graph.add_vertices(['A','B'])
27
+ assert_equal 2, graph.vcount
28
+ graph.add_edges(['A','B'])
29
+ assert_equal 1, graph.ecount
30
+ end
31
+
32
+ def test_add_edge
33
+ graph = IGraph.new(['A','B','C','D'],true)
34
+ assert_nothing_raised do
35
+ graph.add_edge('A','D')
36
+ end
37
+ assert_equal [2], graph.degree(['A'],IGraph::ALL,true)
38
+ end
39
+
40
+ def test_add_vertex
41
+ graph = IGraph.new(['A','B','C','D'],true)
42
+ assert_nothing_raised do
43
+ graph.add_vertex('E')
44
+ end
45
+ assert_equal 5, graph.vcount
46
+ assert_equal [0], graph.degree(['E'],IGraph::ALL,true)
47
+ end
48
+
49
+ end
@@ -0,0 +1,10 @@
1
+ require 'test/unit'
2
+ require 'igraph'
3
+
4
+ class TestGraph < Test::Unit::TestCase
5
+ def test_are_connected
6
+ graph = IGraph.new(['A','B','C','D'],true)
7
+ assert graph.are_connected('A','B')
8
+ assert !(graph.are_connected('A','C'))
9
+ end
10
+ end
@@ -0,0 +1,54 @@
1
+ require 'test/unit'
2
+ require 'igraph'
3
+
4
+ class TestGraph < Test::Unit::TestCase
5
+ def test_graph_size
6
+ assert_equal 4, IGraph.new([1,2,3,4],true).vcount
7
+ assert_equal 2, IGraph.new([1,2,3,4],true).ecount
8
+ end
9
+
10
+ def test_eid_get_edge
11
+ assert_nothing_raised do
12
+ IGraph.new(['A','B','C','D'],true).get_eid('A','B')
13
+ end
14
+ graph = IGraph.new(['A','B','C','D'],true)
15
+ eid1 = graph.get_eid('A','B')
16
+ eid2 = graph.get_eid('C','D')
17
+ assert_equal ['A','B'], graph.edge(eid1)
18
+ assert_equal ['C','D'], graph.edge(eid2);
19
+ assert_not_equal eid1,eid2
20
+ end
21
+
22
+ def test_neighbours
23
+ assert_nothing_raised do
24
+ IGraph.new(['A','B','C','D'],true).neighbors('A',IGraph::ALL)
25
+ end
26
+ graph = IGraph.new(['A','B','C','D'],true)
27
+ assert_equal ['B'], graph.neighbors('A',IGraph::ALL)
28
+ assert_equal ['D'], graph.neighbors('C',IGraph::ALL)
29
+ end
30
+
31
+ def test_adjacent
32
+ assert_nothing_raised do
33
+ IGraph.new(['A','B','C','D'],true).adjacent('A',IGraph::ALL)
34
+ end
35
+ graph = IGraph.new(['A','B','C','D'],true)
36
+ eid1 = graph.get_eid('A','B')
37
+ eid2 = graph.adjacent('A',IGraph::ALL)[0]
38
+ assert_equal eid1, eid2
39
+ end
40
+
41
+ def test_directed
42
+ assert IGraph.new(['A','B','C','D'],true).is_directed?
43
+ assert !(IGraph.new(['A','B','C','D'],false).is_directed?)
44
+ end
45
+
46
+ def test_degree
47
+ graph = IGraph.new(['A','B','C','D'],true)
48
+ assert_equal [1], graph.degree(['A'], IGraph::ALL,true)
49
+ assert_equal [1,1],graph.degree(['A','B'],IGraph::ALL,true)
50
+ assert_raises IGraphError do
51
+ graph.degree('A',IGraph::ALL,true)
52
+ end
53
+ end
54
+ end
data/test/tc_create.rb ADDED
@@ -0,0 +1,11 @@
1
+ require 'test/unit'
2
+ require 'igraph'
3
+
4
+ class TestGraph < Test::Unit::TestCase
5
+
6
+ def test_graph
7
+ assert_nothing_raised{IGraph.new([],true)}
8
+ assert_nothing_raised{IGraph.new(['A','B','C','D'],true)}
9
+ end
10
+
11
+ end
@@ -0,0 +1,10 @@
1
+ require 'test/unit'
2
+ require 'igraph'
3
+
4
+ class TestGraph < Test::Unit::TestCase
5
+ def test_edge_fail
6
+ assert_raise IGraphError do
7
+ IGraph.new([1,2,3],true)
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,44 @@
1
+ require 'test/unit'
2
+ require 'igraph'
3
+
4
+ class TestGraph < Test::Unit::TestCase
5
+ def test_each_vertex
6
+ graph = IGraph.new(['A','B','C','D'],true)
7
+ assert_nothing_raised do
8
+ graph.each_vertex do |v|
9
+ end
10
+ end
11
+ assert_nothing_raised do
12
+ graph.each do |v|
13
+ end
14
+ end
15
+ end
16
+
17
+ def test_each_edge
18
+ graph = IGraph.new(['A','B','C','D'],true)
19
+ assert_nothing_raised do
20
+ graph.each_edge(IGraph::EDGEORDER_ID) do |v,w|
21
+ end
22
+ end
23
+ assert_nothing_raised do
24
+ graph.each_edge_eid(IGraph::EDGEORDER_ID) do |v|
25
+ end
26
+ end
27
+ edges = []
28
+ graph.each_edge(IGraph::EDGEORDER_ID){|v,w| edges.push([v,w])}
29
+ assert_equal [['A','B'],['C','D']], edges
30
+ edges = []
31
+ graph.each_edge_eid(IGraph::EDGEORDER_ID){|v| edges.push(v)}
32
+ assert_equal [0,1], edges
33
+ end
34
+
35
+ def test_enumerable
36
+ graph = IGraph.new(['A','B','C','D'],true)
37
+ assert graph.all?{|v| v.kind_of? String}
38
+ assert graph.any?{|v| v == 'B'}
39
+ assert_equal ['A','B','C','D'], graph.collect{|v| v}
40
+ assert graph.detect(Proc.new{true}){|v| }
41
+ assert_equal ['A'], graph.find_all{|v| v < 'B'}
42
+ end
43
+
44
+ end