|
- #include "igraph.h"
- #include "ruby.h"
- #include "cIGraph.h"
-
- //Classes
- VALUE cIGraph;
- VALUE cIGraphError;
-
- void cIGraph_free(void *p){
- igraph_destroy(p);
- }
-
- VALUE cIGraph_alloc(VALUE klass){
-
- igraph_t *graph = malloc(sizeof(igraph_t));
- VALUE obj;
-
- igraph_empty(graph, 0, 1);
- obj = Data_Wrap_Struct(klass, 0, cIGraph_free, graph);
-
- return obj;
-
- }
-
- /* call-seq:
- * IGraph.new(edges,directed) -> IGraph
- *
- * Creates a new IGraph graph with the edges specified in the edges Array.
- * The first two elements define the first edge (the order is from,to for
- * directed graphs). The next two define the second edge and so on. The
- * Array should contain an even number of elements. Graph elements can be
- * any ruby object.
- *
- * The boolean value directed specifies whether a directed or undirected
- * graph is created.
- *
- * Example:
- *
- * IGraph.new([1,2,3,4],true)
- *
- * Creates a graph with four vertices. Vertex 1 is connected to vertex 2.
- * Vertex 3 is connected to vertex 4.
- */
-
- VALUE cIGraph_initialize(int argc, VALUE *argv, VALUE self){
-
- igraph_t *graph;
- igraph_vector_t edge_v;
- VALUE vertex;
- VALUE object_h;
- VALUE id_h;
- VALUE directed;
- VALUE edges;
- VALUE attrs;
- int vertex_n = 0;
- int current_vertex_id;
- int i;
-
- rb_scan_args(argc,argv,"12", &edges, &directed, &attrs);
-
- igraph_set_error_handler(cIGraph_error_handler);
- igraph_set_warning_handler(cIGraph_warning_handler);
- //igraph_i_set_attribute_table(&cIGraph_attribute_table);
-
- //New hash for mapping vertex objects to floats used by iGraph
- object_h = rb_iv_set(self,"@object_ids",rb_hash_new());
- id_h = rb_iv_set(self,"@id_objects",rb_hash_new());
-
- rb_iv_set(self,"@edge_attrs",rb_hash_new());
-
- //Initialize edge vector
- igraph_vector_init_int(&edge_v,0);
-
- Data_Get_Struct(self, igraph_t, graph);
- if(!directed)
- igraph_to_undirected(graph,IGRAPH_TO_UNDIRECTED_COLLAPSE);
-
- //Loop through objects in edge Array
- for (i=0; i<RARRAY(edges)->len; i++) {
- vertex = RARRAY(edges)->ptr[i];
- if(rb_funcall(object_h,rb_intern("has_key?"),1,vertex)){
- //If @vertices includes this vertex then look up the vertex number
- current_vertex_id = NUM2INT(rb_hash_aref(object_h,vertex));
- } else {
- //otherwise add a new entry to Hash
- rb_hash_aset(object_h,vertex,INT2NUM(vertex_n));
- rb_hash_aset(id_h, INT2NUM(vertex_n),vertex);
- current_vertex_id = vertex_n;
- vertex_n++;
- }
- igraph_vector_push_back(&edge_v,current_vertex_id);
- }
-
- if(igraph_vector_size(&edge_v) > 0){
- igraph_add_vertices(graph,vertex_n,0);
- igraph_add_edges(graph,&edge_v,0);
- }
-
- if(attrs != Qnil){
- for (i=0; i<RARRAY(attrs)->len; i++) {
- cIGraph_set_edge_attr(self,
- RARRAY(edges)->ptr[i*2],
- RARRAY(edges)->ptr[(i*2)+1],
- RARRAY(attrs)->ptr[i]);
- }
- }
-
- igraph_vector_destroy(&edge_v);
-
- return 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.
- */
-
- void Init_igraph(){
- cIGraph = rb_define_class("IGraph", rb_cObject);
- cIGraphError = rb_define_class("IGraphError", rb_eRuntimeError);
-
- rb_define_alloc_func(cIGraph, cIGraph_alloc);
- rb_define_method(cIGraph, "initialize", cIGraph_initialize, -1);
-
- rb_define_method(cIGraph, "[]", cIGraph_get_edge_attr, 2);
- rb_define_method(cIGraph, "[]=", cIGraph_set_edge_attr, 3);
- rb_define_method(cIGraph, "get_edge_attr", cIGraph_get_edge_attr, 2);
- rb_define_method(cIGraph, "set_edge_attr", cIGraph_set_edge_attr, 3);
-
- rb_define_method(cIGraph, "each_vertex", cIGraph_each_vertex, 0); /* in cIGraph_iterators.c */
- rb_define_method(cIGraph, "each_edge", cIGraph_each_edge, 1); /* in cIGraph_iterators.c */
- rb_define_method(cIGraph, "each_edge_eid", cIGraph_each_edge_eid,1); /* in cIGraph_iterators.c */
-
- 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_method(cIGraph, "each", cIGraph_each_vertex, 0);
- rb_include_module(cIGraph, rb_mEnumerable);
-
- rb_define_method(cIGraph, "include?", cIGraph_include, 1);
-
- rb_define_method(cIGraph, "all_vertices", cIGraph_all_v, 0);
- rb_define_method(cIGraph, "vertices", cIGraph_all_v, 0); /* in cIGraph_selectors.c */
- rb_define_method(cIGraph, "adjacent_vertices", cIGraph_adj_v, 2); /* in cIGraph_selectors.c */
- rb_define_method(cIGraph, "nonadjacent_vertices", cIGraph_nonadj_v, 2); /* in cIGraph_selectors.c */
-
- rb_define_method(cIGraph, "all_edges", cIGraph_all_e, 1);
- rb_define_method(cIGraph, "edges", cIGraph_all_e, 1);
- rb_define_method(cIGraph, "adjacent_edges", cIGraph_adj_e, 2);
- rb_define_method(cIGraph, "nonadjacent_edges", cIGraph_nonadj_e, 2);
-
- rb_define_method(cIGraph, "vcount", cIGraph_vcount, 0); /* in cIGraph_basic_query.c */
- rb_define_method(cIGraph, "ecount", cIGraph_ecount, 0); /* in cIGraph_basic_query.c */
-
- rb_define_method(cIGraph, "edge", cIGraph_edge, 1); /* in cIGraph_basic_query.c */
- rb_define_method(cIGraph, "get_eid", cIGraph_get_eid, 2); /* in cIGraph_basic_query.c */
-
- rb_define_method(cIGraph, "neighbors", cIGraph_neighbors,2);
- rb_define_method(cIGraph, "neighbours", cIGraph_neighbors,2); /* in cIGraph_basic_query.c */
- rb_define_method(cIGraph, "adjacent", cIGraph_adjacent,2); /* in cIGraph_basic_query.c */
-
- 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_method(cIGraph, "is_directed", cIGraph_is_directed,0);
- rb_define_method(cIGraph, "is_directed?", cIGraph_is_directed,0); /* in cIGraph_basic_query.c */
-
- rb_define_method(cIGraph, "degree", cIGraph_degree,3); /* in cIGraph_basic_query.c */
-
- rb_define_method(cIGraph, "add_edges", cIGraph_add_edges, -1); /* in cIGraph_add_delete.c */
- rb_define_method(cIGraph, "add_vertices", cIGraph_add_vertices, 1); /* in cIGraph_add_delete.c */
-
- rb_define_method(cIGraph, "add_edge", cIGraph_add_edge, -1); /* in cIGraph_add_delete.c */
- rb_define_method(cIGraph, "add_vertex", cIGraph_add_vertex, 1); /* in cIGraph_add_delete.c */
-
- rb_define_method(cIGraph, "are_connected", cIGraph_are_connected,2);
- rb_define_method(cIGraph, "are_connected?", cIGraph_are_connected,2); /* in cIGraph_basic_properties.c */
-
- 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, "neighbourhood_size", cIGraph_neighborhood_size, 3); /* in cIGraph_vertex_neighbourhood.c */
- rb_define_method(cIGraph, "neighborhood_size", cIGraph_neighborhood_size, 3);
- rb_define_method(cIGraph, "neighbourhood", cIGraph_neighborhood, 3); /* in cIGraph_vertex_neighbourhood.c */
- rb_define_method(cIGraph, "neighborhood", cIGraph_neighborhood, 3);
- rb_define_method(cIGraph, "neighbourhood_graphs", cIGraph_neighborhood_graphs, 3); /* in cIGraph_vertex_neighbourhood.c */
- rb_define_method(cIGraph, "neighborhood_graphs", cIGraph_neighborhood_graphs, 3);}
|