示例#1
0
static int igraph_i_bridges_rec(const igraph_t *graph, const igraph_inclist_t *il, igraph_integer_t u, igraph_integer_t *time, igraph_vector_t *bridges, igraph_vector_bool_t *visited, igraph_vector_int_t *disc, igraph_vector_int_t *low, igraph_vector_int_t *parent) {
    igraph_vector_int_t *incedges;
    long nc; /* neighbour count */
    long i;

    VECTOR(*visited)[u] = 1;

    *time += 1;

    VECTOR(*disc)[u] = *time;
    VECTOR(*low)[u] = *time;

    incedges = igraph_inclist_get(il, u);
    nc = igraph_vector_int_size(incedges);
    for (i=0; i < nc; ++i) {
        long edge = (long) VECTOR(*incedges)[i];
        igraph_integer_t v = IGRAPH_TO(graph, edge) == u ? IGRAPH_FROM(graph, edge) : IGRAPH_TO(graph, edge);

        if (! VECTOR(*visited)[v]) {
            VECTOR(*parent)[v] = u;
            IGRAPH_CHECK(igraph_i_bridges_rec(graph, il, v, time, bridges, visited, disc, low, parent));

            VECTOR(*low)[u] = VECTOR(*low)[u] < VECTOR(*low)[v] ? VECTOR(*low)[u] : VECTOR(*low)[v];

            if (VECTOR(*low)[v] > VECTOR(*disc)[u])
                IGRAPH_CHECK(igraph_vector_push_back(bridges, edge));
        }
        else if (v != VECTOR(*parent)[u]) {
            VECTOR(*low)[u] = VECTOR(*low)[u] < VECTOR(*disc)[v] ? VECTOR(*low)[u] : VECTOR(*disc)[v];
        }
    }

    return IGRAPH_SUCCESS;
}
示例#2
0
int igraph_adjlist_init(const igraph_t *graph, igraph_adjlist_t *al, 
			  igraph_neimode_t mode) {
  long int i;

  if (mode != IGRAPH_IN && mode != IGRAPH_OUT && mode != IGRAPH_ALL) {
    IGRAPH_ERROR("Cannot create adjlist view", IGRAPH_EINVMODE);
  }

  if (!igraph_is_directed(graph)) { mode=IGRAPH_ALL; }

  al->length=igraph_vcount(graph);
  al->adjs=igraph_Calloc(al->length, igraph_vector_t);
  if (al->adjs == 0) {
    IGRAPH_ERROR("Cannot create adjlist view", IGRAPH_ENOMEM);
  }

  IGRAPH_FINALLY(igraph_adjlist_destroy, al);
  for (i=0; i<al->length; i++) {
    IGRAPH_ALLOW_INTERRUPTION();
    IGRAPH_CHECK(igraph_vector_init(&al->adjs[i], 0));
    IGRAPH_CHECK(igraph_neighbors(graph, &al->adjs[i], i, mode));
  }

  IGRAPH_FINALLY_CLEAN(1);
  return 0;
}
示例#3
0
int igraph_i_largest_cliques_store(const igraph_vector_t* clique, void* data, igraph_bool_t* cont) {
  igraph_vector_ptr_t* result = (igraph_vector_ptr_t*)data;
  igraph_vector_t* vec;
  long int i, n;

  /* Is the current clique at least as large as the others that we have found? */
  if (!igraph_vector_ptr_empty(result)) {
    n = igraph_vector_size(clique);
    if (n < igraph_vector_size(VECTOR(*result)[0]))
      return IGRAPH_SUCCESS;

    if (n > igraph_vector_size(VECTOR(*result)[0])) {
      for (i = 0; i < igraph_vector_ptr_size(result); i++)
        igraph_vector_destroy(VECTOR(*result)[i]);
      igraph_vector_ptr_free_all(result);
      igraph_vector_ptr_resize(result, 0);
    }
  }

  vec = igraph_Calloc(1, igraph_vector_t);
  if (vec == 0)
    IGRAPH_ERROR("cannot allocate memory for storing next clique", IGRAPH_ENOMEM);

  IGRAPH_CHECK(igraph_vector_copy(vec, clique));
  IGRAPH_CHECK(igraph_vector_ptr_push_back(result, vec));

  return IGRAPH_SUCCESS;
}
/** 
 * \ingroup interface
 * \function igraph_empty_attrs
 * \brief Creates an empty graph with some vertices, no edges and some graph attributes.
 *
 * </para><para>
 * Use this instead of \ref igraph_empty() if you wish to add some graph
 * attributes right after initialization. This function is currently
 * not very interesting for the ordinary user, just supply 0 here or 
 * use \ref igraph_empty().
 * \param graph Pointer to a not-yet initialized graph object.
 * \param n The number of vertices in the graph, a non-negative
 *          integer number is expected.
 * \param directed Whether the graph is directed or not.
 * \param attr The attributes. 
 * \return Error code:
 *         \c IGRAPH_EINVAL: invalid number of vertices.
 * 
 * Time complexity: O(|V|) for a graph with
 * |V| vertices (and no edges).
 */
int igraph_empty_attrs(igraph_t *graph, igraph_integer_t n, igraph_bool_t directed, void* attr) {

  if (n<0) {
    IGRAPH_ERROR("cannot create empty graph with negative number of vertices",
		  IGRAPH_EINVAL);
  }
  
  if (!IGRAPH_FINITE(n)) {
    IGRAPH_ERROR("number of vertices is not finite (NA, NaN or Inf)", IGRAPH_EINVAL);
  }

  graph->n=0;
  graph->directed=directed;
  IGRAPH_VECTOR_INIT_FINALLY(&graph->from, 0);
  IGRAPH_VECTOR_INIT_FINALLY(&graph->to, 0);
  IGRAPH_VECTOR_INIT_FINALLY(&graph->oi, 0);
  IGRAPH_VECTOR_INIT_FINALLY(&graph->ii, 0);
  IGRAPH_VECTOR_INIT_FINALLY(&graph->os, 1);
  IGRAPH_VECTOR_INIT_FINALLY(&graph->is, 1);

  VECTOR(graph->os)[0]=0;
  VECTOR(graph->is)[0]=0;

  /* init attributes */
  graph->attr=0;
  IGRAPH_CHECK(igraph_i_attribute_init(graph, attr));

  /* add the vertices */
  IGRAPH_CHECK(igraph_add_vertices(graph, n, 0));
  
  IGRAPH_FINALLY_CLEAN(6);
  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;
}
示例#6
0
int igraph_similarity_inverse_log_weighted(const igraph_t *graph,
  igraph_matrix_t *res, const igraph_vs_t vids, igraph_neimode_t mode) {
  igraph_vector_t weights;
  igraph_neimode_t mode0;
  long int i, no_of_nodes;

  switch (mode) {
    case IGRAPH_OUT: mode0 = IGRAPH_IN; break;
    case IGRAPH_IN: mode0 = IGRAPH_OUT; break;
    default: mode0 = IGRAPH_ALL;
  }

  no_of_nodes = igraph_vcount(graph);

  IGRAPH_VECTOR_INIT_FINALLY(&weights, no_of_nodes);
  IGRAPH_CHECK(igraph_degree(graph, &weights, igraph_vss_all(), mode0, 1));
  for (i=0; i < no_of_nodes; i++) {
    if (VECTOR(weights)[i] > 1)
      VECTOR(weights)[i] = 1.0 / log(VECTOR(weights)[i]);
  }

  IGRAPH_CHECK(igraph_cocitation_real(graph, res, vids, mode0, &weights));
  igraph_vector_destroy(&weights);
  IGRAPH_FINALLY_CLEAN(1);
  return 0;
}
示例#7
0
int igraph_i_eigen_matrix_lapack_common(const igraph_matrix_t *A,
					const igraph_eigen_which_t *which, 
					igraph_vector_complex_t *values,
					igraph_matrix_complex_t *vectors) {

  igraph_vector_t valuesreal, valuesimag;
  igraph_matrix_t vectorsright, *myvectors= vectors ? &vectorsright : 0;
  int n=(int) igraph_matrix_nrow(A);
  int info=1;

  IGRAPH_VECTOR_INIT_FINALLY(&valuesreal, n);
  IGRAPH_VECTOR_INIT_FINALLY(&valuesimag, n);
  if (vectors) { IGRAPH_MATRIX_INIT_FINALLY(&vectorsright, n, n); }
  IGRAPH_CHECK(igraph_lapack_dgeev(A, &valuesreal, &valuesimag, 
				   /*vectorsleft=*/ 0, myvectors, &info));

  IGRAPH_CHECK(igraph_i_eigen_matrix_lapack_reorder(&valuesreal, 
						    &valuesimag, 
						    myvectors, which, values,
						    vectors));
  
  if (vectors) { 
    igraph_matrix_destroy(&vectorsright);
    IGRAPH_FINALLY_CLEAN(1);
  }
  
  igraph_vector_destroy(&valuesimag);
  igraph_vector_destroy(&valuesreal);
  IGRAPH_FINALLY_CLEAN(2);

  return 0;
  
}
示例#8
0
int igraph_attribute_combination(igraph_attribute_combination_t *comb, ...) {

  va_list ap;

  IGRAPH_CHECK(igraph_attribute_combination_init(comb));
  
  va_start(ap, comb);
  while (1) { 
    void *func=0;
    igraph_attribute_combination_type_t type;
    const char *name;
    
    name=va_arg(ap, const char *);
    
    if (name == IGRAPH_NO_MORE_ATTRIBUTES) { break; }
    
    type=(igraph_attribute_combination_type_t)va_arg(ap, int);
    if (type == IGRAPH_ATTRIBUTE_COMBINE_FUNCTION) {
      func=va_arg(ap, void*);      
    }

    if (strlen(name)==0) { name=0; }
    
    IGRAPH_CHECK(igraph_attribute_combination_add(comb, name, type, func));
  }
示例#9
0
/**
 * \ingroup structural
 * \function igraph_similarity_jaccard_es
 * \brief Jaccard similarity coefficient for a given edge selector.
 *
 * </para><para>
 * The Jaccard similarity coefficient of two vertices is the number of common
 * neighbors divided by the number of vertices that are neighbors of at
 * least one of the two vertices being considered. This function calculates
 * the pairwise Jaccard similarities for the endpoints of edges in a given edge
 * selector.
 *
 * \param graph The graph object to analyze
 * \param res Pointer to a vector, the result of the calculation will
 *        be stored here. The number of elements is the same as the number
 *        of edges in \p es.
 * \param es An edge selector that specifies the edges to be included in the
 *        result.
 * \param mode The type of neighbors to be used for the calculation in
 *        directed graphs. Possible values:
 *        \clist
 *        \cli IGRAPH_OUT
 *          the outgoing edges will be considered for each node.
 *        \cli IGRAPH_IN
 *          the incoming edges will be considered for each node.
 *        \cli IGRAPH_ALL
 *          the directed graph is considered as an undirected one for the
 *          computation.
 *        \endclist
 * \param loops Whether to include the vertices themselves in the neighbor
 *        sets.
 * \return Error code:
 *        \clist
 *        \cli IGRAPH_ENOMEM
 *           not enough memory for temporary data.
 *        \cli IGRAPH_EINVVID
 *           invalid vertex id passed.
 *        \cli IGRAPH_EINVMODE
 *           invalid mode argument.
 *        \endclist
 * 
 * Time complexity: O(nd), n is the number of edges in the edge selector, d is
 * the (maximum) degree of the vertices in the graph.
 *
 * \sa \ref igraph_similarity_jaccard() and \ref igraph_similarity_jaccard_pairs()
 *   to calculate the Jaccard similarity between all pairs of a vertex set or
 *   some selected vertex pairs, or \ref igraph_similarity_dice(),
 *   \ref igraph_similarity_dice_pairs() and \ref igraph_similarity_dice_es() for a
 *   measure very similar to the Jaccard coefficient
 * 
 * \example examples/simple/igraph_similarity.c
 */
int igraph_similarity_jaccard_es(const igraph_t *graph, igraph_vector_t *res,
	const igraph_es_t es, igraph_neimode_t mode, igraph_bool_t loops) {
  igraph_vector_t v;
  igraph_eit_t eit;

  IGRAPH_VECTOR_INIT_FINALLY(&v, 0);

  IGRAPH_CHECK(igraph_eit_create(graph, es, &eit));
  IGRAPH_FINALLY(igraph_eit_destroy, &eit);

  while (!IGRAPH_EIT_END(eit)) {
    long int eid = IGRAPH_EIT_GET(eit);
    igraph_vector_push_back(&v, IGRAPH_FROM(graph, eid));
    igraph_vector_push_back(&v, IGRAPH_TO(graph, eid));
    IGRAPH_EIT_NEXT(eit);
  }

  igraph_eit_destroy(&eit);
  IGRAPH_FINALLY_CLEAN(1);

  IGRAPH_CHECK(igraph_similarity_jaccard_pairs(graph, res, &v, mode, loops));
  igraph_vector_destroy(&v);
  IGRAPH_FINALLY_CLEAN(1);

  return IGRAPH_SUCCESS;
}
示例#10
0
int igraph_inclist_init(const igraph_t *graph, 
			      igraph_inclist_t *il, 
			      igraph_neimode_t mode) {
  long int i;

  if (mode != IGRAPH_IN && mode != IGRAPH_OUT && mode != IGRAPH_ALL) {
    IGRAPH_ERROR("Cannot create incidence list view", IGRAPH_EINVMODE);
  }

  if (!igraph_is_directed(graph)) { mode=IGRAPH_ALL; }

  il->length=igraph_vcount(graph);
  il->incs=igraph_Calloc(il->length, igraph_vector_t);
  if (il->incs == 0) {
    IGRAPH_ERROR("Cannot create incidence list view", IGRAPH_ENOMEM);
  }

  IGRAPH_FINALLY(igraph_inclist_destroy, il);  
  for (i=0; i<il->length; i++) {
    IGRAPH_ALLOW_INTERRUPTION();
    IGRAPH_CHECK(igraph_vector_init(&il->incs[i], 0));
    IGRAPH_CHECK(igraph_incident(graph, &il->incs[i], i, mode));
  }
  
  IGRAPH_FINALLY_CLEAN(1);
  return 0;
}
示例#11
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;
}
示例#12
0
int igraph_is_separator(const igraph_t *graph, 
			const igraph_vs_t candidate,
			igraph_bool_t *res) {

  long int no_of_nodes=igraph_vcount(graph);
  igraph_vector_bool_t removed;
  igraph_dqueue_t Q;
  igraph_vector_t neis;
  igraph_vit_t vit;

  IGRAPH_CHECK(igraph_vit_create(graph, candidate, &vit));
  IGRAPH_FINALLY(igraph_vit_destroy, &vit);
  IGRAPH_CHECK(igraph_vector_bool_init(&removed, no_of_nodes));
  IGRAPH_FINALLY(igraph_vector_bool_destroy, &removed);
  IGRAPH_CHECK(igraph_dqueue_init(&Q, 100));
  IGRAPH_FINALLY(igraph_dqueue_destroy, &Q);
  IGRAPH_VECTOR_INIT_FINALLY(&neis, 0);

  IGRAPH_CHECK(igraph_i_is_separator(graph, &vit, -1, res, &removed, 
				     &Q, &neis, no_of_nodes));

  igraph_vector_destroy(&neis);
  igraph_dqueue_destroy(&Q);
  igraph_vector_bool_destroy(&removed);
  igraph_vit_destroy(&vit);
  IGRAPH_FINALLY_CLEAN(4);

  return 0;
}
示例#13
0
文件: matrix.c 项目: FEYoung/rigraph
int igraph_matrix_complex_imag(const igraph_matrix_complex_t *v,
			       igraph_matrix_t *imag) {
  long int nrow=igraph_matrix_complex_nrow(v);
  long int ncol=igraph_matrix_complex_ncol(v);
  IGRAPH_CHECK(igraph_matrix_resize(imag, nrow, ncol));
  IGRAPH_CHECK(igraph_vector_complex_imag(&v->data, &imag->data));
  return 0;
}
示例#14
0
文件: matrix.c 项目: FEYoung/rigraph
int igraph_matrix_complex_real(const igraph_matrix_complex_t *v,
			       igraph_matrix_t *real) {
  long int nrow=igraph_matrix_complex_nrow(v);
  long int ncol=igraph_matrix_complex_ncol(v);
  IGRAPH_CHECK(igraph_matrix_resize(real, nrow, ncol));
  IGRAPH_CHECK(igraph_vector_complex_real(&v->data, &real->data));
  return 0;
}
示例#15
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;
}
示例#16
0
int igraph_i_maximum_bipartite_matching_unweighted_relabel(const igraph_t* graph,
    const igraph_vector_bool_t* types, igraph_vector_t* labels,
    igraph_vector_long_t* match, igraph_bool_t smaller_set) {
  long int i, j, n, no_of_nodes = igraph_vcount(graph), matched_to;
  igraph_dqueue_long_t q;
  igraph_vector_t neis;

  debug("Running global relabeling.\n");

  /* Set all the labels to no_of_nodes first */
  igraph_vector_fill(labels, no_of_nodes);

  /* Allocate vector for neighbors */
  IGRAPH_VECTOR_INIT_FINALLY(&neis, 0);

  /* Create a FIFO for the BFS and initialize it with the unmatched rows
   * (i.e. members of the larger set) */
  IGRAPH_CHECK(igraph_dqueue_long_init(&q, 0));
  IGRAPH_FINALLY(igraph_dqueue_long_destroy, &q);
  for (i = 0; i < no_of_nodes; i++) {
    if (VECTOR(*types)[i] != smaller_set && VECTOR(*match)[i] == -1) {
      IGRAPH_CHECK(igraph_dqueue_long_push(&q, i));
      VECTOR(*labels)[i] = 0;
    }
  }

  /* Run the BFS */
  while (!igraph_dqueue_long_empty(&q)) {
    long int v = igraph_dqueue_long_pop(&q);
    long int w;

    IGRAPH_CHECK(igraph_neighbors(graph, &neis, (igraph_integer_t) v,
				  IGRAPH_ALL));

    n = igraph_vector_size(&neis);
    //igraph_vector_shuffle(&neis);
    for (j = 0; j < n; j++) {
      w = (long int) VECTOR(neis)[j];
      if (VECTOR(*labels)[w] == no_of_nodes) {
        VECTOR(*labels)[w] = VECTOR(*labels)[v] + 1;
        matched_to = VECTOR(*match)[w];
        if (matched_to != -1 && VECTOR(*labels)[matched_to] == no_of_nodes) {
          IGRAPH_CHECK(igraph_dqueue_long_push(&q, matched_to));
          VECTOR(*labels)[matched_to] = VECTOR(*labels)[w] + 1;
        }
      }
    }
  }
  printf("Inside relabel : ");
  igraph_vector_print(labels);
  igraph_dqueue_long_destroy(&q);
  igraph_vector_destroy(&neis);
  IGRAPH_FINALLY_CLEAN(2);

  return IGRAPH_SUCCESS;
}
示例#17
0
int igraph_eigen_matrix_symmetric(const igraph_matrix_t *A,
				  const igraph_sparsemat_t *sA,
				  igraph_arpack_function_t *fun, int n,
				  void *extra,
				  igraph_eigen_algorithm_t algorithm,
				  const igraph_eigen_which_t *which,
				  igraph_arpack_options_t *options,
				  igraph_arpack_storage_t *storage,
				  igraph_vector_t *values, 
				  igraph_matrix_t *vectors) {

  IGRAPH_CHECK(igraph_i_eigen_checks(A, sA, fun, n));
  
  if (which->pos != IGRAPH_EIGEN_LM && 
      which->pos != IGRAPH_EIGEN_SM && 
      which->pos != IGRAPH_EIGEN_LA && 
      which->pos != IGRAPH_EIGEN_SA && 
      which->pos != IGRAPH_EIGEN_BE && 
      which->pos != IGRAPH_EIGEN_ALL && 
      which->pos != IGRAPH_EIGEN_INTERVAL && 
      which->pos != IGRAPH_EIGEN_SELECT) {
    IGRAPH_ERROR("Invalid 'pos' position in 'which'", IGRAPH_EINVAL);
  }

  switch (algorithm) {
  case IGRAPH_EIGEN_AUTO:
    if (which->howmany==n || n < 100) {
      IGRAPH_CHECK(igraph_i_eigen_matrix_symmetric_lapack(A, sA, fun, n,
							  extra, which, 
							  values, vectors));
    } else {
      IGRAPH_CHECK(igraph_i_eigen_matrix_symmetric_arpack(A, sA, fun, n, 
							  extra, which, 
							  options, storage,
							  values, vectors));
    }
    break;
  case IGRAPH_EIGEN_LAPACK:
    IGRAPH_CHECK(igraph_i_eigen_matrix_symmetric_lapack(A, sA, fun, n ,extra,
							which, values, 
							vectors));
    break;
  case IGRAPH_EIGEN_ARPACK:
    IGRAPH_CHECK(igraph_i_eigen_matrix_symmetric_arpack(A, sA, fun, n, extra,
							which, options, 
							storage,
							values, vectors));
    break;
  default:
    IGRAPH_ERROR("Unknown 'algorithm'", IGRAPH_EINVAL);
  }
    
  return 0;
}
示例#18
0
int igraph_i_maximal_or_largest_cliques_or_indsets(const igraph_t *graph,
                                        igraph_vector_ptr_t *res,
                                        igraph_integer_t *clique_number,
                                        igraph_bool_t keep_only_largest,
                                        igraph_bool_t complementer) {
  igraph_i_max_ind_vsets_data_t clqdata;
  long int no_of_nodes = igraph_vcount(graph), i;

  if (igraph_is_directed(graph))
    IGRAPH_WARNING("directionality of edges is ignored for directed graphs");

  clqdata.matrix_size=no_of_nodes;
  clqdata.keep_only_largest=keep_only_largest;

  if (complementer)
    IGRAPH_CHECK(igraph_adjlist_init_complementer(graph, &clqdata.adj_list, IGRAPH_ALL, 0));
  else
    IGRAPH_CHECK(igraph_adjlist_init(graph, &clqdata.adj_list, IGRAPH_ALL));
  IGRAPH_FINALLY(igraph_adjlist_destroy, &clqdata.adj_list);

  clqdata.IS = igraph_Calloc(no_of_nodes, igraph_integer_t);
  if (clqdata.IS == 0)
    IGRAPH_ERROR("igraph_i_maximal_or_largest_cliques_or_indsets failed", IGRAPH_ENOMEM);
  IGRAPH_FINALLY(igraph_free, clqdata.IS);

  IGRAPH_VECTOR_INIT_FINALLY(&clqdata.deg, no_of_nodes);
  for (i=0; i<no_of_nodes; i++)
    VECTOR(clqdata.deg)[i] = igraph_vector_size(igraph_adjlist_get(&clqdata.adj_list, i));

  clqdata.buckets = igraph_Calloc(no_of_nodes+1, igraph_set_t);
  if (clqdata.buckets == 0)
    IGRAPH_ERROR("igraph_maximal_or_largest_cliques_or_indsets failed", IGRAPH_ENOMEM);
  IGRAPH_FINALLY(igraph_i_free_set_array, clqdata.buckets);

  for (i=0; i<no_of_nodes; i++)
    IGRAPH_CHECK(igraph_set_init(&clqdata.buckets[i], 0));

  if (res) igraph_vector_ptr_clear(res);
  
  /* Do the show */
  clqdata.largest_set_size=0;
  IGRAPH_CHECK(igraph_i_maximal_independent_vertex_sets_backtrack(graph, res, &clqdata, 0));

  /* Cleanup */
  for (i=0; i<no_of_nodes; i++) igraph_set_destroy(&clqdata.buckets[i]);
  igraph_adjlist_destroy(&clqdata.adj_list);
  igraph_vector_destroy(&clqdata.deg);
  igraph_free(clqdata.IS);
  igraph_free(clqdata.buckets);
  IGRAPH_FINALLY_CLEAN(4);

  if (clique_number) *clique_number = clqdata.largest_set_size;
  return 0;
}
示例#19
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;
}
示例#20
0
/**
 * \function igraph_is_matching
 * Checks whether the given matching is valid for the given graph.
 *
 * This function checks a matching vector and verifies whether its length
 * matches the number of vertices in the given graph, its values are between
 * -1 (inclusive) and the number of vertices (exclusive), and whether there
 * exists a corresponding edge in the graph for every matched vertex pair.
 * For bipartite graphs, it also verifies whether the matched vertices are
 * in different parts of the graph.
 *
 * \param graph The input graph. It can be directed but the edge directions
 *              will be ignored.
 * \param types If the graph is bipartite and you are interested in bipartite
 *              matchings only, pass the vertex types here. If the graph is
 *              non-bipartite, simply pass \c NULL.
 * \param matching The matching itself. It must be a vector where element i
 *                 contains the ID of the vertex that vertex i is matched to,
 *                 or -1 if vertex i is unmatched.
 * \param result Pointer to a boolean variable, the result will be returned
 *               here.
 *
 * \sa \ref igraph_is_maximal_matching() if you are also interested in whether
 *     the matching is maximal (i.e. non-extendable).
 *
 * Time complexity: O(|V|+|E|) where |V| is the number of vertices and
 * |E| is the number of edges.
 * 
 * \example examples/simple/igraph_maximum_bipartite_matching.c
 */
int igraph_is_matching(const igraph_t* graph,
    const igraph_vector_bool_t* types, const igraph_vector_long_t* matching,
    igraph_bool_t* result) {
  long int i, j, no_of_nodes = igraph_vcount(graph);
  igraph_bool_t conn;

  /* Checking match vector length */
  if (igraph_vector_long_size(matching) != no_of_nodes) {
    *result = 0; return IGRAPH_SUCCESS;
  }

  for (i = 0; i < no_of_nodes; i++) {
    j = VECTOR(*matching)[i];

    /* Checking range of each element in the match vector */
    if (j < -1 || j >= no_of_nodes) {
      *result = 0; return IGRAPH_SUCCESS;
    }
    /* When i is unmatched, we're done */
    if (j == -1)
      continue;
    /* Matches must be mutual */
    if (VECTOR(*matching)[j] != i) {
      *result = 0; return IGRAPH_SUCCESS;
    }
    /* Matched vertices must be connected */
    IGRAPH_CHECK(igraph_are_connected(graph, (igraph_integer_t) i, 
				      (igraph_integer_t) j, &conn));
    if (!conn) {
      /* Try the other direction -- for directed graphs */
      IGRAPH_CHECK(igraph_are_connected(graph, (igraph_integer_t) j, 
					(igraph_integer_t) i, &conn));
      if (!conn) {
        *result = 0; return IGRAPH_SUCCESS;
      }
    }
  }

  if (types != 0) {
    /* Matched vertices must be of different types */
    for (i = 0; i < no_of_nodes; i++) {
      j = VECTOR(*matching)[i];
      if (j == -1)
        continue;
      if (VECTOR(*types)[i] == VECTOR(*types)[j]) {
        *result = 0; return IGRAPH_SUCCESS;
      }
    }
  }

  *result = 1;
  return IGRAPH_SUCCESS;
}
示例#21
0
/**
 * \ingroup structural
 * \function igraph_similarity_jaccard
 * \brief Jaccard similarity coefficient for the given vertices.
 *
 * </para><para>
 * The Jaccard similarity coefficient of two vertices is the number of common
 * neighbors divided by the number of vertices that are neighbors of at
 * least one of the two vertices being considered. This function calculates
 * the pairwise Jaccard similarities for some (or all) of the vertices.
 *
 * \param graph The graph object to analyze
 * \param res Pointer to a matrix, the result of the calculation will
 *        be stored here. The number of its rows and columns is the same
 *        as the number of vertex ids in \p vids.
 * \param vids The vertex ids of the vertices for which the
 *        calculation will be done.
 * \param mode The type of neighbors to be used for the calculation in
 *        directed graphs. Possible values:
 *        \clist
 *        \cli IGRAPH_OUT
 *          the outgoing edges will be considered for each node.
 *        \cli IGRAPH_IN
 *          the incoming edges will be considered for each node.
 *        \cli IGRAPH_ALL
 *          the directed graph is considered as an undirected one for the
 *          computation.
 *        \endclist
 * \param loops Whether to include the vertices themselves in the neighbor
 *        sets.
 * \return Error code:
 *        \clist
 *        \cli IGRAPH_ENOMEM
 *           not enough memory for temporary data.
 *        \cli IGRAPH_EINVVID
 *           invalid vertex id passed.
 *        \cli IGRAPH_EINVMODE
 *           invalid mode argument.
 *        \endclist
 * 
 * Time complexity: O(|V|^2 d),
 * |V| is the number of vertices in the vertex iterator given, d is the
 * (maximum) degree of the vertices in the graph.
 *
 * \sa \ref igraph_similarity_dice(), a measure very similar to the Jaccard
 *   coefficient
 * 
 * \example examples/simple/igraph_similarity.c
 */
int igraph_similarity_jaccard(const igraph_t *graph, igraph_matrix_t *res,
    const igraph_vs_t vids, igraph_neimode_t mode, igraph_bool_t loops) {
  igraph_lazy_adjlist_t al;
  igraph_vit_t vit, vit2;
  long int i, j, k;
  long int len_union, len_intersection;
  igraph_vector_t *v1, *v2;

  IGRAPH_CHECK(igraph_vit_create(graph, vids, &vit));
  IGRAPH_FINALLY(igraph_vit_destroy, &vit);
  IGRAPH_CHECK(igraph_vit_create(graph, vids, &vit2));
  IGRAPH_FINALLY(igraph_vit_destroy, &vit2);

  IGRAPH_CHECK(igraph_lazy_adjlist_init(graph, &al, mode, IGRAPH_SIMPLIFY));
  IGRAPH_FINALLY(igraph_lazy_adjlist_destroy, &al);

  IGRAPH_CHECK(igraph_matrix_resize(res, IGRAPH_VIT_SIZE(vit), IGRAPH_VIT_SIZE(vit)));

  if (loops) {
    for (IGRAPH_VIT_RESET(vit); !IGRAPH_VIT_END(vit); IGRAPH_VIT_NEXT(vit)) {
      i=IGRAPH_VIT_GET(vit);
      v1=igraph_lazy_adjlist_get(&al, (igraph_integer_t) i);
      if (!igraph_vector_binsearch(v1, i, &k))
        igraph_vector_insert(v1, k, i);
    }
  }

  for (IGRAPH_VIT_RESET(vit), i=0;
    !IGRAPH_VIT_END(vit); IGRAPH_VIT_NEXT(vit), i++) {
    MATRIX(*res, i, i) = 1.0;
    for (IGRAPH_VIT_RESET(vit2), j=0;
      !IGRAPH_VIT_END(vit2); IGRAPH_VIT_NEXT(vit2), j++) {
      if (j <= i)
        continue;
      v1=igraph_lazy_adjlist_get(&al, IGRAPH_VIT_GET(vit));
      v2=igraph_lazy_adjlist_get(&al, IGRAPH_VIT_GET(vit2));
      igraph_i_neisets_intersect(v1, v2, &len_union, &len_intersection);
      if (len_union > 0)
        MATRIX(*res, i, j) = ((igraph_real_t)len_intersection)/len_union;
      else
        MATRIX(*res, i, j) = 0.0;
      MATRIX(*res, j, i) = MATRIX(*res, i, j);
    }
  }

  igraph_lazy_adjlist_destroy(&al);
  igraph_vit_destroy(&vit);
  igraph_vit_destroy(&vit2);
  IGRAPH_FINALLY_CLEAN(3);

  return 0;
}
示例#22
0
int igraph_is_connected_weak(const igraph_t *graph, igraph_bool_t *res) {

  long int no_of_nodes=igraph_vcount(graph);
  char *already_added;
  igraph_vector_t neis=IGRAPH_VECTOR_NULL;
  igraph_dqueue_t q=IGRAPH_DQUEUE_NULL;
  
  long int i, j;

  if (no_of_nodes == 0) {
    *res = 1;
    return IGRAPH_SUCCESS;
  }

  already_added=igraph_Calloc(no_of_nodes, char);
  if (already_added==0) {
    IGRAPH_ERROR("is connected (weak) failed", IGRAPH_ENOMEM);
  }
  IGRAPH_FINALLY(free, already_added); /* TODO: hack */

  IGRAPH_DQUEUE_INIT_FINALLY(&q, 10);
  IGRAPH_VECTOR_INIT_FINALLY(&neis, 0);
  
  /* Try to find at least two clusters */
  already_added[0]=1;
  IGRAPH_CHECK(igraph_dqueue_push(&q, 0));
  
  j=1;
  while ( !igraph_dqueue_empty(&q)) {
    long int actnode=(long int) igraph_dqueue_pop(&q);
    IGRAPH_ALLOW_INTERRUPTION();
    IGRAPH_CHECK(igraph_neighbors(graph, &neis, (igraph_integer_t) actnode,
				  IGRAPH_ALL));
    for (i=0; i <igraph_vector_size(&neis); i++) {
      long int neighbor=(long int) VECTOR(neis)[i];
      if (already_added[neighbor] != 0) { continue; }
      IGRAPH_CHECK(igraph_dqueue_push(&q, neighbor));
      j++;
      already_added[neighbor]++;
    }
  }
  
  /* Connected? */
  *res = (j == no_of_nodes);

  igraph_Free(already_added);
  igraph_dqueue_destroy(&q);
  igraph_vector_destroy(&neis);
  IGRAPH_FINALLY_CLEAN(3);

  return 0;
}
示例#23
0
int igraph_biguint_mul_limb(igraph_biguint_t *res, igraph_biguint_t *b,
			    limb_t l) {
  long int nlimb=igraph_biguint_size(b);
  limb_t carry;
  
  if (res!= b) { IGRAPH_CHECK(igraph_biguint_resize(res, nlimb)); }
  
  carry=bn_mul_limb( VECTOR(res->v), VECTOR(b->v), l, nlimb);
  if (carry) { 
    IGRAPH_CHECK(igraph_biguint_extend(res, carry));
  }
  return 0;
}
示例#24
0
int igraph_i_maximal_cliques_store(const igraph_vector_t* clique, void* data, igraph_bool_t* cont) {
  igraph_vector_ptr_t* result = (igraph_vector_ptr_t*)data;
  igraph_vector_t* vec;

  vec = igraph_Calloc(1, igraph_vector_t);
  if (vec == 0)
    IGRAPH_ERROR("cannot allocate memory for storing next clique", IGRAPH_ENOMEM);

  IGRAPH_CHECK(igraph_vector_copy(vec, clique));
  IGRAPH_CHECK(igraph_vector_ptr_push_back(result, vec));

  return IGRAPH_SUCCESS;
}
示例#25
0
int igraph_is_minimal_separator(const igraph_t *graph,
				const igraph_vs_t candidate, 
				igraph_bool_t *res) {

  long int no_of_nodes=igraph_vcount(graph);
  igraph_vector_bool_t removed;
  igraph_dqueue_t Q;
  igraph_vector_t neis;
  long int candsize;
  igraph_vit_t vit;
  
  IGRAPH_CHECK(igraph_vit_create(graph, candidate, &vit));
  IGRAPH_FINALLY(igraph_vit_destroy, &vit);
  candsize=IGRAPH_VIT_SIZE(vit);

  IGRAPH_CHECK(igraph_vector_bool_init(&removed, no_of_nodes));
  IGRAPH_FINALLY(igraph_vector_bool_destroy, &removed);
  IGRAPH_CHECK(igraph_dqueue_init(&Q, 100));
  IGRAPH_FINALLY(igraph_dqueue_destroy, &Q);
  IGRAPH_VECTOR_INIT_FINALLY(&neis, 0);

  /* Is it a separator at all? */
  IGRAPH_CHECK(igraph_i_is_separator(graph, &vit, -1, res, &removed, 
				     &Q, &neis, no_of_nodes));
  if (!(*res)) {
    /* Not a separator at all, nothing to do, *res is already set */
  } else if (candsize == 0) {
    /* Nothing to do, minimal, *res is already set */
  } else {
    /* General case, we need to remove each vertex from 'candidate'
     * and check whether the remainder is a separator. If this is
     * false for all vertices, then 'candidate' is a minimal
     * separator.
     */
    long int i;
    for (i=0, *res=0; i<candsize && (!*res); i++) {
      igraph_vector_bool_null(&removed);
      IGRAPH_CHECK(igraph_i_is_separator(graph, &vit, i, res, &removed, 
					 &Q, &neis, no_of_nodes));    
    }
    (*res) = (*res) ? 0 : 1;	/* opposite */
  }
  
  igraph_vector_destroy(&neis);
  igraph_dqueue_destroy(&Q);
  igraph_vector_bool_destroy(&removed);
  igraph_vit_destroy(&vit);
  IGRAPH_FINALLY_CLEAN(4);

  return 0;
}
示例#26
0
文件: vector.c 项目: pombredanne/RCA
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;
}
示例#27
0
int igraph_create_bipartite(igraph_t *graph, const igraph_vector_bool_t *types,
			    const igraph_vector_t *edges, 
			    igraph_bool_t directed) {

  igraph_integer_t no_of_nodes=
    (igraph_integer_t) igraph_vector_bool_size(types);
  long int no_of_edges=igraph_vector_size(edges);
  igraph_real_t min_edge=0, max_edge=0;
  igraph_bool_t min_type=0, max_type=0;
  long int i;

  if (no_of_edges % 2 != 0) {
    IGRAPH_ERROR("Invalid (odd) edges vector", IGRAPH_EINVEVECTOR);
  }
  no_of_edges /= 2;
  
  if (no_of_edges != 0) {
    igraph_vector_minmax(edges, &min_edge, &max_edge);
  }
  if (min_edge < 0 || max_edge >= no_of_nodes) {
    IGRAPH_ERROR("Invalid (negative) vertex id", IGRAPH_EINVVID);
  }

  /* Check types vector */
  if (no_of_nodes != 0) {
    igraph_vector_bool_minmax(types, &min_type, &max_type);
    if (min_type < 0 || max_type > 1) {
      IGRAPH_WARNING("Non-binary type vector when creating a bipartite graph");
    }
  }

  /* Check bipartiteness */
  for (i=0; i<no_of_edges*2; i+=2) {
    long int from=(long int) VECTOR(*edges)[i];
    long int to=(long int) VECTOR(*edges)[i+1];
    long int t1=VECTOR(*types)[from];
    long int t2=VECTOR(*types)[to];
    if ( (t1 && t2) || (!t1 && !t2) ) {
      IGRAPH_ERROR("Invalid edges, not a bipartite graph", IGRAPH_EINVAL);
    }
  }
  
  IGRAPH_CHECK(igraph_empty(graph, no_of_nodes, directed));
  IGRAPH_FINALLY(igraph_destroy, graph);
  IGRAPH_CHECK(igraph_add_edges(graph, edges, 0));
  
  IGRAPH_FINALLY_CLEAN(1);
  return 0;
}
示例#28
0
int igraph_dot_product_game(igraph_t *graph, const igraph_matrix_t *vecs,
			    igraph_bool_t directed) {

  igraph_integer_t nrow=igraph_matrix_nrow(vecs);
  igraph_integer_t ncol=igraph_matrix_ncol(vecs);
  int i, j;
  igraph_vector_t edges;
  igraph_bool_t warned_neg=0, warned_big=0;
  
  IGRAPH_VECTOR_INIT_FINALLY(&edges, 0);
    
  RNG_BEGIN();

  for (i = 0; i < ncol; i++) {
    int from=directed ? 0 : i+1;
    igraph_vector_t v1;
    igraph_vector_view(&v1, &MATRIX(*vecs, 0, i), nrow);
    for (j = from; j < ncol; j++) {
      igraph_real_t prob;
      igraph_vector_t v2;
      if (i==j) { continue; }
      igraph_vector_view(&v2, &MATRIX(*vecs, 0, j), nrow);
      igraph_lapack_ddot(&v1, &v2, &prob);
      if (prob < 0 && ! warned_neg) {
	warned_neg=1;
	IGRAPH_WARNING("Negative connection probability in "
		       "dot-product graph");
      } else if (prob > 1 && ! warned_big) {
	warned_big=1;
	IGRAPH_WARNING("Greater than 1 connection probability in "
		       "dot-product graph");
	IGRAPH_CHECK(igraph_vector_push_back(&edges, i));
	IGRAPH_CHECK(igraph_vector_push_back(&edges, j));
      } else if (RNG_UNIF01() < prob) { 
	IGRAPH_CHECK(igraph_vector_push_back(&edges, i));
	IGRAPH_CHECK(igraph_vector_push_back(&edges, j));
      }
    }
  }

  RNG_END();
  
  igraph_create(graph, &edges, ncol, directed);
  igraph_vector_destroy(&edges);
  IGRAPH_FINALLY_CLEAN(1);

  return 0;
}
/*
 * Converts a Java VertexSet to an igraph_vs_t
 * @return:  zero if everything went fine, 1 if a null pointer was passed
 */
int Java_net_sf_igraph_VertexSet_to_igraph_vs(JNIEnv *env, jobject jobj, igraph_vs_t *result) {
  jint typeHint;
  jobject idArray;

  if (jobj == 0) {
    IGRAPH_CHECK(igraph_vs_all(result));
	return IGRAPH_SUCCESS;
  }

  typeHint = (*env)->CallIntMethod(env, jobj, net_sf_igraph_VertexSet_getTypeHint_mid);
  if (typeHint != 1 && typeHint != 2) {
    IGRAPH_CHECK(igraph_vs_all(result));
    return IGRAPH_SUCCESS;
  }
  
  idArray = (*env)->CallObjectMethod(env, jobj, net_sf_igraph_VertexSet_getIdArray_mid);
  if ((*env)->ExceptionCheck(env)) {
	return IGRAPH_EINVAL;
  }

  if (typeHint == 1) {
    /* Single vertex */
	jlong id[1];
	(*env)->GetLongArrayRegion(env, idArray, 0, 1, id);
	IGRAPH_CHECK(igraph_vs_1(result, (igraph_integer_t)id[0]));
  } else if (typeHint == 2) {
    /* List of vertices */
	jlong* ids;
	igraph_vector_t vec;
	long i, n;

	ids = (*env)->GetLongArrayElements(env, idArray, 0);
	n = (*env)->GetArrayLength(env, idArray);

	IGRAPH_VECTOR_INIT_FINALLY(&vec, n);
	for (i = 0; i < n; i++)
		VECTOR(vec)[i] = ids[i];
	IGRAPH_CHECK(igraph_vs_vector_copy(result, &vec));
	igraph_vector_destroy(&vec);
	IGRAPH_FINALLY_CLEAN(1);

	(*env)->ReleaseLongArrayElements(env, idArray, ids, JNI_ABORT);
  }

  (*env)->DeleteLocalRef(env, idArray);

  return IGRAPH_SUCCESS;
}
示例#30
0
文件: scan.c 项目: abeham/igraph
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;
}