Exemplo n.º 1
0
int igraph_random_walk(const igraph_t *graph, igraph_vector_t *walk,
		       igraph_integer_t start, igraph_neimode_t mode,
		       igraph_integer_t steps,
		       igraph_random_walk_stuck_t stuck) {

  /* TODO:
     - multiple walks potentially from multiple start vertices
     - weights
  */

  igraph_lazy_adjlist_t adj;
  igraph_integer_t vc = igraph_vcount(graph);
  igraph_integer_t i;

  if (start < 0 || start >= vc) {
    IGRAPH_ERROR("Invalid start vertex", IGRAPH_EINVAL);
  }
  if (steps < 0) {
    IGRAPH_ERROR("Invalid number of steps", IGRAPH_EINVAL);
  }

  IGRAPH_CHECK(igraph_lazy_adjlist_init(graph, &adj, mode,
					IGRAPH_DONT_SIMPLIFY));
  IGRAPH_FINALLY(igraph_lazy_adjlist_destroy, &adj);

  IGRAPH_CHECK(igraph_vector_resize(walk, steps));

  RNG_BEGIN();

  VECTOR(*walk)[0] = start;
  for (i = 1; i < steps; i++) {
    igraph_vector_t *neis;
    igraph_integer_t nn;
    neis = igraph_lazy_adjlist_get(&adj, start);
    nn = igraph_vector_size(neis);

    if (IGRAPH_UNLIKELY(nn == 0)) {
      igraph_vector_resize(walk, i);
      if (stuck == IGRAPH_RANDOM_WALK_STUCK_RETURN) {
	break;
      } else {
	IGRAPH_ERROR("Random walk got stuck", IGRAPH_ERWSTUCK);
      }
    }
    start = VECTOR(*walk)[i] = VECTOR(*neis)[ RNG_INTEGER(0, nn - 1) ];
  }

  RNG_END();

  igraph_lazy_adjlist_destroy(&adj);
  IGRAPH_FINALLY_CLEAN(1);

  return 0;
}
Exemplo n.º 2
0
int main() {

  igraph_sparsemat_t A, B, C;
  igraph_vector_t b, x;
  long int i;

  /* lsolve */

#define DIM 10
#define EDGES (DIM*DIM/6)
  igraph_sparsemat_init(&A, DIM, DIM, EDGES+DIM);
  for (i=0; i<DIM; i++) {
    igraph_sparsemat_entry(&A, i, i, RNG_INTEGER(1,3));
  }
  for (i=0; i<EDGES; i++) {
    long int r=RNG_INTEGER(0, DIM-1);
    long int c=RNG_INTEGER(0, r);
    igraph_real_t value=RNG_INTEGER(1,5);
    igraph_sparsemat_entry(&A, r, c, value);
  }
  igraph_sparsemat_compress(&A, &B);
  igraph_sparsemat_destroy(&A);
  igraph_sparsemat_dupl(&B);
  
  igraph_vector_init(&b, DIM);
  for (i=0; i<DIM; i++) {    
    VECTOR(b)[i] = RNG_INTEGER(1,10);
  }

  igraph_vector_init(&x, DIM);
  igraph_sparsemat_lsolve(&B, &b, &x);

  if (! check_solution(&B, &x, &b)) { return 1; }

  igraph_vector_destroy(&b);
  igraph_vector_destroy(&x);
  igraph_sparsemat_destroy(&B);

#undef DIM
#undef EDGES

  /* ltsolve */

#define DIM 10
#define EDGES (DIM*DIM/6)
  igraph_sparsemat_init(&A, DIM, DIM, EDGES+DIM);
  for (i=0; i<DIM; i++) {
    igraph_sparsemat_entry(&A, i, i, RNG_INTEGER(1,3));
  }
  for (i=0; i<EDGES; i++) {
    long int r=RNG_INTEGER(0, DIM-1);
    long int c=RNG_INTEGER(0, r);
    igraph_real_t value=RNG_INTEGER(1,5);
    igraph_sparsemat_entry(&A, r, c, value);
  }
  igraph_sparsemat_compress(&A, &B);
  igraph_sparsemat_destroy(&A);
  igraph_sparsemat_dupl(&B);
  
  igraph_vector_init(&b, DIM);
  for (i=0; i<DIM; i++) {    
    VECTOR(b)[i] = RNG_INTEGER(1,10);
  }

  igraph_vector_init(&x, DIM);
  igraph_sparsemat_ltsolve(&B, &b, &x);

  igraph_sparsemat_transpose(&B, &A, /*values=*/ 1);
  if (! check_solution(&A, &x, &b)) { return 2; }

  igraph_vector_destroy(&b);
  igraph_vector_destroy(&x);
  igraph_sparsemat_destroy(&B);
  igraph_sparsemat_destroy(&A);

#undef DIM
#undef EDGES

  /* usolve */

#define DIM 10
#define EDGES (DIM*DIM/6)
  igraph_sparsemat_init(&A, DIM, DIM, EDGES+DIM);
  for (i=0; i<DIM; i++) {
    igraph_sparsemat_entry(&A, i, i, RNG_INTEGER(1,3));
  }
  for (i=0; i<EDGES; i++) {
    long int r=RNG_INTEGER(0, DIM-1);
    long int c=RNG_INTEGER(0, r);
    igraph_real_t value=RNG_INTEGER(1,5);
    igraph_sparsemat_entry(&A, r, c, value);
  }
  igraph_sparsemat_compress(&A, &B);
  igraph_sparsemat_destroy(&A);
  igraph_sparsemat_dupl(&B);
  igraph_sparsemat_transpose(&B, &A, /*values=*/ 1);
  
  igraph_vector_init(&b, DIM);
  for (i=0; i<DIM; i++) {    
    VECTOR(b)[i] = RNG_INTEGER(1,10);
  }

  igraph_vector_init(&x, DIM);
  igraph_sparsemat_usolve(&A, &b, &x);

  if (! check_solution(&A, &x, &b)) { return 3; }

  igraph_vector_destroy(&b);
  igraph_vector_destroy(&x);
  igraph_sparsemat_destroy(&B);
  igraph_sparsemat_destroy(&A);

#undef DIM
#undef EDGES  

  /* utsolve */

#define DIM 10
#define EDGES (DIM*DIM/6)
  igraph_sparsemat_init(&A, DIM, DIM, EDGES+DIM);
  for (i=0; i<DIM; i++) {
    igraph_sparsemat_entry(&A, i, i, RNG_INTEGER(1,3));
  }
  for (i=0; i<EDGES; i++) {
    long int r=RNG_INTEGER(0, DIM-1);
    long int c=RNG_INTEGER(0, r);
    igraph_real_t value=RNG_INTEGER(1,5);
    igraph_sparsemat_entry(&A, r, c, value);
  }
  igraph_sparsemat_compress(&A, &B);
  igraph_sparsemat_destroy(&A);
  igraph_sparsemat_dupl(&B);
  igraph_sparsemat_transpose(&B, &A, /*values=*/ 1);
  igraph_sparsemat_destroy(&B);
  
  igraph_vector_init(&b, DIM);
  for (i=0; i<DIM; i++) {    
    VECTOR(b)[i] = RNG_INTEGER(1,10);
  }

  igraph_vector_init(&x, DIM);
  igraph_sparsemat_utsolve(&A, &b, &x);

  igraph_sparsemat_transpose(&A, &B, /*values=*/ 1);
  if (! check_solution(&B, &x, &b)) { return 4; }

  igraph_vector_destroy(&b);
  igraph_vector_destroy(&x);
  igraph_sparsemat_destroy(&B);
  igraph_sparsemat_destroy(&A);

#undef DIM
#undef EDGES  

  /* cholsol */
  /* We need a positive definite matrix, so we create a full-rank
     matrix first and then calculate A'A, which will be positive
     definite. */

#define DIM 10
#define EDGES (DIM*DIM/6)
  igraph_sparsemat_init(&A, DIM, DIM, EDGES+DIM);
  for (i=0; i<DIM; i++) {
    igraph_sparsemat_entry(&A, i, i, RNG_INTEGER(1,3));
  }
  for (i=0; i<EDGES; i++) {
    long int from=RNG_INTEGER(0, DIM-1);
    long int to=RNG_INTEGER(0, DIM-1);
    igraph_real_t value=RNG_INTEGER(1, 5);
    igraph_sparsemat_entry(&A, from, to, value);
  }
  igraph_sparsemat_compress(&A, &B);
  igraph_sparsemat_destroy(&A);
  igraph_sparsemat_dupl(&B);
  igraph_sparsemat_transpose(&B, &A, /*values=*/ 1);
  igraph_sparsemat_multiply(&A, &B, &C);
  igraph_sparsemat_destroy(&A);
  igraph_sparsemat_destroy(&B);
  
  igraph_vector_init(&b, DIM);
  for (i=0; i<DIM; i++) {
    VECTOR(b)[i] = RNG_INTEGER(1,10);
  }

  igraph_vector_init(&x, DIM);
  igraph_sparsemat_cholsol(&C, &b, &x, /*order=*/ 0);
  
  if (! check_solution(&C, &x, &b)) { return 5; }

  igraph_vector_destroy(&b);
  igraph_vector_destroy(&x);
  igraph_sparsemat_destroy(&C);

#undef DIM
#undef EDGES

  /* lusol */

#define DIM 10
#define EDGES (DIM*DIM/4)
  igraph_sparsemat_init(&A, DIM, DIM, EDGES+DIM);
  for (i=0; i<DIM; i++) {
    igraph_sparsemat_entry(&A, i, i, RNG_INTEGER(1,3));
  }
  for (i=0; i<EDGES; i++) {
    long int from=RNG_INTEGER(0, DIM-1);
    long int to=RNG_INTEGER(0, DIM-1);
    igraph_real_t value=RNG_INTEGER(1, 5);
    igraph_sparsemat_entry(&A, from, to, value);
  }
  igraph_sparsemat_compress(&A, &B);
  igraph_sparsemat_destroy(&A);
  igraph_sparsemat_dupl(&B);

  igraph_vector_init(&b, DIM);
  for (i=0; i<DIM; i++) {
    VECTOR(b)[i] = RNG_INTEGER(1,10);
  }

  igraph_vector_init(&x, DIM);
  igraph_sparsemat_lusol(&B, &b, &x, /*order=*/ 0, /*tol=*/ 1e-10);
  
  if (! check_solution(&B, &x, &b)) { return 6; }

  igraph_vector_destroy(&b);
  igraph_vector_destroy(&x);
  igraph_sparsemat_destroy(&B);

#undef DIM
#undef EDGES

  return 0;
}
Exemplo n.º 3
0
int igraph_forest_fire_game(igraph_t *graph, igraph_integer_t nodes,
			    igraph_real_t fw_prob, igraph_real_t bw_factor,
			    igraph_integer_t pambs, igraph_bool_t directed) {
  
  igraph_vector_long_t visited;
  long int no_of_nodes=nodes, actnode, i;
  igraph_vector_t edges;
  igraph_vector_t *inneis, *outneis;
  igraph_i_forest_fire_data_t data;
  igraph_dqueue_t neiq;
  long int ambs=pambs;
  igraph_real_t param_geom_out=1-fw_prob;
  igraph_real_t param_geom_in=1-fw_prob*bw_factor;
  
  if (fw_prob < 0) {
    IGRAPH_ERROR("Forest fire model: 'fw_prob' should be between non-negative", 
		 IGRAPH_EINVAL);
  }
  if (bw_factor < 0) {
    IGRAPH_ERROR("Forest fire model: 'bw_factor' should be non-negative",
		 IGRAPH_EINVAL);
  }
  if (ambs < 0) {
    IGRAPH_ERROR("Number of ambassadors ('ambs') should be non-negative",
		 IGRAPH_EINVAL);
  }
  
  if (fw_prob == 0 || ambs == 0) {
    IGRAPH_WARNING("'fw_prob or ambs is zero, creating empty graph");
    IGRAPH_CHECK(igraph_empty(graph, nodes, directed));
    return 0;
  }
  
  IGRAPH_VECTOR_INIT_FINALLY(&edges, 0);

  inneis=igraph_Calloc(no_of_nodes, igraph_vector_t);
  if (!inneis) {
    IGRAPH_ERROR("Cannot run forest fire model", IGRAPH_ENOMEM);
  }
  IGRAPH_FINALLY(igraph_free, inneis);
  outneis=igraph_Calloc(no_of_nodes, igraph_vector_t);
  if (!outneis) {
    IGRAPH_ERROR("Cannot run forest fire model", IGRAPH_ENOMEM);
  }
  IGRAPH_FINALLY(igraph_free, outneis);  
  data.inneis=inneis; 
  data.outneis=outneis;
  data.no_of_nodes=no_of_nodes;
  IGRAPH_FINALLY(igraph_i_forest_fire_free, &data);
  for (i=0; i<no_of_nodes; i++) {
    IGRAPH_CHECK(igraph_vector_init(inneis+i, 0));
    IGRAPH_CHECK(igraph_vector_init(outneis+i, 0));
  }  

  IGRAPH_CHECK(igraph_vector_long_init(&visited, no_of_nodes));
  IGRAPH_FINALLY(igraph_vector_long_destroy, &visited);
  IGRAPH_DQUEUE_INIT_FINALLY(&neiq, 10);

  RNG_BEGIN();

#define ADD_EDGE_TO(nei) \
      if (VECTOR(visited)[(nei)] != actnode+1) {                     \
	VECTOR(visited)[(nei)] = actnode+1;                          \
	IGRAPH_CHECK(igraph_dqueue_push(&neiq, nei));                \
	IGRAPH_CHECK(igraph_vector_push_back(&edges, actnode));      \
	IGRAPH_CHECK(igraph_vector_push_back(&edges, nei));          \
	IGRAPH_CHECK(igraph_vector_push_back(outneis+actnode, nei)); \
	IGRAPH_CHECK(igraph_vector_push_back(inneis+nei, actnode));  \
      }
  
  IGRAPH_PROGRESS("Forest fire: ", 0.0, NULL);
  
  for (actnode=1; actnode < no_of_nodes; actnode++) {

    IGRAPH_PROGRESS("Forest fire: ", 100.0*actnode/no_of_nodes, NULL);

    IGRAPH_ALLOW_INTERRUPTION();    
    
    /* We don't want to visit the current vertex */
    VECTOR(visited)[actnode] = actnode+1;

    /* Choose ambassador(s) */
    for (i=0; i<ambs; i++) {
      long int a=RNG_INTEGER(0, actnode-1);
      ADD_EDGE_TO(a);
    }
    
    while (!igraph_dqueue_empty(&neiq)) {
      long int actamb=(long int) igraph_dqueue_pop(&neiq);
      igraph_vector_t *outv=outneis+actamb;
      igraph_vector_t *inv=inneis+actamb;
      long int no_in=igraph_vector_size(inv);
      long int no_out=igraph_vector_size(outv);
      long int neis_out=(long int) RNG_GEOM(param_geom_out);
      long int neis_in=(long int) RNG_GEOM(param_geom_in);
      /* outgoing neighbors */
      if (neis_out >= no_out) {
	for (i=0; i<no_out; i++) {
	  long int nei=(long int) VECTOR(*outv)[i];
	  ADD_EDGE_TO(nei);
	}
      } else {
	long int oleft=no_out;
	for (i=0; i<neis_out && oleft > 0; ) {
	  long int which=RNG_INTEGER(0, oleft-1);
	  long int nei=(long int) VECTOR(*outv)[which];
	  VECTOR(*outv)[which] = VECTOR(*outv)[oleft-1];
	  VECTOR(*outv)[oleft-1] = nei;
	  if (VECTOR(visited)[nei] != actnode+1) {
	    ADD_EDGE_TO(nei);
	    i++;
	  }
	  oleft--;
	}
      }
      /* incoming neighbors */
      if (neis_in >= no_in) {
	for (i=0; i<no_in; i++) {
	  long int nei=(long int) VECTOR(*inv)[i];
	  ADD_EDGE_TO(nei);
	}
      } else {
	long int ileft=no_in;
	for (i=0; i<neis_in && ileft > 0; ) {
	  long int which=RNG_INTEGER(0, ileft-1);
	  long int nei=(long int) VECTOR(*inv)[which];
	  VECTOR(*inv)[which] = VECTOR(*inv)[ileft-1];
	  VECTOR(*inv)[ileft-1] = nei;
	  if (VECTOR(visited)[nei] != actnode+1) {
	    ADD_EDGE_TO(nei);
	    i++;
	  }
	  ileft--;
	}
      }
      
    } /* while neiq not empty */

  } /* actnode < no_of_nodes */

#undef ADD_EDGE_TO  

  RNG_END();

  IGRAPH_PROGRESS("Forest fire: ", 100.0, NULL);
  
  igraph_dqueue_destroy(&neiq);
  igraph_vector_long_destroy(&visited);
  igraph_i_forest_fire_free(&data);
  igraph_free(outneis);
  igraph_free(inneis);  
  IGRAPH_FINALLY_CLEAN(5);

  IGRAPH_CHECK(igraph_create(graph, &edges, nodes, directed));
  igraph_vector_destroy(&edges);
  IGRAPH_FINALLY_CLEAN(1);

  return 0;
}
Exemplo n.º 4
0
int splicing_simulate_reads(const splicing_gff_t *gff, int gene,
			    const splicing_vector_t *expression,
			    int noreads, int readLength,
			    splicing_vector_int_t *isoform, 
			    splicing_vector_int_t *position, 
			    splicing_strvector_t *cigar, 
			    splicing_vector_t *sample_prob) {
  
  size_t i, p, noiso, goodiso=0, nogenes;
  splicing_vector_int_t effisolen;
  splicing_vector_t sampleprob;
  double rand, sumpsi=0.0;
  splicing_vector_int_t exstart, exend, exidx;

  SPLICING_CHECK(splicing_gff_nogenes(gff, &nogenes));
  if (gene < 0 || gene >= nogenes) {
    SPLICING_ERROR("Invalid gene id", SPLICING_EINVAL);
  }

  /* TODO: more error checks */

  SPLICING_CHECK(splicing_gff_noiso_one(gff, gene, &noiso));
    
  SPLICING_CHECK(splicing_vector_int_init(&effisolen, noiso));
  SPLICING_FINALLY(splicing_vector_int_destroy, &effisolen);
  SPLICING_CHECK(splicing_vector_init(&sampleprob, noiso));
  SPLICING_FINALLY(splicing_vector_destroy, &sampleprob);
  SPLICING_CHECK(splicing_vector_int_resize(isoform, noreads));
  SPLICING_CHECK(splicing_gff_isolength_one(gff, gene, &effisolen));
  for (i=0; i<noiso; i++) {
    int l=VECTOR(effisolen)[i]-readLength+1;
    VECTOR(effisolen)[i] = l > 0 ? l : 0;
    VECTOR(sampleprob)[i] = VECTOR(*expression)[i] * VECTOR(effisolen)[i];
    if (VECTOR(sampleprob)[i] != 0) { goodiso++; }
    sumpsi += VECTOR(sampleprob)[i];
  }

  if (goodiso==0) {
    SPLICING_ERROR("No isoform is possible", SPLICING_FAILURE);
  }

  if (sample_prob) {
    SPLICING_CHECK(splicing_vector_update(sample_prob, &sampleprob));
  }

  for (i=1; i<noiso; i++) {
    VECTOR(sampleprob)[i] += VECTOR(sampleprob)[i-1];
  }

  for (i=0; i<noreads; i++) {
    int w;
    if (noiso==1) {
      w=0;
    } else if (noiso==2) {
      rand = RNG_UNIF01() * sumpsi;
      w = (rand < VECTOR(sampleprob)[0]) ? 0 : 1;
    } else {
      rand = RNG_UNIF01() * sumpsi;
      for (w=0; rand > VECTOR(sampleprob)[w]; w++) ;
    }
    VECTOR(*isoform)[i]=w;
  }
  
  splicing_vector_destroy(&sampleprob);
  SPLICING_FINALLY_CLEAN(1);

  /* OK, we have the isoforms, now we need the read positions, 
     these are uniformly sampled from the individual isoforms. */

  SPLICING_CHECK(splicing_vector_int_resize(position, noreads));
  SPLICING_CHECK(splicing_vector_int_init(&exstart, 0));
  SPLICING_FINALLY(splicing_vector_int_destroy, &exstart);
  SPLICING_CHECK(splicing_vector_int_init(&exend, 0));
  SPLICING_FINALLY(splicing_vector_int_destroy, &exend);
  SPLICING_CHECK(splicing_vector_int_init(&exidx, 0));
  SPLICING_FINALLY(splicing_vector_int_destroy, &exidx);
  SPLICING_CHECK(splicing_gff_exon_start_end(gff, &exstart, &exend, &exidx,
					     gene));

  /* Positions in isoform coordinates first */

  for (i=0; i<noreads; i++) { 
    int iso=VECTOR(*isoform)[i];
    int len=VECTOR(effisolen)[iso];
    VECTOR(*position)[i]=RNG_INTEGER(1, len);
  }

  /* Translate isoform coordinates to genomic coordintes */

  /* TODO: some of this is already calculated */
  SPLICING_CHECK(splicing_iso_to_genomic(gff, gene, isoform, /*converter=*/ 0,
					 position));

  /* CIGAR strings */

  splicing_strvector_clear(cigar);
  SPLICING_CHECK(splicing_strvector_reserve(cigar, noreads));
  for (i=0; i<noreads; i++) {
    char tmp[1000], *tmp2=tmp;
    int iso=VECTOR(*isoform)[i];
    size_t rs=VECTOR(*position)[i];
    int ex=0;
    int rl=readLength;
    for (ex=VECTOR(exidx)[iso]; VECTOR(exend)[ex] < rs; ex++) ;
    while (VECTOR(exend)[ex] < rs+rl-1) {
      tmp2 += snprintf(tmp2, sizeof(tmp)/sizeof(char)-(tmp2-tmp)-1, "%iM%iN",
		       (int) (VECTOR(exend)[ex]-rs+1), 
		       (int) (VECTOR(exstart)[ex+1]-VECTOR(exend)[ex]-1));
      if (tmp2 >= tmp + sizeof(tmp)/sizeof(char)) {
	SPLICING_ERROR("CIGAR string too long", SPLICING_EINVAL);
      }
      rl -= (VECTOR(exend)[ex] - rs + 1);
      rs = VECTOR(exstart)[ex+1];
      ex++;
    }
    tmp2 += snprintf(tmp2, sizeof(tmp)/sizeof(char)-(tmp2-tmp)-1, "%iM", rl);
    if (tmp2 >= tmp + sizeof(tmp)/sizeof(char)) {
      SPLICING_ERROR("CIGAR string too long", SPLICING_EINVAL); }
    SPLICING_CHECK(splicing_strvector_append(cigar, tmp));
  }

  splicing_vector_int_destroy(&exidx);
  splicing_vector_int_destroy(&exend);
  splicing_vector_int_destroy(&exstart);
  splicing_vector_int_destroy(&effisolen);
  SPLICING_FINALLY_CLEAN(4);
  
  return 0;
}
Exemplo n.º 5
0
int check_simple() {

  igraph_t g;
  long int nodes=100;
  long int edges=1000;
  igraph_real_t p=3.0/nodes;
  long int runs=10;
  long int r, e, ecount;
  igraph_vector_t eids, pairs, path;

  srand(time(0));

  igraph_vector_init(&pairs, edges*2);
  igraph_vector_init(&path, 0);
  igraph_vector_init(&eids, 0);

  for (r=0; r<runs; r++) {
    igraph_erdos_renyi_game(&g, IGRAPH_ERDOS_RENYI_GNP, nodes, p, 
			    /*directed=*/ 0, /*loops=*/ 0);
    ecount=igraph_ecount(&g);
    for (e=0; e<edges; e++) {
      long int edge=RNG_INTEGER(0, ecount-1);
      VECTOR(pairs)[2*e] = IGRAPH_FROM(&g, edge);
      VECTOR(pairs)[2*e+1] = IGRAPH_TO(&g, edge);
    }
    igraph_get_eids(&g, &eids, &pairs, /*path=*/ 0, 0, /*error=*/ 1);
    for (e=0; e<edges; e++) {
      long int edge=VECTOR(eids)[e];
      long int from1=VECTOR(pairs)[2*e];
      long int to1=VECTOR(pairs)[2*e+1];
      long int from2=IGRAPH_FROM(&g, edge);
      long int to2=IGRAPH_TO(&g, edge);
      long int min1= from1 < to1 ? from1 : to1;
      long int max1= from1 < to1 ? to1 : from1;
      long int min2= from2 < to2 ? from2 : to2;
      long int max2= from2 < to2 ? to2 : from2;
      if (min1 != min2 || max1 != max2) {
	return 11;
      }
    }
    
    igraph_diameter(&g, /*res=*/ 0, /*from=*/ 0, /*to=*/ 0, &path,
		    IGRAPH_UNDIRECTED, /*unconn=*/ 1);
    igraph_get_eids(&g, &eids, /*pairs=*/ 0, &path, 0, /*error=*/ 1);
    for (e=0; e<igraph_vector_size(&path)-1; e++) {
      long int edge=VECTOR(eids)[e];
      long int from1=VECTOR(path)[e];
      long int to1=VECTOR(path)[e+1];
      long int from2=IGRAPH_FROM(&g, edge);
      long int to2=IGRAPH_TO(&g, edge);
      long int min1= from1 < to1 ? from1 : to1;
      long int max1= from1 < to1 ? to1 : from1;
      long int min2= from2 < to2 ? from2 : to2;
      long int max2= from2 < to2 ? to2 : from2;
      if (min1 != min2 || max1 != max2) {
	return 12;
      }
    }

    igraph_destroy(&g);
  }

  igraph_vector_destroy(&path);
  igraph_vector_destroy(&pairs);
  igraph_vector_destroy(&eids);

  return 0;
}