From 722b16bd181fa227bfbeaeafcbcd922d6ce46a64 Mon Sep 17 00:00:00 2001 From: alexgutteridge Date: Tue, 3 Jul 2007 06:25:19 +0000 Subject: [PATCH] --- Manifest.txt | 5 +++ ext/cIGraph.c | 17 +++++++- ext/cIGraph.h | 11 +++++ ext/cIGraph_add_delete.c | 79 +++++++++++++++++++++++++++++++++++- ext/cIGraph_shortest_paths.c | 4 +- test/tc_add_delete.rb | 22 ++++++++++ test/tc_shortest_paths.rb | 11 ++++- test/test_all.rb | 1 + 8 files changed, 144 insertions(+), 6 deletions(-) diff --git a/Manifest.txt b/Manifest.txt index 68c3a34..1116906 100644 --- a/Manifest.txt +++ b/Manifest.txt @@ -8,6 +8,9 @@ ext/cIGraph_add_delete.c ext/cIGraph_basic_properties.c ext/cIGraph_basic_query.c ext/cIGraph_error_handlers.c +ext/cIGraph_iterators.c +ext/cIGraph_operators.c +ext/cIGraph_selectors.c ext/cIGraph_shortest_paths.c ext/cIGraph_utility.c test/tc_add_delete.rb @@ -15,5 +18,7 @@ test/tc_basic_properties.rb test/tc_basic_query.rb test/tc_create.rb test/tc_error_handling.rb +test/tc_iterators.rb +test/tc_selectors.rb test/tc_shortest_paths.rb test/test_all.rb diff --git a/ext/cIGraph.c b/ext/cIGraph.c index 182db73..7a48563 100644 --- a/ext/cIGraph.c +++ b/ext/cIGraph.c @@ -105,6 +105,16 @@ void Init_igraph(){ rb_define_method(cIGraph, "include?", cIGraph_include, 1); + rb_define_method(cIGraph, "all_vertices", cIGraph_all_v, 0); + rb_define_method(cIGraph, "vertices", cIGraph_all_v, 0); + rb_define_method(cIGraph, "adjacent_vertices", cIGraph_adj_v, 2); + rb_define_method(cIGraph, "nonadjacent_vertices", cIGraph_nonadj_v, 2); + + rb_define_method(cIGraph, "all_edges", cIGraph_all_e, 1); + rb_define_method(cIGraph, "edges", cIGraph_all_e, 1); + rb_define_method(cIGraph, "adjacent_edges", cIGraph_adj_e, 2); + rb_define_method(cIGraph, "nonadjacent_edges", cIGraph_nonadj_e, 2); + rb_define_method(cIGraph, "vcount", cIGraph_vcount, 0); rb_define_method(cIGraph, "ecount", cIGraph_ecount, 0); @@ -125,8 +135,11 @@ void Init_igraph(){ rb_define_method(cIGraph, "degree", cIGraph_degree,3); - rb_define_method(cIGraph, "add_edges", cIGraph_add_edges,1); - rb_define_method(cIGraph, "add_vertices", cIGraph_add_vertices,1); + rb_define_method(cIGraph, "add_edges", cIGraph_add_edges, 1); + rb_define_method(cIGraph, "add_vertices", cIGraph_add_vertices, 1); + + rb_define_method(cIGraph, "add_edge", cIGraph_add_edge, 2); + rb_define_method(cIGraph, "add_vertex", cIGraph_add_vertex, 1); rb_define_method(cIGraph, "are_connected", cIGraph_are_connected,2); rb_define_method(cIGraph, "are_connected?", cIGraph_are_connected,2); diff --git a/ext/cIGraph.h b/ext/cIGraph.h index 38b56b0..48e7f48 100644 --- a/ext/cIGraph.h +++ b/ext/cIGraph.h @@ -25,6 +25,15 @@ VALUE cIGraph_each_vertex (VALUE self); VALUE cIGraph_each_edge (VALUE self, VALUE order); VALUE cIGraph_each_edge_eid(VALUE self, VALUE order); +//Selectors +VALUE cIGraph_all_v (VALUE self); +VALUE cIGraph_adj_v (VALUE self, VALUE v, VALUE mode); +VALUE cIGraph_nonadj_v(VALUE self, VALUE v, VALUE mode); + +VALUE cIGraph_all_e (VALUE self, VALUE mode); +VALUE cIGraph_adj_e (VALUE self, VALUE v, VALUE mode); +VALUE cIGraph_nonadj_e(VALUE self, VALUE v, VALUE mode); + //Basic query operations VALUE cIGraph_vcount (VALUE self); VALUE cIGraph_ecount (VALUE self); @@ -40,6 +49,8 @@ VALUE cIGraph_add_edges (VALUE self, VALUE edges); VALUE cIGraph_add_vertices (VALUE self, VALUE vs); VALUE cIGraph_delete_edges (VALUE self, VALUE edges); VALUE cIGraph_delete_vertices(VALUE self, VALUE vs); +VALUE cIGraph_add_edge (VALUE self, VALUE from, VALUE to); +VALUE cIGraph_add_vertex (VALUE self, VALUE v); //Basic properties VALUE cIGraph_are_connected(VALUE self, VALUE from, VALUE to); diff --git a/ext/cIGraph_add_delete.c b/ext/cIGraph_add_delete.c index caefdce..3367f2e 100644 --- a/ext/cIGraph_add_delete.c +++ b/ext/cIGraph_add_delete.c @@ -62,7 +62,9 @@ VALUE cIGraph_add_vertices(VALUE self, VALUE vs){ while(vertex != Qnil){ if(rb_funcall(object_h,rb_intern("has_key?"),1,vertex)){ //If @vertices includes this vertex then raise an error - rb_raise(cIGraphError, "Vertex already added to graph"); + //Silently ignore + //rb_raise(cIGraphError, "Vertex already added to graph"); + length--; } else { //otherwise add a new entry to Hash rb_hash_aset(object_h,vertex,INT2NUM(vertex_n)); @@ -76,3 +78,78 @@ VALUE cIGraph_add_vertices(VALUE self, VALUE vs){ return INT2NUM(code); } + +VALUE cIGraph_add_edge(VALUE self, VALUE from, VALUE to){ + + igraph_t *graph; + igraph_vector_t edge_v; + VALUE object_h; + int vid; + int code = 0; + + //Initialize edge vector + igraph_vector_init_int(&edge_v,0); + object_h = rb_iv_get(self,"@object_ids"); + + Data_Get_Struct(self, igraph_t, graph); + + if(rb_funcall(object_h,rb_intern("has_key?"),1,from)){ + //If @vertices includes this vertex then look up the vertex number + vid = NUM2INT(rb_hash_aref(object_h,from)); + } else { + rb_raise(cIGraphError, "Unknown vertex in edge array. Use add_vertices first"); + } + igraph_vector_push_back(&edge_v,vid); + + if(rb_funcall(object_h,rb_intern("has_key?"),1,to)){ + //If @vertices includes this vertex then look up the vertex number + vid = NUM2INT(rb_hash_aref(object_h,to)); + } else { + rb_raise(cIGraphError, "Unknown vertex in edge array. Use add_vertices first"); + } + igraph_vector_push_back(&edge_v,vid); + + code = igraph_add_edges(graph,&edge_v,0); + + igraph_vector_destroy(&edge_v); + + return INT2NUM(code); + +} + +VALUE cIGraph_add_vertex(VALUE self, VALUE v){ + + igraph_t *graph; + VALUE vertex; + VALUE object_h; + VALUE id_h; + int vertex_n; + int code = 0; + int length; + + object_h = rb_iv_get(self,"@object_ids"); + id_h = rb_iv_get(self,"@id_objects"); + length = 1; + vertex_n = NUM2INT(rb_funcall(object_h,rb_intern("length"),0)); + + Data_Get_Struct(self, igraph_t, graph); + + //Loop through objects in vertex array + if(rb_funcall(object_h,rb_intern("has_key?"),1,v)){ + //If @vertices includes this vertex then raise an error + //Silently ignore + //rb_raise(cIGraphError, "Vertex already added to graph"); + length--; + } else { + //otherwise add a new entry to Hash + rb_hash_aset(object_h,v,INT2NUM(vertex_n)); + rb_hash_aset(id_h, INT2NUM(vertex_n),v); + vertex_n++; + } + + if(length != 0) + code = igraph_add_vertices(graph,length,0); + + return INT2NUM(code); + +} diff --git a/ext/cIGraph_shortest_paths.c b/ext/cIGraph_shortest_paths.c index 23fc1e0..709f7df 100644 --- a/ext/cIGraph_shortest_paths.c +++ b/ext/cIGraph_shortest_paths.c @@ -12,6 +12,7 @@ VALUE cIGraph_shortest_paths(VALUE self, VALUE from, VALUE mode){ int i; int j; VALUE row; + VALUE path_length; VALUE matrix = rb_ary_new(); int n_row; int n_col; @@ -35,7 +36,8 @@ VALUE cIGraph_shortest_paths(VALUE self, VALUE from, VALUE mode){ row = rb_ary_new(); rb_ary_push(matrix,row); for(j=0; j