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; }
/* Takes a pointer vector of vectors. Sorts each vector, then sorts the pointer vector */ void canonicalize_list(igraph_vector_ptr_t *list) { long i, len; len = igraph_vector_ptr_size(list); for (i=0; i<len; ++i) { igraph_vector_sort((igraph_vector_t *) VECTOR(*list)[i]); } qsort(&(VECTOR(*list)[0]), len, sizeof(void *), &compare_vectors); }
void sort_cliques(igraph_vector_ptr_t *cliques) { int i, n=igraph_vector_ptr_size(cliques); for (i=0; i<n; i++) { igraph_vector_t *v=VECTOR(*cliques)[i]; igraph_vector_sort(v); } igraph_qsort(VECTOR(*cliques), (size_t) n, sizeof(igraph_vector_t *), sort_cmp); }
int igraph_i_separators_store(igraph_vector_ptr_t *separators, const igraph_adjlist_t *adjlist, igraph_vector_t *components, igraph_vector_t *leaveout, unsigned long int *mark, igraph_vector_t *sorter) { /* We need to stote N(C), the neighborhood of C, but only if it is * not already stored among the separators. */ long int cptr=0, next, complen=igraph_vector_size(components); while (cptr < complen) { long int saved=cptr; igraph_vector_clear(sorter); /* Calculate N(C) for the next C */ while ( (next=(long int) VECTOR(*components)[cptr++]) != -1) { VECTOR(*leaveout)[next] = *mark; } cptr=saved; while ( (next=(long int) VECTOR(*components)[cptr++]) != -1) { igraph_vector_int_t *neis=igraph_adjlist_get(adjlist, next); long int j, nn=igraph_vector_int_size(neis); for (j=0; j<nn; j++) { long int nei=(long int) VECTOR(*neis)[j]; if (VECTOR(*leaveout)[nei] != *mark) { igraph_vector_push_back(sorter, nei); VECTOR(*leaveout)[nei] = *mark; } } } igraph_vector_sort(sorter); UPDATEMARK(); /* Add it to the list of separators, if it is new */ if (igraph_i_separators_newsep(separators, sorter)) { igraph_vector_t *newc=igraph_Calloc(1, igraph_vector_t); if (!newc) { IGRAPH_ERROR("Cannot calculate minimal separators", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, newc); igraph_vector_copy(newc, sorter); IGRAPH_FINALLY(igraph_vector_destroy, newc); IGRAPH_CHECK(igraph_vector_ptr_push_back(separators, newc)); IGRAPH_FINALLY_CLEAN(2); } } /* while cptr < complen */ return 0; }
int cliques_load_unordered_maximal_cliques_list(cliques *c, const char *path) { FILE *input; igraph_vector_t *k_clique_v; int size, node_id; int max_size=0,cur_size=0; if (c == NULL || path == NULL) return -1; if ((input = fopen(path, "r")) == NULL) return -2; k_clique_v = (igraph_vector_t*) malloc(sizeof (igraph_vector_t)); igraph_vector_init(k_clique_v, 0); // read the file and compute the maximum size // of the cliques while (fscanf(input, "%i", &node_id) != EOF) { if (node_id == -1){ if(cur_size > max_size) max_size = cur_size; cur_size=0; } else cur_size++; } // initialize cliques structure internal vectors // according to the size of the maximum clique if((cliques_init_member_vectors(c, max_size)) < 0) return -3; // reset the file position indicator to the beginning of the file fseek(input, 0L, SEEK_SET); // load maximal cliques from the file while (fscanf(input, "%i", &node_id) != EOF) { if (node_id != -1){ igraph_vector_push_back(k_clique_v, node_id); }else { size = igraph_vector_size(k_clique_v); igraph_vector_sort(k_clique_v); igraph_vector_ptr_push_back(VECTOR(c->maximal_cliques_v_ptr)[size], k_clique_v); k_clique_v = (igraph_vector_t*) malloc(sizeof (igraph_vector_t)); igraph_vector_init(k_clique_v, 0); } } cliques_order_cliques_by_decreasing_k(c, NULL); igraph_vector_destroy(k_clique_v); return 0; }
int igraph_dfsd(const igraph_t *graph, igraph_integer_t root, igraph_neimode_t mode, igraph_bool_t unreachable, igraph_vector_t *order, igraph_vector_t *order_out, igraph_vector_t *father, igraph_vector_t *dist, igraph_dfshandler_t *in_callback, igraph_dfshandler_t *out_callback, void *extra) { long int no_of_nodes=igraph_vcount(graph); igraph_lazy_adjlist_t adjlist; igraph_stack_t stack; igraph_vector_char_t added; igraph_vector_long_t nptr; long int actroot; long int act_rank=0; long int rank_out=0; long int act_dist=0; if (root < 0 || root >= no_of_nodes) { IGRAPH_ERROR("Invalid root vertex for DFS", IGRAPH_EINVAL); } if (mode != IGRAPH_OUT && mode != IGRAPH_IN && mode != IGRAPH_ALL) { IGRAPH_ERROR("Invalid mode argument", IGRAPH_EINVMODE); } if (!igraph_is_directed(graph)) { mode=IGRAPH_ALL; } IGRAPH_CHECK(igraph_vector_char_init(&added, no_of_nodes)); IGRAPH_FINALLY(igraph_vector_char_destroy, &added); IGRAPH_CHECK(igraph_stack_init(&stack, 100)); IGRAPH_FINALLY(igraph_stack_destroy, &stack); IGRAPH_CHECK(igraph_lazy_adjlist_init(graph, &adjlist, mode, /*simplify=*/ 0)); IGRAPH_FINALLY(igraph_lazy_adjlist_destroy, &adjlist); IGRAPH_CHECK(igraph_vector_long_init(&nptr, no_of_nodes)); IGRAPH_FINALLY(igraph_vector_long_destroy, &nptr); # define FREE_ALL() do { \ igraph_vector_long_destroy(&nptr); \ igraph_lazy_adjlist_destroy(&adjlist); \ igraph_stack_destroy(&stack); \ igraph_vector_char_destroy(&added); \ IGRAPH_FINALLY_CLEAN(4); } while (0) /* Resize result vectors and fill them with IGRAPH_NAN */ # define VINIT(v) if (v) { \ igraph_vector_resize(v, no_of_nodes); \ igraph_vector_fill(v, IGRAPH_NAN); } VINIT(order); VINIT(order_out); VINIT(father); VINIT(dist); # undef VINIT IGRAPH_CHECK(igraph_stack_push(&stack, root)); VECTOR(added)[(long int)root] = 1; if (father) { VECTOR(*father)[(long int)root] = -1; } if (order) { VECTOR(*order)[act_rank++] = root; } if (dist) { VECTOR(*dist)[(long int)root] = 0; } if (in_callback) { igraph_bool_t terminate=in_callback(graph, root, 0, extra); if (terminate) { FREE_ALL(); return 0; } } for (actroot=0; actroot<no_of_nodes; actroot++) { /* 'root' first, then all other vertices */ if (igraph_stack_empty(&stack)) { if (!unreachable) { break; } if (VECTOR(added)[actroot]) { continue; } IGRAPH_CHECK(igraph_stack_push(&stack, actroot)); VECTOR(added)[actroot] = 1; if (father) { VECTOR(*father)[actroot] = -1; } if (order) { VECTOR(*order)[act_rank++] = actroot; } if (dist) { VECTOR(*dist)[actroot] = 0; } if (in_callback) { igraph_bool_t terminate=in_callback(graph, (igraph_integer_t) actroot, 0, extra); if (terminate) { FREE_ALL(); return 0; } } } while (!igraph_stack_empty(&stack)) { long int actvect=(long int) igraph_stack_top(&stack); igraph_vector_t *neis=igraph_lazy_adjlist_get(&adjlist, (igraph_integer_t) actvect); long int n=igraph_vector_size(neis); long int *ptr=igraph_vector_long_e_ptr(&nptr, actvect); igraph_vector_sort(neis); /* Search for a neighbor that was not yet visited */ igraph_bool_t any=0; long int nei; while (!any && (*ptr) <n) { nei=(long int) VECTOR(*neis)[(*ptr)]; any=!VECTOR(added)[nei]; (*ptr) ++; } if (any) { /* There is such a neighbor, add it */ IGRAPH_CHECK(igraph_stack_push(&stack, nei)); VECTOR(added)[nei] = 1; if (father) { VECTOR(*father)[ nei ] = actvect; } if (order) { VECTOR(*order)[act_rank++] = nei; } act_dist++; if (dist) { VECTOR(*dist)[nei] = act_dist; } if (in_callback) { igraph_bool_t terminate=in_callback(graph, (igraph_integer_t) nei, (igraph_integer_t) act_dist, extra); if (terminate) { FREE_ALL(); return 0; } } } else { /* There is no such neighbor, finished with the subtree */ igraph_stack_pop(&stack); if (order_out) { VECTOR(*order_out)[rank_out++] = actvect; } act_dist--; if (out_callback) { igraph_bool_t terminate=out_callback(graph, (igraph_integer_t) actvect, (igraph_integer_t) act_dist, extra); if (terminate) { FREE_ALL(); return 0; } } } } } FREE_ALL(); # undef FREE_ALL return 0; }
/** * \ingroup communities * \function igraph_i_community_multilevel_step * \brief Performs a single step of the multi-level modularity optimization method * * This function implements a single step of the multi-level modularity optimization * algorithm for finding community structure, see VD Blondel, J-L Guillaume, * R Lambiotte and E Lefebvre: Fast unfolding of community hierarchies in large * networks, http://arxiv.org/abs/0803.0476 for the details. * * This function was contributed by Tom Gregorovic. * * \param graph The input graph. It must be an undirected graph. * \param weights Numeric vector containing edge weights. If \c NULL, every edge * has equal weight. The weights are expected to be non-negative. * \param membership The membership vector, the result is returned here. * For each vertex it gives the ID of its community. * \param modularity The modularity of the partition is returned here. * \c NULL means that the modularity is not needed. * \return Error code. * * Time complexity: in average near linear on sparse graphs. */ int igraph_i_community_multilevel_step(igraph_t *graph, igraph_vector_t *weights, igraph_vector_t *membership, igraph_real_t *modularity) { long int i, j; long int vcount = igraph_vcount(graph); long int ecount = igraph_ecount(graph); igraph_integer_t ffrom, fto; igraph_real_t q, pass_q; int pass; igraph_bool_t changed = 0; igraph_vector_t links_community; igraph_vector_t links_weight; igraph_vector_t edges; igraph_vector_t temp_membership; igraph_i_multilevel_community_list communities; /* Initial sanity checks on the input parameters */ if (igraph_is_directed(graph)) { IGRAPH_ERROR("multi-level community detection works for undirected graphs only", IGRAPH_UNIMPLEMENTED); } if (igraph_vector_size(weights) < igraph_ecount(graph)) IGRAPH_ERROR("multi-level community detection: weight vector too short", IGRAPH_EINVAL); if (igraph_vector_any_smaller(weights, 0)) IGRAPH_ERROR("weights must be positive", IGRAPH_EINVAL); /* Initialize data structures */ IGRAPH_VECTOR_INIT_FINALLY(&links_community, 0); IGRAPH_VECTOR_INIT_FINALLY(&links_weight, 0); IGRAPH_VECTOR_INIT_FINALLY(&edges, 0); IGRAPH_VECTOR_INIT_FINALLY(&temp_membership, vcount); IGRAPH_CHECK(igraph_vector_resize(membership, vcount)); /* Initialize list of communities from graph vertices */ communities.vertices_no = vcount; communities.communities_no = vcount; communities.weights = weights; communities.weight_sum = 2 * igraph_vector_sum(weights); communities.membership = membership; communities.item = igraph_Calloc(vcount, igraph_i_multilevel_community); if (communities.item == 0) { IGRAPH_ERROR("multi-level community structure detection failed", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, communities.item); /* Still initializing the communities data structure */ for (i=0; i < vcount; i++) { VECTOR(*communities.membership)[i] = i; communities.item[i].size = 1; communities.item[i].weight_inside = 0; communities.item[i].weight_all = 0; } /* Some more initialization :) */ for (i = 0; i < ecount; i++) { igraph_real_t weight = 1; igraph_edge(graph, (igraph_integer_t) i, &ffrom, &fto); weight = VECTOR(*weights)[i]; communities.item[(long int) ffrom].weight_all += weight; communities.item[(long int) fto].weight_all += weight; if (ffrom == fto) communities.item[(long int) ffrom].weight_inside += 2*weight; } q = igraph_i_multilevel_community_modularity(&communities); pass = 1; do { /* Pass begin */ long int temp_communities_no = communities.communities_no; pass_q = q; changed = 0; /* Save the current membership, it will be restored in case of worse result */ IGRAPH_CHECK(igraph_vector_update(&temp_membership, communities.membership)); for (i = 0; i < vcount; i++) { /* Exclude vertex from its current community */ igraph_real_t weight_all = 0; igraph_real_t weight_inside = 0; igraph_real_t weight_loop = 0; igraph_real_t max_q_gain = 0; igraph_real_t max_weight; long int old_id, new_id, n; igraph_i_multilevel_community_links(graph, &communities, (igraph_integer_t) i, &edges, &weight_all, &weight_inside, &weight_loop, &links_community, &links_weight); old_id = (long int)VECTOR(*(communities.membership))[i]; new_id = old_id; /* Update old community */ igraph_vector_set(communities.membership, i, -1); communities.item[old_id].size--; if (communities.item[old_id].size == 0) {communities.communities_no--;} communities.item[old_id].weight_all -= weight_all; communities.item[old_id].weight_inside -= 2*weight_inside + weight_loop; /* debug("Remove %ld all: %lf Inside: %lf\n", i, -weight_all, -2*weight_inside + weight_loop); */ /* Find new community to join with the best modification gain */ max_q_gain = 0; max_weight = weight_inside; n = igraph_vector_size(&links_community); igraph_vector_sort(&links_community); for (j = 0; j < n; j++) { long int c = (long int) VECTOR(links_community)[j]; igraph_real_t w = VECTOR(links_weight)[j]; igraph_real_t q_gain = igraph_i_multilevel_community_modularity_gain(&communities, (igraph_integer_t) c, (igraph_integer_t) i, weight_all, w); /* debug("Link %ld -> %ld weight: %lf gain: %lf\n", i, c, (double) w, (double) q_gain); */ if (q_gain > max_q_gain) { new_id = c; max_q_gain = q_gain; max_weight = w; } } /* debug("Added vertex %ld to community %ld (gain %lf).\n", i, new_id, (double) max_q_gain); */ /* Add vertex to "new" community and update it */ igraph_vector_set(communities.membership, i, new_id); if (communities.item[new_id].size == 0) {communities.communities_no++;} communities.item[new_id].size++; communities.item[new_id].weight_all += weight_all; communities.item[new_id].weight_inside += 2*max_weight + weight_loop; if (new_id != old_id) { changed++; } } q = igraph_i_multilevel_community_modularity(&communities); if (changed && (q > pass_q)) { /* debug("Pass %d (changed: %d) Communities: %ld Modularity from %lf to %lf\n", pass, changed, communities.communities_no, (double) pass_q, (double) q); */ pass++; } else { /* No changes or the modularity became worse, restore last membership */ IGRAPH_CHECK(igraph_vector_update(communities.membership, &temp_membership)); communities.communities_no = temp_communities_no; break; } IGRAPH_ALLOW_INTERRUPTION(); } while (changed && (q > pass_q)); /* Pass end */ if (modularity) { *modularity = q; } /* debug("Result Communities: %ld Modularity: %lf\n", communities.communities_no, (double) q); */ IGRAPH_CHECK(igraph_reindex_membership(membership, 0)); /* Shrink the nodes of the graph according to the present community structure * and simplify the resulting graph */ /* TODO: check if we really need to copy temp_membership */ IGRAPH_CHECK(igraph_vector_update(&temp_membership, membership)); IGRAPH_CHECK(igraph_i_multilevel_shrink(graph, &temp_membership)); igraph_vector_destroy(&temp_membership); IGRAPH_FINALLY_CLEAN(1); /* Update edge weights after shrinking and simplification */ /* Here we reuse the edges vector as we don't need the previous contents anymore */ /* TODO: can we use igraph_simplify here? */ IGRAPH_CHECK(igraph_i_multilevel_simplify_multiple(graph, &edges)); /* We reuse the links_weight vector to store the old edge weights */ IGRAPH_CHECK(igraph_vector_update(&links_weight, weights)); igraph_vector_fill(weights, 0); for (i = 0; i < ecount; i++) { VECTOR(*weights)[(long int)VECTOR(edges)[i]] += VECTOR(links_weight)[i]; } igraph_free(communities.item); igraph_vector_destroy(&links_community); igraph_vector_destroy(&links_weight); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(4); return 0; }
int main() { igraph_real_t d; igraph_vector_t u, v; int ret; long int i, k, n; /******************************** * Example usage ********************************/ /* Sequences with one element. Such sequences are trivially permuted. * The result of any Fisher-Yates shuffle on a sequence with one element * must be the original sequence itself. */ n = 1; igraph_vector_init(&v, n); igraph_rng_seed(igraph_rng_default(), time(0)); k = R_INTEGER(-1000, 1000); VECTOR(v)[0] = k; igraph_vector_shuffle(&v); if (VECTOR(v)[0] != k) { return 1; } d = R_UNIF(-1000.0, 1000.0); VECTOR(v)[0] = d; igraph_vector_shuffle(&v); if (VECTOR(v)[0] != d) { return 2; } igraph_vector_destroy(&v); /* Sequences with multiple elements. A Fisher-Yates shuffle of a sequence S * is a random permutation \pi(S) of S. Thus \pi(S) must have the same * length and elements as the original sequence S. A major difference between * S and its random permutation \pi(S) is that the order in which elements * appear in \pi(S) is probably different from how elements are ordered in S. * If S has length n = 1, then both \pi(S) and S are equivalent sequences in * that \pi(S) is merely S and no permutation has taken place. If S has * length n > 1, then there are n! possible permutations of S. Assume that * each such permutation is equally likely to appear as a result of the * Fisher-Yates shuffle. As n increases, the probability that S is different * from \pi(S) also increases. We have a probability of 1 / n! that S and * \pi(S) are equivalent sequences. */ n = 100; igraph_vector_init(&u, n); igraph_vector_init(&v, n); for (i = 0; i < n; i++) { k = R_INTEGER(-1000, 1000); VECTOR(u)[i] = k; VECTOR(v)[i] = k; } igraph_vector_shuffle(&v); /* must have same length */ if (igraph_vector_size(&v) != n) { return 3; } if (igraph_vector_size(&u) != igraph_vector_size(&v)) { return 4; } /* must have same elements */ igraph_vector_sort(&u); igraph_vector_sort(&v); if (!igraph_vector_all_e(&u, &v)) { return 5; } igraph_vector_destroy(&u); igraph_vector_destroy(&v); /* empty sequence */ igraph_vector_init(&v, 0); ret = igraph_vector_shuffle(&v); igraph_vector_destroy(&v); return ret == 0 ? 0 : 6; }
void igraph_adjlist_sort(igraph_adjlist_t *al) { long int i; for (i=0; i<al->length; i++) igraph_vector_sort(&al->adjs[i]); }
int igraph_i_minimum_spanning_tree_unweighted(const igraph_t* graph, igraph_vector_t* res) { long int no_of_nodes=igraph_vcount(graph); long int no_of_edges=igraph_ecount(graph); char *already_added; char *added_edges; igraph_dqueue_t q=IGRAPH_DQUEUE_NULL; igraph_vector_t tmp=IGRAPH_VECTOR_NULL; long int i, j; igraph_vector_clear(res); added_edges=igraph_Calloc(no_of_edges, char); if (added_edges==0) { IGRAPH_ERROR("unweighted spanning tree failed", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, added_edges); already_added=igraph_Calloc(no_of_nodes, char); if (already_added==0) { IGRAPH_ERROR("unweighted spanning tree failed", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, already_added); IGRAPH_VECTOR_INIT_FINALLY(&tmp, 0); IGRAPH_DQUEUE_INIT_FINALLY(&q, 100); for (i=0; i<no_of_nodes; i++) { if (already_added[i]>0) { continue; } IGRAPH_ALLOW_INTERRUPTION(); already_added[i]=1; IGRAPH_CHECK(igraph_dqueue_push(&q, i)); while (! igraph_dqueue_empty(&q)) { long int act_node=(long int) igraph_dqueue_pop(&q); IGRAPH_CHECK(igraph_incident(graph, &tmp, (igraph_integer_t) act_node, IGRAPH_ALL)); igraph_vector_sort(&tmp); for (j=0; j<igraph_vector_size(&tmp); j++) { long int edge=(long int) VECTOR(tmp)[j]; if (added_edges[edge]==0) { igraph_integer_t from, to; igraph_edge(graph, (igraph_integer_t) edge, &from, &to); if (act_node==to) { to=from; } if (already_added[(long int) to]==0) { already_added[(long int) to]=1; added_edges[edge]=1; IGRAPH_CHECK(igraph_vector_push_back(res, edge)); IGRAPH_CHECK(igraph_dqueue_push(&q, to)); } } } } } igraph_dqueue_destroy(&q); igraph_Free(already_added); igraph_vector_destroy(&tmp); igraph_Free(added_edges); IGRAPH_FINALLY_CLEAN(4); return IGRAPH_SUCCESS; }
int check_multi() { igraph_t g; igraph_vector_t vec; igraph_vector_t eids, eids2; int ret; long int i; igraph_real_t q1[] = { 0,1, 0,1 }; igraph_real_t q2[] = { 0,1, 0,1, 0,1 }; igraph_real_t q3[] = { 1,0, 3,4, 1,0, 0,1, 3,4, 0,1 }; igraph_vector_init(&eids, 0); /*********************************/ igraph_small(&g, /*n=*/ 10, /*directed=*/ 1, 0,1, 0,1, 1,0, 1,2, 3,4, 3,4, 3,4, 3,5, 3,7, 9,8, -1); igraph_vector_view(&vec, q1, sizeof(q1) / sizeof(igraph_real_t)); igraph_get_eids_multi(&g, &eids, &vec, 0, /*directed=*/ 1, /*error=*/ 1); igraph_vector_sort(&eids); print_vector(&eids, stdout); igraph_vector_view(&vec, q2, sizeof(q2) / sizeof(igraph_real_t)); igraph_get_eids_multi(&g, &eids, &vec, 0, /*directed=*/ 0, /*error=*/ 1); igraph_vector_sort(&eids); print_vector(&eids, stdout); igraph_vector_view(&vec, q2, sizeof(q2) / sizeof(igraph_real_t)); igraph_set_error_handler(igraph_error_handler_ignore); ret=igraph_get_eids_multi(&g, &eids, &vec, 0, /*directed=*/ 1, /*error=*/1); if (ret != IGRAPH_EINVAL) { return 1; } igraph_set_error_handler(igraph_error_handler_abort); igraph_destroy(&g); /*********************************/ /*********************************/ igraph_small(&g, /*n=*/10, /*directed=*/0, 0,1, 1,0, 0,1, 3,4, 3,4, 5,4, 9,8, -1); igraph_vector_view(&vec, q1, sizeof(q1) / sizeof(igraph_real_t)); igraph_get_eids_multi(&g, &eids, &vec, 0, /*directed=*/1, /*error=*/ 1); igraph_vector_sort(&eids); print_vector(&eids, stdout); igraph_vector_view(&vec, q3, sizeof(q3) / sizeof(igraph_real_t)); igraph_set_error_handler(igraph_error_handler_ignore); ret=igraph_get_eids_multi(&g, &eids, &vec, 0, /*directed=*/0, /*error=*/ 1); if (ret != IGRAPH_EINVAL) { return 2; } igraph_set_error_handler(igraph_error_handler_abort); igraph_destroy(&g); /*********************************/ igraph_vector_destroy(&eids); /*********************************/ /* Speed tests */ #define NODES 10000 igraph_barabasi_game(&g, /*n=*/ NODES, /*power=*/ 1.0, /*m=*/ 3, /*outseq=*/ 0, /*outpref=*/ 0, /*A=*/ 1, /*directed=*/ 1, IGRAPH_BARABASI_BAG, /*start_from=*/ 0); igraph_simplify(&g, /*multiple=*/ 1, /*loops=*/ 0, /*edge_comb=*/ 0); igraph_vector_init(&eids, NODES/2); igraph_random_sample(&eids, 0, igraph_ecount(&g)-1, NODES/2); igraph_vector_init(&vec, NODES); for (i=0; i<NODES/2; i++) { VECTOR(vec)[2*i] = IGRAPH_FROM(&g, VECTOR(eids)[i]); VECTOR(vec)[2*i+1] = IGRAPH_TO(&g, VECTOR(eids)[i]); } igraph_vector_init(&eids2, 0); igraph_get_eids_multi(&g, &eids2, &vec, 0, /*directed=*/ 1, /*error=*/ 1); if (!igraph_vector_all_e(&eids, &eids2)) { return 3; } /**/ for (i=0; i<NODES/2; i++) { VECTOR(vec)[2*i] = IGRAPH_TO(&g, VECTOR(eids)[i]); VECTOR(vec)[2*i+1] = IGRAPH_FROM(&g, VECTOR(eids)[i]); } igraph_get_eids_multi(&g, &eids2, &vec, 0, /*directed=*/ 0, /*error=*/ 1); if (!igraph_vector_all_e(&eids, &eids2)) { return 4; } igraph_vector_destroy(&eids); igraph_vector_destroy(&eids2); igraph_vector_destroy(&vec); igraph_destroy(&g); /*********************************/ return 0; }