diff --git a/ext/cIGraph.c b/ext/cIGraph.c index 6f6656b..2131674 100644 --- a/ext/cIGraph.c +++ b/ext/cIGraph.c @@ -48,11 +48,10 @@ VALUE cIGraph_initialize(int argc, VALUE *argv, VALUE self){ igraph_t *graph; igraph_vector_t edge_v; VALUE vertex; - VALUE object_h; - VALUE id_h; VALUE directed; VALUE edges; VALUE attrs; + VALUE v_ary; int vertex_n = 0; int current_vertex_id; int i; @@ -62,15 +61,6 @@ VALUE cIGraph_initialize(int argc, VALUE *argv, VALUE self){ rb_scan_args(argc,argv,"12", &edges, &directed, &attrs); - igraph_set_error_handler(cIGraph_error_handler); - igraph_set_warning_handler(cIGraph_warning_handler); - - //New hash for mapping vertex objects to floats used by iGraph - object_h = rb_iv_set(self,"@object_ids",rb_hash_new()); - id_h = rb_iv_set(self,"@id_objects",rb_hash_new()); - - rb_iv_set(self,"@edge_attrs",rb_hash_new()); - //Initialize edge vector igraph_vector_init_int(&edge_v,0); @@ -79,29 +69,34 @@ VALUE cIGraph_initialize(int argc, VALUE *argv, VALUE self){ Data_Get_Struct(self, igraph_t, graph); + v_ary = rb_ary_new(); + if(!directed) igraph_to_undirected(graph,IGRAPH_TO_UNDIRECTED_COLLAPSE); //Loop through objects in edge Array for (i=0; ilen; i++) { vertex = RARRAY(edges)->ptr[i]; - if(rb_funcall(object_h,rb_intern("has_key?"),1,vertex)){ + if(rb_ary_includes(v_ary,vertex)){ //If @vertices includes this vertex then look up the vertex number - current_vertex_id = NUM2INT(rb_hash_aref(object_h,vertex)); + current_vertex_id = NUM2INT(rb_funcall(v_ary,rb_intern("index"),1,vertex)); } else { - //otherwise add a new entadd_vertry to Hash - rb_hash_aset(object_h,vertex,INT2NUM(vertex_n)); - rb_hash_aset(id_h, INT2NUM(vertex_n),vertex); + //Otherwise add to the list of vertices + rb_ary_push(v_ary,vertex); current_vertex_id = vertex_n; - - igraph_vector_ptr_push_back(&vertex_attr,(void*)RARRAY(edges)->ptr[i]); - vertex_n++; + //Add object to list of vertex attributes + igraph_vector_ptr_push_back(&vertex_attr,(void*)vertex); + } igraph_vector_push_back(&edge_v,current_vertex_id); - if (attrs != Qnil && i % 2){ - igraph_vector_ptr_push_back(&edge_attr,(void*)RARRAY(attrs)->ptr[i/2]); + if (i % 2){ + if (attrs != Qnil){ + igraph_vector_ptr_push_back(&edge_attr,(void*)RARRAY(attrs)->ptr[i/2]); + } else { + igraph_vector_ptr_push_back(&edge_attr,(void*)Qnil); + } } } @@ -131,10 +126,10 @@ void Init_igraph(){ rb_define_alloc_func(cIGraph, cIGraph_alloc); rb_define_method(cIGraph, "initialize", cIGraph_initialize, -1); - //rb_define_method(cIGraph, "[]", cIGraph_get_edge_attr, 2); - //rb_define_method(cIGraph, "[]=", cIGraph_set_edge_attr, 3); - //rb_define_method(cIGraph, "get_edge_attr", cIGraph_get_edge_attr, 2); - //rb_define_method(cIGraph, "set_edge_attr", cIGraph_set_edge_attr, 3); + rb_define_method(cIGraph, "[]", cIGraph_get_edge_attr, 2); + rb_define_method(cIGraph, "[]=", cIGraph_set_edge_attr, 3); + rb_define_method(cIGraph, "get_edge_attr", cIGraph_get_edge_attr, 2); + rb_define_method(cIGraph, "set_edge_attr", cIGraph_set_edge_attr, 3); rb_define_method(cIGraph, "each_vertex", cIGraph_each_vertex, 0); /* in cIGraph_iterators.c */ rb_define_method(cIGraph, "each_edge", cIGraph_each_edge, 1); /* in cIGraph_iterators.c */ @@ -211,5 +206,7 @@ void Init_igraph(){ rb_define_method(cIGraph, "write_graph_edgelist", cIGraph_write_graph_edgelist, 1); /* in cIGraph_file.c */ igraph_i_set_attribute_table(&cIGraph_attribute_table); + igraph_set_error_handler(cIGraph_error_handler); + igraph_set_warning_handler(cIGraph_warning_handler); } diff --git a/ext/cIGraph.h b/ext/cIGraph.h index b5f1f27..2de5579 100644 --- a/ext/cIGraph.h +++ b/ext/cIGraph.h @@ -23,8 +23,8 @@ VALUE cIGraph_alloc(VALUE klass); VALUE cIGraph_initialize(int argc, VALUE *argv, VALUE self); //Attribute accessors -//VALUE cIGraph_get_edge_attr(VALUE self, VALUE from, VALUE to); -//VALUE cIGraph_set_edge_attr(VALUE self, VALUE from, VALUE to, VALUE attr); +VALUE cIGraph_get_edge_attr(VALUE self, VALUE from, VALUE to); +VALUE cIGraph_set_edge_attr(VALUE self, VALUE from, VALUE to, VALUE attr); //Iterators VALUE cIGraph_each_vertex (VALUE self); diff --git a/ext/cIGraph_add_delete.c b/ext/cIGraph_add_delete.c index b1ce2af..49f3dd9 100644 --- a/ext/cIGraph_add_delete.c +++ b/ext/cIGraph_add_delete.c @@ -51,8 +51,12 @@ VALUE cIGraph_add_edges(int argc, VALUE *argv, VALUE self){ rb_raise(cIGraphError, "Unknown vertex in edge array. Use add_vertices first"); } igraph_vector_push_back(&edge_v,vid); - if (attrs != Qnil && i % 2){ - igraph_vector_ptr_push_back(&edge_attr,(void*)RARRAY(attrs)->ptr[i/2]); + if (i % 2){ + if (attrs != Qnil){ + igraph_vector_ptr_push_back(&edge_attr,(void*)RARRAY(attrs)->ptr[i/2]); + } else { + igraph_vector_ptr_push_back(&edge_attr,(void*)Qnil); + } } } @@ -160,16 +164,11 @@ VALUE cIGraph_add_edge(int argc, VALUE *argv, VALUE self){ //If graph includes this vertex then look up the vertex number igraph_vector_push_back(&edge_v,cIGraph_get_vertex_id(self, from)); igraph_vector_push_back(&edge_v,cIGraph_get_vertex_id(self, to)); - if (attr != Qnil){ - igraph_vector_ptr_push_back(&edge_attr,(void*)attr); - } + igraph_vector_ptr_push_back(&edge_attr,(void*)attr); } else { - rb_raise(cIGraphError, "Unknown vertex in edge array. Use add_vertices first"); + rb_raise(cIGraphError, "Unknown vertex in edge array. Use add_vertices"); } - igraph_vector_push_back(&edge_v,cIGraph_get_vertex_id(self, from)); - igraph_vector_push_back(&edge_v,cIGraph_get_vertex_id(self, to)); - code = igraph_add_edges(graph,&edge_v,&edge_attr); igraph_vector_ptr_destroy(&edge_attr); diff --git a/ext/cIGraph_attribute_handler.c b/ext/cIGraph_attribute_handler.c index 276de52..7f36c73 100644 --- a/ext/cIGraph_attribute_handler.c +++ b/ext/cIGraph_attribute_handler.c @@ -2,6 +2,36 @@ #include "ruby.h" #include "cIGraph.h" +VALUE cIGraph_get_edge_attr(VALUE self, VALUE from, VALUE to){ + + int idx; + igraph_t *graph; + VALUE e_ary; + + Data_Get_Struct(self, igraph_t, graph); + e_ary = ((VALUE*)graph->attr)[1]; + + idx = NUM2INT(cIGraph_get_eid(self, from, to, 1)); + return rb_ary_entry(e_ary,idx); + +} + +VALUE cIGraph_set_edge_attr(VALUE self, VALUE from, VALUE to, VALUE attr){ + + int idx; + igraph_t *graph; + VALUE e_ary; + + Data_Get_Struct(self, igraph_t, graph); + e_ary = ((VALUE*)graph->attr)[1]; + + idx = NUM2INT(cIGraph_get_eid(self, from, to, 1)); + rb_ary_store(e_ary,idx,attr); + + return Qtrue; + +} + igraph_attribute_table_t cIGraph_attribute_table = { cIGraph_attribute_init, cIGraph_attribute_destroy, @@ -136,38 +166,38 @@ int cIGraph_get_numeric_graph_attr(const igraph_t *graph, /* Getting string graph attributes */ int cIGraph_get_string_graph_attr(const igraph_t *graph, - const char *name, igraph_strvector_t *value) { + const char *name, igraph_strvector_t *value) { return 0; } /* Getting numeric vertex attributes */ int cIGraph_get_numeric_vertex_attr(const igraph_t *graph, - const char *name, - igraph_vs_t vs, - igraph_vector_t *value) { + const char *name, + igraph_vs_t vs, + igraph_vector_t *value) { return 0; } /* Getting string vertex attributes */ int cIGraph_get_string_vertex_attr(const igraph_t *graph, - const char *name, - igraph_vs_t vs, - igraph_strvector_t *value) { + const char *name, + igraph_vs_t vs, + igraph_strvector_t *value) { return 0; } /* Getting numeric edge attributes */ int cIGraph_get_numeric_edge_attr(const igraph_t *graph, - const char *name, - igraph_es_t es, - igraph_vector_t *value) { + const char *name, + igraph_es_t es, + igraph_vector_t *value) { return 0; } /* Getting string edge attributes */ int cIGraph_get_string_edge_attr(const igraph_t *graph, - const char *name, - igraph_es_t es, - igraph_strvector_t *value) { + const char *name, + igraph_es_t es, + igraph_strvector_t *value) { return 0; } diff --git a/ext/cIGraph_utility.c b/ext/cIGraph_utility.c index 2117d54..f0c6c0f 100644 --- a/ext/cIGraph_utility.c +++ b/ext/cIGraph_utility.c @@ -29,7 +29,7 @@ VALUE cIGraph_get_vertex_object(VALUE graph, igraph_integer_t n){ Data_Get_Struct(graph, igraph_t, igraph); v_ary = ((VALUE*)igraph->attr)[0]; - obj = rb_ary_entry(graph,n); + obj = rb_ary_entry(v_ary,n); return obj;