| @@ -244,6 +244,8 @@ void Init_igraph(){ | |||
| rb_define_alias (cIGraph, "neighborhood", "neighbourhood"); | |||
| rb_define_alias (cIGraph, "neighborhood_graphs", "neighbourhood_graphs"); | |||
| rb_define_method(cIGraph, "subcomponent", cIGraph_subcomponent, 2); /* in cIGraph_components.c */ | |||
| rb_define_method(cIGraph, "topological_sorting", cIGraph_topological_sorting, 1); /* in cIGraph_topological_sort.c */ | |||
| rb_define_singleton_method(cIGraph, "read_graph_edgelist", cIGraph_read_graph_edgelist, 2); /* in cIGraph_file.c */ | |||
| @@ -181,12 +181,12 @@ int cIGraph_attribute_add_vertices(igraph_t *graph, long int nv, igraph_vector_p | |||
| VALUE values; | |||
| if(attr){ | |||
| if(((igraph_i_attribute_record_t*)VECTOR(*attr)[0])->type == IGRAPH_ATTRIBUTE_PY_OBJECT){ | |||
| if(igraph_vector_ptr_size(attr) > 0 && ((igraph_i_attribute_record_t*)VECTOR(*attr)[0])->type == IGRAPH_ATTRIBUTE_PY_OBJECT){ | |||
| values = (VALUE)((igraph_i_attribute_record_t*)VECTOR(*attr)[0])->value; | |||
| Check_Type(values, T_ARRAY); | |||
| for(i=0;i<RARRAY(values)->len;i++){ | |||
| rb_ary_push(vertex_array, RARRAY(values)->ptr[i]); | |||
| rb_ary_push(vertex_array, RARRAY(values)->ptr[i]); | |||
| } | |||
| //Otherwise read each attriute into hashes and use those | |||
| } else { | |||
| @@ -196,6 +196,12 @@ int cIGraph_attribute_add_vertices(igraph_t *graph, long int nv, igraph_vector_p | |||
| igraph_i_attribute_record_t *attr_rec; | |||
| char *s; | |||
| record = rb_hash_new(); | |||
| //For when no attributes are given | |||
| if(igraph_vector_ptr_size(attr) == 0){ | |||
| record = INT2NUM(i+1); | |||
| } | |||
| for (j=0; j<igraph_vector_ptr_size(attr); j++) { | |||
| VALUE key; | |||
| VALUE value; | |||
| @@ -0,0 +1,37 @@ | |||
| #include "igraph.h" | |||
| #include "ruby.h" | |||
| #include "cIGraph.h" | |||
| /* call-seq: | |||
| * graph.subcomponent(v,mode) -> Array | |||
| * | |||
| * Returns an Array of vertices that are in the same component as the vertex v. | |||
| * mode defines the type of the component for directed graphs, possible | |||
| * values: IGraph::OUT: the set of vertices reachable from the vertex, | |||
| * IGraph::IN the set of vertices from which the vertex is reachable, | |||
| * IGraph::ALL the graph is considered as an undirected graph. Note that | |||
| * this is not the same as the union of the previous two. | |||
| */ | |||
| VALUE cIgraph_subcomponent(VALUE self, VALUE v, VALUE mode){ | |||
| igraph_t *graph; | |||
| igraph_neimode_t pmode = NUM2INT(mode); | |||
| igraph_vector_t neis; | |||
| int i; | |||
| VALUE component = rb_ary_new(); | |||
| igraph_vector_init_int(&neis,0); | |||
| Data_Get_Struct(self, igraph_t, graph); | |||
| igraph_subcomponent(graph, &neis, cIGraph_get_vertex_id(self,from), pmode); | |||
| for(i=0;i<igraph_vector_size(&neis);i++){ | |||
| rb_ary_push(component,cIGraph_get_vertex_object(self,VECTOR(neis)[i])); | |||
| } | |||
| igraph_vector_destroy(&neis); | |||
| return component; | |||
| } | |||
| @@ -0,0 +1,176 @@ | |||
| #include "igraph.h" | |||
| #include "ruby.h" | |||
| #include "cIGraph.h" | |||
| /* call-seq: | |||
| * IGraph.read_graph_edgelist(file,mode) -> IGraph | |||
| * | |||
| * Reads an edge list from a File (or any IO) and creates a graph. | |||
| * | |||
| * This format is simply a series of even number integers separated by | |||
| * whitespace. The one edge (ie. two integers) per line format is thus not | |||
| * required (but recommended for readability). Edges of directed graphs are | |||
| * assumed to be in from, to order. | |||
| */ | |||
| VALUE cIGraph_read_graph_edgelist(VALUE self, VALUE file, VALUE directed){ | |||
| VALUE string; | |||
| FILE *stream; | |||
| VALUE new_graph; | |||
| VALUE v_ary; | |||
| igraph_t *graph; | |||
| igraph_bool_t directed_b = 0; | |||
| igraph_vs_t vs; | |||
| igraph_vit_t vit; | |||
| int vid; | |||
| if(directed) | |||
| directed_b = 1; | |||
| new_graph = cIGraph_alloc(cIGraph); | |||
| Data_Get_Struct(new_graph, igraph_t, graph); | |||
| string = rb_funcall(file, rb_intern("read"), 0); | |||
| stream = fmemopen(RSTRING(string)->ptr,RSTRING(string)->len, "r"); | |||
| igraph_read_graph_edgelist(graph, stream, 0, directed_b); | |||
| fclose(stream); | |||
| igraph_vs_all(&vs); | |||
| igraph_vit_create(graph, vs, &vit); | |||
| v_ary = ((VALUE*)graph->attr)[0]; | |||
| while (!IGRAPH_VIT_END(vit)) { | |||
| vid = IGRAPH_VIT_GET(vit); | |||
| rb_ary_push(v_ary,INT2NUM(vid)); | |||
| IGRAPH_VIT_NEXT(vit); | |||
| } | |||
| igraph_vit_destroy(&vit); | |||
| igraph_vs_destroy(&vs); | |||
| return new_graph; | |||
| } | |||
| /* call-seq: | |||
| * graph.write_graph_edgelist(file) -> Integer | |||
| * | |||
| * Writes an edge list to an IO | |||
| * | |||
| * This format is simply a series of even number integers separated by | |||
| * whitespace. The one edge (ie. two integers) per line format is thus not | |||
| * required (but recommended for readability). Edges of directed graphs are | |||
| * assumed to be in from, to order. | |||
| */ | |||
| VALUE cIGraph_write_graph_edgelist(VALUE self, VALUE file){ | |||
| char *buf; | |||
| size_t size; | |||
| FILE *stream; | |||
| igraph_t *graph; | |||
| int e; | |||
| Data_Get_Struct(self, igraph_t, graph); | |||
| stream = open_memstream(&buf,&size); | |||
| e = igraph_write_graph_edgelist(graph, stream); | |||
| fflush(stream); | |||
| rb_funcall(file, rb_intern("write"), 1, rb_str_new(buf,size)); | |||
| fclose(stream); | |||
| return e; | |||
| } | |||
| VALUE cIGraph_read_graph_graphml(VALUE self, VALUE file, VALUE index){ | |||
| VALUE string; | |||
| FILE *stream; | |||
| VALUE new_graph; | |||
| igraph_t *graph; | |||
| new_graph = cIGraph_alloc(cIGraph); | |||
| Data_Get_Struct(new_graph, igraph_t, graph); | |||
| string = rb_funcall(file, rb_intern("read"), 0); | |||
| stream = fmemopen(RSTRING(string)->ptr,RSTRING(string)->len, "r"); | |||
| igraph_read_graph_graphml(graph, stream, NUM2INT(index)); | |||
| fclose(stream); | |||
| return new_graph; | |||
| } | |||
| VALUE cIGraph_write_graph_graphml(VALUE self, VALUE file){ | |||
| char *buf; | |||
| size_t size; | |||
| FILE *stream; | |||
| igraph_t *graph; | |||
| int e; | |||
| Data_Get_Struct(self, igraph_t, graph); | |||
| stream = open_memstream(&buf,&size); | |||
| e = igraph_write_graph_graphml(graph, stream); | |||
| fflush(stream); | |||
| rb_funcall(file, rb_intern("write"), 1, rb_str_new(buf,size)); | |||
| fclose(stream); | |||
| return e; | |||
| } | |||
| VALUE cIGraph_read_graph_pajek(VALUE self, VALUE file){ | |||
| VALUE string; | |||
| FILE *stream; | |||
| VALUE new_graph; | |||
| igraph_t *graph; | |||
| new_graph = cIGraph_alloc(cIGraph); | |||
| Data_Get_Struct(new_graph, igraph_t, graph); | |||
| string = rb_funcall(file, rb_intern("read"), 0); | |||
| stream = fmemopen(RSTRING(string)->ptr,RSTRING(string)->len, "r"); | |||
| igraph_read_graph_pajek(graph, stream); | |||
| fclose(stream); | |||
| return new_graph; | |||
| } | |||
| VALUE cIGraph_write_graph_pajek(VALUE self, VALUE file){ | |||
| char *buf; | |||
| size_t size; | |||
| FILE *stream; | |||
| igraph_t *graph; | |||
| int e; | |||
| Data_Get_Struct(self, igraph_t, graph); | |||
| stream = open_memstream(&buf,&size); | |||
| e = igraph_write_graph_pajek(graph, stream); | |||
| fflush(stream); | |||
| rb_funcall(file, rb_intern("write"), 1, rb_str_new(buf,size)); | |||
| fclose(stream); | |||
| return e; | |||
| } | |||
| @@ -0,0 +1,62 @@ | |||
| #include "igraph.h" | |||
| #include "ruby.h" | |||
| #include "cIGraph.h" | |||
| /* call-seq: | |||
| * graph.layout_random -> IGraphMatrix | |||
| * | |||
| * Returns a random layout | |||
| */ | |||
| VALUE cIGraph_layout_random(VALUE self){ | |||
| igraph_t *graph; | |||
| igraph_matrix_t *res = malloc(sizeof(igraph_matrix_t)); | |||
| Data_Get_Struct(self, igraph_t, graph); | |||
| igraph_matrix_init(res,0,0); | |||
| igraph_layout_random(graph,res); | |||
| return Data_Wrap_Struct(cIGraphMatrix, 0, cIGraph_matrix_free, res); | |||
| } | |||
| VALUE cIGraph_layout_circle(VALUE self){ | |||
| igraph_t *graph; | |||
| igraph_matrix_t *res = malloc(sizeof(igraph_matrix_t)); | |||
| Data_Get_Struct(self, igraph_t, graph); | |||
| igraph_matrix_init(res,0,0); | |||
| igraph_layout_circle(graph,res); | |||
| return Data_Wrap_Struct(cIGraphMatrix, 0, cIGraph_matrix_free, res); | |||
| } | |||
| VALUE cIGraph_layout_fruchterman_reingold(VALUE self, | |||
| VALUE niter, | |||
| VALUE maxdelta, | |||
| VALUE area, | |||
| VALUE coolexp, | |||
| VALUE repulserad, | |||
| VALUE use_seed){ | |||
| igraph_t *graph; | |||
| igraph_matrix_t *res = malloc(sizeof(igraph_matrix_t)); | |||
| Data_Get_Struct(self, igraph_t, graph); | |||
| igraph_matrix_init(res,0,0); | |||
| igraph_layout_fruchterman_reingold(graph,res, | |||
| NUM2INT(niter), | |||
| NUM2DBL(maxdelta), | |||
| NUM2DBL(area), | |||
| NUM2DBL(coolexp), | |||
| NUM2DBL(repulserad), | |||
| use_seed == Qtrue ? 1: 0); | |||
| return Data_Wrap_Struct(cIGraphMatrix, 0, cIGraph_matrix_free, res); | |||
| } | |||
| @@ -0,0 +1,199 @@ | |||
| #include "igraph.h" | |||
| #include "ruby.h" | |||
| #include "cIGraph.h" | |||
| //Classes | |||
| VALUE cIGraphMatrix; | |||
| void cIGraph_matrix_free(void *p){ | |||
| igraph_matrix_destroy(p); | |||
| } | |||
| VALUE cIGraph_matrix_alloc(VALUE klass){ | |||
| igraph_matrix_t *m = malloc(sizeof(igraph_matrix_t)); | |||
| VALUE obj; | |||
| igraph_matrix_init(m, 0, 0); | |||
| obj = Data_Wrap_Struct(klass, 0, cIGraph_matrix_free, m); | |||
| return obj; | |||
| } | |||
| /* Document-method: initialize_copy | |||
| * | |||
| * Internal method for copying IGraph objects. | |||
| */ | |||
| VALUE cIGraph_matrix_init_copy(VALUE copy, VALUE orig){ | |||
| igraph_matrix_t *orig_m; | |||
| igraph_matrix_t *copy_m; | |||
| if (copy == orig) | |||
| return copy; | |||
| if(TYPE(orig) != T_DATA || RDATA(orig)->dfree != (RUBY_DATA_FUNC)cIGraph_free){ | |||
| rb_raise(rb_eTypeError, "Wrong argument type."); | |||
| } | |||
| Data_Get_Struct(copy, igraph_matrix_t, copy_m); | |||
| Data_Get_Struct(orig, igraph_matrix_t, orig_m); | |||
| igraph_matrix_copy(copy_m,orig_m); | |||
| return copy; | |||
| } | |||
| /* call-seq: | |||
| * IGraphMatrix[[x,y,...],...] -> IGraphMatrix | |||
| * | |||
| * IGraphMatrix[[1,2],[3,4]] | |||
| * | |||
| * Creates a graph with four vertices. Vertex 1 is connected to vertex 2. | |||
| * Vertex 3 is connected to vertex 4. | |||
| */ | |||
| VALUE cIGraph_matrix_initialize(int argc, VALUE *argv, VALUE self){ | |||
| igraph_matrix_t *m; | |||
| VALUE rows; | |||
| int nrows; | |||
| int ncols; | |||
| int i; | |||
| int j; | |||
| rb_scan_args(argc,argv,"0*", &rows); | |||
| Data_Get_Struct(self, igraph_matrix_t, m); | |||
| nrows = RARRAY(rows)->len; | |||
| ncols = RARRAY(RARRAY(rows)->ptr[0])->len; | |||
| igraph_matrix_resize(m, nrows, ncols); | |||
| //Loop through rows | |||
| for (i=0; i<nrows; i++) { | |||
| for (j=0; j<ncols; j++){ | |||
| MATRIX(*m,i,j) = NUM2DBL(RARRAY(RARRAY(rows)->ptr[i])->ptr[j]); | |||
| } | |||
| } | |||
| return self; | |||
| } | |||
| VALUE cIGraph_matrix_get(VALUE self, VALUE i, VALUE j){ | |||
| igraph_matrix_t *m; | |||
| Data_Get_Struct(self, igraph_matrix_t, m); | |||
| return rb_float_new(MATRIX(*m,NUM2INT(i),NUM2INT(j))); | |||
| } | |||
| VALUE cIGraph_matrix_set(VALUE self, VALUE i, VALUE j, VALUE x){ | |||
| igraph_matrix_t *m; | |||
| Data_Get_Struct(self, igraph_matrix_t, m); | |||
| MATRIX(*m,NUM2INT(i),NUM2INT(j)) = NUM2DBL(x); | |||
| return x; | |||
| } | |||
| VALUE cIGraph_matrix_each(VALUE self){ | |||
| igraph_matrix_t *m; | |||
| int i; | |||
| int j; | |||
| Data_Get_Struct(self, igraph_matrix_t, m); | |||
| for(i=0;i < m->nrow;i++){ | |||
| for(j=0;j < m->ncol;j++){ | |||
| rb_yield(rb_float_new(MATRIX(*m,i,j))); | |||
| } | |||
| } | |||
| return Qnil; | |||
| } | |||
| VALUE cIGraph_matrix_size(VALUE self){ | |||
| igraph_matrix_t *m; | |||
| Data_Get_Struct(self, igraph_matrix_t, m); | |||
| return LONG2FIX(igraph_matrix_size(m)); | |||
| } | |||
| VALUE cIGraph_matrix_nrow(VALUE self){ | |||
| igraph_matrix_t *m; | |||
| Data_Get_Struct(self, igraph_matrix_t, m); | |||
| return LONG2FIX(igraph_matrix_nrow(m)); | |||
| } | |||
| VALUE cIGraph_matrix_ncol(VALUE self){ | |||
| igraph_matrix_t *m; | |||
| Data_Get_Struct(self, igraph_matrix_t, m); | |||
| return LONG2FIX(igraph_matrix_ncol(m)); | |||
| } | |||
| VALUE cIGraph_matrix_max(VALUE self){ | |||
| igraph_matrix_t *m; | |||
| Data_Get_Struct(self, igraph_matrix_t, m); | |||
| return rb_float_new(igraph_matrix_max(m)); | |||
| } | |||
| VALUE cIGraph_matrix_multiply(VALUE self, VALUE x){ | |||
| igraph_matrix_t *m; | |||
| igraph_matrix_t *n = malloc(sizeof(igraph_matrix_t)); | |||
| VALUE nobj; | |||
| Data_Get_Struct(self, igraph_matrix_t, m); | |||
| igraph_matrix_copy(n,m); | |||
| igraph_matrix_multiply(n, NUM2DBL(x)); | |||
| nobj = Data_Wrap_Struct(cIGraphMatrix, 0, cIGraph_matrix_free, n); | |||
| return nobj; | |||
| } | |||
| VALUE cIGraph_matrix_toa(VALUE self){ | |||
| igraph_matrix_t *m; | |||
| int i; | |||
| int j; | |||
| VALUE a = rb_ary_new(); | |||
| VALUE row; | |||
| Data_Get_Struct(self, igraph_matrix_t, m); | |||
| for(i=0;i < m->nrow;i++){ | |||
| row = rb_ary_new(); | |||
| for(j=0;j < m->ncol;j++){ | |||
| rb_ary_push(row,rb_float_new(MATRIX(*m,i,j))); | |||
| } | |||
| rb_ary_push(a,row); | |||
| } | |||
| return a; | |||
| } | |||
| @@ -0,0 +1,43 @@ | |||
| #include "igraph.h" | |||
| #include "ruby.h" | |||
| #include "cIGraph.h" | |||
| /* call-seq: | |||
| * graph.topological_sorting(mode) -> Array | |||
| * | |||
| * Calculate a possible topological sorting of the graph. A topological | |||
| * sorting of a directed acyclic graph is a linear ordering of its nodes | |||
| * where each node comes before all nodes to which it has edges. Every DAG | |||
| * has at least one topological sort, and may have many. This function | |||
| * returns a possible topological sort among them. If the graph is not | |||
| * acyclic (it has at least one cycle), a partial topological sort is | |||
| * returned and a warning is issued. mode specifies how to use the direction | |||
| * of the edges. For IGRAPH_OUT, the sorting order ensures that each node | |||
| * comes before all nodes to which it has edges, so nodes with no incoming | |||
| * edges go first. For IGRAPH_IN, it is quite the opposite: each node comes | |||
| * before all nodes from which it receives edges. Nodes with no outgoing | |||
| * edges go first. | |||
| */ | |||
| VALUE cIGraph_topological_sorting(VALUE self, VALUE mode){ | |||
| igraph_t *graph; | |||
| igraph_vector_t res; | |||
| igraph_neimode_t pmode = NUM2INT(mode); | |||
| VALUE result = rb_ary_new(); | |||
| int i; | |||
| igraph_vector_init_int(&res,0); | |||
| Data_Get_Struct(self, igraph_t, graph); | |||
| igraph_topological_sorting(graph, &res, pmode); | |||
| for(i=0;i<igraph_vector_size(&res);i++){ | |||
| rb_ary_push(result,cIGraph_get_vertex_object(self,VECTOR(res)[i])); | |||
| } | |||
| igraph_vector_destroy(&res); | |||
| return result; | |||
| } | |||
| @@ -0,0 +1,54 @@ | |||
| require 'test/unit' | |||
| require 'igraph' | |||
| class TestGraph < Test::Unit::TestCase | |||
| def test_graph_size | |||
| assert_equal 4, IGraph.new([1,2,3,4],true).vcount | |||
| assert_equal 2, IGraph.new([1,2,3,4],true).ecount | |||
| end | |||
| def test_eid_get_edge | |||
| assert_nothing_raised do | |||
| IGraph.new(['A','B','C','D'],true).get_eid('A','B') | |||
| end | |||
| graph = IGraph.new(['A','B','C','D'],true) | |||
| eid1 = graph.get_eid('A','B') | |||
| eid2 = graph.get_eid('C','D') | |||
| assert_equal ['A','B'], graph.edge(eid1) | |||
| assert_equal ['C','D'], graph.edge(eid2); | |||
| assert_not_equal eid1,eid2 | |||
| end | |||
| def test_neighbours | |||
| assert_nothing_raised do | |||
| IGraph.new(['A','B','C','D'],true).neighbors('A',IGraph::ALL) | |||
| end | |||
| graph = IGraph.new(['A','B','C','D'],true) | |||
| assert_equal ['B'], graph.neighbors('A',IGraph::ALL) | |||
| assert_equal ['D'], graph.neighbors('C',IGraph::ALL) | |||
| end | |||
| def test_adjacent | |||
| assert_nothing_raised do | |||
| IGraph.new(['A','B','C','D'],true).adjacent('A',IGraph::ALL) | |||
| end | |||
| graph = IGraph.new(['A','B','C','D'],true) | |||
| eid1 = graph.get_eid('A','B') | |||
| eid2 = graph.adjacent('A',IGraph::ALL)[0] | |||
| assert_equal eid1, eid2 | |||
| end | |||
| def test_directed | |||
| assert IGraph.new(['A','B','C','D'],true).is_directed? | |||
| assert !(IGraph.new(['A','B','C','D'],false).is_directed?) | |||
| end | |||
| def test_degree | |||
| graph = IGraph.new(['A','B','C','D'],true) | |||
| assert_equal [1], graph.degree(['A'], IGraph::ALL,true) | |||
| assert_equal [1,1],graph.degree(['A','B'],IGraph::ALL,true) | |||
| assert_raises IGraphError do | |||
| graph.degree('A',IGraph::ALL,true) | |||
| end | |||
| end | |||
| end | |||
| @@ -0,0 +1,13 @@ | |||
| require 'test/unit' | |||
| require 'igraph' | |||
| class TestGraph < Test::Unit::TestCase | |||
| def test_copy | |||
| g = IGraph.new(['A','B','C','D'],true,[1,2]); | |||
| h = g.dup | |||
| assert g.vcount == h.vcount | |||
| assert g['A','B'] == h['A','B'] | |||
| h['A','B'] = g['A','B'] + 1 | |||
| assert g['A','B'] != h['A','B'] | |||
| end | |||
| end | |||
| @@ -0,0 +1,10 @@ | |||
| require 'test/unit' | |||
| require 'igraph' | |||
| class TestGraph < Test::Unit::TestCase | |||
| def test_adj | |||
| graph = IGraph.new(['A','B','C','D'],true) | |||
| assert_equal ['B'], graph.adjacent_vertices('A',IGraph::ALL) | |||
| end | |||
| end | |||
| @@ -0,0 +1,161 @@ | |||
| require 'test/unit' | |||
| require 'igraph' | |||
| require 'stringio' | |||
| class TestGraph < Test::Unit::TestCase | |||
| def test_edgelist_read | |||
| g = nil | |||
| assert_nothing_raised{ | |||
| g = IGraph.read_graph_edgelist(StringIO.new("0 1 2 3"),true) | |||
| } | |||
| assert_instance_of IGraph, g | |||
| assert_equal 4, g.vcount | |||
| assert g.are_connected?(0,1) | |||
| end | |||
| def test_edgelist_write | |||
| g = IGraph.new([0,1,2,3]) | |||
| s = StringIO.new("") | |||
| str = g.write_graph_edgelist(s) | |||
| s.rewind | |||
| assert_equal "0 1\n2 3\n", s.read | |||
| end | |||
| def test_graphml_read | |||
| g = nil | |||
| g = IGraph.read_graph_graphml(StringIO.new(Graphml),0) | |||
| assert_instance_of IGraph, g | |||
| assert_equal '2006-11-12', g.attributes['date'] | |||
| h = g.dup | |||
| assert_equal g.to_a,h.to_a | |||
| assert_equal g.attributes['date'], h.attributes['date'] | |||
| end | |||
| def test_graphml_write | |||
| g = IGraph.new([{'id'=>0,'name'=>'a','type' => 4.0}, | |||
| {'id'=>1,'name'=>'b','type' => 5}, | |||
| {'id'=>2,'type' => 6}, | |||
| {'id'=>3,'name'=>'d'}], | |||
| true, | |||
| [{'eid'=>'e1'}, | |||
| {'eid'=>'e2'}]) | |||
| g.attributes['date'] = 'Friday' | |||
| s = StringIO.new("") | |||
| str = g.write_graph_graphml(s) | |||
| s.rewind | |||
| assert_equal Graphml_out, s.read | |||
| end | |||
| def test_pajek_read_write | |||
| g = nil | |||
| g = IGraph.read_graph_pajek(StringIO.new(Pajek),0) | |||
| assert_instance_of IGraph, g | |||
| assert_equal 4, g.vcount | |||
| assert_equal 1, g[4,1]['weight'] | |||
| h = g.dup | |||
| s = StringIO.new('') | |||
| h.write_graph_pajek(s) | |||
| s.rewind | |||
| str = s.read | |||
| str.gsub!(/\r/,'') | |||
| assert_equal Pajek, str | |||
| end | |||
| Graphml = %q{<?xml version="1.0" encoding="UTF-8"?> | |||
| <!-- This file was written by the JAVA GraphML Library.--> | |||
| <graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3 | |||
| .org/2001/XMLSchema-instance" | |||
| xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://graphml.graphdr | |||
| awing.org/xmlns/1.0/graphml.xsd"> | |||
| <key id="d0" for="node" attr.name="color" attr.type="string">yellow</key> | |||
| <key id="d1" for="edge" attr.name="weight" attr.type="double"/> | |||
| <key id="d2" for="graph" attr.name="date" attr.type="string"></key> | |||
| <graph id="G" edgedefault="undirected"> | |||
| <data key="d2">2006-11-12</data> | |||
| <node id="n0"> | |||
| <data key="d0">green</data> | |||
| <data key="d3">incorrect</data> | |||
| <!-- incorrect attribute key, should issue a warning --> | |||
| </node> | |||
| <node id="n1"/> | |||
| <node id="n2"> | |||
| <data key="d0">blue</data> | |||
| </node> | |||
| <node id="n3"> | |||
| <data key="d0">red</data> | |||
| </node> | |||
| <node id="n4"/> | |||
| <node id="n5"> | |||
| <data key="d0">turquoise</data> | |||
| </node> | |||
| <edge id="e0" source="n0" target="n2"> | |||
| <data key="d1">1.0</data> | |||
| </edge> | |||
| <edge id="e1" source="n0" target="n1"> | |||
| <data key="d1">1.0</data> | |||
| </edge> | |||
| <edge id="e2" source="n1" target="n3"> | |||
| <data key="d1">2.0</data> | |||
| </edge> | |||
| <edge id="e3" source="n3" target="n2"/> | |||
| <edge id="e4" source="n2" target="n4"/> | |||
| <edge id="e5" source="n3" target="n5"/> | |||
| <edge id="e6" source="n5" target="n4"> | |||
| <data key="d1">1.1</data> | |||
| </edge> | |||
| </graph> | |||
| </graphml> | |||
| } | |||
| Graphml_out = %q{<?xml version="1.0" encoding="UTF-8"?> | |||
| <graphml xmlns="http://graphml.graphdrawing.org/xmlns" | |||
| xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |||
| xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns | |||
| http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd"> | |||
| <!-- Created by igraph --> | |||
| <key id="date" for="graph" attr.name="date" attr.type="string"/> | |||
| <key id="name" for="node" attr.name="name" attr.type="string"/> | |||
| <key id="type" for="node" attr.name="type" attr.type="double"/> | |||
| <key id="id" for="node" attr.name="id" attr.type="double"/> | |||
| <key id="eid" for="edge" attr.name="eid" attr.type="string"/> | |||
| <graph id="G" edgedefault="directed"> | |||
| <data key="date">Friday</data> | |||
| <node id="n0"> | |||
| <data key="name">a</data> | |||
| <data key="type">4</data> | |||
| <data key="id">0</data> | |||
| </node> | |||
| <node id="n1"> | |||
| <data key="name">b</data> | |||
| <data key="type">5</data> | |||
| <data key="id">1</data> | |||
| </node> | |||
| <node id="n2"> | |||
| <data key="name"></data> | |||
| <data key="type">6</data> | |||
| <data key="id">2</data> | |||
| </node> | |||
| <node id="n3"> | |||
| <data key="name">d</data> | |||
| <data key="id">3</data> | |||
| </node> | |||
| <edge source="n0" target="n1"> | |||
| <data key="eid">e1</data> | |||
| </edge> | |||
| <edge source="n2" target="n3"> | |||
| <data key="eid">e2</data> | |||
| </edge> | |||
| </graph> | |||
| </graphml> | |||
| } | |||
| Pajek = %q{*Vertices 4 | |||
| *Edges | |||
| 4 1 1 | |||
| 1 2 4 | |||
| 1 3 2 | |||
| 2 3 2 | |||
| } | |||
| end | |||
| @@ -0,0 +1,26 @@ | |||
| require 'test/unit' | |||
| require 'igraph' | |||
| class TestGraph < Test::Unit::TestCase | |||
| def test_random | |||
| g = IGraph.new([1,2,3,4],true) | |||
| l = g.layout_random | |||
| assert_instance_of IGraphMatrix, l | |||
| assert_equal g.vcount, l.nrow | |||
| assert_equal 2, l.ncol | |||
| end | |||
| def test_circle | |||
| g = IGraph.new([1,2,3,4],true) | |||
| l = g.layout_circle | |||
| assert_instance_of IGraphMatrix, l | |||
| assert_equal g.vcount, l.nrow | |||
| assert_equal 2, l.ncol | |||
| end | |||
| def test_fruchterman_reingold | |||
| g = IGraph.new([1,2,3,4],true) | |||
| l = g.layout_fruchterman_reingold(10,1,1,2,1,false) | |||
| assert_instance_of IGraphMatrix, l | |||
| assert_equal g.vcount, l.nrow | |||
| assert_equal 2, l.ncol | |||
| end | |||
| end | |||
| @@ -0,0 +1,32 @@ | |||
| require 'test/unit' | |||
| require 'igraph' | |||
| class TestGraph < Test::Unit::TestCase | |||
| def test_matrix | |||
| m = IGraphMatrix.new([1,2],[3,4]) | |||
| assert_equal 1, m[0,0] | |||
| assert_equal 3, m[1,0] | |||
| end | |||
| def test_set | |||
| m = IGraphMatrix.new([1,2],[3,4]) | |||
| m[0,0] = 6 | |||
| assert_equal 6, m[0,0] | |||
| end | |||
| def test_prop | |||
| m = IGraphMatrix.new([1,2],[3,4]) | |||
| assert_equal 4, m.size | |||
| assert_equal 2, m.nrow | |||
| assert_equal 2, m.ncol | |||
| assert_equal 4, m.max | |||
| end | |||
| def test_op | |||
| m = IGraphMatrix.new([1,2],[3,4]) | |||
| n = m * 2 | |||
| assert_equal 1, m[0,0] | |||
| assert_equal 2, n[0,0] | |||
| end | |||
| def test_to_a | |||
| m = IGraphMatrix.new([1,2],[3,4]) | |||
| assert_equal [[1,2],[3,4]], m.to_a | |||
| end | |||
| end | |||
| @@ -0,0 +1,10 @@ | |||
| require 'test/unit' | |||
| require 'igraph' | |||
| class TestGraph < Test::Unit::TestCase | |||
| def test_top_sort | |||
| g = IGraph.new([1,2,2,3,3,4]) | |||
| assert_equal [1,2,3,4], g.topological_sorting(IGraph::OUT) | |||
| end | |||
| end | |||