igraph 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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