| @@ -207,6 +207,14 @@ void Init_igraph(){ | |||
| rb_define_const(cIGraph, "GET_ADJACENCY_LOWER", INT2NUM(1)); | |||
| rb_define_const(cIGraph, "GET_ADJACENCY_BOTH", INT2NUM(2)); | |||
| rb_define_const(cIGraph, "ERDOS_RENYI_GNP", INT2NUM(0)); | |||
| rb_define_const(cIGraph, "ERDOS_RENYI_GNM", INT2NUM(1)); | |||
| rb_define_singleton_method(cIGraph, "grg_game", cIGraph_grg_game, 3); /* in cIGraph_generators_random.c */ | |||
| rb_define_singleton_method(cIGraph, "barabasi_game", cIGraph_barabasi_game, 4); /* in cIGraph_generators_random.c */ | |||
| rb_define_singleton_method(cIGraph, "nonlinear_barabasi_game", cIGraph_nonlinear_barabasi_game, 6); /* in cIGraph_generators_random.c */ | |||
| rb_define_singleton_method(cIGraph, "erdos_renyi_game", cIGraph_erdos_renyi_game, 5); /* in cIGraph_generators_random.c */ | |||
| rb_define_method(cIGraph, "[]", cIGraph_get_edge_attr, 2); /* in cIGraph_attribute_handler.c */ | |||
| rb_define_method(cIGraph, "[]=", cIGraph_set_edge_attr, 3); /* in cIGraph_attribute_handler.c */ | |||
| rb_define_alias (cIGraph, "get_edge_attr", "[]"); | |||
| @@ -328,9 +336,14 @@ void Init_igraph(){ | |||
| rb_define_method(cIGraph, "write_graph_graphml", cIGraph_write_graph_graphml, 1); /* in cIGraph_file.c */ | |||
| rb_define_method(cIGraph, "write_graph_pajek", cIGraph_write_graph_pajek, 1); /* in cIGraph_file.c */ | |||
| rb_define_method(cIGraph, "layout_random", cIGraph_layout_random, 0); /* in cIGraph_layout.c */ | |||
| rb_define_method(cIGraph, "layout_circle", cIGraph_layout_circle, 0); /* in cIGraph_layout.c */ | |||
| rb_define_method(cIGraph, "layout_fruchterman_reingold", cIGraph_layout_fruchterman_reingold, 6); /* in cIGraph_layout.c */ | |||
| rb_define_method(cIGraph, "layout_random", cIGraph_layout_random, 0); /* in cIGraph_layout.c */ | |||
| rb_define_method(cIGraph, "layout_circle", cIGraph_layout_circle, 0); /* in cIGraph_layout.c */ | |||
| rb_define_method(cIGraph, "layout_fruchterman_reingold", cIGraph_layout_fruchterman_reingold, 6); /* in cIGraph_layout.c */ | |||
| rb_define_method(cIGraph, "layout_kamada_kawai", cIGraph_layout_kamada_kawai, 5); /* in cIGraph_layout.c */ | |||
| rb_define_method(cIGraph, "layout_reingold_tilford", cIGraph_layout_reingold_tilford, 1); /* in cIGraph_layout.c */ | |||
| rb_define_method(cIGraph, "layout_reingold_tilford_circular", cIGraph_layout_reingold_tilford_circular, 1); /* in cIGraph_layout.c */ | |||
| rb_define_method(cIGraph, "layout_grid_fruchterman_reingold", cIGraph_layout_grid_fruchterman_reingold, 7); /* in cIGraph_layout.c */ | |||
| rb_define_method(cIGraph, "layout_lgl", cIGraph_layout_lgl, 7); /* in cIGraph_layout.c */ | |||
| //Matrix class | |||
| cIGraphMatrix = rb_define_class("IGraphMatrix", rb_cObject); | |||
| @@ -30,6 +30,15 @@ VALUE cIGraph_alloc(VALUE klass); | |||
| VALUE cIGraph_initialize(int argc, VALUE *argv, VALUE self); | |||
| VALUE cIGraph_init_copy(VALUE copy, VALUE orig); | |||
| //Random graph generators | |||
| VALUE cIGraph_grg_game (VALUE self, VALUE nodes, | |||
| VALUE radius, VALUE torus); | |||
| VALUE cIGraph_barabasi_game(VALUE self, VALUE nodes, | |||
| VALUE m, VALUE outpref, VALUE directed); | |||
| VALUE cIGraph_nonlinear_barabasi_game(VALUE self, VALUE nodes, VALUE power, | |||
| VALUE m, VALUE outpref, VALUE zeroappeal, VALUE directed); | |||
| VALUE cIGraph_erdos_renyi_game (VALUE self, VALUE type, VALUE nodes, VALUE mp, VALUE directed, VALUE loops); | |||
| //Attribute accessors | |||
| int replace_i(VALUE key, VALUE val, VALUE hash); | |||
| VALUE cIGraph_get_edge_attr(VALUE self, VALUE from, VALUE to); | |||
| @@ -171,8 +180,8 @@ VALUE cIGraph_read_graph_pajek (VALUE self, VALUE file); | |||
| VALUE cIGraph_write_graph_pajek (VALUE self, VALUE file); | |||
| //Layouts | |||
| VALUE cIGraph_layout_random(VALUE self); | |||
| VALUE cIGraph_layout_circle(VALUE self); | |||
| VALUE cIGraph_layout_random (VALUE self); | |||
| VALUE cIGraph_layout_circle (VALUE self); | |||
| VALUE cIGraph_layout_fruchterman_reingold(VALUE self, | |||
| VALUE niter, | |||
| VALUE maxdelta, | |||
| @@ -180,6 +189,33 @@ VALUE cIGraph_layout_fruchterman_reingold(VALUE self, | |||
| VALUE coolexp, | |||
| VALUE repulserad, | |||
| VALUE use_seed); | |||
| VALUE cIGraph_layout_kamada_kawai (VALUE self, | |||
| VALUE niter, | |||
| VALUE sigma, | |||
| VALUE initemp, | |||
| VALUE coolexp, | |||
| VALUE kkconst); | |||
| VALUE cIGraph_layout_reingold_tilford (VALUE self, | |||
| VALUE root); | |||
| VALUE cIGraph_layout_reingold_tilford_circular(VALUE self, | |||
| VALUE root); | |||
| VALUE cIGraph_layout_grid_fruchterman_reingold(VALUE self, | |||
| VALUE niter, | |||
| VALUE maxdelta, | |||
| VALUE area, | |||
| VALUE coolexp, | |||
| VALUE repulserad, | |||
| VALUE cellsize, | |||
| VALUE use_seed); | |||
| VALUE cIGraph_layout_lgl(VALUE self, | |||
| VALUE maxit, | |||
| VALUE maxdelta, | |||
| VALUE area, | |||
| VALUE coolexp, | |||
| VALUE repulserad, | |||
| VALUE cellsize, | |||
| VALUE proot); | |||
| //Attributes | |||
| int cIGraph_attribute_init(igraph_t *graph, | |||
| @@ -22,7 +22,7 @@ VALUE cIGraph_layout_random(VALUE self){ | |||
| } | |||
| /* call-seq: | |||
| * graph.layout_random -> IGraphMatrix | |||
| * graph.layout_circle -> IGraphMatrix | |||
| * | |||
| * Returns a layout with nodes laid out around a circle. | |||
| */ | |||
| @@ -41,7 +41,7 @@ VALUE cIGraph_layout_circle(VALUE self){ | |||
| } | |||
| /* call-seq: | |||
| * graph.layout_random -> IGraphMatrix | |||
| * graph.layout_fruchterman_reingold -> IGraphMatrix | |||
| * | |||
| * Places the vertices on a plane according to the Fruchterman-Reingold | |||
| * algorithm. | |||
| @@ -75,3 +75,175 @@ VALUE cIGraph_layout_fruchterman_reingold(VALUE self, | |||
| return Data_Wrap_Struct(cIGraphMatrix, 0, cIGraph_matrix_free, res); | |||
| } | |||
| /* call-seq: | |||
| * graph.layout_kamada_kawai -> IGraphMatrix | |||
| * | |||
| * Places the vertices on a plane according the Kamada-Kawai algorithm. | |||
| * | |||
| * This is a force directed layout, see Kamada, T. and Kawai, S.: An | |||
| * Algorithm for Drawing General Undirected Graphs. Information Processing | |||
| * Letters, 31/1, 7--15, 1989. | |||
| */ | |||
| VALUE cIGraph_layout_kamada_kawai(VALUE self, | |||
| VALUE niter, | |||
| VALUE sigma, | |||
| VALUE initemp, | |||
| VALUE coolexp, | |||
| VALUE kkconst){ | |||
| 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_kamada_kawai(graph,res, | |||
| NUM2INT(niter), | |||
| NUM2DBL(sigma), | |||
| NUM2DBL(initemp), | |||
| NUM2DBL(coolexp), | |||
| NUM2DBL(kkconst)); | |||
| return Data_Wrap_Struct(cIGraphMatrix, 0, cIGraph_matrix_free, res); | |||
| } | |||
| /* call-seq: | |||
| * graph.layout_reingold_tilford -> IGraphMatrix | |||
| * | |||
| * Reingold-Tilford layout for tree graphs | |||
| * | |||
| * Arranges the nodes in a tree where the given node is used as the root. | |||
| * The tree is directed downwards and the parents are centered above its | |||
| * children. For the exact algorithm, see: | |||
| * | |||
| * Reingold, E and Tilford, J: Tidier drawing of trees. IEEE Trans. Softw. | |||
| * Eng., SE-7(2):223--228, 1981 | |||
| * | |||
| * If the given graph is not a tree, a breadth-first search is executed | |||
| * first to obtain a possible spanning tree. | |||
| */ | |||
| VALUE cIGraph_layout_reingold_tilford(VALUE self, | |||
| VALUE root){ | |||
| 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_reingold_tilford(graph,res, | |||
| cIGraph_get_vertex_id(self, root)); | |||
| return Data_Wrap_Struct(cIGraphMatrix, 0, cIGraph_matrix_free, res); | |||
| } | |||
| /* call-seq: | |||
| * graph.layout_reingold_tilford_circular -> IGraphMatrix | |||
| * | |||
| * Reingold-Tilford layout for tree graphs, drawn in a circular style | |||
| * | |||
| * Arranges the nodes in a tree where the given node is used as the root. | |||
| * The tree is directed downwards and the parents are centered above its | |||
| * children. For the exact algorithm, see: | |||
| * | |||
| * Reingold, E and Tilford, J: Tidier drawing of trees. IEEE Trans. Softw. | |||
| * Eng., SE-7(2):223--228, 1981 | |||
| * | |||
| * If the given graph is not a tree, a breadth-first search is executed | |||
| * first to obtain a possible spanning tree. | |||
| */ | |||
| VALUE cIGraph_layout_reingold_tilford_circular(VALUE self, | |||
| VALUE root){ | |||
| 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_reingold_tilford_circular(graph,res, | |||
| cIGraph_get_vertex_id(self, root)); | |||
| return Data_Wrap_Struct(cIGraphMatrix, 0, cIGraph_matrix_free, res); | |||
| } | |||
| /* call-seq: | |||
| * graph.layout_grid_fruchterman_reingold -> IGraphMatrix | |||
| * | |||
| * Places the vertices on a plane according to the Fruchterman-Reingold | |||
| * algorithm. | |||
| * | |||
| * This is a force-directed layout, see Fruchterman, T.M.J. and Reingold, | |||
| * E.M.: Graph Drawing by Force-directed Placement. Software -- Practice and | |||
| * Experience, 21/11, 1129--1164, 1991. | |||
| */ | |||
| VALUE cIGraph_layout_grid_fruchterman_reingold(VALUE self, | |||
| VALUE niter, | |||
| VALUE maxdelta, | |||
| VALUE area, | |||
| VALUE coolexp, | |||
| VALUE repulserad, | |||
| VALUE cellsize, | |||
| 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_grid_fruchterman_reingold(graph,res, | |||
| NUM2INT(niter), | |||
| NUM2DBL(maxdelta), | |||
| NUM2DBL(area), | |||
| NUM2DBL(coolexp), | |||
| NUM2DBL(repulserad), | |||
| NUM2DBL(cellsize), | |||
| use_seed == Qtrue ? 1: 0); | |||
| return Data_Wrap_Struct(cIGraphMatrix, 0, cIGraph_matrix_free, res); | |||
| } | |||
| /* call-seq: | |||
| * graph.layout_lgl -> IGraphMatrix | |||
| * | |||
| * Places the vertices on a plane according to the Fruchterman-Reingold | |||
| * algorithm. | |||
| * | |||
| * This is a force-directed layout, see Fruchterman, T.M.J. and Reingold, | |||
| * E.M.: Graph Drawing by Force-directed Placement. Software -- Practice and | |||
| * Experience, 21/11, 1129--1164, 1991. | |||
| */ | |||
| VALUE cIGraph_layout_lgl(VALUE self, | |||
| VALUE maxit, | |||
| VALUE maxdelta, | |||
| VALUE area, | |||
| VALUE coolexp, | |||
| VALUE repulserad, | |||
| VALUE cellsize, | |||
| VALUE proot){ | |||
| 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_lgl(graph,res, | |||
| NUM2INT(maxit), | |||
| NUM2DBL(maxdelta), | |||
| NUM2DBL(area), | |||
| NUM2DBL(coolexp), | |||
| NUM2DBL(repulserad), | |||
| NUM2DBL(cellsize), | |||
| cIGraph_get_vertex_id(self, proot)); | |||
| return Data_Wrap_Struct(cIGraphMatrix, 0, cIGraph_matrix_free, res); | |||
| } | |||
| @@ -23,4 +23,39 @@ class TestGraph < Test::Unit::TestCase | |||
| assert_equal g.vcount, l.nrow | |||
| assert_equal 2, l.ncol | |||
| end | |||
| def test_kamada_kawai | |||
| g = IGraph.new([1,2,3,4],true) | |||
| l = g.layout_kamada_kawai(10,1,1,2,1) | |||
| assert_instance_of IGraphMatrix, l | |||
| assert_equal g.vcount, l.nrow | |||
| assert_equal 2, l.ncol | |||
| end | |||
| def test_reingold_tilford | |||
| g = IGraph.new([1,2,3,4],true) | |||
| l = g.layout_reingold_tilford(1) | |||
| assert_instance_of IGraphMatrix, l | |||
| assert_equal g.vcount, l.nrow | |||
| assert_equal 2, l.ncol | |||
| end | |||
| def test_reingold_tilford_circular | |||
| g = IGraph.new([1,2,3,4],true) | |||
| l = g.layout_reingold_tilford_circular(1) | |||
| assert_instance_of IGraphMatrix, l | |||
| assert_equal g.vcount, l.nrow | |||
| assert_equal 2, l.ncol | |||
| end | |||
| def test_grid_fruchterman_reingold | |||
| g = IGraph.new([1,2,3,4],true) | |||
| l = g.layout_grid_fruchterman_reingold(10,1,1,2,1,1,false) | |||
| assert_instance_of IGraphMatrix, l | |||
| assert_equal g.vcount, l.nrow | |||
| assert_equal 2, l.ncol | |||
| end | |||
| def test_lgl | |||
| g = IGraph.new([1,2,3,4],true) | |||
| l = g.layout_lgl(10,1,1,2,1,1,1) | |||
| assert_instance_of IGraphMatrix, l | |||
| assert_equal g.vcount, l.nrow | |||
| assert_equal 2, l.ncol | |||
| end | |||
| end | |||
| @@ -16,6 +16,7 @@ require 'tc_dijkstra' | |||
| require 'tc_directedness' | |||
| require 'tc_error_handling' | |||
| require 'tc_file_read_write' | |||
| require 'tc_generators_random' | |||
| require 'tc_independent_vertex_sets' | |||
| require 'tc_isomorphic' | |||
| require 'tc_iterators' | |||