int real_cplx_mult(const igraph_matrix_t *A,
		   const igraph_vector_t *v_real,
		   const igraph_vector_t *v_imag, 
		   igraph_vector_t *res_real,
		   igraph_vector_t *res_imag) {

  int n=igraph_vector_size(v_real);
  int r, c;

  if (igraph_matrix_nrow(A) != n || 
      igraph_matrix_ncol(A) != n || 
      igraph_vector_size(v_imag) != n) {
    printf("Wrong matrix or vector size");
    return 1;
  }

  igraph_vector_resize(res_real, n);
  igraph_vector_resize(res_imag, n);

  for (r=0; r<n; r++) {
    igraph_real_t s_real=0.0;
    igraph_real_t s_imag=0.0;
    for (c=0; c<n; c++) {
      s_real += MATRIX(*A, r, c) * VECTOR(*v_real)[c];
      s_imag += MATRIX(*A, r, c) * VECTOR(*v_imag)[c];
    }
    VECTOR(*res_real)[r]=s_real;
    VECTOR(*res_imag)[r]=s_imag;
  }
  
  return 0;
}
int sc_cplx_cplx_mult(igraph_real_t lambda_real,
		      igraph_real_t lambda_imag,
		      const igraph_vector_t *v_real,
		      const igraph_vector_t *v_imag,
		      igraph_vector_t *res_real,
		      igraph_vector_t *res_imag) {
  
  int r;
  int n=igraph_vector_size(v_real);
  
  if (igraph_vector_size(v_imag) != n) {
    printf("Wrong vector sizes");
    return 1;
  }
  
  igraph_vector_resize(res_real, n);
  igraph_vector_resize(res_imag, n);

  for (r=0; r<n; r++) {
    VECTOR(*res_real)[r] = (lambda_real * VECTOR(*v_real)[r] -
			    lambda_imag * VECTOR(*v_imag)[r]);
    VECTOR(*res_imag)[r] = (lambda_imag * VECTOR(*v_real)[r] + 
			    lambda_real * VECTOR(*v_imag)[r]);
  }

  return 0;
}
/**
 * \ingroup interface
 * \function igraph_add_vertices
 * \brief Adds vertices to a graph. 
 *
 * </para><para>
 * This function invalidates all iterators.
 *
 * \param graph The graph object to extend.
 * \param nv Non-negative integer giving the number of 
 *           vertices to add.
 * \param attr The attributes of the new vertices, only used by 
 *           high level interfaces, you can supply 0 here.
 * \return Error code: 
 *         \c IGRAPH_EINVAL: invalid number of new
 *         vertices. 
 *
 * Time complexity: O(|V|) where
 * |V| is 
 * the number of vertices in the \em new, extended graph.
 */
int igraph_add_vertices(igraph_t *graph, igraph_integer_t nv, void *attr) {
  long int ec=igraph_ecount(graph);
  long int i;

  if (nv < 0) {
    IGRAPH_ERROR("cannot add negative number of vertices", IGRAPH_EINVAL);
  }

  IGRAPH_CHECK(igraph_vector_reserve(&graph->os, graph->n+nv+1));
  IGRAPH_CHECK(igraph_vector_reserve(&graph->is, graph->n+nv+1));
  
  igraph_vector_resize(&graph->os, graph->n+nv+1); /* reserved */
  igraph_vector_resize(&graph->is, graph->n+nv+1); /* reserved */
  for (i=graph->n+1; i<graph->n+nv+1; i++) {
    VECTOR(graph->os)[i]=ec;
    VECTOR(graph->is)[i]=ec;
  }
  
  graph->n += nv;   
  
  if (graph->attr) {
    IGRAPH_CHECK(igraph_i_attribute_add_vertices(graph, nv, attr));
  }

  return 0;
}
Beispiel #4
0
int main() {
  
  igraph_t g;
  igraph_vector_t v1, v2;
  int ret;
  
  /* simple use */
  igraph_vector_init(&v1, 8);
  VECTOR(v1)[0]=0; VECTOR(v1)[1]=1;
  VECTOR(v1)[2]=1; VECTOR(v1)[3]=2;
  VECTOR(v1)[4]=2; VECTOR(v1)[5]=3;
  VECTOR(v1)[6]=2; VECTOR(v1)[7]=2;
  igraph_create(&g, &v1, 0, 0);
  if (igraph_vcount(&g) != 4) {
    return 1;
  }
  igraph_vector_init(&v2, 0);
  igraph_get_edgelist(&g, &v2, 0);
  igraph_vector_sort(&v1);
  igraph_vector_sort(&v2);
  if (!igraph_vector_all_e(&v1, &v2)) {
    return 2;
  }
  igraph_destroy(&g);
  
  /* higher number of vertices */
  igraph_create(&g, &v1, 10, 0);
  if (igraph_vcount(&g) != 10) {
    return 1;
  }
  igraph_get_edgelist(&g, &v2, 0);
  igraph_vector_sort(&v1);
  igraph_vector_sort(&v2);
  if (!igraph_vector_all_e(&v1, &v2)) {
    return 3;
  }
  igraph_destroy(&g);

  /* error: IGRAPH_EINVEVECTOR */
  igraph_set_error_handler(igraph_error_handler_ignore);
  igraph_vector_resize(&v1, 9);
  VECTOR(v1)[8]=0;
  ret=igraph_create(&g, &v1, 0, 0);
  if (ret != IGRAPH_EINVEVECTOR) {
    return 4;
  }
  
  /* error: IGRAPH_EINVVID */
  igraph_vector_resize(&v1, 8);
  VECTOR(v1)[7]=-1;
  ret=igraph_create(&g, &v1, 10, 1);
  if (ret != IGRAPH_EINVVID) {
    return 5;
  }
  igraph_vector_destroy(&v1);
  igraph_vector_destroy(&v2);

  return 0;
}
Beispiel #5
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;
}
Beispiel #6
0
int igraph_vector_complex_realimag(const igraph_vector_complex_t *v, 
				   igraph_vector_t *real, 
				   igraph_vector_t *imag) {
  int i, n=igraph_vector_complex_size(v);
  IGRAPH_CHECK(igraph_vector_resize(real, n));
  IGRAPH_CHECK(igraph_vector_resize(imag, n));
  for (i=0; i<n; i++) {
    igraph_complex_t z=VECTOR(*v)[i];
    VECTOR(*real)[i] = IGRAPH_REAL(z);
    VECTOR(*imag)[i] = IGRAPH_IMAG(z);
  }

  return 0;
}
Beispiel #7
0
int igraph_i_local_scan_1_directed(const igraph_t *graph,
				   igraph_vector_t *res,
				   const igraph_vector_t *weights,
				   igraph_neimode_t mode) {

  int no_of_nodes=igraph_vcount(graph);
  igraph_inclist_t incs;
  int i, node;

  igraph_vector_int_t neis;

  IGRAPH_CHECK(igraph_inclist_init(graph, &incs, mode));
  IGRAPH_FINALLY(igraph_inclist_destroy, &incs);

  igraph_vector_int_init(&neis, no_of_nodes);
  IGRAPH_FINALLY(igraph_vector_int_destroy, &neis);

  igraph_vector_resize(res, no_of_nodes);
  igraph_vector_null(res);

  for (node=0; node < no_of_nodes; node++) {
    igraph_vector_int_t *edges1=igraph_inclist_get(&incs, node);
    int edgeslen1=igraph_vector_int_size(edges1);

    IGRAPH_ALLOW_INTERRUPTION();

    /* Mark neighbors and self*/
    VECTOR(neis)[node] = node+1;
    for (i=0; i<edgeslen1; i++) {
      int e=VECTOR(*edges1)[i];
      int nei=IGRAPH_OTHER(graph, e, node);
      igraph_real_t w= weights ? VECTOR(*weights)[e] : 1;
      VECTOR(neis)[nei] = node+1;
      VECTOR(*res)[node] += w;
    }

    /* Crawl neighbors */
    for (i=0; i<edgeslen1; i++) {
      int e2=VECTOR(*edges1)[i];
      int nei=IGRAPH_OTHER(graph, e2, node);
      igraph_vector_int_t *edges2=igraph_inclist_get(&incs, nei);
      int j, edgeslen2=igraph_vector_int_size(edges2);
      for (j=0; j<edgeslen2; j++) {
	int e2=VECTOR(*edges2)[j];
	int nei2=IGRAPH_OTHER(graph, e2, nei);
	igraph_real_t w2= weights ? VECTOR(*weights)[e2] : 1;
	if (VECTOR(neis)[nei2] == node+1) {
	  VECTOR(*res)[node] += w2;
	}
      }
    }

  } /* node < no_of_nodes */

  igraph_vector_int_destroy(&neis);
  igraph_inclist_destroy(&incs);
  IGRAPH_FINALLY_CLEAN(2);

  return 0;
}
Beispiel #8
0
igraph_vector_t *igraph_lazy_adjlist_get_real(igraph_lazy_adjlist_t *al,
						igraph_integer_t pno) {
  long int no=pno;
  int ret;
  if (al->adjs[no] == 0) {
    al->adjs[no] = igraph_Calloc(1, igraph_vector_t);
    if (al->adjs[no] == 0) {
      igraph_error("Lazy adjlist failed", __FILE__, __LINE__, 
		   IGRAPH_ENOMEM);
    }
    ret=igraph_vector_init(al->adjs[no], 0);
    if (ret != 0) {
      igraph_error("", __FILE__, __LINE__, ret);
    }
    ret=igraph_neighbors(al->graph, al->adjs[no], no, al->mode);
    if (ret != 0) {
      igraph_error("", __FILE__, __LINE__, ret);
    }

    if (al->simplify == IGRAPH_SIMPLIFY) {
      igraph_vector_t *v=al->adjs[no];
      long int i, p=0, n=igraph_vector_size(v);
      for (i=0; i<n; i++) {
	if (VECTOR(*v)[i] != no && 
	    (i==n-1 || VECTOR(*v)[i+1] != VECTOR(*v)[i])) {
	  VECTOR(*v)[p]=VECTOR(*v)[i];
	  p++;
	}
      }
      igraph_vector_resize(v, p);
    }
  }
  
  return al->adjs[no];
}
Beispiel #9
0
int igraph_vector_rank(const igraph_vector_t *v, igraph_vector_t *res,
		       long int nodes) {
  
  igraph_vector_t rad;
  igraph_vector_t ptr;
  long int edges = igraph_vector_size(v);
  long int i, c=0;
  
  IGRAPH_VECTOR_INIT_FINALLY(&rad, nodes);
  IGRAPH_VECTOR_INIT_FINALLY(&ptr, edges);
  IGRAPH_CHECK(igraph_vector_resize(res, edges));
	       
  for (i=0; i<edges; i++) {
    long int elem=VECTOR(*v)[i];
    VECTOR(ptr)[i] = VECTOR(rad)[elem];
    VECTOR(rad)[elem] = i+1;
  }
  
  for (i=0; i<nodes; i++) {
    long int p=VECTOR(rad)[i];
    while (p != 0) {      
      VECTOR(*res)[p-1]=c++;
      p=VECTOR(ptr)[p-1];
    }
  }

  igraph_vector_destroy(&ptr);
  igraph_vector_destroy(&rad);
  IGRAPH_FINALLY_CLEAN(2);
  return 0;
}
int igraph_get_edgelist(const igraph_t *graph, igraph_vector_t *res, igraph_bool_t bycol) {

  igraph_eit_t edgeit;
  long int no_of_edges=igraph_ecount(graph);
  long int vptr=0;
  igraph_integer_t from, to;
  
  IGRAPH_CHECK(igraph_vector_resize(res, no_of_edges*2));
  IGRAPH_CHECK(igraph_eit_create(graph, igraph_ess_all(IGRAPH_EDGEORDER_ID),
				 &edgeit));
  IGRAPH_FINALLY(igraph_eit_destroy, &edgeit);
  
  if (bycol) {
    while (!IGRAPH_EIT_END(edgeit)) {
      igraph_edge(graph, IGRAPH_EIT_GET(edgeit), &from, &to);
      VECTOR(*res)[vptr]=from;
      VECTOR(*res)[vptr+no_of_edges]=to;
      vptr++;
      IGRAPH_EIT_NEXT(edgeit);
    }
  } else {
    while (!IGRAPH_EIT_END(edgeit)) {
      igraph_edge(graph, IGRAPH_EIT_GET(edgeit), &from, &to);
      VECTOR(*res)[vptr++]=from;
      VECTOR(*res)[vptr++]=to;
      IGRAPH_EIT_NEXT(edgeit);
    }
  }
  
  igraph_eit_destroy(&edgeit);
  IGRAPH_FINALLY_CLEAN(1);
  return 0;
}
Beispiel #11
0
int igraph_running_mean(const igraph_vector_t *data, igraph_vector_t *res, 
			igraph_integer_t binwidth) {

  double sum=0;
  long int i;

  /* Check */
  if (igraph_vector_size(data) < binwidth) {
    IGRAPH_ERROR("Vector too short for this binwidth", IGRAPH_EINVAL); 
  }

  /* Memory for result */

  IGRAPH_CHECK(igraph_vector_resize(res, (long int)(igraph_vector_size(data)-binwidth+1)));
  
  /* Initial bin */
  for (i=0; i<binwidth; i++) {
    sum += VECTOR(*data)[i];
  }
  
  VECTOR(*res)[0]=sum/binwidth;
  
  for (i=1; i<igraph_vector_size(data)-binwidth+1; i++) {
    IGRAPH_ALLOW_INTERRUPTION();
    sum -= VECTOR(*data)[i-1];
    sum += VECTOR(*data)[ (long int)(i+binwidth-1)];
    VECTOR(*res)[i] = sum/binwidth;
  }
  
  return 0;
}
Beispiel #12
0
/* removes multiple edges and returns new edge id's for each edge in |E|log|E| */
int igraph_i_multilevel_simplify_multiple(igraph_t *graph, igraph_vector_t *eids) {
  long int ecount = igraph_ecount(graph);
  long int i, l = -1, last_from = -1, last_to = -1;
  igraph_bool_t directed = igraph_is_directed(graph);
  igraph_integer_t from, to;
  igraph_vector_t edges;
  igraph_i_multilevel_link *links;

  /* Make sure there's enough space in eids to store the new edge IDs */
  IGRAPH_CHECK(igraph_vector_resize(eids, ecount));

  links = igraph_Calloc(ecount, igraph_i_multilevel_link);
  if (links == 0) {
    IGRAPH_ERROR("multi-level community structure detection failed", IGRAPH_ENOMEM);
  }
  IGRAPH_FINALLY(free, links);

  for (i = 0; i < ecount; i++) {
    igraph_edge(graph, (igraph_integer_t) i, &from, &to);
    links[i].from = from;
    links[i].to = to;
    links[i].id = i;
  }  

  qsort((void*)links, (size_t) ecount, sizeof(igraph_i_multilevel_link),
      igraph_i_multilevel_link_cmp);

  IGRAPH_VECTOR_INIT_FINALLY(&edges, 0);
  for (i = 0; i < ecount; i++) {
    if (links[i].from == last_from && links[i].to == last_to) {
      VECTOR(*eids)[links[i].id] = l;
      continue;
    }

    last_from = links[i].from;
    last_to = links[i].to;

    igraph_vector_push_back(&edges, last_from);
    igraph_vector_push_back(&edges, last_to);

    l++;

    VECTOR(*eids)[links[i].id] = l;
  }

  free(links);
  IGRAPH_FINALLY_CLEAN(1);

  igraph_destroy(graph);
  IGRAPH_CHECK(igraph_create(graph, &edges, igraph_vcount(graph), directed));

  igraph_vector_destroy(&edges);
  IGRAPH_FINALLY_CLEAN(1);

  return 0;
}
Beispiel #13
0
int igraph_vector_complex_real(const igraph_vector_complex_t *v, 
			       igraph_vector_t *real) {
  int i, n=igraph_vector_complex_size(v);
  IGRAPH_CHECK(igraph_vector_resize(real, n));
  for (i=0; i<n; i++) {
    VECTOR(*real)[i] = IGRAPH_REAL(VECTOR(*v)[i]);
  }

  return 0;
}
Beispiel #14
0
int igraph_vector_complex_imag(const igraph_vector_complex_t *v, 
			       igraph_vector_t *imag) {
  int i, n=igraph_vector_complex_size(v);
  IGRAPH_CHECK(igraph_vector_resize(imag, n));
  for (i=0; i<n; i++) {
    VECTOR(*imag)[i] = IGRAPH_IMAG(VECTOR(*v)[i]);
  }

  return 0;
}
Beispiel #15
0
int igraph_i_cliquer_histogram(const igraph_t *graph, igraph_vector_t *hist,
                        igraph_integer_t min_size, igraph_integer_t max_size)
{
    graph_t *g;
    int i;
    igraph_integer_t vcount = igraph_vcount(graph);

    if (vcount == 0) {
        igraph_vector_clear(hist);
        return IGRAPH_SUCCESS;
    }

    if (min_size <= 0) min_size = 1;
    if (max_size <= 0) max_size = vcount; /* also used for initial hist vector size, do not set to zero */

    if (max_size < min_size)
        IGRAPH_ERROR("max_size must not be smaller than min_size", IGRAPH_EINVAL);

    igraph_to_cliquer(graph, &g);
    IGRAPH_FINALLY(graph_free, g);

    igraph_vector_resize(hist, max_size);
    igraph_vector_null(hist);
    igraph_cliquer_opt.user_data = hist;
    igraph_cliquer_opt.user_function = &count_cliques_callback;

    CLIQUER_INTERRUPTABLE(clique_unweighted_find_all(g, min_size, max_size, /* maximal= */ FALSE, &igraph_cliquer_opt));

    for (i=max_size; i > 0; --i)
        if (VECTOR(*hist)[i-1] > 0)
            break;
    igraph_vector_resize(hist, i);
    igraph_vector_resize_min(hist);

    graph_free(g);
    IGRAPH_FINALLY_CLEAN(1);

    return IGRAPH_SUCCESS;
}
Beispiel #16
0
int main() {
    igraph_t graph;
    igraph_vector_t walk, weights;
    igraph_integer_t ec, i;

    igraph_rng_seed(igraph_rng_default(), 137);

    igraph_vector_init(&walk, 0);
    igraph_vector_init(&weights, 0);

    /* This directed graph has loop edges.
       It also has multi-edges when considered as undirected. */
    igraph_de_bruijn(&graph, 3, 2);
    ec = igraph_ecount(&graph);

    /* unweighted, directed */
    igraph_random_edge_walk(&graph, NULL, &walk, 0, IGRAPH_OUT, 1000, IGRAPH_RANDOM_WALK_STUCK_RETURN);
    assert(igraph_vector_size(&walk) == 1000);

    /* unweighted, undirected */
    igraph_random_edge_walk(&graph, NULL, &walk, 0, IGRAPH_ALL, 1000, IGRAPH_RANDOM_WALK_STUCK_RETURN);
    assert(igraph_vector_size(&walk) == 1000);

    igraph_vector_resize(&weights, ec);
    for (i=0; i < ec; ++i)
        VECTOR(weights)[i] = igraph_rng_get_unif01(igraph_rng_default());

    /* weighted, directed */
    igraph_random_edge_walk(&graph, &weights, &walk, 0, IGRAPH_OUT, 1000, IGRAPH_RANDOM_WALK_STUCK_RETURN);
    assert(igraph_vector_size(&walk) == 1000);

    /* weighted, undirecetd */
    igraph_random_edge_walk(&graph, &weights, &walk, 0, IGRAPH_ALL, 1000, IGRAPH_RANDOM_WALK_STUCK_RETURN);
    assert(igraph_vector_size(&walk) == 1000);

    igraph_destroy(&graph);

    /* 1-vertex graph, should get stuck */
    igraph_empty(&graph, 1, /* directed = */ 0);
    igraph_random_edge_walk(&graph, NULL, &walk, 0, IGRAPH_OUT, 1000, IGRAPH_RANDOM_WALK_STUCK_RETURN);
    assert(igraph_vector_size(&walk) == 0);
    igraph_destroy(&graph);

    igraph_vector_destroy(&weights);
    igraph_vector_destroy(&walk);

    return 0;
}
int igraph_adjacent(const igraph_t *graph, igraph_vector_t *eids, 
		    igraph_integer_t pnode, igraph_neimode_t mode) {
  
  long int length=0, idx=0;   
  long int no_of_edges;
  long int i, j;

  long int node=pnode;

  if (node<0 || node>igraph_vcount(graph)-1) {
    IGRAPH_ERROR("cannot get neighbors", IGRAPH_EINVVID);
  }
  if (mode != IGRAPH_OUT && mode != IGRAPH_IN && 
      mode != IGRAPH_ALL) {
    IGRAPH_ERROR("cannot get neighbors", IGRAPH_EINVMODE);
  }

  no_of_edges=igraph_vector_size(&graph->from);
  if (! graph->directed) {
    mode=IGRAPH_ALL;
  }

  /* Calculate needed space first & allocate it*/

  if (mode & IGRAPH_OUT) {
    length += (VECTOR(graph->os)[node+1] - VECTOR(graph->os)[node]);
  }
  if (mode & IGRAPH_IN) {
    length += (VECTOR(graph->is)[node+1] - VECTOR(graph->is)[node]);
  }
  
  IGRAPH_CHECK(igraph_vector_resize(eids, length));
  
  if (mode & IGRAPH_OUT) {
    j=VECTOR(graph->os)[node+1];
    for (i=VECTOR(graph->os)[node]; i<j; i++) {
      VECTOR(*eids)[idx++] = VECTOR(graph->oi)[i];
    }
  }
  if (mode & IGRAPH_IN) {
    j=VECTOR(graph->is)[node+1];
    for (i=VECTOR(graph->is)[node]; i<j; i++) {
      VECTOR(*eids)[idx++] = VECTOR(graph->ii)[i];
    }
  }

  return 0;
}
Beispiel #18
0
int ggen_transform_delete(igraph_t *g, enum ggen_transform_t t)
{
	igraph_vector_t vertices;
	igraph_vector_t degrees;
	unsigned int i,vcount,ssize;
	int err;

	if(g == NULL)
		return 1;

	vcount = igraph_vcount(g);

	err = igraph_vector_init(&vertices,vcount);
	if(err) return 1;

	err = igraph_vector_init(&degrees,vcount);
	if(err) goto error_id;

	/* find degree of each vertex, igraph_in if we need to identify sources. */
	err = igraph_degree(g,&degrees,igraph_vss_all(),
		(t==GGEN_TRANSFORM_SOURCE)?IGRAPH_IN:IGRAPH_OUT,0);
	if(err) goto error;

	/* only sources or sinks are of interest */
	ssize = 0;
	for(i = 0; i < vcount; i++)
		if(VECTOR(degrees)[i] == 0)
			VECTOR(vertices)[ssize++] = i;

	/* delete all identified vertices */
	if(ssize > 0)
	{
		/* we should resize the array to avoid strange behaviors */
		err = igraph_vector_resize(&vertices,ssize);
		if(err) goto error;

		err = igraph_delete_vertices(g,igraph_vss_vector(&vertices));
		if(err) goto error;
	}
error:
	igraph_vector_destroy(&degrees);
error_id:
	igraph_vector_destroy(&vertices);
	return err;
}
int igraph_i_create_start(igraph_vector_t *res, igraph_vector_t *el, igraph_vector_t *index, 
			  igraph_integer_t nodes) {
  
# define EDGE(i) (VECTOR(*el)[ (long int) VECTOR(*index)[(i)] ])
  
  long int no_of_nodes;
  long int no_of_edges;
  long int i, j, idx;
  
  no_of_nodes=nodes;
  no_of_edges=igraph_vector_size(el);
  
  /* result */
  
  IGRAPH_CHECK(igraph_vector_resize(res, nodes+1));
  
  /* create the index */

  if (igraph_vector_size(el)==0) {
    /* empty graph */
    igraph_vector_null(res);
  } else {
    idx=-1;
    for (i=0; i<=EDGE(0); i++) {
      idx++; VECTOR(*res)[idx]=0;
    }
    for (i=1; i<no_of_edges; i++) {
      long int n=EDGE(i) - EDGE((long int)VECTOR(*res)[idx]);
      for (j=0; j<n; j++) {
	idx++; VECTOR(*res)[idx]=i;
      }
    }
    j=EDGE((long int)VECTOR(*res)[idx]);
    for (i=0; i<no_of_nodes-j; i++) {
      idx++; VECTOR(*res)[idx]=no_of_edges;
    }
  }

  /* clean */

# undef EDGE
  return 0;
}
int igraph_edges(const igraph_t *graph, igraph_es_t eids,
		 igraph_vector_t *edges) {
  
  igraph_eit_t eit;
  long int n, ptr=0;

  IGRAPH_CHECK(igraph_eit_create(graph, eids, &eit));
  IGRAPH_FINALLY(igraph_eit_destroy, &eit);
  n=IGRAPH_EIT_SIZE(eit);
  IGRAPH_CHECK(igraph_vector_resize(edges, n*2));
  for (; !IGRAPH_EIT_END(eit); IGRAPH_EIT_NEXT(eit)) {
    long int e=IGRAPH_EIT_GET(eit);
    VECTOR(*edges)[ptr++]=IGRAPH_FROM(graph, e);
    VECTOR(*edges)[ptr++]=IGRAPH_TO(graph, e);
  }
  
  igraph_eit_destroy(&eit);
  IGRAPH_FINALLY_CLEAN(1);
  return 0;
}
Beispiel #21
0
int igraph_adjlist_remove_duplicate(const igraph_t *graph,
				    igraph_adjlist_t *al) {
  long int i;
  long int n=al->length;
  for (i=0; i<n; i++) {
    igraph_vector_t *v=&al->adjs[i];
    long int j, p=1, l=igraph_vector_size(v);
    for (j=1; j<l; j++) {
      long int e=VECTOR(*v)[j];
      /* Non-loop edges, and one end of loop edges are fine. */
      /* We use here, that the vector is sorted and we also keep it sorted */
      if (e != i || VECTOR(*v)[j-1] != e) {
	VECTOR(*v)[p++] = e;
      }
    }
    igraph_vector_resize(v, p);
  }
  
  return 0;
}
Beispiel #22
0
int igraph_vector_order1(const igraph_vector_t* v,
			 igraph_vector_t* res, igraph_real_t nodes) {
  long int edges=igraph_vector_size(v);
  igraph_vector_t ptr;
  igraph_vector_t rad;
  long int i, j;

  assert(v!=NULL);
  assert(v->stor_begin != NULL);

  IGRAPH_VECTOR_INIT_FINALLY(&ptr, nodes+1);
  IGRAPH_VECTOR_INIT_FINALLY(&rad, edges);
  IGRAPH_CHECK(igraph_vector_resize(res, edges));
  
  for (i=0; i<edges; i++) {
    long int radix=v->stor_begin[i];
    if (VECTOR(ptr)[radix]!=0) {
      VECTOR(rad)[i]=VECTOR(ptr)[radix];
    }
    VECTOR(ptr)[radix]=i+1;
  }
  
  j=0;
  for (i=0; i<nodes+1; i++) {
    if (VECTOR(ptr)[i] != 0) {
      long int next=VECTOR(ptr)[i]-1;
      res->stor_begin[j++]=next;
      while (VECTOR(rad)[next] != 0) {
	next=VECTOR(rad)[next]-1;
	res->stor_begin[j++]=next;
      }
    }
  }
  
  igraph_vector_destroy(&ptr);
  igraph_vector_destroy(&rad);
  IGRAPH_FINALLY_CLEAN(2);
  
  return 0;
}
Beispiel #23
0
int igraph_local_scan_neighborhood_ecount(const igraph_t *graph,
			  igraph_vector_t *res,
			  const igraph_vector_t *weights,
			  const igraph_vector_ptr_t *neighborhoods) {

  int node, no_of_nodes=igraph_vcount(graph);
  igraph_inclist_t incs;
  igraph_vector_int_t marked;
  igraph_bool_t directed=igraph_is_directed(graph);

  if (weights && igraph_vector_size(weights) != igraph_ecount(graph)) {
    IGRAPH_ERROR("Invalid weight vector length in local scan", IGRAPH_EINVAL);
  }
  if (igraph_vector_ptr_size(neighborhoods) != no_of_nodes) {
    IGRAPH_ERROR("Invalid neighborhood list length in local scan",
		 IGRAPH_EINVAL);
  }

  IGRAPH_CHECK(igraph_vector_int_init(&marked, no_of_nodes));
  IGRAPH_FINALLY(igraph_vector_int_destroy, &marked);
  IGRAPH_CHECK(igraph_inclist_init(graph, &incs, IGRAPH_OUT));
  IGRAPH_FINALLY(igraph_inclist_destroy, &incs);

  IGRAPH_CHECK(igraph_vector_resize(res, no_of_nodes));
  igraph_vector_null(res);

  for (node=0; node < no_of_nodes; node++) {
    igraph_vector_int_t *nei=VECTOR(*neighborhoods)[node];
    int i, neilen=igraph_vector_int_size(nei);
    VECTOR(marked)[node] = node + 1;
    for (i=0; i<neilen; i++) {
      int vertex=VECTOR(*nei)[i];
      if (vertex < 0 || vertex >= no_of_nodes) {
	IGRAPH_ERROR("Invalid vertex id in neighborhood list in local scan",
		     IGRAPH_EINVAL);
      }
      VECTOR(marked)[vertex] = node + 1;
    }

    for (i=0; i<neilen; i++) {
      int vertex=VECTOR(*nei)[i];
      igraph_vector_int_t *edges=igraph_inclist_get(&incs, vertex);
      int j, edgeslen=igraph_vector_int_size(edges);
      for (j=0; j<edgeslen; j++) {
	int edge=VECTOR(*edges)[j];
	int nei2=IGRAPH_OTHER(graph, edge, vertex);
	if (VECTOR(marked)[nei2] == node+1) {
	  igraph_real_t w = weights ? VECTOR(*weights)[edge] : 1;
	  VECTOR(*res)[node] += w;
	}
      }
    }
    if (!directed) { VECTOR(*res)[node] /= 2.0; }
  }

  igraph_inclist_destroy(&incs);
  igraph_vector_int_destroy(&marked);
  IGRAPH_FINALLY_CLEAN(2);

  return 0;
}
Beispiel #24
0
int igraph_local_scan_k_ecount(const igraph_t *graph, int k,
			       igraph_vector_t *res,
			       const igraph_vector_t *weights,
			       igraph_neimode_t mode) {

  int no_of_nodes=igraph_vcount(graph);
  int node;
  igraph_dqueue_int_t Q;
  igraph_vector_int_t marked;
  igraph_inclist_t incs;

  if (k < 0) {
    IGRAPH_ERROR("k must be non-negative in k-scan", IGRAPH_EINVAL);
  }
  if (weights && igraph_vector_size(weights) != igraph_ecount(graph)) {
    IGRAPH_ERROR("Invalid weight vector length in k-scan", IGRAPH_EINVAL);
  }

  if (k==0) { return igraph_local_scan_0(graph, res, weights, mode); }
  if (k==1) { return igraph_local_scan_1_ecount(graph, res, weights, mode); }

  /* We do a BFS form each node, and simply count the number
     of edges on the way */

  IGRAPH_CHECK(igraph_dqueue_int_init(&Q, 100));
  IGRAPH_FINALLY(igraph_dqueue_int_destroy, &Q);
  IGRAPH_CHECK(igraph_vector_int_init(&marked, no_of_nodes));
  IGRAPH_FINALLY(igraph_vector_int_destroy, &marked);
  IGRAPH_CHECK(igraph_inclist_init(graph, &incs, mode));
  IGRAPH_FINALLY(igraph_inclist_destroy, &incs);

  IGRAPH_CHECK(igraph_vector_resize(res, no_of_nodes));
  igraph_vector_null(res);

  for (node=0 ; node < no_of_nodes ; node++) {
    igraph_dqueue_int_push(&Q, node);
    igraph_dqueue_int_push(&Q, 0);
    VECTOR(marked)[node] = node+1;
    while (!igraph_dqueue_int_empty(&Q)) {
      int act=igraph_dqueue_int_pop(&Q);
      int dist=igraph_dqueue_int_pop(&Q) + 1;
      igraph_vector_int_t *edges=igraph_inclist_get(&incs, act);
      int i, edgeslen=igraph_vector_int_size(edges);
      for (i=0; i<edgeslen; i++) {
	int edge=VECTOR(*edges)[i];
	int nei=IGRAPH_OTHER(graph, edge, act);
	if (dist <= k || VECTOR(marked)[nei] == node+1) {
	  igraph_real_t w=weights ? VECTOR(*weights)[edge] : 1;
	  VECTOR(*res)[node] += w;
	}
	if (dist <= k && VECTOR(marked)[nei] != node+1) {
	  igraph_dqueue_int_push(&Q, nei);
	  igraph_dqueue_int_push(&Q, dist);
	  VECTOR(marked)[nei] = node+1;
	}
      }
    }

    if (mode == IGRAPH_ALL || ! igraph_is_directed(graph)) {
      VECTOR(*res)[node] /= 2.0;
    }

  } /* node < no_of_nodes */

  igraph_inclist_destroy(&incs);
  igraph_vector_int_destroy(&marked);
  igraph_dqueue_int_destroy(&Q);
  IGRAPH_FINALLY_CLEAN(3);

  return 0;
}
Beispiel #25
0
int igraph_local_scan_k_ecount_them(const igraph_t *us, const igraph_t *them,
				    int k, igraph_vector_t *res,
				    const igraph_vector_t *weights_them,
				    igraph_neimode_t mode) {

  int no_of_nodes=igraph_vcount(us);
  int node;
  igraph_dqueue_int_t Q;
  igraph_vector_int_t marked;
  igraph_stack_int_t ST;
  igraph_inclist_t incs_us, incs_them;

  if (igraph_vcount(them) != no_of_nodes) {
    IGRAPH_ERROR("Number of vertices must match in scan-k", IGRAPH_EINVAL);
  }
  if (igraph_is_directed(us) != igraph_is_directed(them)) {
    IGRAPH_ERROR("Directedness must match in scan-k", IGRAPH_EINVAL);
  }
  if (k < 0) {
    IGRAPH_ERROR("k must be non-negative in k-scan", IGRAPH_EINVAL);
  }
  if (weights_them &&
      igraph_vector_size(weights_them) != igraph_ecount(them)) {
    IGRAPH_ERROR("Invalid weight vector length in k-scan (them)",
		 IGRAPH_EINVAL);
  }

  if (k==0) {
    return igraph_local_scan_0_them(us, them, res, weights_them, mode);
  }
  if (k==1) {
    return igraph_local_scan_1_ecount_them(us, them, res, weights_them, mode);
  }

  /* We mark the nodes in US in a BFS. Then we check the outgoing edges
     of all marked nodes in THEM. */

  IGRAPH_CHECK(igraph_dqueue_int_init(&Q, 100));
  IGRAPH_FINALLY(igraph_dqueue_int_destroy, &Q);
  IGRAPH_CHECK(igraph_vector_int_init(&marked, no_of_nodes));
  IGRAPH_FINALLY(igraph_vector_int_destroy, &marked);
  IGRAPH_CHECK(igraph_inclist_init(us, &incs_us, mode));
  IGRAPH_FINALLY(igraph_inclist_destroy, &incs_us);
  IGRAPH_CHECK(igraph_inclist_init(them, &incs_them, mode));
  IGRAPH_FINALLY(igraph_inclist_destroy, &incs_them);
  IGRAPH_CHECK(igraph_stack_int_init(&ST, 100));
  IGRAPH_FINALLY(igraph_stack_int_destroy, &ST);

  IGRAPH_CHECK(igraph_vector_resize(res, no_of_nodes));
  igraph_vector_null(res);

  for (node=0; node < no_of_nodes; node++) {

    /* BFS to mark the nodes in US */
    IGRAPH_CHECK(igraph_dqueue_int_push(&Q, node));
    IGRAPH_CHECK(igraph_dqueue_int_push(&Q, 0));
    IGRAPH_CHECK(igraph_stack_int_push(&ST, node));
    VECTOR(marked)[node] = node+1;
    while (!igraph_dqueue_int_empty(&Q)) {
      int act=igraph_dqueue_int_pop(&Q);
      int dist=igraph_dqueue_int_pop(&Q) + 1;
      igraph_vector_int_t *edges=igraph_inclist_get(&incs_us, act);
      int i, edgeslen=igraph_vector_int_size(edges);
      for (i=0; i<edgeslen; i++) {
	int edge=VECTOR(*edges)[i];
	int nei=IGRAPH_OTHER(us, edge, act);
	if (dist <= k && VECTOR(marked)[nei] != node+1) {
	  igraph_dqueue_int_push(&Q, nei);
	  igraph_dqueue_int_push(&Q, dist);
	  VECTOR(marked)[nei] = node+1;
	  igraph_stack_int_push(&ST, nei);
	}
      }
    }

    /* Now check the edges of all nodes in THEM */
    while (!igraph_stack_int_empty(&ST)) {
      int act=igraph_stack_int_pop(&ST);
      igraph_vector_int_t *edges=igraph_inclist_get(&incs_them, act);
      int i, edgeslen=igraph_vector_int_size(edges);
      for (i=0; i<edgeslen; i++) {
	int edge=VECTOR(*edges)[i];
	int nei=IGRAPH_OTHER(them, edge, act);
	if (VECTOR(marked)[nei] == node+1) {
	  igraph_real_t w=weights_them ? VECTOR(*weights_them)[edge] : 1;
	  VECTOR(*res)[node] += w;
	}
      }
    }

    if (mode == IGRAPH_ALL || ! igraph_is_directed(us)) {
      VECTOR(*res)[node] /= 2;
    }

  } /* node < no_of_nodes */

  igraph_stack_int_destroy(&ST);
  igraph_inclist_destroy(&incs_them);
  igraph_inclist_destroy(&incs_us);
  igraph_vector_int_destroy(&marked);
  igraph_dqueue_int_destroy(&Q);
  IGRAPH_FINALLY_CLEAN(5);

  return 0;
}
Beispiel #26
0
int igraph_local_scan_1_ecount_them(const igraph_t *us, const igraph_t *them,
				    igraph_vector_t *res,
				    const igraph_vector_t *weights_them,
				    igraph_neimode_t mode) {

  int no_of_nodes=igraph_vcount(us);
  igraph_adjlist_t adj_us;
  igraph_inclist_t incs_them;
  igraph_vector_int_t neis;
  int node;

  if (igraph_vcount(them) != no_of_nodes) {
    IGRAPH_ERROR("Number of vertices must match in scan-1", IGRAPH_EINVAL);
  }
  if (igraph_is_directed(us) != igraph_is_directed(them)) {
    IGRAPH_ERROR("Directedness must match in scan-1", IGRAPH_EINVAL);
  }
  if (weights_them &&
      igraph_vector_size(weights_them) != igraph_ecount(them)) {
    IGRAPH_ERROR("Invalid weight vector length in scan-1 (them)",
		 IGRAPH_EINVAL);
  }

  igraph_adjlist_init(us, &adj_us, mode);
  IGRAPH_FINALLY(igraph_adjlist_destroy, &adj_us);
  igraph_adjlist_simplify(&adj_us);
  igraph_inclist_init(them, &incs_them, mode);
  IGRAPH_FINALLY(igraph_inclist_destroy, &incs_them);

  igraph_vector_int_init(&neis, no_of_nodes);
  IGRAPH_FINALLY(igraph_vector_int_destroy, &neis);

  igraph_vector_resize(res, no_of_nodes);
  igraph_vector_null(res);

  for (node=0; node < no_of_nodes; node++) {
    igraph_vector_int_t *neis_us=igraph_adjlist_get(&adj_us, node);
    igraph_vector_int_t *edges1_them=igraph_inclist_get(&incs_them, node);
    int len1_us=igraph_vector_int_size(neis_us);
    int len1_them=igraph_vector_int_size(edges1_them);
    int i;

    IGRAPH_ALLOW_INTERRUPTION();

    /* Mark neighbors and self in us */
    VECTOR(neis)[node] = node+1;
    for (i = 0; i < len1_us; i++) {
      int nei=VECTOR(*neis_us)[i];
      VECTOR(neis)[nei] = node+1;
    }

    /* Crawl neighbors in them, first ego */
    for (i = 0; i < len1_them; i++) {
      int e=VECTOR(*edges1_them)[i];
      int nei=IGRAPH_OTHER(them, e, node);
      if (VECTOR(neis)[nei] == node+1) {
	igraph_real_t w=weights_them ? VECTOR(*weights_them)[e] : 1;
	VECTOR(*res)[node] += w;
      }
    }
    /* Then the rest */
    for (i = 0; i < len1_us; i++) {
      int nei=VECTOR(*neis_us)[i];
      igraph_vector_int_t *edges2_them=igraph_inclist_get(&incs_them, nei);
      int j, len2_them=igraph_vector_int_size(edges2_them);
      for (j = 0; j < len2_them; j++) {
	int e2=VECTOR(*edges2_them)[j];
	int nei2=IGRAPH_OTHER(them, e2, nei);
	if (VECTOR(neis)[nei2] == node+1) {
	  igraph_real_t w=weights_them ? VECTOR(*weights_them)[e2] : 1;
	  VECTOR(*res)[node] += w;
	}
      }
    }

    /* For undirected, it was double counted */
    if (mode == IGRAPH_ALL || ! igraph_is_directed(us)) {
      VECTOR(*res)[node] /= 2.0;
    }

  } /* node < no_of_nodes */

  igraph_vector_int_destroy(&neis);
  igraph_inclist_destroy(&incs_them);
  igraph_adjlist_destroy(&adj_us);
  IGRAPH_FINALLY_CLEAN(3);

  return 0;
}
Beispiel #27
0
int igraph_i_local_scan_1_directed_all(const igraph_t *graph,
				       igraph_vector_t *res,
				       const igraph_vector_t *weights) {

  int no_of_nodes=igraph_vcount(graph);
  igraph_inclist_t incs;
  int i, node;

  igraph_vector_int_t neis;

  IGRAPH_CHECK(igraph_inclist_init(graph, &incs, IGRAPH_ALL));
  IGRAPH_FINALLY(igraph_inclist_destroy, &incs);

  igraph_vector_int_init(&neis, no_of_nodes);
  IGRAPH_FINALLY(igraph_vector_int_destroy, &neis);

  igraph_vector_resize(res, no_of_nodes);
  igraph_vector_null(res);

  for (node=0; node < no_of_nodes; node++) {
    igraph_vector_int_t *edges1=igraph_inclist_get(&incs, node);
    int edgeslen1=igraph_vector_int_size(edges1);

    IGRAPH_ALLOW_INTERRUPTION();

    /* Mark neighbors. We also count the edges that are incident to ego.
       Note that this time we do not mark ego, because we don't want to
       double count its incident edges later, when we are going over the
       incident edges of ego's neighbors. */
    for (i=0; i<edgeslen1; i++) {
      int e=VECTOR(*edges1)[i];
      int nei=IGRAPH_OTHER(graph, e, node);
      igraph_real_t w= weights ? VECTOR(*weights)[e] : 1;
      VECTOR(neis)[nei] = node+1;
      VECTOR(*res)[node] += w;
    }

    /* Crawl neighbors. We make sure that each neighbor of 'node' is
       only crawed once. We count all qualifying edges of ego, and
       then unmark ego to avoid double counting. */
    for (i=0; i<edgeslen1; i++) {
      int e2=VECTOR(*edges1)[i];
      int nei=IGRAPH_OTHER(graph, e2, node);
      igraph_vector_int_t *edges2;
      int j, edgeslen2;
      if (VECTOR(neis)[nei] != node+1) { continue; }
      edges2=igraph_inclist_get(&incs, nei);
      edgeslen2=igraph_vector_int_size(edges2);
      for (j=0; j<edgeslen2; j++) {
	int e2=VECTOR(*edges2)[j];
	int nei2=IGRAPH_OTHER(graph, e2, nei);
	igraph_real_t w2= weights ? VECTOR(*weights)[e2] : 1;
	if (VECTOR(neis)[nei2] == node+1) {
	  VECTOR(*res)[node] += w2;
	}
      }
      VECTOR(neis)[nei] = 0;
    }

  } /* node < no_of_nodes */

  igraph_vector_int_destroy(&neis);
  igraph_inclist_destroy(&incs);
  IGRAPH_FINALLY_CLEAN(2);

  return 0;
}
Beispiel #28
0
int igraph_lapack_dgeev(const igraph_matrix_t *A, 
			igraph_vector_t *valuesreal,
			igraph_vector_t *valuesimag, 
			igraph_matrix_t *vectorsleft,
			igraph_matrix_t *vectorsright, 
			int *info) {

  char jobvl= vectorsleft  ? 'V' : 'N';
  char jobvr= vectorsright ? 'V' : 'N';
  int n=(int) igraph_matrix_nrow(A);
  int lda=n, ldvl=n, ldvr=n, lwork=-1;
  igraph_vector_t work;
  igraph_vector_t *myreal=valuesreal, *myimag=valuesimag, vreal, vimag;
  igraph_matrix_t Acopy;
  int error=*info;

  if (igraph_matrix_ncol(A) != n) { 
    IGRAPH_ERROR("Cannot calculate eigenvalues (dgeev)", IGRAPH_NONSQUARE);
  }
  
  IGRAPH_CHECK(igraph_matrix_copy(&Acopy, A));
  IGRAPH_FINALLY(igraph_matrix_destroy, &Acopy);
  
  IGRAPH_VECTOR_INIT_FINALLY(&work, 1);
  
  if (!valuesreal) {
    IGRAPH_VECTOR_INIT_FINALLY(&vreal, n);
    myreal=&vreal;
  } else {
    IGRAPH_CHECK(igraph_vector_resize(myreal, n));
  }
  if (!valuesimag) {
    IGRAPH_VECTOR_INIT_FINALLY(&vimag, n);
    myimag=&vimag;
  } else {
    IGRAPH_CHECK(igraph_vector_resize(myimag, n));
  }
  if (vectorsleft) { 
    IGRAPH_CHECK(igraph_matrix_resize(vectorsleft, n, n));
  }
  if (vectorsright) {
    IGRAPH_CHECK(igraph_matrix_resize(vectorsright, n, n));
  }

  igraphdgeev_(&jobvl, &jobvr, &n, &MATRIX(Acopy,0,0), &lda, 
	       VECTOR(*myreal), VECTOR(*myimag), 
	       vectorsleft  ? &MATRIX(*vectorsleft ,0,0) : 0, &ldvl,
	       vectorsright ? &MATRIX(*vectorsright,0,0) : 0, &ldvr,
	       VECTOR(work), &lwork, info);

  lwork=(int) VECTOR(work)[0];
  IGRAPH_CHECK(igraph_vector_resize(&work, lwork));
  
  igraphdgeev_(&jobvl, &jobvr, &n, &MATRIX(Acopy,0,0), &lda, 
	       VECTOR(*myreal), VECTOR(*myimag), 
	       vectorsleft  ? &MATRIX(*vectorsleft ,0,0) : 0, &ldvl,
	       vectorsright ? &MATRIX(*vectorsright,0,0) : 0, &ldvr,
	       VECTOR(work), &lwork, info);  

  if (*info < 0) {
      IGRAPH_ERROR("Cannot calculate eigenvalues (dgeev)", IGRAPH_ELAPACK);
  } else if (*info > 0) {    
    if (error) {
      IGRAPH_ERROR("Cannot calculate eigenvalues (dgeev)", IGRAPH_ELAPACK);
    } else {
      IGRAPH_WARNING("Cannot calculate eigenvalues (dgeev)");
    }
  }

  if (!valuesimag) {
    igraph_vector_destroy(&vimag);
    IGRAPH_FINALLY_CLEAN(1);
  }
  if (!valuesreal) { 
    igraph_vector_destroy(&vreal);
    IGRAPH_FINALLY_CLEAN(1);
  }

  igraph_vector_destroy(&work);
  igraph_matrix_destroy(&Acopy);
  IGRAPH_FINALLY_CLEAN(2);
  
  return 0;
}
int main() {

    igraph_t g;
    igraph_vector_t v, v2;
    int i, ret;

    igraph_barabasi_game(&g, 10, 2, 0, 0, 1);
    if (igraph_ecount(&g) != 18) {
        return 1;
    }
    if (igraph_vcount(&g) != 10) {
        return 2;
    }
    if (!igraph_is_directed(&g)) {
        return 3;
    }

    igraph_vector_init(&v, 0);
    igraph_get_edgelist(&g, &v, 0);
    for (i=0; i<igraph_ecount(&g); i++) {
        if (VECTOR(v)[2*i] <= VECTOR(v)[2*i+1]) {
            return 4;
        }
    }
    igraph_destroy(&g);

    /* out degree sequence */
    igraph_vector_resize(&v, 10);
    VECTOR(v)[0]=0;
    VECTOR(v)[1]=1;
    VECTOR(v)[2]=3;
    VECTOR(v)[3]=3;
    VECTOR(v)[4]=4;
    VECTOR(v)[5]=5;
    VECTOR(v)[6]=6;
    VECTOR(v)[7]=7;
    VECTOR(v)[8]=8;
    VECTOR(v)[9]=9;

    igraph_barabasi_game(&g, 10, 0, &v, 0, 1);
    if (igraph_ecount(&g) != igraph_vector_sum(&v)) {
        return 5;
    }
    igraph_vector_init(&v2, 0);
    igraph_degree(&g, &v2, igraph_vss_all(), IGRAPH_OUT, 1);
    for (i=0; i<igraph_vcount(&g); i++) {
        if (VECTOR(v)[i] != VECTOR(v2)[i]) {
            return 6;
        }
    }
    igraph_vector_destroy(&v);
    igraph_vector_destroy(&v2);
    igraph_destroy(&g);

    /* outpref, we cannot really test this quantitatively,
       would need to set random seed */
    igraph_barabasi_game(&g, 10, 2, 0, 1, 1);
    igraph_vector_init(&v, 0);
    igraph_get_edgelist(&g, &v, 0);
    for (i=0; i<igraph_ecount(&g); i++) {
        if (VECTOR(v)[2*i] <= VECTOR(v)[2*i+1]) {
            return 7;
        }
    }
    if (!igraph_is_directed(&g)) {
        return 8;
    }
    igraph_vector_destroy(&v);
    igraph_destroy(&g);

    /* Error tests */
    igraph_set_error_handler(igraph_error_handler_ignore);
    ret=igraph_barabasi_game(&g, -10, 1, 0, 0, 0);
    if (ret != IGRAPH_EINVAL) {
        return 9;
    }
    ret=igraph_barabasi_game(&g, 10, -2, 0, 0, 0);
    if (ret != IGRAPH_EINVAL) {
        return 10;
    }
    igraph_vector_init(&v, 9);
    ret=igraph_barabasi_game(&g, 10, 0, &v, 0, 0);
    if (ret != IGRAPH_EINVAL) {
        return 11;
    }
    igraph_vector_destroy(&v);

    return 0;
}
Beispiel #30
0
int igraph_lapack_dgeevx(igraph_lapack_dgeevx_balance_t balance,
			 const igraph_matrix_t *A,
			 igraph_vector_t *valuesreal,
			 igraph_vector_t *valuesimag,
			 igraph_matrix_t *vectorsleft,
			 igraph_matrix_t *vectorsright,
			 int *ilo, int *ihi, igraph_vector_t *scale,
			 igraph_real_t *abnrm,
			 igraph_vector_t *rconde,
			 igraph_vector_t *rcondv,
			 int *info) {

  char balanc;
  char jobvl= vectorsleft  ? 'V' : 'N';
  char jobvr= vectorsright ? 'V' : 'N';
  char sense;
  int n=(int) igraph_matrix_nrow(A);
  int lda=n, ldvl=n, ldvr=n, lwork=-1;
  igraph_vector_t work;
  igraph_vector_int_t iwork;
  igraph_matrix_t Acopy;
  int error=*info;
  igraph_vector_t *myreal=valuesreal, *myimag=valuesimag, vreal, vimag;
  igraph_vector_t *myscale=scale, vscale;

  if (igraph_matrix_ncol(A) != n) { 
    IGRAPH_ERROR("Cannot calculate eigenvalues (dgeevx)", IGRAPH_NONSQUARE);
  }
  
  switch (balance) {
  case IGRAPH_LAPACK_DGEEVX_BALANCE_NONE:
    balanc='N';
    break;
  case IGRAPH_LAPACK_DGEEVX_BALANCE_PERM:
    balanc='P';
    break;
  case IGRAPH_LAPACK_DGEEVX_BALANCE_SCALE:
    balanc='S';
    break;
  case IGRAPH_LAPACK_DGEEVX_BALANCE_BOTH:
    balanc='B';
    break;
  default:
    IGRAPH_ERROR("Invalid 'balance' argument", IGRAPH_EINVAL);
    break;
  }

  if (!rconde && !rcondv) {
    sense='N';
  } else if (rconde && !rcondv) {
    sense='E';
  } else if (!rconde && rcondv) {
    sense='V';
  } else {
    sense='B';
  }
  
  IGRAPH_CHECK(igraph_matrix_copy(&Acopy, A));
  IGRAPH_FINALLY(igraph_matrix_destroy, &Acopy);

  IGRAPH_VECTOR_INIT_FINALLY(&work, 1);
  IGRAPH_CHECK(igraph_vector_int_init(&iwork, n));
  IGRAPH_FINALLY(igraph_vector_int_destroy, &iwork);
  
  if (!valuesreal) {
    IGRAPH_VECTOR_INIT_FINALLY(&vreal, n);
    myreal=&vreal;
  } else {
    IGRAPH_CHECK(igraph_vector_resize(myreal, n));
  }
  if (!valuesimag) {
    IGRAPH_VECTOR_INIT_FINALLY(&vimag, n);
    myimag=&vimag;
  } else {
    IGRAPH_CHECK(igraph_vector_resize(myimag, n));
  }
  if (!scale) {
    IGRAPH_VECTOR_INIT_FINALLY(&vscale, n);
    myscale=&vscale;
  } else {
    IGRAPH_CHECK(igraph_vector_resize(scale, n));
  }
  if (vectorsleft) { 
    IGRAPH_CHECK(igraph_matrix_resize(vectorsleft, n, n));
  }
  if (vectorsright) {
    IGRAPH_CHECK(igraph_matrix_resize(vectorsright, n, n));
  }

  igraphdgeevx_(&balanc, &jobvl, &jobvr, &sense, &n, &MATRIX(Acopy,0,0), 
		&lda, VECTOR(*myreal), VECTOR(*myimag), 
		vectorsleft  ? &MATRIX(*vectorsleft ,0,0) : 0, &ldvl,
		vectorsright ? &MATRIX(*vectorsright,0,0) : 0, &ldvr,
		ilo, ihi, VECTOR(*myscale), abnrm, 
		rconde ? VECTOR(*rconde) : 0, 
		rcondv ? VECTOR(*rcondv) : 0, 
		VECTOR(work), &lwork, VECTOR(iwork), info);
		
  lwork=(int) VECTOR(work)[0];
  IGRAPH_CHECK(igraph_vector_resize(&work, lwork));
  
  igraphdgeevx_(&balanc, &jobvl, &jobvr, &sense, &n, &MATRIX(Acopy,0,0), 
		&lda, VECTOR(*myreal), VECTOR(*myimag), 
		vectorsleft  ? &MATRIX(*vectorsleft ,0,0) : 0, &ldvl,
		vectorsright ? &MATRIX(*vectorsright,0,0) : 0, &ldvr,
		ilo, ihi, VECTOR(*myscale), abnrm, 
		rconde ? VECTOR(*rconde) : 0, 
		rcondv ? VECTOR(*rcondv) : 0, 
		VECTOR(work), &lwork, VECTOR(iwork), info);
		
  if (*info < 0) {
      IGRAPH_ERROR("Cannot calculate eigenvalues (dgeev)", IGRAPH_ELAPACK);
  } else if (*info > 0) {    
    if (error) {
      IGRAPH_ERROR("Cannot calculate eigenvalues (dgeev)", IGRAPH_ELAPACK);
    } else {
      IGRAPH_WARNING("Cannot calculate eigenvalues (dgeev)");
    }
  }

  if (!scale) {
    igraph_vector_destroy(&vscale);
    IGRAPH_FINALLY_CLEAN(1);
  }

  if (!valuesimag) {
    igraph_vector_destroy(&vimag);
    IGRAPH_FINALLY_CLEAN(1);
  }

  if (!valuesreal) {
    igraph_vector_destroy(&vreal);
    IGRAPH_FINALLY_CLEAN(1);
  }

  igraph_vector_int_destroy(&iwork);
  igraph_vector_destroy(&work);
  igraph_matrix_destroy(&Acopy);
  IGRAPH_FINALLY_CLEAN(3);

  return 0;
}