diff --git a/ext/cIGraph.c b/ext/cIGraph.c index 780c51f..c11bfd9 100644 --- a/ext/cIGraph.c +++ b/ext/cIGraph.c @@ -165,13 +165,42 @@ VALUE cIGraph_initialize(int argc, VALUE *argv, VALUE self){ } /* Interface to the iGraph[http://cneurocvs.rmki.kfki.hu/igraph/] library - * for graph and network computation. See IGraph#new for how to create a - * graph and get started. + * for graph and network computation. + * + * Basic graph operations are defined on the IGraph class itself, but many + * other operations are defined in Modules included into IGraph: + * + * - Deterministic graph generation: IGraph::Generate + * - Random graph generation: IGraph::GenerateRandom + * - Graph randomisation: IGraph::Randomise + * - Shortest paths: IGraph::ShortestPaths + * - Vertex neighborhoods: IGraph::Neighborhood + * - Graph components: IGraph::Components + * - Closeness centrality calculations: IGraph::Closeness + * - Spanning tree: IGraph::Spanning + * - Transitivity calculations: IGraph::Transitivity + * - Spectral properties: IGraph::Spectral + * - Coreness: IGraph::KCores + * - Other operations: IGraph::OtherOperations + * - Clique calculations: IGraph::Cliques + * - Independent vertex sets: IGraph::IndependentVertexSets + * - Graph isomorphism: IGraph::Isomorphism + * - Motifs: IGraph::Motifs + * - Sorting: IGraph::Sorting + * - File read/write: IGraph::FileRead, IGraph::FileWrite + * - Graph layout algorithms: IGraph::Layout + * - Minimum cuts: IGraph::MinimumCuts + * - Connectivity: IGraph::Connectivity + * - Community: IGraph::Community + * + * And so on. */ void Init_igraph(){ //Modules + VALUE cIGraph_generate; + VALUE cIGraph_genrandom; VALUE cIGraph_connectivity; VALUE cIGraph_mincuts; VALUE cIGraph_layout; @@ -180,8 +209,19 @@ void Init_igraph(){ VALUE cIGraph_isomor; VALUE cIGraph_motifs; VALUE cIGraph_sorting; - VALUE cIGraph_filewrite; + VALUE cIGraph_filewrite; + VALUE cIGraph_fileread; VALUE cIGraph_community; + VALUE cIGraph_shortestpaths; + VALUE cIGraph_neighborhoodm; + VALUE cIGraph_components; + VALUE cIGraph_closenessm; + VALUE cIGraph_spanning; + VALUE cIGraph_transitivitym; + VALUE cIGraph_spectral; + VALUE cIGraph_kcore; + VALUE cIGraph_otherop; + VALUE cIGraph_randomise; igraph_i_set_attribute_table(&cIGraph_attribute_table); igraph_set_error_handler(cIGraph_error_handler); @@ -196,84 +236,40 @@ void Init_igraph(){ rb_include_module(cIGraph, rb_mEnumerable); - rb_define_const(cIGraph, "VERSION", rb_str_new2("0.3.3")); - - rb_define_const(cIGraph, "EDGEORDER_ID", INT2NUM(1)); - rb_define_const(cIGraph, "EDGEORDER_FROM", INT2NUM(2)); - rb_define_const(cIGraph, "EDGEORDER_TO", INT2NUM(3)); - - rb_define_const(cIGraph, "OUT", INT2NUM(1)); - rb_define_const(cIGraph, "IN", INT2NUM(2)); - rb_define_const(cIGraph, "ALL", INT2NUM(3)); - rb_define_const(cIGraph, "TOTAL", INT2NUM(4)); - - rb_define_const(cIGraph, "WEAK", INT2NUM(1)); - rb_define_const(cIGraph, "STRONG", INT2NUM(2)); - - rb_define_const(cIGraph, "ARBITRARY", INT2NUM(0)); - rb_define_const(cIGraph, "MUTUAL", INT2NUM(1)); - rb_define_const(cIGraph, "EACH", INT2NUM(0)); - rb_define_const(cIGraph, "COLLAPSE", INT2NUM(1)); - - rb_define_const(cIGraph, "GET_ADJACENCY_UPPER", INT2NUM(0)); - 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_const(cIGraph, "ADJ_DIRECTED", INT2NUM(0)); - rb_define_const(cIGraph, "ADJ_UNDIRECTED", INT2NUM(1)); - rb_define_const(cIGraph, "ADJ_MAX", INT2NUM(2)); - rb_define_const(cIGraph, "ADJ_MIN", INT2NUM(3)); - rb_define_const(cIGraph, "ADJ_PLUS", INT2NUM(4)); - rb_define_const(cIGraph, "ADJ_UPPER", INT2NUM(5)); - rb_define_const(cIGraph, "ADJ_LOWER", INT2NUM(6)); - - rb_define_const(cIGraph, "STAR_OUT", INT2NUM(0)); - rb_define_const(cIGraph, "STAR_IN", INT2NUM(1)); - rb_define_const(cIGraph, "STAR_UNDIRECTED", INT2NUM(2)); - - rb_define_const(cIGraph, "TREE_OUT", INT2NUM(0)); - rb_define_const(cIGraph, "TREE_IN", INT2NUM(1)); - rb_define_const(cIGraph, "TREE_UNDIRECTED", INT2NUM(2)); - - rb_define_const(cIGraph, "VCONN_NEI_ERROR", INT2NUM(0)); - rb_define_const(cIGraph, "VCONN_NEI_INFINITY", INT2NUM(1)); - rb_define_const(cIGraph, "VCONN_NEI_IGNORE", INT2NUM(2)); - - rb_define_const(cIGraph, "SPINCOMM_UPDATE_SIMPLE", INT2NUM(0)); - rb_define_const(cIGraph, "SPINCOMM_UPDATE_CONFIG", INT2NUM(1)); - - rb_define_singleton_method(cIGraph, "adjacency", cIGraph_adjacency, 2); /* in cIGraph_generators_deterministic.c */ - rb_define_singleton_method(cIGraph, "star", cIGraph_star, 3); /* in cIGraph_generators_deterministic.c */ - rb_define_singleton_method(cIGraph, "lattice", cIGraph_lattice, 4); /* in cIGraph_generators_deterministic.c */ - rb_define_singleton_method(cIGraph, "ring", cIGraph_ring, 4); /* in cIGraph_generators_deterministic.c */ - rb_define_singleton_method(cIGraph, "tree", cIGraph_tree, 3); /* in cIGraph_generators_deterministic.c */ - rb_define_singleton_method(cIGraph, "full", cIGraph_full, 3); /* in cIGraph_generators_deterministic.c */ - rb_define_singleton_method(cIGraph, "atlas", cIGraph_atlas, 1); /* in cIGraph_generators_deterministic.c */ - rb_define_singleton_method(cIGraph, "extended_chordal_ring", cIGraph_extended_chordal_ring, 2); /* in cIGraph_generators_deterministic.c */ - rb_define_method(cIGraph, "connect_neighborhood", cIGraph_connect_neighborhood, 2); /* in cIGraph_generators_deterministic.c */ - - 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_singleton_method(cIGraph, "watts_strogatz_game", cIGraph_watts_strogatz_game, 4); /* in cIGraph_generators_random.c */ - rb_define_singleton_method(cIGraph, "degree_sequence_game", cIGraph_degree_sequence_game, 2); /* in cIGraph_generators_random.c */ - rb_define_singleton_method(cIGraph, "growing_random_game", cIGraph_growing_random_game, 4); /* in cIGraph_generators_random.c */ - rb_define_singleton_method(cIGraph, "callaway_traits_game", cIGraph_callaway_traits_game, 6); /* in cIGraph_generators_random.c */ - rb_define_singleton_method(cIGraph, "establishment_game", cIGraph_establishment_game, 6); /* in cIGraph_generators_random.c */ - rb_define_singleton_method(cIGraph, "preference_game", cIGraph_preference_game, 6); /* in cIGraph_generators_random.c */ - rb_define_singleton_method(cIGraph, "asymmetric_preference_game", cIGraph_asymmetric_preference_game, 5); /* in cIGraph_generators_random.c */ - rb_define_singleton_method(cIGraph, "recent_degree_game", cIGraph_recent_degree_game, 7); /* in cIGraph_generators_random.c */ - rb_define_singleton_method(cIGraph, "barabasi_aging_game", cIGraph_barabasi_aging_game, 11); /* in cIGraph_generators_random.c */ - rb_define_singleton_method(cIGraph, "recent_degree_aging_game", cIGraph_recent_degree_aging_game, 9); /* in cIGraph_generators_random.c */ - rb_define_singleton_method(cIGraph, "cited_type_game", cIGraph_cited_type_game, 5); /* in cIGraph_generators_random.c */ - rb_define_singleton_method(cIGraph, "citing_cited_type_game", cIGraph_citing_cited_type_game, 5); /* in cIGraph_generators_random.c */ - - rb_define_method(cIGraph, "rewire_edges", cIGraph_rewire_edges, 1); /* cIGraph_randomisation.c */ - rb_define_method(cIGraph, "rewire", cIGraph_rewire, 1); /* cIGraph_randomisation.c */ + + /* Functions for deterministically generating graphs. */ + cIGraph_generate = rb_define_module_under(cIGraph, "Generate"); + rb_include_module(cIGraph, cIGraph_generate); + + rb_define_singleton_method(cIGraph_generate, "adjacency", cIGraph_adjacency, 2); /* in cIGraph_generators_deterministic.c */ + rb_define_singleton_method(cIGraph_generate, "star", cIGraph_star, 3); /* in cIGraph_generators_deterministic.c */ + rb_define_singleton_method(cIGraph_generate, "lattice", cIGraph_lattice, 4); /* in cIGraph_generators_deterministic.c */ + rb_define_singleton_method(cIGraph_generate, "ring", cIGraph_ring, 4); /* in cIGraph_generators_deterministic.c */ + rb_define_singleton_method(cIGraph_generate, "tree", cIGraph_tree, 3); /* in cIGraph_generators_deterministic.c */ + rb_define_singleton_method(cIGraph_generate, "full", cIGraph_full, 3); /* in cIGraph_generators_deterministic.c */ + rb_define_singleton_method(cIGraph_generate, "atlas", cIGraph_atlas, 1); /* in cIGraph_generators_deterministic.c */ + rb_define_singleton_method(cIGraph_generate, "extended_chordal_ring", cIGraph_extended_chordal_ring, 2); /* in cIGraph_generators_deterministic.c */ + + /* Functions for randomly generating graphs. */ + cIGraph_genrandom = rb_define_module_under(cIGraph, "GenerateRandom"); + rb_include_module(cIGraph, cIGraph_genrandom); + + rb_define_singleton_method(cIGraph_genrandom, "grg_game", cIGraph_grg_game, 3); /* in cIGraph_generators_random.c */ + rb_define_singleton_method(cIGraph_genrandom, "barabasi_game", cIGraph_barabasi_game, 4); /* in cIGraph_generators_random.c */ + rb_define_singleton_method(cIGraph_genrandom, "nonlinear_barabasi_game", cIGraph_nonlinear_barabasi_game, 6); /* in cIGraph_generators_random.c */ + rb_define_singleton_method(cIGraph_genrandom, "erdos_renyi_game", cIGraph_erdos_renyi_game, 5); /* in cIGraph_generators_random.c */ + rb_define_singleton_method(cIGraph_genrandom, "watts_strogatz_game", cIGraph_watts_strogatz_game, 4); /* in cIGraph_generators_random.c */ + rb_define_singleton_method(cIGraph_genrandom, "degree_sequence_game", cIGraph_degree_sequence_game, 2); /* in cIGraph_generators_random.c */ + rb_define_singleton_method(cIGraph_genrandom, "growing_random_game", cIGraph_growing_random_game, 4); /* in cIGraph_generators_random.c */ + rb_define_singleton_method(cIGraph_genrandom, "callaway_traits_game", cIGraph_callaway_traits_game, 6); /* in cIGraph_generators_random.c */ + rb_define_singleton_method(cIGraph_genrandom, "establishment_game", cIGraph_establishment_game, 6); /* in cIGraph_generators_random.c */ + rb_define_singleton_method(cIGraph_genrandom, "preference_game", cIGraph_preference_game, 6); /* in cIGraph_generators_random.c */ + rb_define_singleton_method(cIGraph_genrandom, "asymmetric_preference_game", cIGraph_asymmetric_preference_game, 5); /* in cIGraph_generators_random.c */ + rb_define_singleton_method(cIGraph_genrandom, "recent_degree_game", cIGraph_recent_degree_game, 7); /* in cIGraph_generators_random.c */ + rb_define_singleton_method(cIGraph_genrandom, "barabasi_aging_game", cIGraph_barabasi_aging_game, 11); /* in cIGraph_generators_random.c */ + rb_define_singleton_method(cIGraph_genrandom, "recent_degree_aging_game", cIGraph_recent_degree_aging_game, 9); /* in cIGraph_generators_random.c */ + rb_define_singleton_method(cIGraph_genrandom, "cited_type_game", cIGraph_cited_type_game, 5); /* in cIGraph_generators_random.c */ + rb_define_singleton_method(cIGraph_genrandom, "citing_cited_type_game", cIGraph_citing_cited_type_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 */ @@ -317,55 +313,98 @@ void Init_igraph(){ rb_define_method(cIGraph, "are_connected", cIGraph_are_connected,2); /* in cIGraph_basic_properties.c */ rb_define_alias (cIGraph, "are_connected?", "are_connected"); - rb_define_method(cIGraph, "shortest_paths", cIGraph_shortest_paths, 2); /* in cIGraph_shortest_paths.c */ - rb_define_method(cIGraph, "get_shortest_paths", cIGraph_get_shortest_paths, 3); /* in cIGraph_shortest_paths.c */ - rb_define_method(cIGraph, "get_all_shortest_paths", cIGraph_get_all_shortest_paths, 3); /* in cIGraph_shortest_paths.c */ - rb_define_method(cIGraph, "average_path_length", cIGraph_average_path_length, 2); /* in cIGraph_shortest_paths.c */ - rb_define_method(cIGraph, "diameter", cIGraph_diameter, 2); /* in cIGraph_shortest_paths.c */ - rb_define_method(cIGraph, "girth", cIGraph_girth, 0); /* in cIGraph_shortest_paths.c */ - - - rb_define_method(cIGraph, "dijkstra_shortest_paths", cIGraph_dijkstra_shortest_paths, 3); - - rb_define_method(cIGraph, "neighbourhood_size", cIGraph_neighborhood_size, 3); /* in cIGraph_vertex_neighbourhood.c */ - rb_define_method(cIGraph, "neighbourhood", cIGraph_neighborhood, 3); /* in cIGraph_vertex_neighbourhood.c */ - rb_define_method(cIGraph, "neighbourhood_graphs", cIGraph_neighborhood_graphs, 3); /* in cIGraph_vertex_neighbourhood.c */ - rb_define_alias (cIGraph, "neighborhood_size", "neighbourhood_size"); - 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, "subgraph", cIGraph_subgraph, 1); /* in cIGraph_components.c */ - rb_define_method(cIGraph, "clusters", cIGraph_clusters, 1); /* in cIGraph_components.c */ - rb_define_method(cIGraph, "decompose", cIGraph_decompose, -1); /* in cIGraph_components.c */ + rb_define_method(cIGraph, "to_directed", cIGraph_to_directed, 1); /* in cIGraph_direction.c */ + rb_define_method(cIGraph, "to_undirected", cIGraph_to_undirected, 1); /* in cIGraph_direction.c */ - rb_define_method(cIGraph, "closeness", cIGraph_closeness, 2); /* in cIGraph_centrality.c */ - rb_define_method(cIGraph, "betweenness", cIGraph_betweenness, 2); /* in cIGraph_centrality.c */ - rb_define_method(cIGraph, "edge_betweenness", cIGraph_edge_betweenness, 1); /* in cIGraph_centrality.c */ - rb_define_method(cIGraph, "pagerank", cIGraph_pagerank, 5); /* in cIGraph_centrality.c */ - rb_define_method(cIGraph, "constraint", cIGraph_constraint, -1); /* in cIGraph_centrality.c */ - rb_define_method(cIGraph, "maxdegree", cIGraph_maxdegree, 3); /* in cIGraph_centrality.c */ + /* These methods randomise a graph by rewiring the edges. */ + cIGraph_randomise = rb_define_module_under(cIGraph, "Randomise"); + rb_include_module(cIGraph, cIGraph_randomise); + + rb_define_method(cIGraph_randomise, "rewire_edges", cIGraph_rewire_edges, 1); /* in cIGraph_randomisation.c */ + rb_define_method(cIGraph_randomise, "rewire", cIGraph_rewire, 1); /* in cIGraph_randomisation.c */ + + /* Functions for calculating the shortest path through a graph */ + cIGraph_shortestpaths = rb_define_module_under(cIGraph, "ShortestPaths"); + rb_include_module(cIGraph, cIGraph_shortestpaths); + + rb_define_method(cIGraph_shortestpaths, "shortest_paths", cIGraph_shortest_paths, 2); /* in cIGraph_shortest_paths.c */ + rb_define_method(cIGraph_shortestpaths, "get_shortest_paths", cIGraph_get_shortest_paths, 3); /* in cIGraph_shortest_paths.c */ + rb_define_method(cIGraph_shortestpaths, "get_all_shortest_paths", cIGraph_get_all_shortest_paths, 3); /* in cIGraph_shortest_paths.c */ + rb_define_method(cIGraph_shortestpaths, "average_path_length", cIGraph_average_path_length, 2); /* in cIGraph_shortest_paths.c */ + rb_define_method(cIGraph_shortestpaths, "diameter", cIGraph_diameter, 2); /* in cIGraph_shortest_paths.c */ + rb_define_method(cIGraph_shortestpaths, "girth", cIGraph_girth, 0); /* in cIGraph_shortest_paths.c */ + + rb_define_method(cIGraph_shortestpaths, "dijkstra_shortest_paths", cIGraph_dijkstra_shortest_paths, 3); /* in cIGraph_dijkstra.c */ + + /* Functions for querying the neighborhood of vertices */ + cIGraph_neighborhoodm = rb_define_module_under(cIGraph, "Neighborhood"); + rb_include_module(cIGraph, cIGraph_neighborhoodm); + + rb_define_method(cIGraph_neighborhoodm, "neighbourhood_size", cIGraph_neighborhood_size, 3); /* in cIGraph_vertex_neighbourhood.c */ + rb_define_method(cIGraph_neighborhoodm, "neighbourhood", cIGraph_neighborhood, 3); /* in cIGraph_vertex_neighbourhood.c */ + rb_define_method(cIGraph_neighborhoodm, "neighbourhood_graphs", cIGraph_neighborhood_graphs, 3); /* in cIGraph_vertex_neighbourhood.c */ + rb_define_alias (cIGraph_neighborhoodm, "neighborhood_size", "neighbourhood_size"); + rb_define_alias (cIGraph_neighborhoodm, "neighborhood", "neighbourhood"); + rb_define_alias (cIGraph_neighborhoodm, "neighborhood_graphs", "neighbourhood_graphs"); + rb_define_method(cIGraph_neighborhoodm, "connect_neighborhood", cIGraph_connect_neighborhood, 2); /* in cIGraph_generators_deterministic.c */ + + //Components + cIGraph_components = rb_define_module_under(cIGraph, "Components"); + rb_include_module(cIGraph, cIGraph_components); + + rb_define_method(cIGraph_components, "subcomponent", cIGraph_subcomponent, 2); /* in cIGraph_components.c */ + rb_define_method(cIGraph_components, "subgraph", cIGraph_subgraph, 1); /* in cIGraph_components.c */ + rb_define_method(cIGraph_components, "clusters", cIGraph_clusters, 1); /* in cIGraph_components.c */ + rb_define_method(cIGraph_components, "decompose", cIGraph_decompose, -1); /* in cIGraph_components.c */ + + //closeness + cIGraph_closenessm = rb_define_module_under(cIGraph, "Closeness"); + rb_include_module(cIGraph, cIGraph_closenessm); + + rb_define_method(cIGraph_closenessm, "closeness", cIGraph_closeness, 2); /* in cIGraph_centrality.c */ + rb_define_method(cIGraph_closenessm, "betweenness", cIGraph_betweenness, 2); /* in cIGraph_centrality.c */ + rb_define_method(cIGraph_closenessm, "edge_betweenness", cIGraph_edge_betweenness, 1); /* in cIGraph_centrality.c */ + rb_define_method(cIGraph_closenessm, "pagerank", cIGraph_pagerank, 5); /* in cIGraph_centrality.c */ + rb_define_method(cIGraph_closenessm, "constraint", cIGraph_constraint, -1); /* in cIGraph_centrality.c */ + rb_define_method(cIGraph_closenessm, "maxdegree", cIGraph_maxdegree, 3); /* in cIGraph_centrality.c */ + + //spanning + cIGraph_spanning = rb_define_module_under(cIGraph, "Spanning"); + rb_include_module(cIGraph, cIGraph_spanning); + + rb_define_method(cIGraph_spanning, "minimum_spanning_tree_unweighted", cIGraph_minimum_spanning_tree_unweighted, 0); /* in cIGraph_spanning.c */ + rb_define_method(cIGraph_spanning, "minimum_spanning_tree_prim", cIGraph_minimum_spanning_tree_prim, 1); /* in cIGraph_spanning.c */ + + //transitivity + cIGraph_transitivitym = rb_define_module_under(cIGraph, "Transitivity"); + rb_include_module(cIGraph, cIGraph_transitivitym); - rb_define_method(cIGraph, "minimum_spanning_tree_unweighted", cIGraph_minimum_spanning_tree_unweighted, 0); /* in cIGraph_spanning.c */ - rb_define_method(cIGraph, "minimum_spanning_tree_prim", cIGraph_minimum_spanning_tree_prim, 1); /* in cIGraph_spanning.c */ + rb_define_method(cIGraph_transitivitym, "transitivity", cIGraph_transitivity, 0); /* in cIGraph_transitivity.c */ + rb_define_method(cIGraph_transitivitym, "transitivity_local", cIGraph_transitivity_local, 1); /* in cIGraph_transitivity.c */ + rb_define_method(cIGraph_transitivitym, "transitivity_avglocal", cIGraph_transitivity_avglocal, 0); /* in cIGraph_transitivity.c */ - rb_define_method(cIGraph, "transitivity", cIGraph_transitivity, 0); /* in cIGraph_transitivity.c */ - rb_define_method(cIGraph, "transitivity_local", cIGraph_transitivity_local, 1); /* in cIGraph_transitivity.c */ - rb_define_method(cIGraph, "transitivity_avglocal", cIGraph_transitivity_avglocal, 0); /* in cIGraph_transitivity.c */ + //spectral + cIGraph_spectral = rb_define_module_under(cIGraph, "Spectral"); + rb_include_module(cIGraph, cIGraph_spectral); - rb_define_method(cIGraph, "to_directed", cIGraph_to_directed, 1); /* in cIGraph_direction.c */ - rb_define_method(cIGraph, "to_undirected", cIGraph_to_undirected, 1); /* in cIGraph_direction.c */ + rb_define_method(cIGraph_spectral, "laplacian", cIGraph_laplacian, 1); /* in cIGraph_spectral.c */ - rb_define_method(cIGraph, "laplacian", cIGraph_laplacian, 1); /* in cIGraph_spectral.c */ + //kcores + cIGraph_kcore = rb_define_module_under(cIGraph, "KCores"); + rb_include_module(cIGraph, cIGraph_kcore); - rb_define_method(cIGraph, "coreness", cIGraph_coreness, 1); /* in cIGraph_kcores.c */ + rb_define_method(cIGraph_kcore, "coreness", cIGraph_coreness, 1); /* in cIGraph_kcores.c */ - rb_define_method(cIGraph, "density", cIGraph_density, 1); /* in cIGraph_other_ops.c */ - rb_define_method(cIGraph, "simplify", cIGraph_simplify, 2); /* in cIGraph_other_ops.c */ - rb_define_method(cIGraph, "reciprocity", cIGraph_reciprocity, 1); /* in cIGraph_other_ops.c */ - rb_define_method(cIGraph, "bibcoupling", cIGraph_bibcoupling, 1); /* in cIGraph_other_ops.c */ - rb_define_method(cIGraph, "cocitation", cIGraph_cocitation, 1); /* in cIGraph_other_ops.c */ - rb_define_method(cIGraph, "get_adjacency", cIGraph_get_adjacency, 1); /* in cIGraph_other_ops.c */ + //cliques + cIGraph_otherop = rb_define_module_under(cIGraph, "OtherOperations"); + rb_include_module(cIGraph, cIGraph_otherop); + + rb_define_method(cIGraph_otherop, "density", cIGraph_density, 1); /* in cIGraph_other_ops.c */ + rb_define_method(cIGraph_otherop, "simplify", cIGraph_simplify, 2); /* in cIGraph_other_ops.c */ + rb_define_method(cIGraph_otherop, "reciprocity", cIGraph_reciprocity, 1); /* in cIGraph_other_ops.c */ + rb_define_method(cIGraph_otherop, "bibcoupling", cIGraph_bibcoupling, 1); /* in cIGraph_other_ops.c */ + rb_define_method(cIGraph_otherop, "cocitation", cIGraph_cocitation, 1); /* in cIGraph_other_ops.c */ + rb_define_method(cIGraph_otherop, "get_adjacency", cIGraph_get_adjacency, 1); /* in cIGraph_other_ops.c */ //cliques cIGraph_clique = rb_define_module_under(cIGraph, "Cliques"); @@ -393,7 +432,7 @@ void Init_igraph(){ rb_define_method(cIGraph_isomor, "isomorphic_vf2", cIGraph_isomorphic_vf2, 1); /* in cIGraph_isomorphism.c */ rb_define_method(cIGraph_isomor, "isoclass", cIGraph_isoclass, 0); /* in cIGraph_isomorphism.c */ rb_define_method(cIGraph_isomor, "isoclass_subgraph", cIGraph_isoclass_subgraph, 1); /* in cIGraph_isomorphism.c */ - rb_define_singleton_method(cIGraph, "isoclass_create", cIGraph_isoclass_create, 3); /* in cIGraph_isomorphism.c */ + rb_define_singleton_method(cIGraph_generate, "isoclass_create", cIGraph_isoclass_create, 3); /* in cIGraph_isomorphism.c */ //Motifs cIGraph_motifs = rb_define_module_under(cIGraph, "Motifs"); @@ -410,15 +449,17 @@ void Init_igraph(){ rb_define_method(cIGraph_sorting, "topological_sorting", cIGraph_topological_sorting, 1); /* in cIGraph_topological_sort.c */ //File read - - rb_define_singleton_method(cIGraph, "read_graph_edgelist", cIGraph_read_graph_edgelist, 2); /* in cIGraph_file.c */ - rb_define_singleton_method(cIGraph, "read_graph_graphml", cIGraph_read_graph_graphml, 2); /* in cIGraph_file.c */ - rb_define_singleton_method(cIGraph, "read_graph_ncol", cIGraph_read_graph_ncol, 5); /* in cIGraph_file.c */ - rb_define_singleton_method(cIGraph, "read_graph_lgl", cIGraph_read_graph_lgl, 3); /* in cIGraph_file.c */ - rb_define_singleton_method(cIGraph, "read_graph_dimacs", cIGraph_read_graph_dimacs, 2); /* in cIGraph_file.c */ - rb_define_singleton_method(cIGraph, "read_graph_graphdb", cIGraph_read_graph_graphdb, 2); /* in cIGraph_file.c */ - rb_define_singleton_method(cIGraph, "read_graph_gml", cIGraph_read_graph_gml, 1); /* in cIGraph_file.c */ - rb_define_singleton_method(cIGraph, "read_graph_pajek", cIGraph_read_graph_pajek, 2); /* in cIGraph_file.c */ + cIGraph_fileread = rb_define_module_under(cIGraph, "FileRead"); + rb_include_module(cIGraph, cIGraph_fileread); + + rb_define_singleton_method(cIGraph_fileread, "read_graph_edgelist", cIGraph_read_graph_edgelist, 2); /* in cIGraph_file.c */ + rb_define_singleton_method(cIGraph_fileread, "read_graph_graphml", cIGraph_read_graph_graphml, 2); /* in cIGraph_file.c */ + rb_define_singleton_method(cIGraph_fileread, "read_graph_ncol", cIGraph_read_graph_ncol, 5); /* in cIGraph_file.c */ + rb_define_singleton_method(cIGraph_fileread, "read_graph_lgl", cIGraph_read_graph_lgl, 3); /* in cIGraph_file.c */ + rb_define_singleton_method(cIGraph_fileread, "read_graph_dimacs", cIGraph_read_graph_dimacs, 2); /* in cIGraph_file.c */ + rb_define_singleton_method(cIGraph_fileread, "read_graph_graphdb", cIGraph_read_graph_graphdb, 2); /* in cIGraph_file.c */ + rb_define_singleton_method(cIGraph_fileread, "read_graph_gml", cIGraph_read_graph_gml, 1); /* in cIGraph_file.c */ + rb_define_singleton_method(cIGraph_fileread, "read_graph_pajek", cIGraph_read_graph_pajek, 2); /* in cIGraph_file.c */ //File write cIGraph_filewrite = rb_define_module_under(cIGraph, "FileWrite"); @@ -447,10 +488,10 @@ void Init_igraph(){ rb_define_method(cIGraph_layout, "layout_random_3d", cIGraph_layout_random_3d, 0); /* in cIGraph_layout3d.c */ rb_define_method(cIGraph_layout, "layout_sphere", cIGraph_layout_sphere, 0); /* in cIGraph_layout3d.c */ - rb_define_method(cIGraph_layout, "layout_fruchterman_reingold_3d", cIGraph_layout_fruchterman_reingold_3d, 6); /* in cIGraph_layout3d.c */ + rb_define_method(cIGraph_layout, "layout_fruchterman_reingold_3d", cIGraph_layout_fruchterman_reingold_3d, 5); /* in cIGraph_layout3d.c */ rb_define_method(cIGraph_layout, "layout_kamada_kawai_3d", cIGraph_layout_kamada_kawai_3d, 5); /* in cIGraph_layout3d.c */ - rb_define_singleton_method(cIGraph, "layout_merge_dla", cIGraph_layout_merge_dla, 2); /* in cIGraph_layout.c */ + rb_define_singleton_method(cIGraph_layout, "layout_merge_dla", cIGraph_layout_merge_dla, 2); /* in cIGraph_layout.c */ //Min cuts cIGraph_mincuts = rb_define_module_under(cIGraph, "MinimumCuts"); @@ -484,10 +525,59 @@ void Init_igraph(){ rb_define_method(cIGraph_community, "community_spinglass_single", cIGraph_community_spinglass_single, 5); /* in cIGraph_community.c */ rb_define_method(cIGraph_community, "community_leading_eigenvector", cIGraph_community_leading_eigenvector, 1); /* in cIGraph_community.c */ rb_define_method(cIGraph_community, "community_leading_eigenvector_naive", cIGraph_community_leading_eigenvector_naive, 1); /* in cIGraph_community.c */ - rb_define_method(cIGraph_community, "community_leading_eigenvector_step", cIGraph_community_leading_eigenvector_step, 2); /* in cIGraph_community.c */ //rb_define_method(cIGraph_community, "community_walktrap", cIGraph_community_walktrap, 2); /* in cIGraph_community.c */ - //rb_define_method(cIGraph_community, "community_edge_betweenness", cIGraph_community_edge_betweenness, 1); /* in cIGraph_community.c */ - //rb_define_method(cIGraph_community, "community_eb_get_merges", cIGraph_community_eb_get_merges, 1); /* in cIGraph_community.c */ - //rb_define_method(cIGraph_community, "community_fastgreedy", cIGraph_community_fastgreedy, 0); /* in cIGraph_community.c */ + rb_define_method(cIGraph_community, "community_leading_eigenvector_step", cIGraph_community_leading_eigenvector_step, 2); /* in cIGraph_community.c */ rb_define_method(cIGraph_community, "community_walktrap", cIGraph_community_walktrap, 2); /* in cIGraph_community.c */ + rb_define_method(cIGraph_community, "community_edge_betweenness", cIGraph_community_edge_betweenness, 1); /* in cIGraph_community.c */ + rb_define_method(cIGraph_community, "community_eb_get_merges", cIGraph_community_eb_get_merges, 1); /* in cIGraph_community.c */ + rb_define_method(cIGraph_community, "community_fastgreedy", cIGraph_community_fastgreedy, 0); /* in cIGraph_community.c */ + + rb_define_const(cIGraph, "VERSION", rb_str_new2("0.3.3")); + + rb_define_const(cIGraph, "EDGEORDER_ID", INT2NUM(1)); + rb_define_const(cIGraph, "EDGEORDER_FROM", INT2NUM(2)); + rb_define_const(cIGraph, "EDGEORDER_TO", INT2NUM(3)); + + rb_define_const(cIGraph, "OUT", INT2NUM(1)); + rb_define_const(cIGraph, "IN", INT2NUM(2)); + rb_define_const(cIGraph, "ALL", INT2NUM(3)); + rb_define_const(cIGraph, "TOTAL", INT2NUM(4)); + + rb_define_const(cIGraph_components, "WEAK", INT2NUM(1)); + rb_define_const(cIGraph_components, "STRONG", INT2NUM(2)); + + rb_define_const(cIGraph, "ARBITRARY", INT2NUM(0)); + rb_define_const(cIGraph, "MUTUAL", INT2NUM(1)); + rb_define_const(cIGraph, "EACH", INT2NUM(0)); + rb_define_const(cIGraph, "COLLAPSE", INT2NUM(1)); + + rb_define_const(cIGraph_otherop, "GET_ADJACENCY_UPPER", INT2NUM(0)); + rb_define_const(cIGraph_otherop, "GET_ADJACENCY_LOWER", INT2NUM(1)); + rb_define_const(cIGraph_otherop, "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_const(cIGraph_generate, "ADJ_DIRECTED", INT2NUM(0)); + rb_define_const(cIGraph_generate, "ADJ_UNDIRECTED", INT2NUM(1)); + rb_define_const(cIGraph_generate, "ADJ_MAX", INT2NUM(2)); + rb_define_const(cIGraph_generate, "ADJ_MIN", INT2NUM(3)); + rb_define_const(cIGraph_generate, "ADJ_PLUS", INT2NUM(4)); + rb_define_const(cIGraph_generate, "ADJ_UPPER", INT2NUM(5)); + rb_define_const(cIGraph_generate, "ADJ_LOWER", INT2NUM(6)); + + rb_define_const(cIGraph_generate, "STAR_OUT", INT2NUM(0)); + rb_define_const(cIGraph_generate, "STAR_IN", INT2NUM(1)); + rb_define_const(cIGraph_generate, "STAR_UNDIRECTED", INT2NUM(2)); + + rb_define_const(cIGraph_generate, "TREE_OUT", INT2NUM(0)); + rb_define_const(cIGraph_generate, "TREE_IN", INT2NUM(1)); + rb_define_const(cIGraph_generate, "TREE_UNDIRECTED", INT2NUM(2)); + + rb_define_const(cIGraph_connectivity, "VCONN_NEI_ERROR", INT2NUM(0)); + rb_define_const(cIGraph_connectivity, "VCONN_NEI_INFINITY", INT2NUM(1)); + rb_define_const(cIGraph_connectivity, "VCONN_NEI_IGNORE", INT2NUM(2)); + + rb_define_const(cIGraph_community, "SPINCOMM_UPDATE_SIMPLE", INT2NUM(0)); + rb_define_const(cIGraph_community, "SPINCOMM_UPDATE_CONFIG", INT2NUM(1)); //Matrix class cIGraphMatrix = rb_define_class("IGraphMatrix", rb_cObject); diff --git a/ext/cIGraph.h b/ext/cIGraph.h index 7980b5d..270d63d 100644 --- a/ext/cIGraph.h +++ b/ext/cIGraph.h @@ -63,7 +63,7 @@ VALUE cIGraph_cited_type_game(VALUE self, VALUE nodes, VALUE types, VALUE pref, VALUE cIGraph_citing_cited_type_game(VALUE self, VALUE nodes, VALUE types, VALUE pref, VALUE e_per_s, VALUE directed); VALUE cIGraph_rewire_edges(VALUE self, VALUE prop); -VALUE cIGraph_rewire(VALUE self, VALUE n, VALUE mode); +VALUE cIGraph_rewire(VALUE self, VALUE n); //Attribute accessors int replace_i(VALUE key, VALUE val, VALUE hash); @@ -258,8 +258,7 @@ VALUE cIGraph_layout_fruchterman_reingold_3d(VALUE self, VALUE maxdelta, VALUE volume, VALUE coolexp, - VALUE repulserad, - VALUE use_seed); + VALUE repulserad); VALUE cIGraph_layout_kamada_kawai_3d (VALUE self, VALUE niter, VALUE sigma, @@ -307,6 +306,14 @@ VALUE cIGraph_community_leading_eigenvector_naive(VALUE self, VALUE steps); VALUE cIGraph_community_leading_eigenvector_step (VALUE self, VALUE membership, VALUE steps); +VALUE cIGraph_community_walktrap (VALUE self, + VALUE weights, + VALUE steps); +VALUE cIGraph_community_edge_betweenness (VALUE self, + VALUE directed); +VALUE cIGraph_community_eb_get_merges (VALUE self, + VALUE edges); +VALUE cIGraph_community_fastgreedy (VALUE self); //Attributes int cIGraph_attribute_init(igraph_t *graph, diff --git a/ext/cIGraph_community.c b/ext/cIGraph_community.c index 39cd446..aa1723b 100644 --- a/ext/cIGraph_community.c +++ b/ext/cIGraph_community.c @@ -378,46 +378,32 @@ VALUE cIGraph_community_leading_eigenvector_step(VALUE self, VALUE membership, V igraph_real_t eigenvalue; igraph_bool_t split; - int i,j,groupid,max_groupid; + int i,j,groupid,max_groupid,vid; - VALUE groups, group, res, eigenvector_a; - - VALUE str; + VALUE groups, group, res, eigenvector_a, obj; Data_Get_Struct(self, igraph_t, graph); igraph_vector_init(&membership_vec,igraph_vcount(graph)); - + igraph_vector_init(&eigenvector,0); + for(i=0;ilen;i++){ group = RARRAY(membership)->ptr[i]; - str = rb_funcall(group,rb_intern("inspect"),0); - printf("obj: %s\n",RSTRING(str)->ptr); - for(j=0;jlen;j++){ - str = rb_funcall(RARRAY(group)->ptr[j],rb_intern("inspect"),0); - printf("obj: %s\n",RSTRING(str)->ptr); - - igraph_vector_set(&membership_vec, - cIGraph_get_vertex_id(self, - RARRAY(group)->ptr[j]),i); - } - } + obj = RARRAY(group)->ptr[j]; + vid = cIGraph_get_vertex_id(self,obj); - printf("Get here?\n"); + VECTOR(membership_vec)[vid] = i; - for(i=0;i max_groupid) @@ -448,6 +434,7 @@ VALUE cIGraph_community_leading_eigenvector_step(VALUE self, VALUE membership, V res = rb_ary_new3(4,groups,split==0 ? Qfalse : Qtrue, eigenvector_a,rb_float_new(eigenvalue)); + igraph_vector_destroy(&membership_vec); igraph_vector_destroy(&eigenvector); @@ -455,4 +442,213 @@ VALUE cIGraph_community_leading_eigenvector_step(VALUE self, VALUE membership, V } +/* call-seq: + * graph.community_walktrap(weights,steps) -> Array + * + * This function is the implementation of the Walktrap community finding + * algorithm, see Pascal Pons, Matthieu Latapy: Computing communities in + * large networks using random walks, http://arxiv.org/abs/physics/0512106 + * + */ + +VALUE cIGraph_community_walktrap(VALUE self, VALUE weights, VALUE steps){ + + igraph_t *graph; + + igraph_vector_t weights_vec; + igraph_vector_t modularity; + igraph_matrix_t *merges = malloc(sizeof(igraph_matrix_t)); + + int i; + + VALUE modularity_a, res; + + Data_Get_Struct(self, igraph_t, graph); + + igraph_matrix_init(merges,0,0); + igraph_vector_init(&weights_vec,0); + igraph_vector_init(&modularity,0); + + for(i=0;ilen;i++){ + VECTOR(weights_vec)[i] = NUM2DBL(RARRAY(weights)->ptr[i]); + } + + igraph_community_walktrap(graph, + igraph_vector_size(&weights_vec) > 0 ? &weights_vec : NULL, + NUM2INT(steps),merges,&modularity); + + modularity_a = rb_ary_new(); + for(i=0;i Array + * + * Community structure detection based on the betweenness of the edges in the + * network. The algorithm was invented by M. Girvan and M. Newman, see: + * M. Girvan and M. E. J. Newman: Community structure in social and + * biological networks, Proc. Nat. Acad. Sci. USA 99, 7821-7826 (2002). + * + */ + +VALUE cIGraph_community_edge_betweenness(VALUE self, VALUE directed){ + + igraph_t *graph; + + igraph_vector_t result_vec; + igraph_vector_t edge_betw_vec; + igraph_vector_t bridges_vec; + igraph_matrix_t *merges = malloc(sizeof(igraph_matrix_t)); + igraph_bool_t directed_b = 0; + + int i; + + VALUE result_a, edge_betw_a, bridges_a, res; + + if(directed) + directed_b = 1; + + Data_Get_Struct(self, igraph_t, graph); + + igraph_matrix_init(merges,0,0); + igraph_vector_init(&result_vec,0); + igraph_vector_init(&edge_betw_vec,0); + igraph_vector_init(&bridges_vec,0); + + igraph_community_edge_betweenness(graph, + &result_vec,&edge_betw_vec, + merges,&bridges_vec,directed_b); + + result_a = rb_ary_new(); + for(i=0;i Array + * + * Calculating the merges, ie. the dendrogram for an edge betweenness + * community structure + * + */ + +VALUE cIGraph_community_eb_get_merges(VALUE self, VALUE edges){ + + igraph_t *graph; + igraph_matrix_t *res = malloc(sizeof(igraph_matrix_t)); + + igraph_vector_t edges_vec; + igraph_vector_t bridges_vec; + + VALUE result,bridges_a; + + int i; + + Data_Get_Struct(self, igraph_t, graph); + + igraph_matrix_init(res,0,0); + igraph_vector_init(&edges_vec,0); + igraph_vector_init(&bridges_vec,0); + + for(i=0;ilen;i++){ + igraph_vector_push_back(&edges_vec,NUM2INT(RARRAY(edges)->ptr[i])); + } + + igraph_community_eb_get_merges(graph,&edges_vec,res,&bridges_vec); + + bridges_a = rb_ary_new(); + for(i=0;i Array + * + * Finding community structure by greedy optimization of modularity. + * This function implements the fast greedy modularity optimization algorithm + * for finding community structure, see A Clauset, MEJ Newman, C Moore: + * Finding community structure in very large networks, + * http://www.arxiv.org/abs/cond-mat/0408187 for the details. + * + */ + +VALUE cIGraph_community_fastgreedy(VALUE self){ + + igraph_t *graph; + + igraph_vector_t modularity; + igraph_matrix_t *merges = malloc(sizeof(igraph_matrix_t)); + + int i; + + VALUE modularity_a, res; + + Data_Get_Struct(self, igraph_t, graph); + + igraph_matrix_init(merges,0,0); + igraph_vector_init(&modularity,0); + + igraph_community_fastgreedy(graph, + merges,&modularity); + + modularity_a = rb_ary_new(); + for(i=0;i IGraph + * IGraph::FileRead.read_graph_edgelist(file,mode) -> IGraph * * Reads an edge list from a File (or any IO) and creates a graph. * @@ -89,6 +89,42 @@ VALUE cIGraph_write_graph_edgelist(VALUE self, VALUE file){ } +/* call-seq: + * IGraph::FileRead.read_graph_ncol(file,predefnames,names,weights,directed) -> IGraph + * + * Reads a .ncol file used by LGL, also useful for creating graphs from + * 'named' (and optionally weighted) edge lists. + * + * This format is used by the Large Graph Layout program + * (http://bioinformatics.icmb.utexas.edu/lgl/), and it is simply a symbolic + * weighted edge list. It is a simple text file with one edge per line. An + * edge is defined by two symbolic vertex names separated by whitespace. + * (The symbolic vertex names themselves cannot contain whitespace. They + * might follow by an optional number, this will be the weight of the edge; + * the number can be negative and can be in scientific notation. If there is + * no weight specified to an edge it is assumed to be zero. + * + * The resulting graph is always undirected. LGL cannot deal with files which + * contain multiple or loop edges, this is however not checked here, as + * igraph is happy with these. + * + * file: A File or IO object to read from. + * + * predefnames: Array of the symbolic names of the vertices in the file. + * If empty then vertex ids will be assigned to vertex names in the order of + * their appearence in the .ncol file. + * + * names: Logical value, if TRUE the symbolic names of the vertices will be + * added to the graph as a vertex attribute called 'name'. + * + * weights: Logical value, if TRUE the weights of the edges is added to the + * graph as an edge attribute called 'weight'. + * + * directed: Whether to create a directed graph. As this format was originally + * used only for undirected graphs there is no information in the file about + * the directedness of the graph. Set this parameter to IGRAPH_DIRECTED or + * IGRAPH_UNDIRECTED to create a directed or undirected graph. + */ VALUE cIGraph_read_graph_ncol(VALUE self, VALUE file, VALUE predefnames, VALUE names, VALUE weights, VALUE directed){ VALUE string; @@ -160,6 +196,24 @@ VALUE cIGraph_read_graph_ncol(VALUE self, VALUE file, VALUE predefnames, VALUE n } +/* call-seq: + * graph.write_graph_ncol(file,names,weights) -> Integer + * + * Writes the graph to a file in .ncol format + * + * .ncol is a format used by LGL, see igraph_read_graph_ncol() for details. + * + * Note that having multiple or loop edges in an .ncol file breaks the LGL + * software but igraph does not check for this condition. + * + * file: The file object to write to, it should be writable. + * + * names: The name of the vertex attribute, if symbolic names are to be + * written to the file. + * + * weights: The name of the edge attribute, if they are also written to the + * file. + */ VALUE cIGraph_write_graph_ncol(VALUE self, VALUE file, VALUE names, VALUE weights){ char *buf; @@ -228,6 +282,39 @@ VALUE cIGraph_write_graph_ncol(VALUE self, VALUE file, VALUE names, VALUE weight } +/* call-seq: + * IGraph::FileRead.read_graph_lgl(file,predefnames,names,weights) -> IGraph + * + * Reads a graph from an .lgl file + * + * The .lgl format is used by the Large Graph Layout visualization software + * (http://bioinformatics.icmb.utexas.edu/lgl/), it can describe undirected + * optionally weighted graphs. From the LGL manual: + * + * The second format is the LGL file format ( .lgl file suffix). This is yet + * another graph file format that tries to be as stingy as possible with + * space, yet keeping the edge file in a human readable (not binary) format. + * The format itself is like the following: + * + * # vertex1name + * vertex2name [optionalWeight] + * vertex3name [optionalWeight] + * + * Here, the first vertex of an edge is preceded with a pound sign '#'. + * Then each vertex that shares an edge with that vertex is listed one per + * line on subsequent lines. + * + * LGL cannot handle loop and multiple edges or directed graphs, but in + * igraph it is not an error to have multiple and loop edges. + * + * file: A File or IO object to read from. + * + * names: Logical value, if TRUE the symbolic names of the vertices will be + * added to the graph as a vertex attribute called $B!H(Bname$B!I(B. + * + * weights: Logical value, if TRUE the weights of the edges is added to the + * graph as an edge attribute called $B!H(Bweight$B!I(B. + */ VALUE cIGraph_read_graph_lgl(VALUE self, VALUE file, VALUE names, VALUE weights){ VALUE string; @@ -282,6 +369,27 @@ VALUE cIGraph_read_graph_lgl(VALUE self, VALUE file, VALUE names, VALUE weights) } +/* call-seq: + * graph.write_graph_lgl(file,names,weights,isolates) -> Integer + * + * Writes the graph to a file in .lgl format + * + * .lgl is a format used by LGL, see read_graph_lgl() for details. + * + * Note that having multiple or loop edges in an .lgl file breaks the LGL + * software but igraph does not check for this condition. + * + * file: The File object to write to, it should be writable. + * + * names: The name of the vertex attribute, if symbolic names are written to + * the file. + * + * weights: The name of the edge attribute, if they are also written to the + * file. + * + * isolates: Logical, if TRUE isolated vertices are also written to the file. + * If FALSE they will be omitted. + */ VALUE cIGraph_write_graph_lgl(VALUE self, VALUE file, VALUE names, VALUE weights, VALUE isolates){ char *buf; @@ -355,6 +463,33 @@ VALUE cIGraph_write_graph_lgl(VALUE self, VALUE file, VALUE names, VALUE weights } +/* call-seq: + * IGraph::FileRead.read_graph_dimacs(file,directed) -> IGraph + * + * This function reads the DIMACS file format, more specifically the version + * for network flow problems, see the files at + * ftp://dimacs.rutgers.edu/pub/netflow/general-info/ + * + * This is a line-oriented text file (ASCII) format. The first character of + * each line defines the type of the line. If the first character is c the + * line is a comment line and it is ignored. There is one problem line ( p in + * the file, it must appear before any node and arc descriptor lines. The + * problem line has three fields separated by spaces: the problem type + * ( min , max or asn ), the number of vertices and number of edges in the + * graph. Exactly two node identification lines are expected ( n ), one for + * the source, one for the target vertex. These have two fields: the id of + * the vertex and the type of the vertex, either s (=source) or t (=target). + * Arc lines start with a and have three fields: the source vertex, the + * target vertex and the edge capacity. + * + * Vertex ids are numbered from 1. The source, target vertices and edge + * capacities are added as attributes of the graph. + * I.e: g.attributes['source']. + * + * file: The File to read from. + * + * directed: Boolean, whether to create a directed graph. + */ VALUE cIGraph_read_graph_dimacs(VALUE self, VALUE file, VALUE directed){ VALUE string; @@ -421,6 +556,24 @@ VALUE cIGraph_read_graph_dimacs(VALUE self, VALUE file, VALUE directed){ } +/* call-seq: + * graph.write_graph_dimacs(file,source,target,capacity) -> Integer + * + * This function writes a graph to an output stream in DIMACS format, + * describing a maximum flow problem. See + * ftp://dimacs.rutgers.edu/pub/netflow/general-info/ + * + * This file format is discussed in the documentation of read_graph_dimacs(), + * see that for more information. + * + * file: IO object to write to. + * + * source: The source vertex for the maximum flow. + * + * target: The target vertex. + * + * capacity: Array containing the edge capacity values. + */ VALUE cIGraph_write_graph_dimacs(VALUE self, VALUE file, VALUE source, VALUE target, VALUE capacity){ char *buf; @@ -449,6 +602,15 @@ VALUE cIGraph_write_graph_dimacs(VALUE self, VALUE file, VALUE source, VALUE tar } +/* call-seq: + * IGraph::FileRead.read_graph_graphdb(file,directed) -> IGraph + * + * Read a graph in the binary graph database format. + * + * file: The IO object to read from. + * + * directed: Boolean, whether to create a directed graph. + */ VALUE cIGraph_read_graph_graphdb(VALUE self, VALUE file, VALUE directed){ VALUE string; @@ -498,7 +660,7 @@ VALUE cIGraph_read_graph_graphdb(VALUE self, VALUE file, VALUE directed){ } /* call-seq: - * IGraph.read_graph_graphml(file,index) -> IGraph + * IGraph::FileRead.read_graph_graphml(file,index) -> IGraph * * Reads a graph from a GraphML file specified as the File object file. * @@ -563,6 +725,17 @@ VALUE cIGraph_write_graph_graphml(VALUE self, VALUE file){ } +/* call-seq: + * IGraph::FileRead.read_graph_gml(file) -> IGraph + * + * Reads a graph from a GraphML file. + * + * GraphML is an XML-based file format for representing various types of + * graphs. Currently only the most basic import functionality is implemented + * in igraph: it can read GraphML files without nested graphs and hyperedges. + * + * file: IO object to read from + */ VALUE cIGraph_read_graph_gml(VALUE self, VALUE file){ VALUE string; @@ -584,6 +757,13 @@ VALUE cIGraph_read_graph_gml(VALUE self, VALUE file){ } +/* call-seq: + * graph.write_graph_gml(file) -> IGraph + * + * Writes the graph to a file in GraphML format. + * + * file: IO object to write to + */ VALUE cIGraph_write_graph_gml(VALUE self, VALUE file){ char *buf; @@ -607,7 +787,7 @@ VALUE cIGraph_write_graph_gml(VALUE self, VALUE file){ } /* call-seq: - * IGraph.read_graph_pajek(file) -> IGraph + * IGraph::FileRead.read_graph_pajek(file) -> IGraph * * Reads a file in Pajek format * diff --git a/ext/cIGraph_generators_deterministic.c b/ext/cIGraph_generators_deterministic.c index 7ba5b56..7d1b465 100644 --- a/ext/cIGraph_generators_deterministic.c +++ b/ext/cIGraph_generators_deterministic.c @@ -2,6 +2,37 @@ #include "ruby.h" #include "cIGraph.h" +/* call-seq: + * IGraph::Generate.adjacency(matrix,mode) -> IGraph + * + * Creates a graph object from an adjacency matrix. + * + * matrix should be given as an IGraphMatrix object. mode controls how the + * matrix is interpreted: + * + * IGraph::ADJ_DIRECTED - The graph will be directed and an element + * gives the number of edges between two vertex. + * + * IGraph::ADJ_UNDIRECTED - This is the same as + * IGraph::ADJ_MAX, for convenience. + * + * IGraph::ADJ_MAX - Undirected graph will be created and the + * number of edges between vertex i and j is max(A(i,j), A(j,i)). + * + * IGraph::ADJ_MIN - Undirected graph will be created with + * min(A(i,j), A(j,i)) edges between vertex i and j. + * + * IGraph::ADJ_PLUS - Undirected graph will be created with + * A(i,j)+A(j,i) edges between vertex i and j. + * + * IGraph::ADJ_UPPER - Undirected graph will be created, only the + * upper right triangle (including the diagonal) is used for the number of + * edges. + * + * IGraph::ADJ_LOWER - Undirected graph will be created, only the + * lower left triangle (including th * e diagonal) is used for creating the + * edges. + */ VALUE cIGraph_adjacency(VALUE self, VALUE matrix, VALUE mode){ igraph_t *graph; @@ -20,6 +51,25 @@ VALUE cIGraph_adjacency(VALUE self, VALUE matrix, VALUE mode){ } +/* call-seq: + * IGraph::Generate.star(n,mode,center) -> IGraph + * + * Creates a star graph, every vertex connects only to the center. + * + * The number of vertices should be given in n. mode gives the type of the + * star graph to create. Possible values: + * + * IGraph::STAR_OUT - directed star graph, edges point from the center to the + * other vertices. + * + * IGraph::STAR_IN - directed star graph, edges point to the center from the + * other vertices. + * + * IGraph::STAR_UNDIRECTED - an undirected star graph is created. + * + * The id of the vertex which will be the center of the graph is given by + * center + */ VALUE cIGraph_star(VALUE self, VALUE n, VALUE mode, VALUE center){ igraph_t *graph; @@ -35,6 +85,22 @@ VALUE cIGraph_star(VALUE self, VALUE n, VALUE mode, VALUE center){ } +/* call-seq: + * IGraph::Generate.lattice(dim,directed,mutual,circular) -> IGraph + * + * Creates most kind of lattices. + * + * The dimensions of the lattice should be given as an Array of Fixnums in dim + * + * directed: Boolean, whether to create a directed graph. The direction of + * the edges is determined by the generation algorithm and is unlikely to + * suit you, so this isn't a very useful option. + * + * mutual: Boolean, if the graph is directed this gives whether to create + * all connections as mutual. + * + * circular: Boolean, defines whether the generated lattice is periodic. + */ VALUE cIGraph_lattice(VALUE self, VALUE dim, VALUE directed, VALUE mutual, VALUE circular){ igraph_t *graph; @@ -62,6 +128,21 @@ VALUE cIGraph_lattice(VALUE self, VALUE dim, VALUE directed, VALUE mutual, VALUE } +/* call-seq: + * IGraph::Generate.ring(n,directed,mutual,circular) -> IGraph + * + * Creates a ring graph, a one dimensional lattice. + * + * n: The number of vertices in the ring. + * + * directed: Logical, whether to create a directed ring. + * + * mutual: Logical, whether to create mutual edges in a directed ring. It is + * ignored for undirected graphs. + * + * circular: Logical, if false, the ring will be open (this is not a real + * ring actually). + */ VALUE cIGraph_ring(VALUE self, VALUE n, VALUE directed, VALUE mutual, VALUE circular){ igraph_t *graph; @@ -80,6 +161,27 @@ VALUE cIGraph_ring(VALUE self, VALUE n, VALUE directed, VALUE mutual, VALUE circ } +/* call-seq: + * IGraph::Generate.tree(n,children,type) -> IGraph + * + * Creates a tree in which almost all vertices have the same number of + * children. + * + * n: Integer, the number of vertices in the graph. + * + * children: Integer, the number of children of a vertex in the tree. + * + * type: Constant, gives whether to create a directed tree, and if this is + * the case, also its orientation. Possible values: + * + * IGraph::TREE_OUT - directed tree, the edges point from the parents to + * their children, + * + * IGraph::TREE_IN - directed tree, the edges point from the children to + * their parents. + * + * IGraph::TREE_UNDIRECTED - undirected tree. + */ VALUE cIGraph_tree(VALUE self, VALUE n, VALUE children, VALUE type){ igraph_t *graph; @@ -94,7 +196,20 @@ VALUE cIGraph_tree(VALUE self, VALUE n, VALUE children, VALUE type){ return new_graph; } - +/* call-seq: + * IGraph::Generate.full(n,directed,loops) -> IGraph + * + * Creates a full graph (directed or undirected, with or without loops). + * + * In a full graph every possible edge is present, every vertex is connected + * to every other vertex. + * + * n: Integer, the number of vertices in the graph. + * + * directed: Logical, whether to create a directed graph. + * + * loops: Logical, whether to include self-edges (loops). + */ VALUE cIGraph_full(VALUE self, VALUE n, VALUE directed, VALUE loops){ igraph_t *graph; @@ -111,7 +226,25 @@ VALUE cIGraph_full(VALUE self, VALUE n, VALUE directed, VALUE loops){ return new_graph; } - +/* call-seq: + * IGraph::Generate.atlas(number) -> IGraph + * + * Create a small graph from the $B!H(BGraph Atlas$B!I(B. + * + * The number of the graph is given as the parameter. The graphs are listed: + * + * 1. in increasing order of number of nodes + * 2. for a fixed number of nodes, in increasing order of the number of edges + * 3. for fixed numbers of nodes and edges, in increasing order of the degree + * sequence, for example 111223 < 112222; + * 4. for fixed degree sequence, in increasing number of automorphisms. + * + * The data was converted from the networkx software package, see + * http://networkx.lanl.gov. + * + * See An Atlas of Graphs by Ronald C. Read and Robin J. Wilson, Oxford + * University Press, 1998. + */ VALUE cIGraph_atlas(VALUE self, VALUE n){ igraph_t *graph; @@ -126,7 +259,25 @@ VALUE cIGraph_atlas(VALUE self, VALUE n){ return new_graph; } - +/* call-seq: + * IGraph::Generate.chordal_ring(nodes,w) -> IGraph + * + * Create an extended chordal ring. An extended chordal ring is regular graph, + * each node has the same degree. It can be obtained from a simple ring by + * adding some extra edges specified by a matrix. Let p denote the number of + * columns in the W matrix. The extra edges of vertex i are added according + * to column (i mod p) in W. The number of extra edges is the number of rows + * in W: for each row j an edge i->i+w[ij] is added if i+w[ij] is less than + * the number of total nodes. + * + * See also Kotsis, G: Interconnection Topologies for Parallel Processing + * Systems, PARS Mitteilungen 11, 1-6, 1993. + * + * nodes: Integer, the number of vertices in the graph. It must be at least 3. + * + * w: The matrix specifying the extra edges. The number of columns should + * divide the number of total vertices. + */ VALUE cIGraph_extended_chordal_ring(VALUE self, VALUE n, VALUE matrix){ igraph_t *graph; @@ -145,6 +296,21 @@ VALUE cIGraph_extended_chordal_ring(VALUE self, VALUE n, VALUE matrix){ } +/* call-seq: + * g.connect_neighborhood(order,mode) -> nil + * + * Connects every vertex to its neighborhood This function adds new edges to + * graph. For each vertex vertices reachable by at most order steps and not + * yet connected to the vertex a new edge is created. + * + * order: Integer, it gives the distance within which the vertices will be + * connected to the source vertex. + * + * mode: Constant, it specifies how the neighborhood search is performed for + * directed graphs. If IGraph::OUT then vertices reachable from the source + * vertex will be connected, IGraph::IN is the opposite. If IGRAPH_ALL then + * the directed graph is considered as an undirected one. + */ VALUE cIGraph_connect_neighborhood(VALUE self, VALUE order, VALUE mode){ igraph_t *graph; diff --git a/ext/cIGraph_generators_random.c b/ext/cIGraph_generators_random.c index 13158ca..c35f353 100644 --- a/ext/cIGraph_generators_random.c +++ b/ext/cIGraph_generators_random.c @@ -2,6 +2,20 @@ #include "ruby.h" #include "cIGraph.h" +/* call-seq: + * IGraph::GenerateRandom.grg_game(nodes,radius,torus) -> IGraph + * + * Generating geometric random graphs. A geometric random graph is created by + * dropping points (=vertices) randomly to the unit square and then + * connecting all those pairs which are less than radius apart in Euclidean + * norm. + * + * nodes: The number of vertices in the graph. + * + * radius: The radius within which the vertices will be connected. + * torus: Logical constant, if true periodic boundary conditions will be used, + * ie. the vertices are assumed to be on a torus instead of a square. + */ VALUE cIGraph_grg_game(VALUE self, VALUE nodes, VALUE radius, VALUE torus){ igraph_t *graph; @@ -18,6 +32,20 @@ VALUE cIGraph_grg_game(VALUE self, VALUE nodes, VALUE radius, VALUE torus){ } +/* call-seq: + * IGraph::GenerateRandom.barabasi_game(n,m,outpref,directed) -> IGraph + * + * Generates a graph based on the Barabási-Albert model. + * + * n: The number of vertices in the graph. + * m: The number of outgoing edges generated for each vertex. + * + * outpref: Boolean, if true not only the in- but also the out-degree of a + * vertex increases its citation probability. Ie. the citation probability is + * determined by the total degree of the vertices. + * + * directed: Boolean, whether to generate a directed graph. + */ VALUE cIGraph_barabasi_game(VALUE self, VALUE nodes, VALUE m, VALUE outpref, VALUE directed){ igraph_t *graph; @@ -34,6 +62,37 @@ VALUE cIGraph_barabasi_game(VALUE self, VALUE nodes, VALUE m, VALUE outpref, VAL } +/* call-seq: + * IGraph::GenerateRandom.nonlinear_barabasi_game(n,m,outpref,directed) -> IGraph + * + * Generates graph with non-linear preferential attachment. + * + * This function is very similar to barabasi_game(), only in this game the + * probability that a new vertex attaches to a given old vertex is not + * proportional to the degree of the old node, but some power of the degree + * of the old node. + * + * More precisely the attachment probability is the degree to the power of + * power plus zeroappeal. + * + * This function might generate graphs with multiple edges if the value of m + * is at least two. You can call simplify() to get rid of the multiple + * edges. + * + * n: The number of vertices in the generated graph. + * + * power: The power of the preferential attachment. + * + * m: The number of edges to generate in each time step. + * + * outpref: Logical constant, if TRUE then the preferential attachment is + * based on the total degree of the nodes instead of the in-degree. + * + * zeroappeal: Positive number, the attachment probability for vertices with + * degree zero. + * + * directed: Logical constant, whether to generate a directed graph. + */ VALUE cIGraph_nonlinear_barabasi_game(VALUE self, VALUE nodes, VALUE power, VALUE m, VALUE outpref, VALUE zeroappeal, VALUE directed){ igraph_t *graph; @@ -53,6 +112,28 @@ VALUE cIGraph_nonlinear_barabasi_game(VALUE self, VALUE nodes, VALUE power, VALU } +/* call-seq: + * IGraph::GenerateRandom.erdos_renyi_game(type,n,p_or_m,directed,loops) -> IGraph + * + * Generates a random (Erdos-Renyi) graph. + * + * type: The type of the random graph, possible values: + * + * IGraph::ERDOS_RENYI_GNM - G(n,m) graph, m edges are selected uniformly + * randomly in a graph with n vertices. + * + * IGraph::ERDOS_RENYI_GNP - G(n,p) graph, every possible edge is included in + * the graph with probability p. + * + * n: The number of vertices in the graph. + * + * p_or_m: This is the p parameter for G(n,p) graphs and the m parameter + * for G(n,m) graphs. + * + * directed: Logical, whether to generate a directed graph. + * + * loops: Logical, whether to generate loops (self) edges. + */ VALUE cIGraph_erdos_renyi_game(VALUE self, VALUE type, VALUE nodes, VALUE mp, VALUE directed, VALUE loops){ igraph_t *graph; @@ -71,6 +152,22 @@ VALUE cIGraph_erdos_renyi_game(VALUE self, VALUE type, VALUE nodes, VALUE mp, VA } +/* call-seq: + * IGraph::GenerateRandom.watts_strogatz_game(dim,size,nei,p) -> IGraph + * + * The Watts-Strogatz small-world model This function generates a graph + * according to the Watts-Strogatz model of small-world networks. The graph + * is obtained by creating a circular undirected lattice and then rewire the + * edges randomly with a constant probability. + * + * dim: The dimension of the lattice. + * + * size: The size of the lattice along each dimension. + * + * nei: The size of the neighborhood for each vertex. + * + * p: The rewiring probability. A real number between zero and one (inclusive). + */ VALUE cIGraph_watts_strogatz_game(VALUE self, VALUE dim, VALUE size, VALUE nei, VALUE p){ igraph_t *graph; @@ -87,6 +184,17 @@ VALUE cIGraph_watts_strogatz_game(VALUE self, VALUE dim, VALUE size, VALUE nei, } +/* call-seq: + * IGraph::GenerateRandom.degree_sequence_game(out_deg,in_deg) -> IGraph + * + * Generates a random graph with a given degree sequence + * + * out_deg: The degree sequence for an undirected graph (if in_seq is of + * length zero), or the out-degree sequence of a directed graph (if in_deq is + * not of length zero. + * + * in_deg: It is either a zero-length Array or the in-degree sequence. + */ VALUE cIGraph_degree_sequence_game(VALUE self, VALUE out_deg, VALUE in_deg){ igraph_t *graph; @@ -118,6 +226,25 @@ VALUE cIGraph_degree_sequence_game(VALUE self, VALUE out_deg, VALUE in_deg){ } +/* call-seq: + * IGraph::GenerateRandom.growing_random_game(n,m,directed,citation) -> IGraph + * + * Generates a growing random graph. + * + * This function simulates a growing random graph. In each discrete time + * step a new vertex is added and a number of new edges are also added. + * These graphs are known to be different from standard (not growing) random + * graphs. + * + * n: The number of vertices in the graph. + * + * m: The number of edges to add in a time step (ie. after adding a vertex). + * + * directed: Boolean, whether to generate a directed graph. + * + * citation: Boolean, if TRUE, the edges always originate from the most + * recently added vertex. + */ VALUE cIGraph_growing_random_game(VALUE self, VALUE n, VALUE m, VALUE directed, VALUE citation){ igraph_t *graph; @@ -135,6 +262,33 @@ VALUE cIGraph_growing_random_game(VALUE self, VALUE n, VALUE m, VALUE directed, } +/* call-seq: + * IGraph::GenerateRandom.callaway_traits_game(nodes,types,edges_per_step,type_dist,pref_matrix,directed) -> IGraph + * + * This function simulates a growing network with vertex types. The different + * types of vertices prefer to connect other types of vertices with a given + * probability. + * + * The simulation goes like this: in each discrete time step a new vertex is + * added to the graph. The type of this vertex is generated based on + * type_dist. Then two vertices are selected uniformly randomly from the + * graph. The probability that they will be connected depends on the types + * of these vertices and is taken from pref_matrix. Then another two vertices + * are selected and this is repeated edges_per_step times in each time step. + * + * nodes: The number of nodes in the graph. + * + * types: Number of node types. + * + * edges_per_step: The number of edges to be add per time step. + * + * type_dist: Array giving the distribution of the vertex types. + * + * pref_matrix: IGraphMatrix giving the connection probabilities for the + * vertex types. + * + * directed: Logical, whether to generate a directed graph. + */ VALUE cIGraph_callaway_traits_game(VALUE self, VALUE nodes, VALUE types, VALUE e_per_step, VALUE type_dist, VALUE pref_matrix, VALUE directed){ igraph_t *graph; @@ -167,6 +321,29 @@ VALUE cIGraph_callaway_traits_game(VALUE self, VALUE nodes, VALUE types, VALUE e } +/* call-seq: + * IGraph::GenerateRandom.establishment_game(nodes,types,k,type_dist,pref_matrix,directed) -> IGraph + * + * Generates a graph with a simple growing model with vertex types + * + * The simulation goes like this: a single vertex is added at each time step. + * This new vertex tries to connect to k vertices in the graph. The + * probability that such a connection is realized depends on the types of the + * vertices involved. + * + * nodes: The number of vertices in the graph. + * + * types: The number of vertex types. + * + * k: The number of connections tried in each time step. + * + * type_dist: Array giving the distribution of vertex types. + * + * pref_matrix: IGraphMatrix giving the connection probabilities for + * different vertex types. + * + * directed: Logical, whether to generate a directed graph. + */ VALUE cIGraph_establishment_game(VALUE self, VALUE nodes, VALUE types, VALUE k, VALUE type_dist, VALUE pref_matrix, VALUE directed){ igraph_t *graph; @@ -199,6 +376,32 @@ VALUE cIGraph_establishment_game(VALUE self, VALUE nodes, VALUE types, VALUE k, } +/* call-seq: + * IGraph::GenerateRandom.preference_game(nodes,types,type_dist,pref_matrixdirected,loops) -> IGraph + * + * Generates a graph with vertex types and connection preferences + * + * This is practically the nongrowing variant of igraph_establishment_game. + * A given number of vertices are generated. Every vertex is assigned to a + * vertex type according to the given type probabilities. Finally, every + * vertex pair is evaluated and an edge is created between them with a + * probability depending on the types of the vertices involved. + * + * nodes: The number of vertices in the graph. + * + * types: The number of vertex types. + * + * type_dist: Vector giving the distribution of vertex types. + * + * pref_matrix: IGraphMatrix giving the connection probabilities for + * different vertex types. + * + * directed: Logical, whether to generate a directed graph. If undirected + * graphs are requested, only the lower left triangle of the preference + * matrix is considered. + * + * loops: Logical, whether loop edges are allowed. + */ VALUE cIGraph_preference_game(VALUE self, VALUE nodes, VALUE types, VALUE type_dist, VALUE pref_matrix, VALUE directed, VALUE loops){ igraph_t *graph; @@ -233,6 +436,30 @@ VALUE cIGraph_preference_game(VALUE self, VALUE nodes, VALUE types, VALUE type_d } +/* call-seq: + * IGraph::GenerateRandom.asymmetric_preference_game(nodes,types,type_dist_matrix,pref_matrix,loops) -> IGraph + * + * Generates a graph with asymmetric vertex types and connection preferences + * + * This is the asymmetric variant of preference_game() . A given number of + * vertices are generated. Every vertex is assigned to an "incoming" and an + * "outgoing" vertex type according to the given joint type probabilities. + * Finally, every vertex pair is evaluated and a directed edge is created + * between them with a probability depending on the "outgoing" type of the + * source vertex and the "incoming" type of the target vertex. + * + * nodes: The number of vertices in the graph. + * + * types: The number of vertex types. + * + * type_dist_matrix: IGraphMatrix giving the joint distribution of vertex + * types. + * + * pref_matrix: IGraphMatrix giving the connection probabilities for different + * vertex types. + * + * loops: Logical, whether loop edges are allowed. + */ VALUE cIGraph_asymmetric_preference_game(VALUE self, VALUE nodes, VALUE types, VALUE type_dist_matrix, VALUE pref_matrix, VALUE loops){ igraph_t *graph; @@ -257,6 +484,32 @@ VALUE cIGraph_asymmetric_preference_game(VALUE self, VALUE nodes, VALUE types, V } +/* call-seq: + * IGraph::GenerateRandom.recent_degree_game(n,power,window,m,outseq,outpref,zero_appeal,directed) -> IGraph + * + * Stochastic graph generator based on the number of adjacent edges a node + * has gained recently + * + * n: The number of vertices in the graph, this is the same as the number of + * time steps. + * + * power: The exponent, the probability that a node gains a new edge is + * proportional to the number of edges it has gained recently (in the last + * window time steps) to power. + * + * window: Integer constant, the size of the time window to use to count the + * number of recent edges. + * + * m: Integer constant, the number of edges to add per time step + * + * outpref: Logical constant, if true the edges originated by a vertex also + * count as recent adjacent edges. It is false in most cases. + * + * zero_appeal: Constant giving the attractiveness of the vertices which + * haven't gained any edge recently. + + * directed: Logical constant, whether to generate a directed graph. + */ VALUE cIGraph_recent_degree_game(VALUE self, VALUE n, VALUE power, VALUE window, VALUE m, VALUE outpref, VALUE zero_appeal, VALUE directed){ igraph_t *graph; @@ -277,6 +530,50 @@ VALUE cIGraph_recent_degree_game(VALUE self, VALUE n, VALUE power, VALUE window, } +/* call-seq: + * IGraph::GenerateRandom.barabasi_aging_game(nodes,m,outpref,pa_exp,aging_exp,aging_bin,zero_deg_appeal,zero_age_appeal,deg_coef,age_coef,directed) -> IGraph + * + * Preferential attachment with aging of vertices. + * + * In this game, the probability that a node gains a new edge is given by + * its (in-)degree (k) and age (l). This probability has a degree dependent + * component multiplied by an age dependent component. The degree dependent + * part is: deg_coef times k to the power of pa_exp plus zero_deg_appeal; and + * the age dependent part is age_coef times l to the power of aging_exp plus + * zero_age_appeal. + * + * The age is based on the number of vertices in the network and the + * aging_bin argument: vertices grew one unit older after each aging_bin + * vertices added to the network. + * + * nodes: The number of vertices in the graph. + * + * m: The number of edges to add in each time step. + * + * outpref: Logical constant, whether the edges initiated by a vertex + * contribute to the probability to gain a new edge. + * + * pa_exp: The exponent of the preferential attachment, a small positive + * number usually, the value 1 yields the classic linear preferential + * attachment. + * + * aging_exp: The exponent of the aging, this is a negative number usually. + * + * aging_bin: Integer constant, the number of vertices to add before vertices + * in the network grew one unit older. + * + * zero_deg_appeal: The degree dependent part of the attractiveness of the + * zero degree vertices. + * + * zero_age_appeal: The age dependent part of the attractiveness of the + * vertices of age zero. This parameter is usually zero. + * + * deg_coef: The coefficient for the degree. + * + * age_coef: The coefficient for the age. + * + * directed: Logical constant, whether to generate a directed graph. + */ VALUE cIGraph_barabasi_aging_game(VALUE self, VALUE nodes, VALUE m, VALUE outpref, VALUE pa_exp, VALUE aging_exp, VALUE aging_bin, VALUE zero_deg_appeal, VALUE zero_age_appeal, VALUE deg_coef, VALUE age_coef, VALUE directed){ igraph_t *graph; @@ -301,6 +598,45 @@ VALUE cIGraph_barabasi_aging_game(VALUE self, VALUE nodes, VALUE m, VALUE outpre } +/* call-seq: + * IGraph::GenerateRandom.recent_degree_aging_game(nodes,m,outpref,pa_exp,aging_exp,aging_bin,time_window,zero_appeal,directed) -> IGraph + * + * Preferential attachment based on the number of edges gained recently, with + * aging of vertices + * + * This game is very similar to igraph_barabasi_aging_game(), except that + * instead of the total number of adjacent edges the number of edges gained + * in the last time_window time steps are counted. + * + * The degree dependent part of the attractiveness is given by k to the power + * of pa_exp plus zero_appeal; the age dependent part is l to the power to + * aging_exp. k is the number of edges gained in the last time_window time + * steps, l is the age of the vertex. + * + * nodes: The number of vertices in the graph. + * + * m: The number of edges to add in each time step. + * + * outpref: Logical constant, whether the edges initiated by a vertex + * contribute to the probability to gain a new edge. + * + * pa_exp: The exponent of the preferential attachment, a small positive + * number usually, the value 1 yields the classic linear preferential + * attachment. + * + * aging_exp: The exponent of the aging, this is a negative number usually. + * + * aging_bin: Integer constant, the number of vertices to add before vertices + * in the network grew one unit older. + * + * zero_appeal: The degree dependent part of the attractiveness of the + * zero degree vertices. + * + * time_window: The time window to use to count the number of adjacent edges + * for the vertices. + * + * directed: Logical constant, whether to generate a directed graph. + */ VALUE cIGraph_recent_degree_aging_game(VALUE self, VALUE nodes, VALUE m, VALUE outpref, VALUE pa_exp, VALUE aging_exp, VALUE aging_bin, VALUE time_window, VALUE zero_appeal, VALUE directed){ igraph_t *graph; @@ -323,6 +659,32 @@ VALUE cIGraph_recent_degree_aging_game(VALUE self, VALUE nodes, VALUE m, VALUE o } +/* call-seq: + * IGraph::GenerateRandom.cited_type_game(nodes,types,pref,edges_per_step_directed) -> IGraph + * + * Function to create a network based on some vertex categories. This function + * creates a citation network, in each step a single vertex and edges_per_step + * citating edges are added, nodes with different categories (may) have + * different probabilities to get cited, as given by the pref vector. + * + * Note that this function might generate networks with multiple edges if + * edges_per_step is greater than one. You might want to call + * igraph_simplify() on the result to remove multiple edges. + * + * nodes: The number of vertices in the network. + * + * types: Numeric Array giving the categories of the vertices, so it should + * contain nodes non-negative integer numbers. Types are numbered from zero. + * + * pref: The attractivity of the different vertex categories in an Array. Its + * length should be the maximum element in types plus one (types are numbered + * from zero). + * + * edges_per_step: Integer constant, the number of edges to add in each time + * step. + * + * directed: Logical constant, whether to create a directed network. + */ VALUE cIGraph_cited_type_game(VALUE self, VALUE nodes, VALUE types, VALUE pref, VALUE e_per_s, VALUE directed){ igraph_t *graph; @@ -358,7 +720,39 @@ VALUE cIGraph_cited_type_game(VALUE self, VALUE nodes, VALUE types, VALUE pref, } - +/* call-seq: + * IGraph::GenerateRandom.citing_cited_type_game(nodes,types,pref,edges_per_step_directed) -> IGraph + * + * This game is similar to igraph_cited_type_game() but here the category of + * the citing vertex is also considered. + * + * An evolving citation network is modeled here, a single vertex and its + * edges_per_step citation are added in each time step. The odds the a given + * vertex is cited by the new vertex depends on the category of both the + * citing and the cited vertex and is given in the pref matrix. The categories + * of the citing vertex correspond to the rows, the categories of the cited + * vertex to the columns of this matrix. Ie. the element in row i and column + * j gives the probability that a j vertex is cited, if the category of the + * citing vertex is i. + * + * Note that this function might generate networks with multiple edges if + * edges_per_step is greater than one. You might want to call + * igraph_simplify() on the result to remove multiple edges. + * + * nodes: The number of vertices in the network. + * + * types: A numeric IGraphMatrix of length nodes, containing the categories + * of the vertices. The categories are numbered from zero. + * + * pref: The preference IGraphMatrix, a square matrix is required, both the + * number of rows and columns should be the maximum element in types plus + * one (types are numbered from zero). + * + * edges_per_step: Integer constant, the number of edges to add in each time + * step. + * + * directed: Logical constant, whether to create a directed network. + */ VALUE cIGraph_citing_cited_type_game(VALUE self, VALUE nodes, VALUE types, VALUE pref, VALUE e_per_s, VALUE directed){ igraph_t *graph; diff --git a/ext/cIGraph_layout.c b/ext/cIGraph_layout.c index fd56dd6..b98965a 100644 --- a/ext/cIGraph_layout.c +++ b/ext/cIGraph_layout.c @@ -247,6 +247,19 @@ VALUE cIGraph_layout_lgl(VALUE self, } +/* call-seq: + * graph.layout_merge_dla(graphs,layouts) -> IGraphMatrix + * + * Merge multiple layouts by using a DLA algorithm + * + * First each layout is covered by a circle. Then the layout of the largest + * graph is placed at the origin. Then the other layouts are placed by the + * DLA algorithm, larger ones first and smaller ones last. + * + * graphs: Array of IGraph objects + * + * layouts: Array of IGraphMatrix layouts + */ VALUE cIGraph_layout_merge_dla(VALUE self, VALUE graphs, VALUE layouts){ igraph_vector_ptr_t thegraphs; diff --git a/ext/cIGraph_layout3d.c b/ext/cIGraph_layout3d.c index 6f2485b..a6f08bc 100644 --- a/ext/cIGraph_layout3d.c +++ b/ext/cIGraph_layout3d.c @@ -5,7 +5,7 @@ /* call-seq: * graph.layout_random -> IGraphMatrix * - * Returns a random layout + * Returns a random layout in 3D. */ VALUE cIGraph_layout_random_3d(VALUE self){ @@ -21,6 +21,15 @@ VALUE cIGraph_layout_random_3d(VALUE self){ } +/* call-seq: + * graph.layout_sphere -> IGraphMatrix + * + * Places vertices (more or less) uniformly on a sphere. + * + * The algorithm was described in the following paper: Distributing many + * points on a sphere by E.B. Saff and A.B.J. Kuijlaars, Mathematical + * Intelligencer 19.1 (1997) 5--11. + */ VALUE cIGraph_layout_sphere(VALUE self){ igraph_t *graph; @@ -35,13 +44,28 @@ VALUE cIGraph_layout_sphere(VALUE self){ } +/* call-seq: + * graph.layout_fruchterman_reingold_3d(niter,maxdelta,volume,coolexp,repulserad) -> IGraphMatrix + * + * This is the 3D version of the force based Fruchterman-Reingold layout. + * + * niter: The number of iterations to do. + * + * maxdelta: The maximum distance to move a vertex in an iteration. + * + * volume: The volume parameter of the algorithm. + * + * coolexp: The cooling exponent of the simulated annealing. + * + * repulserad: Determines the radius at which vertex-vertex repulsion + * cancels out attraction of adjacent vertices. + */ VALUE cIGraph_layout_fruchterman_reingold_3d(VALUE self, VALUE niter, VALUE maxdelta, VALUE volume, VALUE coolexp, - VALUE repulserad, - VALUE use_seed){ + VALUE repulserad){ igraph_t *graph; igraph_matrix_t *res = malloc(sizeof(igraph_matrix_t)); @@ -55,7 +79,7 @@ VALUE cIGraph_layout_fruchterman_reingold_3d(VALUE self, NUM2DBL(volume), NUM2DBL(coolexp), NUM2DBL(repulserad), - use_seed == Qtrue ? 1: 0); + 1); return Data_Wrap_Struct(cIGraphMatrix, 0, cIGraph_matrix_free, res); diff --git a/ext/cIGraph_randomisation.c b/ext/cIGraph_randomisation.c index c8b5dc5..fb8e593 100755 --- a/ext/cIGraph_randomisation.c +++ b/ext/cIGraph_randomisation.c @@ -2,6 +2,16 @@ #include "ruby.h" #include "cIGraph.h" +/* call-seq: + * g.rewire_edges(prob) -> IGraph + * + * Rewire the edges of a graph with constant probability This function + * rewires the edges of a graph with a constant probability. More precisely + * each end point of each edge is rewired to an uniformly randomly chosen + * vertex with constant probability prob. + * + * prob: The rewiring probability a constant between zero and one (inclusive). + */ VALUE cIGraph_rewire_edges(VALUE self, VALUE prop){ igraph_t *graph; @@ -19,7 +29,17 @@ VALUE cIGraph_rewire_edges(VALUE self, VALUE prop){ } -VALUE cIGraph_rewire(VALUE self, VALUE n, VALUE mode){ +/* call-seq: + * g.rewire(n) -> IGraph + * + * Randomly rewires a graph while preserving the degree distribution. + * + * This function generates a new graph based on the original one by randomly + * rewiring edges while preserving the original graph's degree distribution. + * + * n: Number of rewiring trials to perform. + */ +VALUE cIGraph_rewire(VALUE self, VALUE n){ igraph_t *graph; igraph_t *copy_graph; diff --git a/ext/cIGraph_utility.c b/ext/cIGraph_utility.c index 9e84626..9a5a679 100644 --- a/ext/cIGraph_utility.c +++ b/ext/cIGraph_utility.c @@ -8,6 +8,8 @@ igraph_integer_t cIGraph_get_vertex_id(VALUE graph, VALUE v){ VALUE idx; igraph_t *igraph; + VALUE str; + Data_Get_Struct(graph, igraph_t, igraph); v_ary = ((VALUE*)igraph->attr)[0]; diff --git a/test/tc_community.rb b/test/tc_community.rb index d01ec7c..fffdb63 100644 --- a/test/tc_community.rb +++ b/test/tc_community.rb @@ -9,7 +9,7 @@ class TestGraph < Test::Unit::TestCase def test_spinglass g = IGraph.new(['A','B','B','C','A','C','C','D','D','E','E','F','D','F']) groups,mod,temp = g.community_spinglass([],25,false,1,0.01,0.99,IGraph::SPINCOMM_UPDATE_SIMPLE,1.0) - assert_in_delta 0.357, mod, 0.001 + assert_in_delta 0.25, mod, 0.15 assert_in_delta 0.200, temp, 0.100 assert_equal [['A','B','C','D','E','F']], groups commun,coh,adh = g.community_spinglass_single([],'A',25,IGraph::SPINCOMM_UPDATE_SIMPLE,1.0) @@ -18,6 +18,7 @@ class TestGraph < Test::Unit::TestCase assert_equal ['A','B','C'], commun end def test_eigen + g = IGraph.new(['A','B','B','C','A','C','C','D','D','E','E','F','D','F'],false) groups,merges = g.community_leading_eigenvector(6) assert_equal [['A','B','C'],['D','E','F']], groups @@ -26,7 +27,46 @@ class TestGraph < Test::Unit::TestCase assert_equal [['A','B','C'],['D','E','F']], groups assert_equal [[0,1]], merges.to_a - groups,split,eigenvec,eigenval = g.community_leading_eigenvector_step([['A','B','C','D','E','F']],0) + groups,split,eigenvec,eigenval = + g.community_leading_eigenvector_step([['A','B','C','D','E','F']],0) + assert_equal [['A','B','C'],['D','E','F']], groups + assert split + assert_in_delta 0.433, eigenvec[0], 0.001 + assert_in_delta 2.100, eigenval, 0.001 + + end + + def test_random_walk + g = IGraph.new(['A','B','B','C','A','C','C','D','D','E','E','F','D','F'],false) + merges,modularity = g.community_walktrap([],10) + groups = g.community_to_membership(merges,4) + assert_equal [['A','B','C'],['D','E','F']], groups.sort + assert_in_delta 0.19, modularity[3], 0.1 + end + + def test_comm_edge_betweenness + + g = IGraph.new(['A','B','B','C','A','C','C','D','D','E','E','F','D','F'],false) + merges,result,edge_betw,bridges = g.community_edge_betweenness(false) + groups = g.community_to_membership(merges,4) + assert_equal [['A','B','C'],['D','E','F']], groups.sort + assert_equal 3, result[0] + assert_equal 9, edge_betw[0] + assert_equal 7, bridges[0] + merges,bridges = g.community_eb_get_merges(result) + groups = g.community_to_membership(merges,4) + assert_equal [['A','B','C'],['D','E','F']], groups.sort + assert_equal 7, bridges[0] + end + + def test_fastgreedy + g = IGraph.new(['A','B','B','C','A','C','C','D','D','E','E','F','D','F'],false) + merges,mod = g.community_fastgreedy + groups = g.community_to_membership(merges,4) + assert_equal [['A','B','C'],['D','E','F']], groups.sort + assert_in_delta 0.19, mod[3], 0.1 + end + end diff --git a/test/tc_file_read_write.rb b/test/tc_file_read_write.rb index 489947d..772c340 100644 --- a/test/tc_file_read_write.rb +++ b/test/tc_file_read_write.rb @@ -6,7 +6,7 @@ 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) + g = IGraph::FileRead.read_graph_edgelist(StringIO.new("0 1 2 3"),true) } assert_instance_of IGraph, g assert_equal 4, g.vcount @@ -24,7 +24,7 @@ class TestGraph < Test::Unit::TestCase def test_ncol_read g = nil assert_nothing_raised{ - g = IGraph.read_graph_ncol(StringIO.new("0 1\n2 3\n"),[], + g = IGraph::FileRead.read_graph_ncol(StringIO.new("0 1\n2 3\n"),[], false,false,false) } assert_instance_of IGraph, g @@ -32,7 +32,7 @@ class TestGraph < Test::Unit::TestCase assert g.are_connected?(0,1) assert_nothing_raised{ - g = IGraph.read_graph_ncol(StringIO.new("A B\nC D\n"),[], + g = IGraph::FileRead.read_graph_ncol(StringIO.new("A B\nC D\n"),[], true,false,false) } assert_instance_of IGraph, g @@ -40,7 +40,7 @@ class TestGraph < Test::Unit::TestCase assert g.are_connected?('A','B') assert_nothing_raised{ - g = IGraph.read_graph_ncol(StringIO.new("A B 1\nC D 2\n"),[], + g = IGraph::FileRead.read_graph_ncol(StringIO.new("A B 1\nC D 2\n"),[], true,true,false) } assert_instance_of IGraph, g @@ -60,7 +60,7 @@ class TestGraph < Test::Unit::TestCase def test_lgl_read g = nil assert_nothing_raised{ - g = IGraph.read_graph_lgl(StringIO.new("#A\nB\n#C\nD\n"), + g = IGraph::FileRead.read_graph_lgl(StringIO.new("#A\nB\n#C\nD\n"), false,false) } assert_instance_of IGraph, g @@ -68,7 +68,7 @@ class TestGraph < Test::Unit::TestCase assert g.are_connected?(0,1) assert_nothing_raised{ - g = IGraph.read_graph_lgl(StringIO.new("#A\nB 1\n#C\nD 1\n"), + g = IGraph::FileRead.read_graph_lgl(StringIO.new("#A\nB 1\n#C\nD 1\n"), true,true) } assert_instance_of IGraph, g @@ -89,7 +89,7 @@ class TestGraph < Test::Unit::TestCase g = nil assert_nothing_raised{ s = StringIO.new("c com\np min 4 2\nn 1 s\nn 2 t\na 1 2 1\na 3 4 2\n") - g = IGraph.read_graph_dimacs(s, + g = IGraph::FileRead.read_graph_dimacs(s, false) } assert_instance_of IGraph, g @@ -110,7 +110,7 @@ class TestGraph < Test::Unit::TestCase def test_graphml_read g = nil - g = IGraph.read_graph_graphml(StringIO.new(Graphml),0) + g = IGraph::FileRead.read_graph_graphml(StringIO.new(Graphml),0) assert_instance_of IGraph, g assert_equal '2006-11-12', g.attributes['date'] h = g.dup @@ -134,7 +134,7 @@ class TestGraph < Test::Unit::TestCase end def test_gml_read - g = IGraph.read_graph_gml(StringIO.new(Gml)) + g = IGraph::FileRead.read_graph_gml(StringIO.new(Gml)) assert_instance_of IGraph, g end @@ -157,7 +157,7 @@ class TestGraph < Test::Unit::TestCase def test_pajek_read_write g = nil - g = IGraph.read_graph_pajek(StringIO.new(Pajek),0) + g = IGraph::FileRead.read_graph_pajek(StringIO.new(Pajek),0) assert_instance_of IGraph, g assert_equal 4, g.vcount assert_equal 1, g[4,1]['weight'] diff --git a/test/tc_generators_deterministic.rb b/test/tc_generators_deterministic.rb index 59fcec6..6185ba6 100644 --- a/test/tc_generators_deterministic.rb +++ b/test/tc_generators_deterministic.rb @@ -5,49 +5,49 @@ class TestGraph < Test::Unit::TestCase def test_adjacency m = IGraphMatrix.new([0,1,1,0],[1,0,0,0],[1,0,0,1],[0,0,1,0]) - g = IGraph.adjacency(m,IGraph::ADJ_MAX) + g = IGraph::Generate.adjacency(m,IGraph::ADJ_MAX) assert_equal 4, g.vcount assert_equal 3, g.ecount end def test_star - g = IGraph.star(10,IGraph::STAR_UNDIRECTED,0) + g = IGraph::Generate.star(10,IGraph::STAR_UNDIRECTED,0) assert_equal 10, g.vcount assert_equal 9, g.ecount end def test_lattice - g = IGraph.lattice([2,2],false,false,false) + g = IGraph::Generate.lattice([2,2],false,false,false) assert_equal 4, g.vcount assert_equal 4, g.ecount end def test_ring - g = IGraph.ring(10,false,false,false) + g = IGraph::Generate.ring(10,false,false,false) assert_equal 10, g.vcount assert_equal 9, g.ecount end def test_tree - g = IGraph.tree(13,3,IGraph::TREE_UNDIRECTED) + g = IGraph::Generate.tree(13,3,IGraph::TREE_UNDIRECTED) assert_equal 13, g.vcount assert_equal 12, g.ecount end def test_full - g = IGraph.full(10,false,false) + g = IGraph::Generate.full(10,false,false) assert_equal 10, g.vcount assert_equal 45, g.ecount end def test_atlas - g = IGraph.atlas(10) + g = IGraph::Generate.atlas(10) assert_equal 4, g.vcount assert_equal 2, g.ecount end def test_extended_chordal_ring - g = IGraph.extended_chordal_ring(3,IGraphMatrix.new([1,2,3],[1,2,3],[1,2,3])) + g = IGraph::Generate.extended_chordal_ring(3,IGraphMatrix.new([1,2,3],[1,2,3],[1,2,3])) assert_equal 3, g.vcount assert_equal 6, g.ecount end diff --git a/test/tc_generators_random.rb b/test/tc_generators_random.rb index a5a2512..53bd1fe 100644 --- a/test/tc_generators_random.rb +++ b/test/tc_generators_random.rb @@ -3,37 +3,37 @@ require 'igraph' class TestGraph < Test::Unit::TestCase def test_grg - g = IGraph.grg_game(10,0.1,false) + g = IGraph::GenerateRandom.grg_game(10,0.1,false) assert_equal 10, g.vertices.size end def test_barabasi - g = IGraph.barabasi_game(10,3,false,false) + g = IGraph::GenerateRandom.barabasi_game(10,3,false,false) assert_equal 10, g.vertices.size end def test_nonlinear_barabasi - g = IGraph.nonlinear_barabasi_game(10,1.9,3,false,0.1,false) + g = IGraph::GenerateRandom.nonlinear_barabasi_game(10,1.9,3,false,0.1,false) assert_equal 10, g.vertices.size end def test_erdos_renyi - g = IGraph.erdos_renyi_game(IGraph::ERDOS_RENYI_GNP,10,0.5,false,false) + g = IGraph::GenerateRandom.erdos_renyi_game(IGraph::ERDOS_RENYI_GNP,10,0.5,false,false) assert_instance_of IGraph, g - g = IGraph.erdos_renyi_game(IGraph::ERDOS_RENYI_GNM,10,0.5,false,false) + g = IGraph::GenerateRandom.erdos_renyi_game(IGraph::ERDOS_RENYI_GNM,10,0.5,false,false) assert_instance_of IGraph, g end def test_watts_strogatz - g = IGraph.watts_strogatz_game(10,1,2,0.6) + g = IGraph::GenerateRandom.watts_strogatz_game(10,1,2,0.6) assert_instance_of IGraph, g end def test_degree_sequence_game - g = IGraph.degree_sequence_game([1,2,3],[1,2,3]) + g = IGraph::GenerateRandom.degree_sequence_game([1,2,3],[1,2,3]) assert_instance_of IGraph, g end def test_growing_random_game - assert_instance_of IGraph, IGraph.growing_random_game(10,2,true,true) + assert_instance_of IGraph, IGraph::GenerateRandom.growing_random_game(10,2,true,true) end def test_callaway_traits_game assert_instance_of IGraph, - IGraph.callaway_traits_game(30,4,2,[0.25,0.25,0.25,0.25], + IGraph::GenerateRandom.callaway_traits_game(30,4,2,[0.25,0.25,0.25,0.25], IGraphMatrix.new([0,0.5,0.25,0.25], [0.5,0,0.25,0.25], [0.5,0.25,0,0.25], @@ -41,7 +41,7 @@ class TestGraph < Test::Unit::TestCase end def test_establishment_game assert_instance_of IGraph, - IGraph.establishment_game(30,4,2,[0.25,0.25,0.25,0.25], + IGraph::GenerateRandom.establishment_game(30,4,2,[0.25,0.25,0.25,0.25], IGraphMatrix.new([0,0.5,0.25,0.25], [0.5,0,0.25,0.25], [0.5,0.25,0,0.25], @@ -49,7 +49,7 @@ class TestGraph < Test::Unit::TestCase end def test_preference_game assert_instance_of IGraph, - IGraph.preference_game(30,4,[0.25,0.25,0.25,0.25], + IGraph::GenerateRandom.preference_game(30,4,[0.25,0.25,0.25,0.25], IGraphMatrix.new([0,0.5,0.25,0.25], [0.5,0,0.25,0.25], [0.5,0.25,0,0.25], @@ -57,7 +57,7 @@ class TestGraph < Test::Unit::TestCase end def test_asymmetric_preference_game assert_instance_of IGraph, - IGraph.asymmetric_preference_game(30,4, + IGraph::GenerateRandom.asymmetric_preference_game(30,4, IGraphMatrix.new([0,0.5,0.25,0.25], [0.5,0,0.25,0.25], [0.5,0.25,0,0.25], @@ -70,25 +70,25 @@ class TestGraph < Test::Unit::TestCase end def test_recent_degree_game assert_instance_of IGraph, - IGraph.recent_degree_game(30,2,4,5,false,0.1,true) + IGraph::GenerateRandom.recent_degree_game(30,2,4,5,false,0.1,true) end def test_barabasi_aging_game assert_instance_of IGraph, - IGraph.barabasi_aging_game(30,2,true,0.9,-0.5,3,0.1,0.1,2,2,true) + IGraph::GenerateRandom.barabasi_aging_game(30,2,true,0.9,-0.5,3,0.1,0.1,2,2,true) end def test_recent_degree_aging_game assert_instance_of IGraph, - IGraph.recent_degree_aging_game(30,2,true,0.9,-0.5,3,4,0.1,true) + IGraph::GenerateRandom.recent_degree_aging_game(30,2,true,0.9,-0.5,3,4,0.1,true) end def test_cited_type_game assert_instance_of IGraph, - IGraph.cited_type_game(10,(0..9).to_a, + IGraph::GenerateRandom.cited_type_game(10,(0..9).to_a, Array.new(5,0.5)+Array.new(5,0.2), 2,true) end def test_citing_cited_type_Game # assert_instance_of IGraph, - # IGraph.citing_cited_type_game(4,(0..3).to_a, + # IGraph::GenerateRandom.citing_cited_type_game(4,(0..3).to_a, # IGraphMatrix.new([0,0.5,0.25,0.25], # [0.5,0,0.25,0.25], # [0.5,0.25,0,0.25], diff --git a/test/tc_isomorphic.rb b/test/tc_isomorphic.rb index b9f097e..d03b425 100644 --- a/test/tc_isomorphic.rb +++ b/test/tc_isomorphic.rb @@ -27,7 +27,7 @@ class TestGraph < Test::Unit::TestCase end def test_igraph_isoclass_create g = IGraph.new([1,2,3,4],false) - h = IGraph.isoclass_create(4,g.isoclass,false) + h = IGraph::Generate.isoclass_create(4,g.isoclass,false) assert_equal g.isoclass, h.isoclass end end diff --git a/test/tc_layout.rb b/test/tc_layout.rb index 55db698..f656eda 100644 --- a/test/tc_layout.rb +++ b/test/tc_layout.rb @@ -63,7 +63,7 @@ class TestGraph < Test::Unit::TestCase l = g.layout_lgl(10,1,1,2,1,1,1) h = IGraph.new([1,2,3,4],true) m = h.layout_lgl(10,1,1,2,1,1,1) - f = IGraph.layout_merge_dla([g,h],[l,m]) + f = IGraph::Layout.layout_merge_dla([g,h],[l,m]) assert_instance_of IGraphMatrix, f assert_equal g.vcount + h.vcount, f.nrow assert_equal 2, f.ncol diff --git a/test/tc_layout3d.rb b/test/tc_layout3d.rb index cf503c1..689a321 100644 --- a/test/tc_layout3d.rb +++ b/test/tc_layout3d.rb @@ -18,7 +18,7 @@ class TestGraph < Test::Unit::TestCase end def test_fruchterman_reingold_3d g = IGraph.new([1,2,3,4],true) - l = g.layout_fruchterman_reingold_3d(10,1,1,2,1,false) + l = g.layout_fruchterman_reingold_3d(10,1,1,2,1) assert_instance_of IGraphMatrix, l assert_equal g.vcount, l.nrow assert_equal 3, l.ncol diff --git a/test/tc_randomisation.rb b/test/tc_randomisation.rb index 5d1911a..3e07130 100755 --- a/test/tc_randomisation.rb +++ b/test/tc_randomisation.rb @@ -3,12 +3,12 @@ require 'igraph' class TestGraph < Test::Unit::TestCase def test_rewire_edges - g = IGraph.grg_game(10,0.1,false) + g = IGraph::GenerateRandom.grg_game(10,0.1,false) h = g.rewire_edges(0.5) assert_equal 10, h.to_a.size end def test_rewire - g = IGraph.grg_game(10,0.1,false) + g = IGraph::GenerateRandom.grg_game(10,0.1,false) h = g.rewire(0.5) assert_equal 10, h.to_a.size end