int main() {
  
  igraph_vs_t vs;
  igraph_vit_t vit;
  igraph_t g;
  igraph_integer_t size;

  igraph_ring(&g, 10, IGRAPH_UNDIRECTED, 0, 1);
  igraph_vs_seq(&vs, 0, 9);
  igraph_vit_create(&g, vs, &vit);
  igraph_vs_size(&g, &vs, &size);
  printf("%li", (long int) size);
  
  while (!IGRAPH_VIT_END(vit)) {
    printf(" %li", (long int)IGRAPH_VIT_GET(vit));
    IGRAPH_VIT_NEXT(vit);
  }
  printf("\n");

  igraph_vit_destroy(&vit);
  igraph_vs_destroy(&vs);
  igraph_destroy(&g);
  
  return 0;
}
Esempio n. 2
0
/* 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;

}
Esempio n. 3
0
/* 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;

}
Esempio n. 4
0
/* 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;

}
int main() {
  
  igraph_t g;
  igraph_vs_t vertices;
  igraph_vector_t result;
  long int i;
  
  igraph_vs_seq(&vertices, 1, 101);
  igraph_barabasi_game(&g, 100000, /*power=*/ 1, 3, 0, 0, /*A=*/ 1,
		       IGRAPH_DIRECTED, IGRAPH_BARABASI_BAG, 
		       /*start_from=*/ 0);
  igraph_vector_init(&result, 0);
  
  for (i=0; i<1; i++) {
    igraph_transitivity_local_undirected2(&g, &result, igraph_vss_all(),
			IGRAPH_TRANSITIVITY_NAN);
  }

  for (i=0; i<1; i++) {
    igraph_transitivity_local_undirected4(&g, &result, igraph_vss_all(),
			IGRAPH_TRANSITIVITY_NAN);
  }
  
/*   for (i=0; i<igraph_vector_size(&result); i++) { */
/*     printf("%f ", VECTOR(result)[i]); */
/*   } */
/*   printf("\n"); */
  
  igraph_vector_destroy(&result);
  igraph_vs_destroy(&vertices);
  igraph_destroy(&g);
  
  return 0;
}
/* 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;

}
int main() {
  
  igraph_t g;
  igraph_vs_t vertices;
  igraph_vector_t result1, result2;

  igraph_rng_seed(igraph_rng_default(), 42);
  
  igraph_vector_init(&result1, 0);
  igraph_vector_init(&result2, 0);

  igraph_erdos_renyi_game(&g, IGRAPH_ERDOS_RENYI_GNP, 100, .1,
			  IGRAPH_UNDIRECTED, IGRAPH_NO_LOOPS);

  igraph_vs_seq(&vertices, 0, 99);

  igraph_transitivity_local_undirected(&g, &result1, igraph_vss_all(),
				       IGRAPH_TRANSITIVITY_NAN);
  igraph_transitivity_local_undirected(&g, &result2, vertices,
				       IGRAPH_TRANSITIVITY_NAN);
  
  if (!igraph_vector_all_e(&result1, &result2)) {
    igraph_vector_print(&result1);
    igraph_vector_print(&result2);
    return 1;
  }

  igraph_vector_destroy(&result1);
  igraph_vector_destroy(&result2);
  igraph_vs_destroy(&vertices);
  igraph_destroy(&g);
  
  return 0;
}
Esempio n. 8
0
/* 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);

}
int main() {

  igraph_t g;
  igraph_vector_ptr_t vecs;
  long int i;
  igraph_vs_t vs;

  igraph_ring(&g, 10, IGRAPH_DIRECTED, 0, 1);
  
  igraph_vector_ptr_init(&vecs, 5);
  for (i=0; i<igraph_vector_ptr_size(&vecs); i++) {
    VECTOR(vecs)[i] = calloc(1, sizeof(igraph_vector_t));
    igraph_vector_init(VECTOR(vecs)[i], 0);
  }
  igraph_vs_vector_small(&vs, 1, 3, 5, 2, 1,  -1);
  
  igraph_get_shortest_paths(&g, &vecs, 0, vs, IGRAPH_OUT);
  
  for (i=0; i<igraph_vector_ptr_size(&vecs); i++) {
    print_vector(VECTOR(vecs)[i]);
    igraph_vector_destroy(VECTOR(vecs)[i]);
    free(VECTOR(vecs)[i]);
  }
  igraph_vector_ptr_destroy(&vecs);
  igraph_vs_destroy(&vs);
  igraph_destroy(&g);
  
  return 0;
}
Esempio n. 10
0
igraph_integer_t all_degrees(igraph_t *graph, igraph_vector_t *degrees)
{
    igraph_vs_t vs;
    igraph_vs_all(&vs);

    igraph_degree(graph, degrees, vs, IGRAPH_ALL, IGRAPH_LOOPS); 
    igraph_vs_destroy(&vs);
}
Esempio n. 11
0
Bitvector GraphRepresentation::calculateFID(string &source, string &destination) {
    int vertex_id;
    Bitvector result(dm->fid_len * 8);
    igraph_vs_t vs;
    igraph_vector_ptr_t res;
    igraph_vector_t to_vector;
    igraph_vector_t *temp_v;
    igraph_integer_t eid;

    /*find the vertex id in the reverse index*/
    int from = (*reverse_node_index.find(source)).second;
    igraph_vector_init(&to_vector, 1);
    VECTOR(to_vector)[0] = (*reverse_node_index.find(destination)).second;
    /*initialize the sequence*/
    igraph_vs_vector(&vs, &to_vector);
    /*initialize the vector that contains pointers*/
    igraph_vector_ptr_init(&res, 1);
    temp_v = (igraph_vector_t *) VECTOR(res)[0];
    temp_v = (igraph_vector_t *) malloc(sizeof (igraph_vector_t));
    VECTOR(res)[0] = temp_v;
    igraph_vector_init(temp_v, 1);
    /*run the shortest path algorithm from "from"*/
    igraph_get_shortest_paths(&igraph, &res, from, vs, IGRAPH_OUT);
    /*check the shortest path to each destination*/
    temp_v = (igraph_vector_t *) VECTOR(res)[0];
    //click_chatter("Shortest path from %s to %s", igraph_cattribute_VAS(&graph, "NODEID", from), igraph_cattribute_VAS(&graph, "NODEID", VECTOR(*temp_v)[igraph_vector_size(temp_v) - 1]));

    /*now let's "or" the FIDs for each link in the shortest path*/
    for (int j = 0; j < igraph_vector_size(temp_v) - 1; j++) {
        igraph_get_eid(&igraph, &eid, VECTOR(*temp_v)[j], VECTOR(*temp_v)[j + 1], true);
        //click_chatter("node %s -> node %s", igraph_cattribute_VAS(&graph, "NODEID", VECTOR(*temp_v)[j]), igraph_cattribute_VAS(&graph, "NODEID", VECTOR(*temp_v)[j + 1]));
        //click_chatter("link: %s", igraph_cattribute_EAS(&graph, "LID", eid));
        string LID(igraph_cattribute_EAS(&igraph, "LID", eid), dm->fid_len * 8);
        for (int k = 0; k < dm->fid_len * 8; k++) {
            if (LID[k] == '1') {
                (result)[ dm->fid_len * 8 - k - 1].operator |=(true);
            }
        }
        //click_chatter("FID of the shortest path: %s", result.to_string().c_str());
    }
    /*now for all destinations "or" the internal linkID*/
    vertex_id = (*reverse_node_index.find(destination)).second;
    string iLID(igraph_cattribute_VAS(&igraph, "iLID", vertex_id));
    //click_chatter("internal link for node %s: %s", igraph_cattribute_VAS(&graph, "NODEID", vertex_id), iLID.c_str());
    for (int k = 0; k < dm->fid_len * 8; k++) {
        if (iLID[k] == '1') {
            (result)[ dm->fid_len * 8 - k - 1].operator |=(true);
        }
    }

    igraph_vector_destroy((igraph_vector_t *) VECTOR(res)[0]);

    igraph_vector_destroy(&to_vector);
    igraph_vector_ptr_destroy_all(&res);
    igraph_vs_destroy(&vs);

    return result;
}
Esempio n. 12
0
int main(int argc, char*argv[]) {

    // the graph is just a list og from to identifier pairs, one per line
    if (argc != 4) {
	fprintf (stderr, "Usage: %s  <path to graph>  <from id>  <to id>\n", argv[0]);
	exit(1);
    }
    
    // 57572 DOCK6
    // 7049 TGFBR3
    // 2263 FGFBP3
    igraph_vs_t  vertex_to; 
    igraph_integer_t vertex_from;
    vertex_from = atol(argv[2]);
    // in principle, unumber of "to" vertices is arbitrary,
    // but that is a piece of code I will write some other time
    //igraph_vs_vector_small(&vertex_to, 2263, 7049,  -1);
    igraph_vs_vector_small(&vertex_to, atol(argv[3]),  -1);
   
    igraph_t graph;
    /*The number of vertices in the graph. If smaller than the largest integer in
      the file it will be ignored. It is thus safe to supply zero here. */
    igraph_integer_t zero = 0;

    FILE * infile  =  efopen(argv[1], "r") ;
    
    igraph_bool_t directed  = IGRAPH_UNDIRECTED;
    igraph_read_graph_edgelist (&graph, infile,  zero, directed);

    /* shortest path calculation: */
    /* http://igraph.org/c/doc/igraph-Structural.html#igraph_get_all_shortest_paths
       int igraph_get_all_shortest_paths(const igraph_t *graph,
				  igraph_vector_ptr_t *res, 
				  igraph_vector_t *nrgeo,
				  igraph_integer_t from, const igraph_vs_t to,
				  igraph_neimode_t mode);
    */
    igraph_vector_ptr_t result;
    igraph_vector_t nrgeo;
    igraph_integer_t i;
    // the second argument here is the number of "to"  vertices
    igraph_vector_ptr_init (&result, 1);
    igraph_vector_init(&nrgeo, 0);
    igraph_get_all_shortest_paths (&graph, &result, &nrgeo,
			    vertex_from,  vertex_to,
			   IGRAPH_ALL);
    for (i=0; i<igraph_vector_ptr_size(&result); i++) {
	print_vector(VECTOR(result)[i]);
    }

    igraph_vector_ptr_destroy(&result);
    igraph_vs_destroy(&vertex_to);
    igraph_destroy(&graph);

    if (!IGRAPH_FINALLY_STACK_EMPTY) return 1;
  
    return 0;
}
Esempio n. 13
0
int main() {

  igraph_t g;
  igraph_vector_t v=IGRAPH_VECTOR_NULL;
  igraph_real_t edges[] = { 0,1, 1,2, 2,2, 2,3, 2,4, 3,4 };
  igraph_vector_t v2;
  long int i;
  igraph_vit_t vit;
  igraph_vs_t vs;
  igraph_integer_t size;

  igraph_vector_view(&v, edges, sizeof(edges)/sizeof(igraph_real_t));
  igraph_create(&g, &v, 0, IGRAPH_DIRECTED);

  /* Create iterator based on a vector (view) */
  igraph_vector_init(&v2, 6);
  VECTOR(v2)[0]=0;   VECTOR(v2)[1]=2;
  VECTOR(v2)[2]=4;   VECTOR(v2)[3]=0;
  VECTOR(v2)[4]=2;   VECTOR(v2)[5]=4;

  igraph_vit_create(&g, igraph_vss_vector(&v2), &vit);

  i=0;
  while (!IGRAPH_VIT_END(vit)) {
    if (IGRAPH_VIT_GET(vit) != VECTOR(v2)[i]) {
      return 1;
    }
    IGRAPH_VIT_NEXT(vit);
    i++;
  }
  if (i != igraph_vector_size(&v2)) {
    return 2;
  }

  igraph_vit_destroy(&vit);
  igraph_vector_destroy(&v2);

  /* Create small vector iterator */

  igraph_vs_vector_small(&vs, 0, 2, 4, 0, 2, 4, 2, -1);
  igraph_vit_create(&g, vs, &vit);
  igraph_vs_size(&g, &vs, &size);
  printf("%li ", (long int) size);
  for (; !IGRAPH_VIT_END(vit); IGRAPH_VIT_NEXT(vit)) {
    printf("%li ", (long int) IGRAPH_VIT_GET(vit));
  }
  printf("\n");
  
  igraph_vit_destroy(&vit);
  igraph_vs_destroy(&vs);

  /* Clean up */

  igraph_destroy(&g);

  return 0;
}
Esempio n. 14
0
/**
 * \ingroup python_interface_vertexseq
 * \brief Deallocates a Python representation of a given vertex sequence object
 */
void igraphmodule_VertexSeq_dealloc(igraphmodule_VertexSeqObject* self) {
  if (self->weakreflist != NULL)
    PyObject_ClearWeakRefs((PyObject *) self);
  if (self->gref) {
    igraph_vs_destroy(&self->vs);
    Py_DECREF(self->gref);
    self->gref=0;
  }
  Py_TYPE(self)->tp_free((PyObject*)self);
  RC_DEALLOC("VertexSeq", self);
}
Esempio n. 15
0
/* 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;

}
Esempio n. 16
0
std::vector<double> Graph::betweenness() const {
  igraph_vector_t results;
  igraph_vs_t allnods;
  std::vector<double> bet;
  igraph_vector_init(&results, size);
  igraph_vector_null(&results);
  igraph_vs_all(&allnods);
  igraph_betweenness(graph, &results, allnods, false);
  bet.insert(bet.begin(), VECTOR(results), VECTOR(results) + size);
  igraph_vector_destroy(&results);
  igraph_vs_destroy(&allnods);
  return bet;
}
Esempio n. 17
0
std::vector<double> Graph::closeness() const {
  igraph_vector_t results;
  igraph_vs_t allnods;
  std::vector<double> clos;
  igraph_vector_init(&results, size);
  igraph_vector_null(&results);
  igraph_vs_all(&allnods);
  igraph_closeness(graph, &results, allnods, IGRAPH_IN);
  clos.insert(clos.begin(), VECTOR(results), VECTOR(results) + size);
  igraph_vector_destroy(&results);
  igraph_vs_destroy(&allnods);
  return clos;
}
Esempio n. 18
0
std::vector<int> Graph::degrees() {
  igraph_vector_t results;
  igraph_vs_t allnds;
  std::vector<int> degs;
  igraph_vs_all(&allnds);
  igraph_vector_init(&results, size);
  igraph_vector_null(&results);
  igraph_degree(graph, &results, allnds, IGRAPH_ALL, IGRAPH_NO_LOOPS);
  degs.insert(degs.begin(), VECTOR(results), VECTOR(results)+size);
  igraph_vector_destroy(&results);
  igraph_vs_destroy(&allnds);
  return degs;
}
Esempio n. 19
0
/* 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;

}
Esempio n. 20
0
igraph_integer_t d(igraph_t *graph, igraph_integer_t v)
{
    igraph_vector_t res;
    igraph_vs_t vs;

    igraph_vector_init(&res, 1);
    igraph_vs_1(&vs, v);

    igraph_degree(graph, &res, vs, IGRAPH_ALL, IGRAPH_LOOPS); 
    igraph_integer_t d_v = VECTOR(res)[0];

    igraph_vs_destroy(&vs);
    igraph_vector_destroy(&res);
    return d_v;
}
Esempio n. 21
0
/* 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;

}
Esempio n. 22
0
/* 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;

}
Esempio n. 23
0
void TMIgraph::calculateFID(string &source, string &destination, Bitvector &resultFID, unsigned int &numberOfHops) {
    int vertex_id;
    igraph_vs_t vs;
    igraph_vector_ptr_t res;
    igraph_vector_t to_vector;
    igraph_vector_t *temp_v;
    igraph_integer_t eid;

    /*find the vertex id in the reverse index*/
    int from = (*reverse_node_index.find(source)).second;
    igraph_vector_init(&to_vector, 1);
    VECTOR(to_vector)[0] = (*reverse_node_index.find(destination)).second;
    /*initialize the sequence*/
    igraph_vs_vector(&vs, &to_vector);
    /*initialize the vector that contains pointers*/
    igraph_vector_ptr_init(&res, 1);
    temp_v = (igraph_vector_t *) VECTOR(res)[0];
    temp_v = (igraph_vector_t *) malloc(sizeof (igraph_vector_t));
    VECTOR(res)[0] = temp_v;
    igraph_vector_init(temp_v, 1);
    /*run the shortest path algorithm from "from"*/
    igraph_get_shortest_paths(&graph, &res, from, vs, IGRAPH_OUT);
    /*check the shortest path to each destination*/
    temp_v = (igraph_vector_t *) VECTOR(res)[0];

    /*now let's "or" the FIDs for each link in the shortest path*/
    for (int j = 0; j < igraph_vector_size(temp_v) - 1; j++) {
        igraph_get_eid(&graph, &eid, VECTOR(*temp_v)[j], VECTOR(*temp_v)[j + 1], true);
        Bitvector *lid = (*edge_LID.find(eid)).second;
        (resultFID) = (resultFID) | (*lid);
    }
    numberOfHops = igraph_vector_size(temp_v);

    /*now for the destination "or" the internal linkID*/
    Bitvector *ilid = (*nodeID_iLID.find(destination)).second;
    (resultFID) = (resultFID) | (*ilid);
    //cout << "FID of the shortest path: " << resultFID.to_string() << endl;
    igraph_vector_destroy((igraph_vector_t *) VECTOR(res)[0]);
    igraph_vector_destroy(&to_vector);
    igraph_vector_ptr_destroy_all(&res);
    igraph_vs_destroy(&vs);
}
Esempio n. 24
0
/* 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;

}
int main() {

  igraph_t g;
  igraph_vector_ptr_t vecs;
  long int i;
  igraph_real_t weights[] = { 1, 2, 3, 4, 5, 1, 1, 1, 1, 1 }; 
  igraph_real_t weights2[] = { 0,2,1, 0,5,2, 1,1,0, 2,2,8, 1,1,3, 1,1,4, 2,1 };
  igraph_vector_t weights_vec;
  igraph_vs_t vs;

  /* Simple ring graph without weights */

  igraph_ring(&g, 10, IGRAPH_UNDIRECTED, 0, 1);
  
  igraph_vector_ptr_init(&vecs, 5);
  for (i=0; i<igraph_vector_ptr_size(&vecs); i++) {
    VECTOR(vecs)[i] = calloc(1, sizeof(igraph_vector_t));
    igraph_vector_init(VECTOR(vecs)[i], 0);
  }
  igraph_vs_vector_small(&vs, 1, 3, 5, 2, 1,  -1);
  
  igraph_get_shortest_paths_dijkstra(&g, &vecs, 0, vs, 0, IGRAPH_OUT);
  
  for (i=0; i<igraph_vector_ptr_size(&vecs); i++) 
    print_vector(VECTOR(vecs)[i]);

  /* Same ring, but with weights */

  igraph_vector_view(&weights_vec, weights, sizeof(weights)/sizeof(igraph_real_t));
  igraph_get_shortest_paths_dijkstra(&g, &vecs, 0, vs, &weights_vec, IGRAPH_OUT);
  
  for (i=0; i<igraph_vector_ptr_size(&vecs); i++) 
    print_vector(VECTOR(vecs)[i]);

  igraph_destroy(&g);

  /* More complicated example */

  igraph_small(&g, 10, IGRAPH_DIRECTED, 
	       0,1, 0,2, 0,3,    1,2, 1,4, 1,5,
	       2,3, 2,6,         3,2, 3,6,
	       4,5, 4,7,         5,6, 5,8, 5,9,
	       7,5, 7,8,         8,9,
	       5,2,
	       2,1,
	       -1);
  
  igraph_vector_view(&weights_vec, weights2, sizeof(weights2)/sizeof(igraph_real_t));
  igraph_get_shortest_paths_dijkstra(&g, &vecs, 0, vs, &weights_vec, IGRAPH_OUT);
  
  for (i=0; i<igraph_vector_ptr_size(&vecs); i++) {
    print_vector(VECTOR(vecs)[i]);
    igraph_vector_destroy(VECTOR(vecs)[i]);
    free(VECTOR(vecs)[i]);
  }

  igraph_vector_ptr_destroy(&vecs);
  igraph_vs_destroy(&vs);
  igraph_destroy(&g);

  if (!IGRAPH_FINALLY_STACK_EMPTY) return 1;

  return 0;
}
Esempio n. 26
0
igraph_vector_t * ggen_analyze_longest_path(igraph_t *g)
{
	igraph_vector_t topology;
	igraph_vector_t lengths;
	igraph_vector_t preds;
	igraph_vs_t vs;
	igraph_vit_t vit;
	igraph_vector_t *res = NULL;
	int err;
	unsigned long v,i,f,t;
	long maxv;
	if(g == NULL)
		return NULL;

	v = igraph_vcount(g);
	err = igraph_vector_init(&topology,v);
	if(err)	return NULL;

	err = igraph_vector_init(&lengths,v);
	if(err) goto error_il;

	err = igraph_vector_init(&preds,v);
	if(err) goto error_ip;

	res = malloc(sizeof(igraph_vector_t));
	if(res == NULL) goto cleanup;

	err = igraph_vector_init(res,v);
	if(err) goto error_ir;

	// sort topologically the vertices
	err = igraph_topological_sorting(g,&topology,IGRAPH_OUT);
	if(err) goto error;
	// igraph is stupid, it returns 0 even if the graph isn't a dag
	if(igraph_vector_size(&topology) != v)
		goto error;

	// find the best path incomming from every node
	igraph_vector_null(&lengths);
	igraph_vector_fill(&preds,-1);
	maxv = -1;
	for(i = 0; i < v; i++)
	{
		f = VECTOR(topology)[i];
		err = igraph_vs_adj(&vs,f,IGRAPH_OUT);
		if(err) goto error;
		err = igraph_vit_create(g,vs,&vit);
		if(err)
		{
			igraph_vs_destroy(&vs);
			goto error;
		}

		for(vit; !IGRAPH_VIT_END(vit); IGRAPH_VIT_NEXT(vit))
		{
			t = IGRAPH_VIT_GET(vit);
			if(VECTOR(lengths)[t] < VECTOR(lengths)[f] + 1)
			{
				VECTOR(lengths)[t] = VECTOR(lengths)[f] +1;
				VECTOR(preds)[t] = f;
			}
			if(maxv == -1 || VECTOR(lengths)[t] > VECTOR(lengths)[maxv])
				maxv = t;
		}
		igraph_vs_destroy(&vs);
		igraph_vit_destroy(&vit);

	}
	// build the path, using preds and maxv
	f = 0;
	while(maxv != -1)
	{
		VECTOR(*res)[f++] = maxv;
		maxv = VECTOR(preds)[maxv];
	}

	// finish the path correctly, resizing and reversing the array
	err = igraph_vector_resize(res,f);
	if(err) goto error;

	err = igraph_vector_reverse(res);
	if(err) goto error;

	goto cleanup;
error:
	igraph_vector_destroy(res);
error_ir:
	free(res);
	res = NULL;
cleanup:
	igraph_vector_destroy(&preds);
error_ip:
	igraph_vector_destroy(&lengths);
error_il:
	igraph_vector_destroy(&topology);
	return res;
}
Esempio n. 27
0
igraph_vector_t *ggen_analyze_lowest_single_ancestor(igraph_t *g)
{
	unsigned long i,v,l,vid,r;
	int err = 0;
	igraph_vector_t toposort,itopo;
	igraph_vector_t *lsa;
	igraph_t tree;
	igraph_vs_t vs;
	igraph_vit_t vit;
	lca_metadata md;

	if(g == NULL)
		return NULL;

	err = igraph_vector_init(&toposort,igraph_vcount(g));
	if(err) return NULL;

	err = igraph_topological_sorting(g,&toposort,IGRAPH_OUT);
	if(err) goto d_tp;

	/* build a reverse index of the toposort */
	err = igraph_vector_init(&itopo,igraph_vcount(g));
	if(err) goto d_tp;

	for(i = 0; i < igraph_vcount(g); i++)
	{
		v = VECTOR(toposort)[i];
		VECTOR(itopo)[v] = i;
	}

	err = igraph_empty(&tree,1,IGRAPH_DIRECTED);
	if(err) goto d_i;

	lsa = calloc(1,sizeof(igraph_vector_t*));
	if(lsa == NULL) goto cleanup;

	err = igraph_vector_init(lsa,igraph_vcount(g));
	if(err) goto f_l;

	for(v = 1; v < igraph_vcount(g); v++)
	{
		vid = VECTOR(toposort)[v];

		tree_lca_metadata_init(&tree,&md);
		tree_lca_preprocessing(&tree,0,&md);

		/* iterate over parents of v in g
		 * The lsa of a node is the LCA of all its parents in our
		 * special tree.
		 */
		igraph_vs_adj(&vs, vid, IGRAPH_IN);
		igraph_vit_create(g,vs,&vit);
		l = VECTOR(itopo)[IGRAPH_VIT_GET(vit)];
		IGRAPH_VIT_NEXT(vit);

		for(vit;!IGRAPH_VIT_END(vit); IGRAPH_VIT_NEXT(vit))
		{
			tree_lca_query(&tree,l,VECTOR(itopo)[IGRAPH_VIT_GET(vit)],&r,&md);
			l = r;
		}

		igraph_vit_destroy(&vit);
		igraph_vs_destroy(&vs);
		tree_lca_metadata_free(&tree,&md);

		// update tree
		err = igraph_add_vertices(&tree,1,NULL);
		if(err) goto d_l;

		err = igraph_add_edge(&tree,l,v);
		if(err) goto d_l;

		VECTOR(*lsa)[vid] = VECTOR(toposort)[l];
	}
	goto cleanup;
d_l:
	igraph_vector_destroy(lsa);
f_l:
	free(lsa);
	lsa = NULL;
cleanup:
	igraph_destroy(&tree);
d_i:
	igraph_vector_destroy(&itopo);
d_tp:
	igraph_vector_destroy(&toposort);
	return lsa;
}
Esempio n. 28
0
/* 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;
    */
}
Esempio n. 29
0
/**
 * \ingroup python_interface_vertexseq
 * \brief Selects a subset of the vertex sequence based on some criteria
 */
PyObject* igraphmodule_VertexSeq_select(igraphmodule_VertexSeqObject *self,
  PyObject *args) {
  igraphmodule_VertexSeqObject *result;
  igraphmodule_GraphObject *gr;
  long i, j, n, m;

  gr=self->gref;
  result=igraphmodule_VertexSeq_copy(self);
  if (result==0)
    return NULL;

  /* First, filter by positional arguments */
  n = PyTuple_Size(args);

  for (i=0; i<n; i++) {
    PyObject *item = PyTuple_GET_ITEM(args, i);

    if (item == Py_None) {
      /* None means: select nothing */
      igraph_vs_destroy(&result->vs);
      igraph_vs_none(&result->vs);
      /* We can simply bail out here */
      return (PyObject*)result;
    } else if (PyCallable_Check(item)) {
      /* Call the callable for every vertex in the current sequence to
       * determine what's up */
      igraph_bool_t was_excluded = 0;
      igraph_vector_t v;

      if (igraph_vector_init(&v, 0)) {
        igraphmodule_handle_igraph_error();
        return 0;
      }

      m = PySequence_Size((PyObject*)result);
      for (j=0; j<m; j++) {
        PyObject *vertex = PySequence_GetItem((PyObject*)result, j);
        PyObject *call_result;
        if (vertex == 0) {
          Py_DECREF(result);
          igraph_vector_destroy(&v);
          return NULL;
        }
        call_result = PyObject_CallFunctionObjArgs(item, vertex, NULL);
        if (call_result == 0) {
          Py_DECREF(vertex); Py_DECREF(result);
          igraph_vector_destroy(&v);
          return NULL;
        }
        if (PyObject_IsTrue(call_result))
          igraph_vector_push_back(&v,
            igraphmodule_Vertex_get_index_long((igraphmodule_VertexObject*)vertex));
        else was_excluded=1;
        Py_DECREF(call_result);
        Py_DECREF(vertex);
      }

      if (was_excluded) {
        igraph_vs_destroy(&result->vs);
        if (igraph_vs_vector_copy(&result->vs, &v)) {
          Py_DECREF(result);
          igraph_vector_destroy(&v);
          igraphmodule_handle_igraph_error();
          return NULL;
        }
      }

      igraph_vector_destroy(&v);
    } else if (PyInt_Check(item)) {
      /* Integers are treated specially: from now on, all remaining items
       * in the argument list must be integers and they will be used together
       * to restrict the vertex set. Integers are interpreted as indices on the
       * vertex set and NOT on the original, untouched vertex sequence of the
       * graph */
      igraph_vector_t v, v2;
      if (igraph_vector_init(&v, 0)) {
        igraphmodule_handle_igraph_error();
        return 0;
      }
      if (igraph_vector_init(&v2, 0)) {
        igraph_vector_destroy(&v);
        igraphmodule_handle_igraph_error();
        return 0;
      }
      if (igraph_vs_as_vector(&gr->g, self->vs, &v2)) {
        igraph_vector_destroy(&v);
        igraph_vector_destroy(&v2);
        igraphmodule_handle_igraph_error();
        return 0;
      }
      m = igraph_vector_size(&v2);
      for (; i<n; i++) {
        PyObject *item2 = PyTuple_GET_ITEM(args, i);
        long idx;
        if (!PyInt_Check(item2)) {
          Py_DECREF(result);
          PyErr_SetString(PyExc_TypeError, "vertex indices expected");
          igraph_vector_destroy(&v);
          igraph_vector_destroy(&v2);
          return NULL;
        }
        idx = PyInt_AsLong(item2);
        if (idx >= m || idx < 0) {
          PyErr_SetString(PyExc_ValueError, "vertex index out of range");
          igraph_vector_destroy(&v);
          igraph_vector_destroy(&v2);
          return NULL;
        }
        if (igraph_vector_push_back(&v, VECTOR(v2)[idx])) {
          Py_DECREF(result);
          igraphmodule_handle_igraph_error();
          igraph_vector_destroy(&v);
          igraph_vector_destroy(&v2);
          return NULL;
        }
      }
      igraph_vector_destroy(&v2);
      igraph_vs_destroy(&result->vs);
      if (igraph_vs_vector_copy(&result->vs, &v)) {
        Py_DECREF(result);
        igraphmodule_handle_igraph_error();
        igraph_vector_destroy(&v);
        return NULL;
      }
      igraph_vector_destroy(&v);
    } else {
      /* Iterators, slices and everything that was not handled directly */
      PyObject *iter=0, *item2;
      igraph_vector_t v, v2;

      /* Allocate stuff */
      if (igraph_vector_init(&v, 0)) {
        igraphmodule_handle_igraph_error();
        Py_DECREF(result);
        return 0;
      }
      if (igraph_vector_init(&v2, 0)) {
        igraph_vector_destroy(&v);
        Py_DECREF(result);
        igraphmodule_handle_igraph_error();
        return 0;
      }
      if (igraph_vs_as_vector(&gr->g, self->vs, &v2)) {
        igraph_vector_destroy(&v);
        igraph_vector_destroy(&v2);
        Py_DECREF(result);
        igraphmodule_handle_igraph_error();
        return 0;
      }
      m = igraph_vector_size(&v2);

      /* Create an appropriate iterator */
      if (PySlice_Check(item)) {
        /* Create an iterator from the slice (which is not iterable by default) */
        Py_ssize_t start, stop, step, sl;
        PyObject* range;
        igraph_bool_t ok;

        /* Casting to void* because Python 2.x expects PySliceObject*
         * but Python 3.x expects PyObject* */
        ok = (PySlice_GetIndicesEx((void*)item, igraph_vector_size(&v2),
              &start, &stop, &step, &sl) == 0);

        if (ok) {
          range = igraphmodule_PyRange_create(start, stop, step);
          ok = (range != 0);
        }
        if (ok) {
          iter = PyObject_GetIter(range);
          Py_DECREF(range);
          ok = (iter != 0);
        }
        if (!ok) {
          igraph_vector_destroy(&v);
          igraph_vector_destroy(&v2);
          PyErr_SetString(PyExc_TypeError, "error while converting slice to iterator");
          Py_DECREF(result);
          return 0;
        }
      } else {
        /* Simply create the iterator corresponding to the object */
        iter = PyObject_GetIter(item);
      }

      /* Did we manage to get an iterator? */
      if (iter == 0) {
        igraph_vector_destroy(&v);
        igraph_vector_destroy(&v2);
        PyErr_SetString(PyExc_TypeError, "invalid vertex filter among positional arguments");
        Py_DECREF(result);
        return 0;
      }
      /* Do the iteration */
      while ((item2=PyIter_Next(iter)) != 0) {
        if (PyInt_Check(item2)) {
          long idx = PyInt_AsLong(item2);
          Py_DECREF(item2);
          if (idx >= m || idx < 0) {
            PyErr_SetString(PyExc_ValueError, "vertex index out of range");
            Py_DECREF(result);
            Py_DECREF(iter);
            igraph_vector_destroy(&v);
            igraph_vector_destroy(&v2);
            return NULL;
          }
          if (igraph_vector_push_back(&v, VECTOR(v2)[idx])) {
            Py_DECREF(result);
            Py_DECREF(iter);
            igraphmodule_handle_igraph_error();
            igraph_vector_destroy(&v);
            igraph_vector_destroy(&v2);
            return NULL;
          }
        } else {
          /* We simply ignore elements that we don't know */
          Py_DECREF(item2);
        }
      }
      /* Deallocate stuff */
      igraph_vector_destroy(&v2);
      Py_DECREF(iter);
      if (PyErr_Occurred()) {
        igraph_vector_destroy(&v);
        Py_DECREF(result);
        return 0;
      }
      igraph_vs_destroy(&result->vs);
      if (igraph_vs_vector_copy(&result->vs, &v)) {
        Py_DECREF(result);
        igraphmodule_handle_igraph_error();
        igraph_vector_destroy(&v);
        return NULL;
      }
      igraph_vector_destroy(&v);
    }
  }

  return (PyObject*)result;
}
int main() {
  igraph_t g, g2;
  igraph_vector_ptr_t sep;
  igraph_vs_t vs;
  
  igraph_small(&g, 7, IGRAPH_UNDIRECTED,
	       1,0, 2,0, 3,0, 4,0, 5,0, 6,0,
	       -1);
  igraph_vector_ptr_init(&sep, 0);
  igraph_minimum_size_separators(&g, &sep);
  print_and_destroy(&sep);
  igraph_destroy(&g);

  /* ----------------------------------------------------------- */

  igraph_small(&g, 5, IGRAPH_UNDIRECTED,
	       0,3, 1,3, 2,3,
	       0,4, 1,4, 2,4,
	       -1);
  igraph_vector_ptr_init(&sep, 0);
  igraph_minimum_size_separators(&g, &sep);
  print_and_destroy(&sep);
  igraph_destroy(&g);

  /* ----------------------------------------------------------- */

  igraph_small(&g, 5, IGRAPH_UNDIRECTED,
	       2,0, 3,0, 4,0,
	       2,1, 3,1, 4,1,
	       -1);
  igraph_vector_ptr_init(&sep, 0);
  igraph_minimum_size_separators(&g, &sep);
  print_and_destroy(&sep);
  igraph_destroy(&g);

  /* ----------------------------------------------------------- */

  igraph_small(&g, 10, IGRAPH_UNDIRECTED,
	       0,2, 0,3, 1,2, 1,3, 5,2, 5,3, 6,2, 6,3, 
	       7,2, 7,3, 8,2, 8,3, 9,2, 9,3,
	       2,4, 4,3,
	       -1);
  igraph_vector_ptr_init(&sep, 0);
  igraph_minimum_size_separators(&g, &sep);
  print_and_destroy(&sep);
  igraph_destroy(&g);  

  /* ----------------------------------------------------------- */

  igraph_full(&g, 4, IGRAPH_UNDIRECTED, /*loops=*/ 0);
  igraph_vector_ptr_init(&sep, 0);
  igraph_minimum_size_separators(&g, &sep);
  print_and_destroy(&sep);
  igraph_destroy(&g);  

  /* ----------------------------------------------------------- */

  igraph_small(&g, 23, IGRAPH_UNDIRECTED,
	       0,1, 0,2, 0,3, 0,4, 0,5,
	       1,2, 1,3, 1,4, 1,6,
	       2,3, 2,5, 2,6,
	       3,4, 3,5, 3,6,
	       4,5, 4,6, 4,20,
	       5,6, 
	       6,7, 6,10, 6,13, 6,18,
	       7,8, 7,10, 7,13,
	       8,9,
	       9,11, 9,12,
	       10,11, 10,13,
	       11,15,
	       12,15,
	       13,14,
	       14,15,
	       16,17, 16,18, 16,19,
	       17,19, 17,20,
	       18,19, 18,21, 18,22,
	       19,20,
	       20,21, 20,22,
	       21,22,
	       -1);

  igraph_vector_ptr_init(&sep, 0);
  igraph_minimum_size_separators(&g, &sep);
  printf("Orig:\n"); print_and_destroy(&sep);

  igraph_vector_ptr_init(&sep, 0);
  igraph_vs_vector_small(&vs, 0,1,2,3,4,5,6, 16,17,18,19,20,21,22, -1);
  igraph_induced_subgraph(&g, &g2, vs, IGRAPH_SUBGRAPH_AUTO);
  igraph_minimum_size_separators(&g2, &sep);
  printf("1-7,17-23:\n"); print_and_destroy(&sep);
  igraph_vs_destroy(&vs);
  igraph_destroy(&g2);
  
  igraph_vector_ptr_init(&sep, 0);
  igraph_vs_vector_small(&vs, 6,7,8,9,10,11,12,13,14,15, -1);
  igraph_induced_subgraph(&g, &g2, vs, IGRAPH_SUBGRAPH_AUTO);
  igraph_minimum_size_separators(&g2, &sep);
  printf("7-16:\n"); print_and_destroy(&sep);
  igraph_vs_destroy(&vs);
  igraph_destroy(&g2);
  
  igraph_vector_ptr_init(&sep, 0);
  igraph_vs_vector_small(&vs, 16,17,18,19,20,21,22, -1);
  igraph_induced_subgraph(&g, &g2, vs, IGRAPH_SUBGRAPH_AUTO);
  igraph_minimum_size_separators(&g2, &sep);
  printf("17-23:\n"); print_and_destroy(&sep);
  igraph_vs_destroy(&vs);
  igraph_destroy(&g2);
  
  igraph_vector_ptr_init(&sep, 0);
  igraph_vs_vector_small(&vs, 6,7,10,13, -1);
  igraph_induced_subgraph(&g, &g2, vs, IGRAPH_SUBGRAPH_AUTO);
  igraph_minimum_size_separators(&g2, &sep);
  printf("7,8,11,14:\n"); print_and_destroy(&sep);
  igraph_vs_destroy(&vs);
  igraph_destroy(&g2);

  igraph_vector_ptr_init(&sep, 0);
  igraph_vs_vector_small(&vs, 0,1,2,3,4,5,6, -1);
  igraph_induced_subgraph(&g, &g2, vs, IGRAPH_SUBGRAPH_AUTO);
  igraph_minimum_size_separators(&g2, &sep);
  printf("1-7:\n"); print_and_destroy(&sep);
  igraph_vs_destroy(&vs);
  igraph_destroy(&g2);  

  igraph_destroy(&g);  

  return 0;
}