/* call-seq: * graph.transitivity() -> Float * * Calculates the transitivity (clustering coefficient) of a graph. * * The transitivity measures the probability that two neighbors of a vertex * are connected. More precisely this is the ratio of the triangles and * connected triples in the graph, the result is a single real number or * NaN (0/0) if there are no connected triples in the graph. Directed graphs * are considered as undirected ones. */ VALUE cIGraph_transitivity_local(VALUE self, VALUE vs){ igraph_t *graph; igraph_vs_t vids; igraph_vector_t vidv; igraph_vector_t res; VALUE trans = rb_ary_new(); int i; //vector to hold the results of the calculations igraph_vector_init_int(&res,0); //Convert an array of vertices to a vector of vertex ids igraph_vector_init_int(&vidv,0); cIGraph_vertex_arr_to_id_vec(self,vs,&vidv); //create vertex selector from the vecotr of ids igraph_vs_vector(&vids,&vidv); Data_Get_Struct(self, igraph_t, graph); igraph_transitivity_local_undirected(graph,&res,vids); for(i=0;i<igraph_vector_size(&res);i++){ rb_ary_push(trans,rb_float_new(VECTOR(res)[i])); } igraph_vector_destroy(&vidv); igraph_vector_destroy(&res); igraph_vs_destroy(&vids); return trans; }
/* call-seq: * graph.degree(vs,mode,loops) -> Array * * Returns an Array of Integers specifying the degree of each of the * vertices specified in the vs Array. mode defines the type of the degree. * IGraph::OUT, out-degree, IGraph::IN, in-degree, IGraph::ALL, total degree * (sum of the in- and out-degree). This parameter is ignored for undirected * graphs. * * Example: * * g = IGraph.new([1,2,3,4],true) * g.is_directed? #returns true * */ VALUE cIGraph_degree(VALUE self, VALUE v, VALUE mode, VALUE loops){ igraph_t *graph; igraph_vs_t vids; igraph_vector_t vidv; igraph_neimode_t pmode = NUM2INT(mode); igraph_bool_t loop_mode = loops ? 1 : 0; igraph_vector_t res; int i; VALUE degree_r = rb_ary_new(); //vector to hold the results of the degree calculations igraph_vector_init_int(&res,0); Data_Get_Struct(self, igraph_t, graph); //Convert an array of vertices to a vector of vertex ids igraph_vector_init_int(&vidv,0); cIGraph_vertex_arr_to_id_vec(self,v,&vidv); //create vertex selector from the vecotr of ids igraph_vs_vector(&vids,&vidv); igraph_degree(graph,&res,vids,pmode,loop_mode); for(i=0;i<igraph_vector_size(&res);i++){ rb_ary_push(degree_r,INT2NUM(VECTOR(res)[i])); } igraph_vector_destroy(&vidv); igraph_vector_destroy(&res); igraph_vs_destroy(&vids); return degree_r; }
/* call-seq: * graph.maxdegree(vs,mode,loops) -> Vertex * * Returns the vertex Object in the vs Array with the largest degree. * mode defines the type * of the degree. IGRAPH_OUT, out-degree, IGRAPH_IN, in-degree, IGRAPH_ALL, * total degree (sum of the in- and out-degree). This parameter is ignored * for undirected graphs. loops is a boolean gives whether the self-loops * should be counted. */ VALUE cIGraph_maxdegree(VALUE self, VALUE vs, VALUE mode, VALUE loops){ igraph_t *graph; igraph_bool_t loop = 0; igraph_integer_t res; igraph_neimode_t pmode = NUM2INT(mode); igraph_vs_t vids; igraph_vector_t vidv; if(loops == Qtrue) loop = 1; Data_Get_Struct(self, igraph_t, graph); //Convert an array of vertices to a vector of vertex ids igraph_vector_init_int(&vidv,0); cIGraph_vertex_arr_to_id_vec(self,vs,&vidv); //create vertex selector from the vecotr of ids igraph_vs_vector(&vids,&vidv); igraph_maxdegree(graph,&res,vids,pmode,loop); igraph_vector_destroy(&vidv); igraph_vs_destroy(&vids); return INT2NUM(res); }
/* call-seq: * graph.closeness(vs,mode) -> Array * * Returns an Array of closeness centrality measures for the vertices given in * the vs Array. mode defines the type of shortest paths used for the * calculation */ VALUE cIGraph_closeness(VALUE self, VALUE vs, VALUE mode){ igraph_t *graph; igraph_vs_t vids; igraph_vector_t vidv; igraph_neimode_t pmode = NUM2INT(mode); igraph_vector_t res; int i; VALUE closeness = rb_ary_new(); //vector to hold the results of the degree calculations igraph_vector_init_int(&res,0); Data_Get_Struct(self, igraph_t, graph); //Convert an array of vertices to a vector of vertex ids igraph_vector_init_int(&vidv,0); cIGraph_vertex_arr_to_id_vec(self,vs,&vidv); //create vertex selector from the vecotr of ids igraph_vs_vector(&vids,&vidv); igraph_closeness(graph,&res,vids,pmode); for(i=0;i<igraph_vector_size(&res);i++){ rb_ary_push(closeness,rb_float_new(VECTOR(res)[i])); } igraph_vector_destroy(&vidv); igraph_vector_destroy(&res); igraph_vs_destroy(&vids); return closeness; }
/* call-seq: * graph.subgraph(vs) -> IGraph * * Returns an IGraph object containing the vertices defined in the Array vs. */ VALUE cIGraph_subgraph(VALUE self, VALUE vs){ igraph_t *graph; igraph_t *n_graph = malloc(sizeof(igraph_t)); igraph_vs_t vids; igraph_vector_t vidv; VALUE n_graph_obj; Data_Get_Struct(self, igraph_t, graph); //Convert an array of vertices to a vector of vertex ids igraph_vector_init_int(&vidv,0); cIGraph_vertex_arr_to_id_vec(self,vs,&vidv); //create vertex selector from the vecotr of ids igraph_vs_vector(&vids,&vidv); igraph_subgraph(graph,n_graph,vids); n_graph_obj = Data_Wrap_Struct(cIGraph, cIGraph_mark, cIGraph_free, n_graph); igraph_vector_destroy(&vidv); igraph_vs_destroy(&vids); return n_graph_obj; }
/* call-seq: * graph.dijkstra_shortest_paths(varray,weights,mode) -> Array * * Calculates the length of the shortest paths from each of the vertices in * the varray Array to all of the other vertices in the graph given a set of * edge weights given in the weights Array. The result * is returned as an Array of Array. Each top-level Array contains the results * for a vertex in the varray Array. Each entry in the Array is the path length * to another vertex in the graph in vertex order (the order the vertices were * added to the graph. (This should probalby be changed to give a Hash of Hash * to allow easier look up.) */ VALUE cIGraph_dijkstra_shortest_paths(VALUE self, VALUE from, VALUE weights, VALUE mode){ igraph_t *graph; igraph_vs_t vids; igraph_vector_t vidv; igraph_vector_t wghts; igraph_neimode_t pmode = NUM2INT(mode); igraph_matrix_t res; int i; int j; VALUE row; VALUE path_length; VALUE matrix = rb_ary_new(); int n_row; int n_col; Data_Get_Struct(self, igraph_t, graph); n_row = NUM2INT(rb_funcall(from,rb_intern("length"),0)); n_col = igraph_vcount(graph); //matrix to hold the results of the calculations igraph_matrix_init(&res,n_row,n_col); igraph_vector_init(&wghts,RARRAY_LEN(weights)); for(i=0;i<RARRAY_LEN(weights);i++){ VECTOR(wghts)[i] = NUM2DBL(RARRAY_PTR(weights)[i]); } //Convert an array of vertices to a vector of vertex ids igraph_vector_init_int(&vidv,0); cIGraph_vertex_arr_to_id_vec(self,from,&vidv); //create vertex selector from the vecotr of ids igraph_vs_vector(&vids,&vidv); igraph_dijkstra_shortest_paths(graph,&res,vids,&wghts,pmode); for(i=0; i<igraph_matrix_nrow(&res); i++){ row = rb_ary_new(); rb_ary_push(matrix,row); for(j=0; j<igraph_matrix_ncol(&res); j++){ path_length = MATRIX(res,i,j) == n_col ? Qnil : rb_float_new(MATRIX(res,i,j)); rb_ary_push(row,path_length); } } igraph_vector_destroy(&vidv); igraph_matrix_destroy(&res); igraph_vs_destroy(&vids); igraph_vector_destroy(&wghts); return matrix; }
/* call-seq: * graph.constraint(vs,weights) -> Array * * Returns an Array of constraint measures for the vertices * in the graph. Weights is an Array of weight measures for each edge. */ VALUE cIGraph_constraint(int argc, VALUE *argv, VALUE self){ igraph_t *graph; igraph_vs_t vids; igraph_vector_t vidv; igraph_vector_t res; igraph_vector_t wght; int i; VALUE constraints = rb_ary_new(); VALUE vs, weights; rb_scan_args(argc,argv,"11",&vs, &weights); //vector to hold the results of the degree calculations IGRAPH_FINALLY(igraph_vector_destroy, &res); IGRAPH_FINALLY(igraph_vector_destroy, &wght); IGRAPH_FINALLY(igraph_vector_destroy, &vidv); IGRAPH_CHECK(igraph_vector_init(&res,0)); IGRAPH_CHECK(igraph_vector_init(&wght,0)); Data_Get_Struct(self, igraph_t, graph); //Convert an array of vertices to a vector of vertex ids IGRAPH_CHECK(igraph_vector_init_int(&vidv,0)); cIGraph_vertex_arr_to_id_vec(self,vs,&vidv); //create vertex selector from the vecotr of ids igraph_vs_vector(&vids,&vidv); if(weights == Qnil){ IGRAPH_CHECK(igraph_constraint(graph,&res,vids,NULL)); } else { for(i=0;i<RARRAY_LEN(weights);i++){ IGRAPH_CHECK(igraph_vector_push_back(&wght,NUM2DBL(RARRAY_PTR(weights)[i]))); } IGRAPH_CHECK(igraph_constraint(graph,&res,vids,&wght)); } for(i=0;i<igraph_vector_size(&res);i++){ rb_ary_push(constraints,rb_float_new(VECTOR(res)[i])); } igraph_vector_destroy(&vidv); igraph_vector_destroy(&res); igraph_vector_destroy(&wght); igraph_vs_destroy(&vids); IGRAPH_FINALLY_CLEAN(3); return constraints; }
/* call-seq: * graph.cocitation(varray) -> Array * * Cocitation coupling. * * Two vertices are cocited if there is another vertex citing both of them. * igraph_cocitation() simply counts how many types two vertices are cocited. * The cocitation score for each given vertex and all other vertices in the * graph will be calculated. * */ VALUE cIGraph_cocitation(VALUE self, VALUE vs){ igraph_t *graph; igraph_vs_t vids; igraph_vector_t vidv; igraph_matrix_t res; int i; int j; VALUE row; VALUE path_length; VALUE matrix = rb_ary_new(); int n_row; int n_col; Data_Get_Struct(self, igraph_t, graph); n_row = NUM2INT(rb_funcall(vs,rb_intern("length"),0)); n_col = igraph_vcount(graph); //matrix to hold the results of the calculations igraph_matrix_init(&res,n_row,n_col); //Convert an array of vertices to a vector of vertex ids igraph_vector_init_int(&vidv,0); cIGraph_vertex_arr_to_id_vec(self,vs,&vidv); //create vertex selector from the vecotr of ids igraph_vs_vector(&vids,&vidv); igraph_cocitation(graph,&res,vids); for(i=0; i<igraph_matrix_nrow(&res); i++){ row = rb_ary_new(); rb_ary_push(matrix,row); for(j=0; j<igraph_matrix_ncol(&res); j++){ path_length = INT2NUM(MATRIX(res,i,j)); rb_ary_push(row,path_length); } } igraph_vector_destroy(&vidv); igraph_matrix_destroy(&res); igraph_vs_destroy(&vids); return matrix; }
/* call-seq: * graph.betweenness(vs,mode) -> Array * * Returns an Array of betweenness centrality measures for the vertices given * in the vs Array. mode defines whether directed paths or considered for * directed graphs. */ VALUE cIGraph_betweenness(VALUE self, VALUE vs, VALUE directed){ igraph_t *graph; igraph_vs_t vids; igraph_vector_t vidv; igraph_bool_t dir = 0; igraph_vector_t res; int i; VALUE betweenness = rb_ary_new(); if(directed == Qtrue) dir = 1; //vector to hold the results of the degree calculations IGRAPH_FINALLY(igraph_vector_destroy, &res); IGRAPH_FINALLY(igraph_vector_destroy, &vidv); IGRAPH_FINALLY(igraph_vs_destroy,&vids); IGRAPH_CHECK(igraph_vector_init(&res,0)); Data_Get_Struct(self, igraph_t, graph); //Convert an array of vertices to a vector of vertex ids IGRAPH_CHECK(igraph_vector_init_int(&vidv,0)); cIGraph_vertex_arr_to_id_vec(self,vs,&vidv); //create vertex selector from the vecotr of ids IGRAPH_CHECK(igraph_vs_vector(&vids,&vidv)); IGRAPH_CHECK(igraph_betweenness(graph,&res,vids,dir)); for(i=0;i<igraph_vector_size(&res);i++){ rb_ary_push(betweenness,rb_float_new((float)VECTOR(res)[i])); } igraph_vector_destroy(&vidv); igraph_vector_destroy(&res); igraph_vs_destroy(&vids); IGRAPH_FINALLY_CLEAN(3); return betweenness; }
/* call-seq: * igraph.motifs_randesu_estimate(size,cut,samplen,samplev) * */ VALUE cIGraph_motifs_randesu_estimate(VALUE self, VALUE size, VALUE cuts, VALUE samplen, VALUE samplev){ igraph_t *graph; igraph_vector_t cutsv; igraph_vector_t vidv; igraph_integer_t res; int i; if(samplev != Qnil){ igraph_vector_init(&vidv,0); //Convert an array of vertices to a vector of vertex ids igraph_vector_init_int(&vidv,0); cIGraph_vertex_arr_to_id_vec(self,samplev,&vidv); } Data_Get_Struct(self, igraph_t, graph); igraph_vector_init(&cutsv,0); for(i=0;i<RARRAY_LEN(cuts);i++){ igraph_vector_push_back(&cutsv,NUM2DBL(RARRAY_PTR(cuts)[i])); } if(samplev == Qnil){ igraph_motifs_randesu_estimate(graph,&res,NUM2INT(size), &cutsv,NUM2INT(samplen),NULL); } else { igraph_motifs_randesu_estimate(graph,&res,NUM2INT(size), &cutsv,NUM2INT(samplen),&vidv); } igraph_vector_destroy(&cutsv); if(samplev != Qnil){ igraph_vector_destroy(&vidv); } return INT2NUM(res); }
/* call-seq: * graph.pagerank(vs,mode,niter,eps,damping) -> Array * * Returns an Array of PageRank measures for the vertices * in the graph. mode defines whether directed paths or considered for * directed graphs. */ VALUE cIGraph_pagerank(VALUE self, VALUE vs, VALUE directed, VALUE niter, VALUE eps, VALUE damping){ igraph_t *graph; igraph_vs_t vids; igraph_vector_t vidv; igraph_vector_t res; int i; VALUE pagerank = rb_ary_new(); igraph_bool_t dir = 0; if(directed == Qtrue) dir = 1; //vector to hold the results of the degree calculations igraph_vector_init_int(&res,0); Data_Get_Struct(self, igraph_t, graph); //Convert an array of vertices to a vector of vertex ids igraph_vector_init_int(&vidv,0); cIGraph_vertex_arr_to_id_vec(self,vs,&vidv); //create vertex selector from the vecotr of ids igraph_vs_vector(&vids,&vidv); igraph_pagerank_old(graph,&res,vids,dir, NUM2INT(niter),NUM2DBL(eps),NUM2DBL(damping),0); for(i=0;i<igraph_vector_size(&res);i++){ rb_ary_push(pagerank,rb_float_new(VECTOR(res)[i])); } igraph_vector_destroy(&vidv); igraph_vector_destroy(&res); igraph_vs_destroy(&vids); return pagerank; }
/* call-seq: * graph.get_shortest_paths(from,to_array,mode) -> Array * * Calculates the paths from the vertex specified as from to each vertex in the * to_array Array. Returns an Array of Arrays. Each top level Array represents * a path and each entry in each Array is a vertex on the path. mode * represents the type of shortest paths to be calculated: IGraph::OUT * the outgoing paths are calculated. IGraph::IN the incoming paths are * calculated. IGraph::ALL the directed graph is considered as an undirected * one for the computation. */ VALUE cIGraph_get_dijkstra_shortest_paths(VALUE self, VALUE from, VALUE to, VALUE weights, VALUE mode){ igraph_t *graph; igraph_integer_t from_vid; igraph_vs_t to_vids; igraph_vector_t to_vidv; igraph_vector_t wghts; igraph_neimode_t pmode = NUM2INT(mode); igraph_vector_ptr_t res; igraph_vector_t *path_v; int i; int j; VALUE path; VALUE matrix = rb_ary_new(); int n_paths; Data_Get_Struct(self, igraph_t, graph); n_paths = RARRAY_LEN(to); //vector to hold the results of the calculations igraph_vector_ptr_init(&res,0); for(i=0;i<n_paths;i++){ path_v = malloc(sizeof(igraph_vector_t)); igraph_vector_init(path_v,0); igraph_vector_ptr_push_back(&res,path_v); } igraph_vector_init(&wghts,RARRAY_LEN(weights)); for(i=0;i<RARRAY_LEN(weights);i++){ VECTOR(wghts)[i] = NUM2DBL(RARRAY_PTR(weights)[i]); } //Convert an array of vertices to a vector of vertex ids igraph_vector_init_int(&to_vidv,0); cIGraph_vertex_arr_to_id_vec(self,to,&to_vidv); //create vertex selector from the vecotr of ids igraph_vs_vector(&to_vids,&to_vidv); //The id of the vertex from where we are counting from_vid = cIGraph_get_vertex_id(self, from); //igraph_get_shortest_paths(graph,&res,from_vid,to_vids,pmode); igraph_get_shortest_paths_dijkstra(graph,&res,from_vid,to_vids,igraph_vector_size(&wghts) > 0 ? &wghts : NULL,pmode); for(i=0; i<n_paths; i++){ path = rb_ary_new(); rb_ary_push(matrix,path); path_v = VECTOR(res)[i]; for(j=0; j<igraph_vector_size(VECTOR(res)[i]); j++){ rb_ary_push(path,cIGraph_get_vertex_object(self,VECTOR(*path_v)[j])); } } for(i=0;i<n_paths;i++){ igraph_vector_destroy(VECTOR(res)[i]); free(VECTOR(res)[i]); } igraph_vector_destroy(&to_vidv); igraph_vector_ptr_destroy(&res); igraph_vs_destroy(&to_vids); igraph_vector_destroy(&wghts); return matrix; /* igraph_t *graph; igraph_integer_t from_vid; igraph_vs_t to_vids; igraph_vector_t to_vidv; igraph_vector_t wghts; igraph_neimode_t pmode = NUM2INT(mode); igraph_vector_ptr_t res; igraph_vector_t *path_v; int i; int j; VALUE path; VALUE matrix = rb_ary_new(); int n_paths = 0; Data_Get_Struct(self, igraph_t, graph); n_paths = RARRAY_LEN(to); //vector to hold the results of the calculations igraph_vector_ptr_init(&res,0); for(i=0;i<n_paths;i++) { path_v = malloc(sizeof(igraph_vector_t)); igraph_vector_init(path_v,0); igraph_vector_ptr_push_back(&res,path_v); } igraph_vector_init(&wghts,RARRAY_LEN(weights)); for(i=0;i<RARRAY_LEN(weights);i++){ VECTOR(wghts)[i] = NUM2DBL(RARRAY_PTR(weights)[i]); } //Convert an array of vertices to a vector of vertex ids igraph_vector_init_int(&to_vidv,0); cIGraph_vertex_arr_to_id_vec(self,to,&to_vidv); //create vertex selector from the vecotr of ids igraph_vs_vector(&to_vids,&to_vidv); //The id of the vertex from where we are counting from_vid = cIGraph_get_vertex_id(self, from); igraph_get_shortest_paths(graph,&res,from_vid,to_vids,pmode); //igraph_get_shortest_paths_dijkstra(graph,&res,from_vid,to_vids,igraph_vector_size(&wghts) > 0 ? &wghts : NULL,pmode); for(i=0; i<n_paths; i++){ path = rb_ary_new(); rb_ary_push(matrix,path); path_v = VECTOR(res)[i]; for(j=0; j<igraph_vector_size(VECTOR(res)[i]); j++){ rb_ary_push(path,cIGraph_get_vertex_object(self,VECTOR(*path_v)[j])); } } for(i=0;i<n_paths;i++){ igraph_vector_destroy(VECTOR(res)[i]); free(VECTOR(res)[i]); } igraph_vector_destroy(&to_vidv); igraph_vector_ptr_destroy(&res); igraph_vs_destroy(&to_vids); igraph_vector_destroy(&wghts); return matrix; */ }