int main() { igraph_t g; int ret; /* empty directed graph, zero vertices */ igraph_empty(&g, 0, 1); if (igraph_vcount(&g) != 0) { return 1; } if (igraph_ecount(&g) != 0) { return 2; } igraph_destroy(&g); /* empty undirected graph, zero vertices */ igraph_empty(&g, 0, 0); if (igraph_vcount(&g) != 0) { return 3; } if (igraph_ecount(&g) != 0) { return 4; } igraph_destroy(&g); /* empty directed graph, 20 vertices */ igraph_empty(&g, 20, 1); if (igraph_vcount(&g) != 20) { return 5; } if (igraph_ecount(&g) != 0) { return 6; } igraph_destroy(&g); /* empty undirected graph, 30 vertices */ igraph_empty(&g, 30, 0); if (igraph_vcount(&g) != 30) { return 7; } if (igraph_ecount(&g) != 0) { return 8; } igraph_destroy(&g); /* error: negative number of vertices */ igraph_set_error_handler(igraph_error_handler_ignore); ret=igraph_empty(&g, -1, 0); if (ret != IGRAPH_EINVAL) { return 9; } return 0; }
static void barabasi_game(igraph_t *graph, int population, int param, bool isDirected) { vector<double> p (2*param+1, isDirected); vector<int> id; int i, j, from, to; igraph_empty(graph, population, isDirected); for (i = 0; i < 2*param+1; i++) { for (j = i+1; j < 2*param+1; j++) { from = j; to = i; igraph_add_edge (graph, from, to); p[to]++; if (!isDirected) p[from]++; } } int k = 0; for (i = 0; i < 2*param+1; i++) k += p[i]; fprintf (stderr, " awawa %lf\n", k/(double)(2*param+1)); for (; i < population; i++) { Statistic::sample(p, param, id); p.push_back(isDirected); for (j = 0; j < param; j++) { from = i; to = id[j]; igraph_add_edge (graph, from, to); p[to]++; if (!isDirected) p[from]++; } } k = 0; for (i = 0; i < population; i++) k += p[i]; }
int main() { igraph_t g; igraph_vector_t v, weights; long int i; igraph_real_t value; igraph_arpack_options_t options; igraph_star(&g, 100, IGRAPH_STAR_UNDIRECTED, 0); igraph_arpack_options_init(&options); igraph_vector_init(&v, 0); igraph_eigenvector_centrality(&g, &v, &value, /*directed=*/ 0, /*scale=*/0, /*weights=*/0, &options); if (options.info != 0) { return 1; } for (i=0; i<igraph_vector_size(&v); i++) { printf(" %.3f", fabs(VECTOR(v)[i])); } printf("\n"); igraph_destroy(&g); /* Special cases: check for empty graph */ igraph_empty(&g, 10, 0); igraph_eigenvector_centrality(&g, &v, &value, 0, 0, 0, &options); if (value != 0.0) { return 1; } for (i=0; i<igraph_vector_size(&v); i++) { printf(" %.2f", fabs(VECTOR(v)[i])); } printf("\n"); igraph_destroy(&g); /* Special cases: check for full graph, zero weights */ igraph_full(&g, 10, 0, 0); igraph_vector_init(&weights, 45); igraph_vector_fill(&weights, 0); igraph_eigenvector_centrality(&g, &v, &value, 0, 0, &weights, &options); igraph_vector_destroy(&weights); if (value != 0.0) { return 2; } for (i=0; i<igraph_vector_size(&v); i++) { printf(" %.2f", fabs(VECTOR(v)[i])); } printf("\n"); igraph_destroy(&g); igraph_vector_destroy(&v); return 0; }
/* Erdos-Renyi : G(n,M) */ igraph_t *ggen_generate_erdos_gnm(gsl_rng *r, unsigned long n, unsigned long m) { igraph_matrix_t adj; igraph_t *g = NULL; int err; unsigned long i,j; unsigned long added_edges = 0; ggen_error_start_stack(); if(r == NULL) GGEN_SET_ERRNO(GGEN_EINVAL); if(m > (n*(n-1)/2)) GGEN_SET_ERRNO(GGEN_EINVAL); g = malloc(sizeof(igraph_t)); GGEN_CHECK_ALLOC(g); GGEN_FINALLY3(free,g,1); if(m == 0 || n <= 1) { GGEN_CHECK_IGRAPH(igraph_empty(g,n,1)); goto end; } if(m == (n*(n-1))/2) { GGEN_CHECK_IGRAPH(igraph_full_citation(g,n,1)); goto end; } GGEN_CHECK_IGRAPH(igraph_matrix_init(&adj,n,n)); GGEN_FINALLY(igraph_matrix_destroy,&adj); igraph_matrix_null(&adj); while(added_edges < m) { GGEN_CHECK_GSL_DO(i = gsl_rng_uniform_int(r,n)); GGEN_CHECK_GSL_DO(j = gsl_rng_uniform_int(r,n)); if(i < j && igraph_matrix_e(&adj,i,j) == 0) { igraph_matrix_set(&adj,i,j,1); added_edges++; } } GGEN_CHECK_IGRAPH(igraph_adjacency(g,&adj,IGRAPH_ADJ_DIRECTED)); end: ggen_error_clean(1); return g; ggen_error_label: return NULL; }
VALUE cIGraph_alloc(VALUE klass){ igraph_t *graph = malloc(sizeof(igraph_t)); VALUE obj; igraph_empty(graph, 0, 1); obj = Data_Wrap_Struct(klass, cIGraph_mark, cIGraph_free, graph); return obj; }
int main() { igraph_t g; igraph_vector_t v; int ret; /* without edges */ igraph_empty(&g, 5, IGRAPH_DIRECTED); igraph_add_vertices(&g, 2, 0); igraph_add_vertices(&g, 3, 0); igraph_add_vertices(&g, 1, 0); igraph_add_vertices(&g, 4, 0); if (igraph_vcount(&g) != 15) { return 1; } igraph_delete_vertices(&g, igraph_vss_1(2)); if (igraph_vcount(&g) != 14) { return 2; } igraph_destroy(&g); igraph_vector_init(&v, 8); VECTOR(v)[0]=0; VECTOR(v)[1]=1; VECTOR(v)[2]=1; VECTOR(v)[3]=2; VECTOR(v)[4]=2; VECTOR(v)[5]=3; VECTOR(v)[6]=2; VECTOR(v)[7]=2; igraph_create(&g, &v, 0, 0); igraph_vector_destroy(&v); /* resize vector */ igraph_delete_vertices(&g, igraph_vss_1(2)); if (igraph_vcount(&g) != 3) { return 3; } if (igraph_ecount(&g) != 1) { return 4; } /* error test */ igraph_set_error_handler(igraph_error_handler_ignore); ret=igraph_delete_vertices(&g, igraph_vss_1(3)); if (ret != IGRAPH_EINVVID) { return 5; } igraph_destroy(&g); return 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; }
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 GraphRepresentation::buildIGraphTopology() { int source_vertex_id, destination_vertex_id; igraph_i_set_attribute_table(&igraph_cattribute_table); igraph_empty(&igraph, 0, true); //cout << "iGraph: number of nodes: " << dm->number_of_nodes << endl; //cout << "iGraph: number number_of_connections nodes: " << dm->number_of_connections << endl; for (int i = 0; i < dm->network_nodes.size(); i++) { NetworkNode *nn = dm->network_nodes[i]; for (int j = 0; j < nn->connections.size(); j++) { NetworkConnection *nc = nn->connections[j]; map <string, int>::iterator index_it; /*find that node - if exists*/ index_it = reverse_node_index.find(nc->src_label); /*check if the source node exists in the reverse index*/ if (index_it == reverse_node_index.end()) { /*it does not exist...add it*/ source_vertex_id = igraph_vcount(&igraph); igraph_add_vertices(&igraph, 1, 0); reverse_node_index.insert(pair<string, int>(nc->src_label, source_vertex_id)); igraph_cattribute_VAS_set(&igraph, "NODEID", source_vertex_id, nc->src_label.c_str()); //cout << "added node " << nc->src_label << " in the igraph" << endl; } else { source_vertex_id = (*index_it).second; } index_it = reverse_node_index.find(nc->dst_label); /*check if the destination node exists in the reverse index*/ if (index_it == reverse_node_index.end()) { /*it does not exist...add it*/ destination_vertex_id = igraph_vcount(&igraph); igraph_add_vertices(&igraph, 1, 0); reverse_node_index.insert(pair<string, int>(nc->dst_label, destination_vertex_id)); igraph_cattribute_VAS_set(&igraph, "NODEID", destination_vertex_id, nc->dst_label.c_str()); //cout << "added node " << nc->dst_label << " in the igraph" << endl; } else { destination_vertex_id = (*index_it).second; } /*add an edge in the graph*/ igraph_add_edge(&igraph, source_vertex_id, destination_vertex_id); igraph_cattribute_EAS_set(&igraph, "LID", igraph_ecount(&igraph) - 1, nc->LID.to_string().c_str()); reverse_edge_index.insert(pair<string, int>(nc->LID.to_string(), igraph_ecount(&igraph) - 1)); } } for (int i = 0; i < dm->network_nodes.size(); i++) { NetworkNode *nn = dm->network_nodes[i]; igraph_cattribute_VAS_set(&igraph, "iLID", i, nn->iLid.to_string().c_str()); } }
/* Erdos-Renyi : G(n,p) */ igraph_t *ggen_generate_erdos_gnp(gsl_rng *r, unsigned long n, double p) { igraph_matrix_t m; igraph_t *g = NULL; int err; unsigned long i,j; ggen_error_start_stack(); if(r == NULL) GGEN_SET_ERRNO(GGEN_EINVAL); if(p < 0.0 || p > 1.0) GGEN_SET_ERRNO(GGEN_EINVAL); g = malloc(sizeof(igraph_t)); GGEN_CHECK_ALLOC(g); GGEN_FINALLY3(free,g,1); if(p == 0.0) { GGEN_CHECK_IGRAPH(igraph_empty(g,n,1)); goto end; } if(p == 1.0) { GGEN_CHECK_IGRAPH(igraph_full_citation(g,n,1)); goto end; } GGEN_CHECK_IGRAPH(igraph_matrix_init(&m,n,n)); GGEN_FINALLY(igraph_matrix_destroy,&m); for(i = 0; i < n; i++) for(j = 0; j < n; j++) if(i < j) // coin flipping to determine if we add an edge or not igraph_matrix_set(&m,i,j,gsl_ran_bernoulli(r,p)); else igraph_matrix_set(&m,i,j,0); GGEN_CHECK_IGRAPH(igraph_adjacency(g,&m,IGRAPH_ADJ_DIRECTED)); end: ggen_error_clean(1); return g; ggen_error_label: return NULL; }
int main(int argc, char **argv) { unsigned int i; for (i=0; i<1000; ++i) { igraph_t graph; igraph_vector_t edges; igraph_empty(&graph, 1001, 0); igraph_vector_init(&edges, 2000); igraph_add_edges(&graph, &edges, NULL); igraph_destroy(&graph); igraph_vector_destroy(&edges); } return 0; }
static void SF2ER (igraph_t *graph, int N, int param, double alpha, bool isDirected) { int i, j, k, m; igraph_bool_t areconn; vector<int> p (N, 0); //quantidade de arestas PA int etot = 0, acc; igraph_empty(graph, N, isDirected); for (i = 0; i < 2*param+1; i++) for (j = i+1; j < 2*param+1; j++) { igraph_add_edge (graph, i, j); p[j]++; if (!isDirected) p[i]++; etot += 1+(!isDirected); } for (; i < N; i++) { for (m = param; m > 0; m--) { if (Statistic::unif() < alpha) { //ER do { j = rand()%(N-1); if (j >= i) j++; igraph_are_connected(graph, i, j, &areconn); //printf ("er %d\n", (int)areconn); } while (areconn == 1); igraph_add_edge (graph, i, j); } else { //SF do { k = rand()%(etot-p[i]); //printf ("%d %d %d\n", k, etot, p[i]); acc = 0; for (j = 0; j < N; j++) { if (i == j) continue; if (acc+p[j] >= k) break; acc+=p[j]; } igraph_are_connected(graph, i, j, &areconn); //printf ("sf %d %d %d\n",k, (int)areconn, etot); } while (areconn == 1); igraph_add_edge (graph, i, j); p[j]++; if (!isDirected) p[i]++; etot += 1+(!isDirected); } } } }
int main(int argc,char** argv) { igraph_vector_t *lp; igraph_t g; // all ggen methods should fail on incorrect arguments assert(ggen_analyze_longest_path(NULL) == NULL); // an empty graph as a longest path of zero igraph_empty(&g,10,1); lp = ggen_analyze_longest_path(&g); assert(lp != NULL); assert(igraph_vector_size(lp) == 0); igraph_destroy(&g); igraph_vector_destroy(lp); free((void *)lp); // a full dag as a longest path of containing all vertices igraph_full_citation(&g,10,1); lp = ggen_analyze_longest_path(&g); assert(lp != NULL); assert(igraph_vector_size(lp) == 10); igraph_destroy(&g); igraph_vector_destroy(lp); free((void *)lp); // a wrong graph (not dag) should fail // graph is 0 -> 1 -> 2 and 2 -> 0 igraph_small(&g,10,1,0,1,1,2,2,0,-1); assert(ggen_analyze_longest_path(&g) == NULL); igraph_destroy(&g); // a simple graph should work too // graph is 0 -> 1 -> 2 and 0 -> 2 igraph_small(&g,10,1,0,1,1,2,0,2,-1); lp = ggen_analyze_longest_path(&g); assert(lp != NULL); assert(igraph_vector_size(lp) == 3); igraph_destroy(&g); igraph_vector_destroy(lp); free((void *)lp); return 0; }
igraph_t *ggen_generate_erdos_lbl(gsl_rng *r, unsigned long n, double p, unsigned long nbl) { igraph_t *g = NULL; igraph_matrix_t m; igraph_vector_t layers; unsigned long i,j; int err; ggen_error_start_stack(); if(r == NULL) GGEN_SET_ERRNO(GGEN_EINVAL); if(p < 0.0 || p > 1.0) GGEN_SET_ERRNO(GGEN_EINVAL); if(nbl > n || nbl == 0) GGEN_SET_ERRNO(GGEN_EINVAL); g = malloc(sizeof(igraph_t)); GGEN_CHECK_ALLOC(g); GGEN_FINALLY3(free,g,1); if(p == 0.0) { GGEN_CHECK_IGRAPH(igraph_empty(g,n,1)); goto end; } if(p == 1.0 && nbl == n) { GGEN_CHECK_IGRAPH(igraph_full_citation(g,n,1)); goto end; } GGEN_CHECK_IGRAPH(igraph_matrix_init(&m,n,n)); GGEN_FINALLY(igraph_matrix_destroy,&m); GGEN_CHECK_IGRAPH(igraph_vector_init(&layers,n)); GGEN_FINALLY(igraph_vector_destroy,&layers); // asign to each vertex a layer for(i = 0; i < n; i++) { GGEN_CHECK_GSL_DO(j = gsl_rng_uniform_int(r,nbl)); VECTOR(layers)[i] = j; } // create edges for(i = 0; i < n; i++) for(j = 0; j < n; j++) // if the layer allocation allows the edge, we test for it if(VECTOR(layers)[i]<VECTOR(layers)[j]) igraph_matrix_set(&m,i,j,gsl_ran_bernoulli(r,p)); else igraph_matrix_set(&m,i,j,0); //translate the matrix to a graph GGEN_CHECK_IGRAPH(igraph_adjacency(g,&m,IGRAPH_ADJ_DIRECTED)); end: ggen_error_clean(1); return g; ggen_error_label: return NULL; }
igraph_vector_t *ggen_analyze_lowest_single_ancestor(igraph_t *g) { unsigned long i,v,l,vid,r; int err = 0; igraph_vector_t toposort,itopo; igraph_vector_t *lsa; igraph_t tree; igraph_vs_t vs; igraph_vit_t vit; lca_metadata md; if(g == NULL) return NULL; err = igraph_vector_init(&toposort,igraph_vcount(g)); if(err) return NULL; err = igraph_topological_sorting(g,&toposort,IGRAPH_OUT); if(err) goto d_tp; /* build a reverse index of the toposort */ err = igraph_vector_init(&itopo,igraph_vcount(g)); if(err) goto d_tp; for(i = 0; i < igraph_vcount(g); i++) { v = VECTOR(toposort)[i]; VECTOR(itopo)[v] = i; } err = igraph_empty(&tree,1,IGRAPH_DIRECTED); if(err) goto d_i; lsa = calloc(1,sizeof(igraph_vector_t*)); if(lsa == NULL) goto cleanup; err = igraph_vector_init(lsa,igraph_vcount(g)); if(err) goto f_l; for(v = 1; v < igraph_vcount(g); v++) { vid = VECTOR(toposort)[v]; tree_lca_metadata_init(&tree,&md); tree_lca_preprocessing(&tree,0,&md); /* iterate over parents of v in g * The lsa of a node is the LCA of all its parents in our * special tree. */ igraph_vs_adj(&vs, vid, IGRAPH_IN); igraph_vit_create(g,vs,&vit); l = VECTOR(itopo)[IGRAPH_VIT_GET(vit)]; IGRAPH_VIT_NEXT(vit); for(vit;!IGRAPH_VIT_END(vit); IGRAPH_VIT_NEXT(vit)) { tree_lca_query(&tree,l,VECTOR(itopo)[IGRAPH_VIT_GET(vit)],&r,&md); l = r; } igraph_vit_destroy(&vit); igraph_vs_destroy(&vs); tree_lca_metadata_free(&tree,&md); // update tree err = igraph_add_vertices(&tree,1,NULL); if(err) goto d_l; err = igraph_add_edge(&tree,l,v); if(err) goto d_l; VECTOR(*lsa)[vid] = VECTOR(toposort)[l]; } goto cleanup; d_l: igraph_vector_destroy(lsa); f_l: free(lsa); lsa = NULL; cleanup: igraph_destroy(&tree); d_i: igraph_vector_destroy(&itopo); d_tp: igraph_vector_destroy(&toposort); return lsa; }
igraph_vector_t * ggen_analyze_longest_antichain(igraph_t *g) { /* The following steps are implemented : * - Convert our DAG to a specific bipartite graph B * - solve maximum matching on B * - conver maximum matching to min vectex cover * - convert min vertex cover to antichain on G */ int err; unsigned long i,vg,found,added; igraph_t b,gstar; igraph_vector_t edges,*res = NULL; igraph_vector_t c,s,t,todo,n,next,l,r; igraph_eit_t eit; igraph_es_t es; igraph_integer_t from,to; igraph_vit_t vit; igraph_vs_t vs; igraph_real_t value; if(g == NULL) return NULL; /* before creating the bipartite graph, we need all relations * between any two vertices : the transitive closure of g */ err = igraph_copy(&gstar,g); if(err) return NULL; err = ggen_transform_transitive_closure(&gstar); if(err) goto error; /* Bipartite convertion : let G = (S,C), * we build B = (U,V,E) with * - U = V = S (each vertex is present twice) * - (u,v) \in E iff : * - u \in U * - v \in V * - u < v in C (warning, this means that we take * transitive closure into account, not just the * original edges) * We will also need two additional nodes further in the code. */ vg = igraph_vcount(g); err = igraph_empty(&b,vg*2,1); if(err) goto error; /* id and id+vg will be a vertex in U and its copy in V, * iterate over gstar edges to create edges in b */ err = igraph_vector_init(&edges,igraph_ecount(&gstar)); if(err) goto d_b; igraph_vector_clear(&edges); err = igraph_eit_create(&gstar,igraph_ess_all(IGRAPH_EDGEORDER_ID),&eit); if(err) goto d_edges; for(IGRAPH_EIT_RESET(eit); !IGRAPH_EIT_END(eit); IGRAPH_EIT_NEXT(eit)) { err = igraph_edge(&gstar,IGRAPH_EIT_GET(eit),&from,&to); if(err) { igraph_eit_destroy(&eit); goto d_edges; } to += vg; igraph_vector_push_back(&edges,(igraph_real_t)from); igraph_vector_push_back(&edges,(igraph_real_t)to); } igraph_eit_destroy(&eit); err = igraph_add_edges(&b,&edges,NULL); if(err) goto d_edges; /* maximum matching on b */ igraph_vector_clear(&edges); err = bipartite_maximum_matching(&b,&edges); if(err) goto d_edges; /* Let M be the max matching, and N be E - M * Define T as all unmatched vectices from U as well as all vertices * reachable from those by going left-to-right along N and right-to-left along * M. * Define L = U - T, R = V \inter T * C:= L + R * C is a minimum vertex cover */ err = igraph_vector_init_seq(&n,0,igraph_ecount(&b)-1); if(err) goto d_edges; err = vector_diff(&n,&edges); if(err) goto d_n; err = igraph_vector_init(&c,vg); if(err) goto d_n; igraph_vector_clear(&c); /* matched vertices : S */ err = igraph_vector_init(&s,vg); if(err) goto d_c; igraph_vector_clear(&s); for(i = 0; i < igraph_vector_size(&edges); i++) { err = igraph_edge(&b,VECTOR(edges)[i],&from,&to); if(err) goto d_s; igraph_vector_push_back(&s,from); } /* we may have inserted the same vertex multiple times */ err = vector_uniq(&s); if(err) goto d_s; /* unmatched */ err = igraph_vector_init_seq(&t,0,vg-1); if(err) goto d_s; err = vector_diff(&t,&s); if(err) goto d_t; /* alternating paths */ err = igraph_vector_copy(&todo,&t); if(err) goto d_t; err = igraph_vector_init(&next,vg); if(err) goto d_todo; igraph_vector_clear(&next); do { vector_uniq(&todo); added = 0; for(i = 0; i < igraph_vector_size(&todo); i++) { if(VECTOR(todo)[i] < vg) { /* scan edges */ err = igraph_es_adj(&es,VECTOR(todo)[i],IGRAPH_OUT); if(err) goto d_next; err = igraph_eit_create(&b,es,&eit); if(err) { igraph_es_destroy(&es); goto d_next; } for(IGRAPH_EIT_RESET(eit); !IGRAPH_EIT_END(eit); IGRAPH_EIT_NEXT(eit)) { if(igraph_vector_binsearch(&n,IGRAPH_EIT_GET(eit),NULL)) { err = igraph_edge(&b,IGRAPH_EIT_GET(eit),&from,&to); if(err) { igraph_eit_destroy(&eit); igraph_es_destroy(&es); goto d_next; } if(!igraph_vector_binsearch(&t,to,NULL)) { igraph_vector_push_back(&next,to); added = 1; } } } } else { /* scan edges */ err = igraph_es_adj(&es,VECTOR(todo)[i],IGRAPH_IN); if(err) goto d_next; err = igraph_eit_create(&b,es,&eit); if(err) { igraph_es_destroy(&es); goto d_next; } for(IGRAPH_EIT_RESET(eit); !IGRAPH_EIT_END(eit); IGRAPH_EIT_NEXT(eit)) { if(igraph_vector_binsearch(&edges,IGRAPH_EIT_GET(eit),NULL)) { err = igraph_edge(&b,IGRAPH_EIT_GET(eit),&from,&to); if(err) { igraph_eit_destroy(&eit); igraph_es_destroy(&es); goto d_next; } if(!igraph_vector_binsearch(&t,to,NULL)) { igraph_vector_push_back(&next,from); added = 1; } } } } igraph_es_destroy(&es); igraph_eit_destroy(&eit); } igraph_vector_append(&t,&todo); igraph_vector_clear(&todo); igraph_vector_append(&todo,&next); igraph_vector_clear(&next); } while(added); err = igraph_vector_init_seq(&l,0,vg-1); if(err) goto d_t; err = vector_diff(&l,&t); if(err) goto d_l; err = igraph_vector_update(&c,&l); if(err) goto d_l; err = igraph_vector_init(&r,vg); if(err) goto d_l; igraph_vector_clear(&r); /* compute V \inter T */ for(i = 0; i < igraph_vector_size(&t); i++) { if(VECTOR(t)[i] >= vg) igraph_vector_push_back(&r,VECTOR(t)[i]); } igraph_vector_add_constant(&r,(igraph_real_t)-vg); err = vector_union(&c,&r); if(err) goto d_r; /* our antichain is U - C */ res = malloc(sizeof(igraph_vector_t)); if(res == NULL) goto d_r; err = igraph_vector_init_seq(res,0,vg-1); if(err) goto f_res; err = vector_diff(res,&c); if(err) goto d_res; goto ret; d_res: igraph_vector_destroy(res); f_res: free(res); res = NULL; ret: d_r: igraph_vector_destroy(&r); d_l: igraph_vector_destroy(&l); d_next: igraph_vector_destroy(&next); d_todo: igraph_vector_destroy(&todo); d_t: igraph_vector_destroy(&t); d_s: igraph_vector_destroy(&s); d_c: igraph_vector_destroy(&c); d_n: igraph_vector_destroy(&n); d_edges: igraph_vector_destroy(&edges); d_b: igraph_destroy(&b); error: igraph_destroy(&gstar); return res; }
void LayoutBuilder::produce(AbstractPetriNetBuilder *builder){ if(!attrTableAttached){ igraph_i_set_attribute_table(&igraph_cattribute_table); attrTableAttached = true; } size_t V = places.size() + transitions.size(); size_t E = inArcs.size() + outArcs.size(); igraph_t graph; // Create a directed graph igraph_empty(&graph, V, true); // Create vector with all edges igraph_vector_t edges; igraph_vector_init(&edges, E * 2); // Add edges to vector int i = 0; for(ArcIter it = inArcs.begin(); it != inArcs.end(); it++){ VECTOR(edges)[i++] = numberFromName(it->start); VECTOR(edges)[i++] = numberFromName(it->end); } for(ArcIter it = outArcs.begin(); it != outArcs.end(); it++){ VECTOR(edges)[i++] = numberFromName(it->start); VECTOR(edges)[i++] = numberFromName(it->end); } // Add the edges to graph igraph_add_edges(&graph, &edges, 0); // Delete the vector with edges igraph_vector_destroy(&edges); // Arrays to store result in double posx[V]; double posy[V]; // Provide current positions, if they're used at all if(startFromCurrentPositions){ int i = 0; for(PlaceIter it = places.begin(); it != places.end(); it++){ posx[i] = it->x; posy[i] = it->y; igraph_cattribute_VAN_set(&graph, "id", i, i); i++; } for(TransitionIter it = transitions.begin(); it != transitions.end(); it++){ posx[i] = it->x; posy[i] = it->y; igraph_cattribute_VAN_set(&graph, "id", i, i); i++; } } // Decompose the graph, and layout subgraphs induvidually igraph_vector_ptr_t subgraphs; igraph_vector_ptr_init(&subgraphs, 0); igraph_decompose(&graph, &subgraphs, IGRAPH_WEAK, -1, 0); // Offset for places subgraphs double offsetx = 0; double offsety = 0; // Layout, translate and extract results for each subgraph for(int i = 0; i < igraph_vector_ptr_size(&subgraphs); i++){ //Get the subgraph igraph_t* subgraph = (igraph_t*)VECTOR(subgraphs)[i]; // Allocate result matrix igraph_matrix_t sublayout; igraph_matrix_init(&sublayout, 0, 0); // Vertex selector and iterator igraph_vs_t vs; igraph_vit_t vit; // Select all and create iterator igraph_vs_all(&vs); igraph_vit_create(subgraph, vs, &vit); // Initialize sublayout, using original positions if(startFromCurrentPositions){ // Count vertices int vertices = 0; // Iterator over vertices to count them, hacked but it works while(!IGRAPH_VIT_END(vit)){ vertices++; IGRAPH_VIT_NEXT(vit); } //Reset vertex iterator IGRAPH_VIT_RESET(vit); // Resize sublayout igraph_matrix_resize(&sublayout, vertices, 2); // Iterator over vertices while(!IGRAPH_VIT_END(vit)){ int subindex = (int)IGRAPH_VIT_GET(vit); int index = (int)igraph_cattribute_VAN(subgraph, "id", subindex); MATRIX(sublayout, subindex, 0) = posx[index]; MATRIX(sublayout, subindex, 1) = posy[index]; IGRAPH_VIT_NEXT(vit); } //Reset vertex iterator IGRAPH_VIT_RESET(vit); } igraph_layout_kamada_kawai(subgraph, &sublayout, 1000, ((double)V)/4.0, 10, 0.99, V*V, startFromCurrentPositions); // Other layout algorithms with reasonable parameters //igraph_layout_kamada_kawai(subgraph, &sublayout, 1000, ((double)V)/4.0, 10, 0.99, V*V, startFromCurrentPositions); //igraph_layout_grid_fruchterman_reingold(subgraph, &sublayout, 500, V, V*V, 1.5, V*V*V, V*V/4, startFromCurrentPositions); //igraph_layout_fruchterman_reingold(subgraph, &sublayout, 500, V, V*V, 1.5, V*V*V, startFromCurrentPositions, NULL); //igraph_layout_lgl(subgraph, &sublayout, 150, V, V*V, 1.5, V*V*V, sqrt(V), -1); //Find min and max values: double minx = DBL_MAX, miny = DBL_MAX, maxx = -DBL_MAX, maxy = -DBL_MAX; //Iterator over all vertices while(!IGRAPH_VIT_END(vit)){ int subindex = (int)IGRAPH_VIT_GET(vit); double x = MATRIX(sublayout, subindex, 0) * factor; double y = MATRIX(sublayout, subindex, 1) * factor; minx = minx < x ? minx : x; miny = miny < y ? miny : y; maxx = maxx > x ? maxx : x; maxy = maxy > y ? maxy : y; IGRAPH_VIT_NEXT(vit); } //Reset vertex iterator IGRAPH_VIT_RESET(vit); // Compute translation double tx = margin - minx; double ty = margin - miny; // Decide whether to put it below or left of current content if(maxx - minx + offsetx < maxy - miny + offsety){ tx += offsetx; offsetx += maxx - minx + margin; if(offsety < maxy - miny + margin) offsety = maxy - miny + margin; }else{ ty += offsety; offsety += maxy - miny + margin; if(offsetx < maxx - minx + margin) offsetx = maxx - minx + margin; } // Translate and extract results while(!IGRAPH_VIT_END(vit)){ int subindex = (int)IGRAPH_VIT_GET(vit); int index = (int)igraph_cattribute_VAN(subgraph, "id", subindex); double x = MATRIX(sublayout, subindex, 0) * factor; double y = MATRIX(sublayout, subindex, 1) * factor; posx[index] = x + tx; posy[index] = y + ty; IGRAPH_VIT_NEXT(vit); } // Destroy iterator and selector igraph_vit_destroy(&vit); igraph_vs_destroy(&vs); // Destroy the sublayout igraph_matrix_destroy(&sublayout); // Destroy subgraph igraph_destroy(subgraph); free(VECTOR(subgraphs)[i]); } // Remove the attributes igraph_cattribute_remove_v(&graph, "id"); // Destroy the graph igraph_destroy(&graph); // Insert results i = 0; for(PlaceIter it = places.begin(); it != places.end(); it++){ it->x = posx[i]; it->y = posy[i]; i++; } for(TransitionIter it = transitions.begin(); it != transitions.end(); it++){ it->x = posx[i]; it->y = posy[i]; i++; } // Produce variables for(VarIter it = vars.begin(); it != vars.end(); it++) builder->addVariable(it->name, it->initialValue, it->range); for(BoolVarIter it = boolVars.begin(); it != boolVars.end(); it++) builder->addBoolVariable(it->name, it->initialValue); for(PlaceIter it = places.begin(); it != places.end(); it++) builder->addPlace(it->name, it->tokens, it->x, it->y); for(TransitionIter it = transitions.begin(); it != transitions.end(); it++) builder->addTransition(it->name, it->conditions, it->assignments, it->x, it->y); for(ArcIter it = inArcs.begin(); it != inArcs.end(); it++) builder->addInputArc(it->start, it->end, it->weight); for(ArcIter it = outArcs.begin(); it != outArcs.end(); it++) builder->addInputArc(it->start, it->end, it->weight); //Reset builder state (just in case some idoit decides to reuse it! vars.clear(); boolVars.clear(); places.clear(); transitions.clear(); inArcs.clear(); outArcs.clear(); }
TMIgraph::TMIgraph() { igraph_i_set_attribute_table(&igraph_cattribute_table); igraph_empty(&graph, 0, true); }
int igraph_forest_fire_game(igraph_t *graph, igraph_integer_t nodes, igraph_real_t fw_prob, igraph_real_t bw_factor, igraph_integer_t pambs, igraph_bool_t directed) { igraph_vector_long_t visited; long int no_of_nodes=nodes, actnode, i; igraph_vector_t edges; igraph_vector_t *inneis, *outneis; igraph_i_forest_fire_data_t data; igraph_dqueue_t neiq; long int ambs=pambs; igraph_real_t param_geom_out=1-fw_prob; igraph_real_t param_geom_in=1-fw_prob*bw_factor; if (fw_prob < 0) { IGRAPH_ERROR("Forest fire model: 'fw_prob' should be between non-negative", IGRAPH_EINVAL); } if (bw_factor < 0) { IGRAPH_ERROR("Forest fire model: 'bw_factor' should be non-negative", IGRAPH_EINVAL); } if (ambs < 0) { IGRAPH_ERROR("Number of ambassadors ('ambs') should be non-negative", IGRAPH_EINVAL); } if (fw_prob == 0 || ambs == 0) { IGRAPH_WARNING("'fw_prob or ambs is zero, creating empty graph"); IGRAPH_CHECK(igraph_empty(graph, nodes, directed)); return 0; } IGRAPH_VECTOR_INIT_FINALLY(&edges, 0); inneis=igraph_Calloc(no_of_nodes, igraph_vector_t); if (!inneis) { IGRAPH_ERROR("Cannot run forest fire model", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, inneis); outneis=igraph_Calloc(no_of_nodes, igraph_vector_t); if (!outneis) { IGRAPH_ERROR("Cannot run forest fire model", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, outneis); data.inneis=inneis; data.outneis=outneis; data.no_of_nodes=no_of_nodes; IGRAPH_FINALLY(igraph_i_forest_fire_free, &data); for (i=0; i<no_of_nodes; i++) { IGRAPH_CHECK(igraph_vector_init(inneis+i, 0)); IGRAPH_CHECK(igraph_vector_init(outneis+i, 0)); } IGRAPH_CHECK(igraph_vector_long_init(&visited, no_of_nodes)); IGRAPH_FINALLY(igraph_vector_long_destroy, &visited); IGRAPH_DQUEUE_INIT_FINALLY(&neiq, 10); RNG_BEGIN(); #define ADD_EDGE_TO(nei) \ if (VECTOR(visited)[(nei)] != actnode+1) { \ VECTOR(visited)[(nei)] = actnode+1; \ IGRAPH_CHECK(igraph_dqueue_push(&neiq, nei)); \ IGRAPH_CHECK(igraph_vector_push_back(&edges, actnode)); \ IGRAPH_CHECK(igraph_vector_push_back(&edges, nei)); \ IGRAPH_CHECK(igraph_vector_push_back(outneis+actnode, nei)); \ IGRAPH_CHECK(igraph_vector_push_back(inneis+nei, actnode)); \ } IGRAPH_PROGRESS("Forest fire: ", 0.0, NULL); for (actnode=1; actnode < no_of_nodes; actnode++) { IGRAPH_PROGRESS("Forest fire: ", 100.0*actnode/no_of_nodes, NULL); IGRAPH_ALLOW_INTERRUPTION(); /* We don't want to visit the current vertex */ VECTOR(visited)[actnode] = actnode+1; /* Choose ambassador(s) */ for (i=0; i<ambs; i++) { long int a=RNG_INTEGER(0, actnode-1); ADD_EDGE_TO(a); } while (!igraph_dqueue_empty(&neiq)) { long int actamb=(long int) igraph_dqueue_pop(&neiq); igraph_vector_t *outv=outneis+actamb; igraph_vector_t *inv=inneis+actamb; long int no_in=igraph_vector_size(inv); long int no_out=igraph_vector_size(outv); long int neis_out=(long int) RNG_GEOM(param_geom_out); long int neis_in=(long int) RNG_GEOM(param_geom_in); /* outgoing neighbors */ if (neis_out >= no_out) { for (i=0; i<no_out; i++) { long int nei=(long int) VECTOR(*outv)[i]; ADD_EDGE_TO(nei); } } else { long int oleft=no_out; for (i=0; i<neis_out && oleft > 0; ) { long int which=RNG_INTEGER(0, oleft-1); long int nei=(long int) VECTOR(*outv)[which]; VECTOR(*outv)[which] = VECTOR(*outv)[oleft-1]; VECTOR(*outv)[oleft-1] = nei; if (VECTOR(visited)[nei] != actnode+1) { ADD_EDGE_TO(nei); i++; } oleft--; } } /* incoming neighbors */ if (neis_in >= no_in) { for (i=0; i<no_in; i++) { long int nei=(long int) VECTOR(*inv)[i]; ADD_EDGE_TO(nei); } } else { long int ileft=no_in; for (i=0; i<neis_in && ileft > 0; ) { long int which=RNG_INTEGER(0, ileft-1); long int nei=(long int) VECTOR(*inv)[which]; VECTOR(*inv)[which] = VECTOR(*inv)[ileft-1]; VECTOR(*inv)[ileft-1] = nei; if (VECTOR(visited)[nei] != actnode+1) { ADD_EDGE_TO(nei); i++; } ileft--; } } } /* while neiq not empty */ } /* actnode < no_of_nodes */ #undef ADD_EDGE_TO RNG_END(); IGRAPH_PROGRESS("Forest fire: ", 100.0, NULL); igraph_dqueue_destroy(&neiq); igraph_vector_long_destroy(&visited); igraph_i_forest_fire_free(&data); igraph_free(outneis); igraph_free(inneis); IGRAPH_FINALLY_CLEAN(5); IGRAPH_CHECK(igraph_create(graph, &edges, nodes, directed)); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); return 0; }
int ggen_read_graph(igraph_t *g,FILE *input) { Agraph_t *cg; Agnode_t *v; Agedge_t *e; igraph_vector_t edges; igraph_vector_t vertices; int err; unsigned long esize; unsigned long vsize; unsigned long from, to; igraph_integer_t eid; Agsym_t *att; /* read the graph */ cg = agread((void *)input,NULL); if(!cg) return 1; if(!agisdirected(cg)) { error("Input graph is undirected\n"); err = 1; goto error_d; } /* init edge array */ err = igraph_vector_init(&edges,2*agnedges(cg)); if(err) goto error_d; err = igraph_vector_init(&vertices,agnnodes(cg)); if(err) goto error_de; /* init igraph */ igraph_empty(g,agnnodes(cg),1); /* asign id to each vertex */ vsize = 0; for(v = agfstnode(cg); v; v = agnxtnode(cg,v)) VECTOR(vertices)[vsize++] = AGID(v); /* loop through each edge */ esize = 0; for(v = agfstnode(cg); v; v = agnxtnode(cg,v)) { from = find_id(AGID(v),vertices,vsize); for(e = agfstout(cg,v); e; e = agnxtout(cg,e)) { to = find_id(AGID(aghead(e)),vertices,vsize); VECTOR(edges)[esize++] = from; VECTOR(edges)[esize++] = to; } } /* finish the igraph */ err = igraph_add_edges(g,&edges,NULL); if(err) goto error; /* read graph properties */ att = agnxtattr(cg,AGRAPH,NULL); while(att != NULL) { /* copy this attribute to igraph */ SETGAS(g,att->name,agxget(cg,att)); att = agnxtattr(cg,AGRAPH,att); } /* we keep the graph name using a special attribute */ SETGAS(g,GGEN_GRAPH_NAME_ATTR,agnameof(cg)); /* read vertex properties */ att = agnxtattr(cg,AGNODE,NULL); while(att != NULL) { /* iterate over all vertices for this attribute */ for(v = agfstnode(cg); v; v = agnxtnode(cg,v)) { from = find_id(AGID(v),vertices,vsize); SETVAS(g,att->name,from,agxget(v,att)); } att = agnxtattr(cg,AGNODE,att); } /* we keep each vertex name in a special attribute */ for(v = agfstnode(cg); v; v = agnxtnode(cg,v)) { from = find_id(AGID(v),vertices,vsize); SETVAS(g,GGEN_VERTEX_NAME_ATTR,from,agnameof(v)); } /* read edges properties */ att = agnxtattr(cg,AGEDGE,NULL); while(att != NULL) { /* the only way to iterate over all edges is to iterate * over the vertices */ for(v = agfstnode(cg); v; v = agnxtnode(cg,v)) { from = find_id(AGID(v),vertices,vsize); for(e = agfstout(cg,v); e; e = agnxtout(cg,e)) { to = find_id(AGID(aghead(e)),vertices,vsize); igraph_get_eid(g,&eid,from,to,1,0); SETEAS(g,att->name,eid,agxget(e,att)); } } att = agnxtattr(cg,AGEDGE,att); } goto cleanup; error: igraph_destroy(g); cleanup: igraph_vector_destroy(&vertices); error_de: igraph_vector_destroy(&edges); error_d: agclose(cg); return err; }
static void rvine_trees_to_vine(dml_vine_t *vine, igraph_t **trees) { size_t n = vine->dim; size_t *order_inv; gsl_vector_short *B; igraph_integer_t Cea, Ceb; size_t x = 0, x_hat = 0, x_hat_hat = 0; // Initialized to avoid GCC warnings. dml_copula_t *copula = NULL; // Initialized to avoid GCC warnings. igraph_integer_t e; // Edge id. igraph_integer_t a, b, aa, ab, ba, bb; // Vertex id. igraph_t **last_trees = NULL; igraph_t *graph = NULL; gsl_vector_short *Ue, *Ua, *Ub; // Set the number of trees of the vines. vine->trees = n - 1; while (trees[vine->trees - 1] == NULL) vine->trees--; // Nothing to do for vines without trees. if (vine->trees == 0) return; // Selecting a structure for the trees that were truncated. // Is this really necessary? Think a better solution. if (vine->trees != n - 1) { igraph_i_set_attribute_table(&igraph_cattribute_table); last_trees = g_malloc_n(n - 1 - vine->trees, sizeof(igraph_t *)); graph = g_malloc(sizeof(igraph_t)); for (size_t k = vine->trees; k < n - 1; k++) { // Tree index. igraph_empty(graph, n - k, IGRAPH_UNDIRECTED); // Adding all "possible" edges. for (a = 0; a < igraph_vcount(graph) - 1; a++) { for (b = a + 1; b < igraph_vcount(graph); b++) { // Checking the proximity condition. igraph_edge(k <= vine->trees ? trees[k - 1] : last_trees[k - 1 - vine->trees], a, &aa, &ab); igraph_edge(k <= vine->trees ? trees[k - 1] : last_trees[k - 1 - vine->trees], b, &ba, &bb); if (aa == ba || aa == bb || ab == ba || ab == bb) { igraph_add_edge(graph, a, b); igraph_get_eid(graph, &e, a, b, IGRAPH_UNDIRECTED, 1); // Variables "connected" by this edge and conditioned set. Ua = EAP(k <= vine->trees ? trees[k - 1] : last_trees[k - 1 - vine->trees], "Ue", a); Ub = EAP(k <= vine->trees ? trees[k - 1] : last_trees[k - 1 - vine->trees], "Ue", b); Ue = gsl_vector_short_calloc(n); for (size_t i = 0; i < n; i++) { gsl_vector_short_set(Ue, i, gsl_vector_short_get(Ua, i) | gsl_vector_short_get(Ub, i)); if (gsl_vector_short_get(Ua, i) && !gsl_vector_short_get(Ub, i)) { SETEAN(graph, "Cea", e, i + 1); } if (gsl_vector_short_get(Ub, i) && !gsl_vector_short_get(Ua, i)) { SETEAN(graph, "Ceb", e, i + 1); } } SETEAP(graph, "Ue", e, Ue); } } } // Compute the minimum weight spanning tree. last_trees[k - vine->trees] = g_malloc(sizeof(igraph_t)); igraph_minimum_spanning_tree_unweighted(graph, last_trees[k - vine->trees]); igraph_destroy(graph); } } order_inv = g_malloc0_n(n, sizeof(size_t)); B = gsl_vector_short_calloc(n); // for loop in line 2. for (size_t i = 0; i < n - 1; i++) { if (trees[n - i - 2] == NULL) { for (e = 0; e < igraph_ecount(last_trees[n - i - 2 - vine->trees]); e++) { x = EAN(last_trees[n - i - 2 - vine->trees], "Cea", e); x_hat = EAN(last_trees[n - i - 2 - vine->trees], "Ceb", e); if (!gsl_vector_short_get(B, x - 1) && !gsl_vector_short_get(B, x_hat - 1)) { x_hat = 0; copula = NULL; break; } } } else { for (e = 0; e < igraph_ecount(trees[n - i - 2]); e++) { x = EAN(trees[n - i - 2], "Cea", e); x_hat = EAN(trees[n - i - 2], "Ceb", e); if (!gsl_vector_short_get(B, x - 1) && !gsl_vector_short_get(B, x_hat - 1)) { copula = EAP(trees[n - i - 2], "copula", e); break; } } } // Line 4. gsl_vector_short_set(B, x - 1, 1); vine->order[n - i - 1] = x - 1; order_inv[x - 1] = n - i; vine->matrix[i][i] = x; vine->matrix[i + 1][i] = x_hat; vine->copulas[i + 1][i] = copula; // for loop in line 5. for (size_t k = i + 2; k < n; k++) { if (trees[n - k - 1] != NULL) { for (e = 0; e < igraph_ecount(trees[n - k - 1]); e++) { Cea = EAN(trees[n - k - 1], "Cea", e); Ceb = EAN(trees[n - k - 1], "Ceb", e); if (x == Cea) { x_hat_hat = Ceb; if (!gsl_vector_short_get(B, x_hat_hat - 1)) { // The pseudocode of the algorithm does not included // this check. Invalid matrices were generated when // x_hat_hat is set to an index already assigned // to a diagonal entry. copula = EAP(trees[n - k - 1], "copula", e); break; } } else if (x == Ceb) { x_hat_hat = Cea; if (!gsl_vector_short_get(B, x_hat_hat - 1)) { // Ibdem to the previous comment. copula = EAP(trees[n - k - 1], "copula", e); break; } } } vine->matrix[k][i] = x_hat_hat; vine->copulas[k][i] = copula; } } } for (size_t i = 0; i < n; i++) { if (!gsl_vector_short_get(B, i)) { vine->matrix[n - 1][n - 1] = i + 1; vine->order[0] = i; order_inv[i] = 1; break; } } // Reorder the variables. The simulation algorithm assumes that the // diagonal entries of the R-vine matrix are ordered from n to 1. for (size_t i = 0; i < n; i++) { for (size_t j = 0; j <= i; j++) { if (vine->matrix[i][j] > 0) { vine->matrix[i][j] = order_inv[vine->matrix[i][j] - 1]; } } } if (vine->trees != n - 1) { for (size_t i = 0; i < n - 1 - vine->trees; i++) { for (e = 0; e < igraph_ecount(last_trees[i]); e++) { Ue = EAP(last_trees[i], "Ue", e); gsl_vector_short_free(Ue); } DELEA(last_trees[i], "Ue"); igraph_destroy(last_trees[i]); g_free(last_trees[i]); } g_free(last_trees); g_free(graph); } g_free(order_inv); gsl_vector_short_free(B); }
int main() { igraph_t g; igraph_vector_t v, res, reset, weights; igraph_arpack_options_t arpack_options; igraph_real_t value; int ret; igraph_pagerank_power_options_t power_options; /* Test graphs taken from http://www.iprcom.com/papers/pagerank/ */ igraph_vector_init(&v, 10); VECTOR(v)[0]=0; VECTOR(v)[1]=1; VECTOR(v)[2]=1; VECTOR(v)[3]=2; VECTOR(v)[4]=2; VECTOR(v)[5]=0; VECTOR(v)[6]=3; VECTOR(v)[7]=2; VECTOR(v)[8]=0; VECTOR(v)[9]=2; igraph_create(&g, &v, 0, 1); igraph_vector_init(&res, 0); oldwarn=igraph_set_warning_handler(warning_handler_stdout); igraph_pagerank_old(&g, &res, igraph_vss_all(), 1, 1000, 0.001, 0.85, 0); print_vector(&res, stdout); igraph_vector_destroy(&res); igraph_vector_destroy(&v); igraph_destroy(&g); igraph_vector_init(&v, 28); VECTOR(v)[ 0]=0; VECTOR(v)[ 1]=1; VECTOR(v)[ 2]=0; VECTOR(v)[ 3]=2; VECTOR(v)[ 4]=0; VECTOR(v)[ 5]=3; VECTOR(v)[ 6]=1; VECTOR(v)[ 7]=0; VECTOR(v)[ 8]=2; VECTOR(v)[ 9]=0; VECTOR(v)[10]=3; VECTOR(v)[11]=0; VECTOR(v)[12]=3; VECTOR(v)[13]=4; VECTOR(v)[14]=3; VECTOR(v)[15]=5; VECTOR(v)[16]=3; VECTOR(v)[17]=6; VECTOR(v)[18]=3; VECTOR(v)[19]=7; VECTOR(v)[20]=4; VECTOR(v)[21]=0; VECTOR(v)[22]=5; VECTOR(v)[23]=0; VECTOR(v)[24]=6; VECTOR(v)[25]=0; VECTOR(v)[26]=7; VECTOR(v)[27]=0; igraph_create(&g, &v, 0, 1); igraph_vector_init(&res, 0); igraph_pagerank_old(&g, &res, igraph_vss_all(), 1, 10000, 0.0001, 0.85, 0); print_vector(&res, stdout); igraph_vector_destroy(&res); igraph_vector_destroy(&v); igraph_destroy(&g); igraph_set_warning_handler(oldwarn); /* New PageRank */ igraph_star(&g, 11, IGRAPH_STAR_UNDIRECTED, 0); igraph_vector_init(&res, 0); igraph_arpack_options_init(&arpack_options); igraph_pagerank(&g, IGRAPH_PAGERANK_ALGO_ARPACK, &res, 0, igraph_vss_all(), 0, 0.85, 0, &arpack_options); print_vector(&res, stdout); igraph_pagerank(&g, IGRAPH_PAGERANK_ALGO_PRPACK, &res, 0, igraph_vss_all(), 0, 0.85, 0, 0); print_vector(&res, stdout); /* Check twice more for consistency */ igraph_pagerank(&g, IGRAPH_PAGERANK_ALGO_ARPACK, &res, 0, igraph_vss_all(), 0, 0.85, 0, &arpack_options); print_vector(&res, stdout); igraph_pagerank(&g, IGRAPH_PAGERANK_ALGO_PRPACK, &res, 0, igraph_vss_all(), 0, 0.85, 0, 0); print_vector(&res, stdout); igraph_pagerank(&g, IGRAPH_PAGERANK_ALGO_ARPACK, &res, 0, igraph_vss_all(), 0, 0.85, 0, &arpack_options); print_vector(&res, stdout); igraph_pagerank(&g, IGRAPH_PAGERANK_ALGO_PRPACK, &res, 0, igraph_vss_all(), 0, 0.85, 0, 0); print_vector(&res, stdout); /* Check personalized PageRank */ igraph_personalized_pagerank_vs(&g, IGRAPH_PAGERANK_ALGO_ARPACK, &res, 0, igraph_vss_all(), 0, 0.5, igraph_vss_1(1), 0, &arpack_options); print_vector(&res, stdout); igraph_personalized_pagerank_vs(&g, IGRAPH_PAGERANK_ALGO_PRPACK, &res, 0, igraph_vss_all(), 0, 0.5, igraph_vss_1(1), 0, 0); print_vector(&res, stdout); /* Errors */ power_options.niter = -1; power_options.eps=0.0001; igraph_set_error_handler(igraph_error_handler_ignore); igraph_set_warning_handler(igraph_warning_handler_ignore); ret=igraph_pagerank(&g, IGRAPH_PAGERANK_ALGO_POWER, &res, /*value=*/ 0, igraph_vss_all(), 1, 0.85, /*weights=*/ 0, &power_options); if (ret != IGRAPH_EINVAL) { return 1; } power_options.niter=10000; power_options.eps=-1; ret=igraph_pagerank(&g, IGRAPH_PAGERANK_ALGO_POWER, &res, /*value=*/ 0, igraph_vss_all(), 1, 0.85, /*weights=*/ 0, &power_options); if (ret != IGRAPH_EINVAL) { return 2; } power_options.niter=10000; power_options.eps=0.0001; ret=igraph_pagerank(&g, IGRAPH_PAGERANK_ALGO_POWER, &res, /*value=*/ 0, igraph_vss_all(), 1, 1.2, /*weights=*/ 0, &power_options); if (ret != IGRAPH_EINVAL) { return 3; } igraph_vector_init(&reset, 2); ret=igraph_personalized_pagerank(&g, IGRAPH_PAGERANK_ALGO_ARPACK, &res, 0, igraph_vss_all(), 0, 0.85, &reset, 0, &arpack_options); if (ret != IGRAPH_EINVAL) { return 4; } ret=igraph_personalized_pagerank(&g, IGRAPH_PAGERANK_ALGO_PRPACK, &res, 0, igraph_vss_all(), 0, 0.85, &reset, 0, 0); if (ret != IGRAPH_EINVAL) { return 4; } igraph_vector_resize(&reset, 10); igraph_vector_fill(&reset, 0); ret=igraph_personalized_pagerank(&g, IGRAPH_PAGERANK_ALGO_ARPACK, &res, 0, igraph_vss_all(), 0, 0.85, &reset, 0, &arpack_options); if (ret != IGRAPH_EINVAL) { return 5; } ret=igraph_personalized_pagerank(&g, IGRAPH_PAGERANK_ALGO_PRPACK, &res, 0, igraph_vss_all(), 0, 0.85, &reset, 0, 0); if (ret != IGRAPH_EINVAL) { return 5; } igraph_vector_destroy(&reset); igraph_destroy(&g); igraph_set_error_handler(igraph_error_handler_abort); /* Special cases: check for empty graph */ igraph_empty(&g, 10, 0); igraph_pagerank(&g, IGRAPH_PAGERANK_ALGO_ARPACK, &res, &value, igraph_vss_all(), 1, 0.85, 0, &arpack_options); if (value != 1.0) { return 6; } igraph_pagerank(&g, IGRAPH_PAGERANK_ALGO_PRPACK, &res, &value, igraph_vss_all(), 1, 0.85, 0, 0); if (value != 1.0) { return 6; } print_vector(&res, stdout); igraph_destroy(&g); /* Special cases: check for full graph, zero weights */ igraph_full(&g, 10, 0, 0); igraph_vector_init(&v, 45); igraph_vector_fill(&v, 0); igraph_pagerank(&g, IGRAPH_PAGERANK_ALGO_ARPACK, &res, &value, igraph_vss_all(), 1, 0.85, &v, &arpack_options); if (value != 1.0) { return 7; } igraph_pagerank(&g, IGRAPH_PAGERANK_ALGO_PRPACK, &res, &value, igraph_vss_all(), 1, 0.85, &v, 0); if (value != 1.0) { return 7; } igraph_vector_destroy(&v); print_vector(&res, stdout); igraph_destroy(&g); /* Another test case for PageRank (bug #792352) */ igraph_small(&g, 9, 1, 0, 5, 1, 5, 2, 0, 3, 1, 5, 4, 5, 7, 6, 0, 8, 0, 8, 1, -1); igraph_vector_init(&weights, 9); VECTOR(weights)[0] = 4; VECTOR(weights)[1] = 5; VECTOR(weights)[2] = 5; VECTOR(weights)[3] = 4; VECTOR(weights)[4] = 4; VECTOR(weights)[5] = 4; VECTOR(weights)[6] = 3; VECTOR(weights)[7] = 4; VECTOR(weights)[8] = 4; igraph_pagerank(&g, IGRAPH_PAGERANK_ALGO_ARPACK, &res, 0, igraph_vss_all(), 1, 0.85, &weights, &arpack_options); print_vector(&res, stdout); igraph_pagerank(&g, IGRAPH_PAGERANK_ALGO_PRPACK, &res, 0, igraph_vss_all(), 1, 0.85, &weights, 0); print_vector(&res, stdout); igraph_vector_destroy(&weights); igraph_destroy(&g); igraph_vector_destroy(&res); return 0; }
int igraph_bipartite_game_gnm(igraph_t *graph, igraph_vector_bool_t *types, igraph_integer_t n1, igraph_integer_t n2, igraph_integer_t m, igraph_bool_t directed, igraph_neimode_t mode) { igraph_vector_t edges; igraph_vector_t s; int retval=0; if (n1 < 0 || n2 < 0) { IGRAPH_ERROR("Invalid number of vertices", IGRAPH_EINVAL); } if (m < 0) { IGRAPH_ERROR("Invalid number of edges", IGRAPH_EINVAL); } if (types) { long int i; IGRAPH_CHECK(igraph_vector_bool_resize(types, n1 + n2)); igraph_vector_bool_null(types); for (i=n1; i<n1+n2; i++) { VECTOR(*types)[i] = 1; } } if (m == 0 || n1 * n2 == 0) { IGRAPH_CHECK(retval=igraph_empty(graph, n1 + n2, directed)); } else { long int i; double maxedges; if (!directed || mode != IGRAPH_ALL) { maxedges = n1 * n2; } else { maxedges = 2 * n1 * n2; } if (m > maxedges) { IGRAPH_ERROR("Invalid number (too large) of edges", IGRAPH_EINVAL); } if (maxedges == m) { IGRAPH_CHECK(retval=igraph_full_bipartite(graph, types, n1, n2, directed, mode)); } else { long int to, from; IGRAPH_VECTOR_INIT_FINALLY(&edges, 0); IGRAPH_VECTOR_INIT_FINALLY(&s, 0); IGRAPH_CHECK(igraph_random_sample(&s, 0, maxedges-1, m)); IGRAPH_CHECK(igraph_vector_reserve(&edges, igraph_vector_size(&s)*2)); for (i=0; i<m; i++) { if (!directed || mode != IGRAPH_ALL) { to=(long) floor(VECTOR(s)[i]/n1); from=(long) (VECTOR(s)[i] - ((igraph_real_t) to) * n1); to += n1; } else { long int n1n2 = n1 * n2; if (VECTOR(s)[i] < n1n2) { to=(long) floor(VECTOR(s)[i]/n1); from=(long) (VECTOR(s)[i] - ((igraph_real_t) to) * n1); to += n1; } else { to=(long) floor( (VECTOR(s)[i]-n1n2) /n2); from=(long) (VECTOR(s)[i] - n1n2 - ((igraph_real_t) to) * n2); from += n1; } } if (mode != IGRAPH_IN) { igraph_vector_push_back(&edges, from); igraph_vector_push_back(&edges, to); } else { igraph_vector_push_back(&edges, to); igraph_vector_push_back(&edges, from); } } igraph_vector_destroy(&s); IGRAPH_FINALLY_CLEAN(1); IGRAPH_CHECK(retval=igraph_create(graph, &edges, n1+n2, directed)); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); } } return retval; }
int igraph_bipartite_game_gnp(igraph_t *graph, igraph_vector_bool_t *types, igraph_integer_t n1, igraph_integer_t n2, igraph_real_t p, igraph_bool_t directed, igraph_neimode_t mode) { int retval=0; igraph_vector_t edges, s; int i; if (p < 0.0 || p > 1.0) { IGRAPH_ERROR("Invalid connection probability", IGRAPH_EINVAL); } if (types) { IGRAPH_CHECK(igraph_vector_bool_resize(types, n1 + n2)); igraph_vector_bool_null(types); for (i=n1; i<n1+n2; i++) { VECTOR(*types)[i] = 1; } } if (p == 0 || n1 * n2 < 1) { IGRAPH_CHECK(retval=igraph_empty(graph, n1 + n2, directed)); } else if (p == 1.0) { IGRAPH_CHECK(retval=igraph_full_bipartite(graph, types, n1, n2, directed, mode)); } else { long int to, from, slen; double maxedges, last; if (!directed || mode != IGRAPH_ALL) { maxedges = n1 * n2; } else { maxedges = 2 * n1 * n2; } IGRAPH_VECTOR_INIT_FINALLY(&edges, 0); IGRAPH_VECTOR_INIT_FINALLY(&s, 0); IGRAPH_CHECK(igraph_vector_reserve(&s, (long) (maxedges*p*1.1))); RNG_BEGIN(); last=RNG_GEOM(p); while (last < maxedges) { IGRAPH_CHECK(igraph_vector_push_back(&s, last)); last += RNG_GEOM(p); last += 1; } RNG_END(); slen=igraph_vector_size(&s); IGRAPH_CHECK(igraph_vector_reserve(&edges, slen * 2)); for (i=0; i<slen; i++) { if (!directed || mode != IGRAPH_ALL) { to=(long) floor(VECTOR(s)[i]/n1); from=(long) (VECTOR(s)[i] - ((igraph_real_t) to) * n1); to += n1; } else { long int n1n2 = n1 * n2; if (VECTOR(s)[i] < n1n2) { to=(long) floor(VECTOR(s)[i]/n1); from=(long) (VECTOR(s)[i] - ((igraph_real_t) to) * n1); to += n1; } else { to=(long) floor( (VECTOR(s)[i]-n1n2) /n2); from=(long) (VECTOR(s)[i] - n1n2 - ((igraph_real_t) to) * n2); from += n1; } } if (mode != IGRAPH_IN) { igraph_vector_push_back(&edges, from); igraph_vector_push_back(&edges, to); } else { igraph_vector_push_back(&edges, to); igraph_vector_push_back(&edges, from); } } igraph_vector_destroy(&s); IGRAPH_FINALLY_CLEAN(1); IGRAPH_CHECK(retval=igraph_create(graph, &edges, n1+n2, directed)); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); } return retval; }
/* Fan-in/ Fan-out method */ igraph_t *ggen_generate_fifo(gsl_rng *r, unsigned long n, unsigned long od, unsigned long id) { igraph_t *g = NULL; igraph_vector_t available_od; igraph_vector_t out_degrees; igraph_vector_t vertices; igraph_vector_t choice; igraph_vector_t edges; unsigned long max; unsigned long i,j,k; unsigned long vcount = 1; int err; ggen_error_start_stack(); if(r == NULL) GGEN_SET_ERRNO(GGEN_EINVAL); if(id == 0 || od == 0 || od > n || id > n) GGEN_SET_ERRNO(GGEN_EINVAL); g = malloc(sizeof(igraph_t)); GGEN_CHECK_ALLOC(g); GGEN_FINALLY3(free,g,1); GGEN_CHECK_IGRAPH(igraph_empty(g,1,1)); GGEN_FINALLY3(igraph_destroy,g,1); GGEN_CHECK_IGRAPH(igraph_vector_init(&available_od,n)); GGEN_FINALLY(igraph_vector_destroy,&available_od); GGEN_CHECK_IGRAPH(igraph_vector_init(&out_degrees,n)); GGEN_FINALLY(igraph_vector_destroy,&out_degrees); GGEN_CHECK_IGRAPH(igraph_vector_init(&vertices,n)); GGEN_FINALLY(igraph_vector_destroy,&vertices); GGEN_CHECK_IGRAPH(igraph_vector_init(&choice,n)); GGEN_FINALLY(igraph_vector_destroy,&choice); GGEN_CHECK_IGRAPH(igraph_vector_init(&edges,n*2)); GGEN_FINALLY(igraph_vector_destroy,&edges); while(vcount < n) { // never trigger errors as it doesn't allocate or free memory igraph_vector_resize(&available_od,vcount); igraph_vector_resize(&out_degrees,vcount); igraph_vector_resize(&vertices,vcount); // compute the available out degree of each vertex GGEN_CHECK_IGRAPH(igraph_degree(g,&out_degrees,igraph_vss_all(),IGRAPH_OUT,0)); // fill available with od and substract out_degrees igraph_vector_fill(&available_od,od); GGEN_CHECK_IGRAPH(igraph_vector_sub(&available_od,&out_degrees)); if(gsl_ran_bernoulli(r,0.5)) //Fan-out Step { // find max max = igraph_vector_max(&available_od); // register all vertices having max as outdegree j = 0; for (i = 0; i < vcount; i++) if(VECTOR(available_od)[i] == max) VECTOR(vertices)[j++] = i; // choose randomly a vertex among availables GGEN_CHECK_GSL_DO(i = gsl_rng_uniform_int(r,j)); // how many children ? GGEN_CHECK_GSL_DO(j = gsl_rng_uniform_int(r,max)); j = j+1; // create all new nodes and add edges GGEN_CHECK_IGRAPH(igraph_add_vertices(g,j,NULL)); // cannot fail igraph_vector_resize(&edges,j*2); for(k = 0; k < j; k++) { VECTOR(edges)[2*k] = i; VECTOR(edges)[2*k+1] = vcount + k; } vcount+=k; } else //Fan-In Step { // register all vertices having an available outdegree j = 0; for (i = 0; i < vcount; i++) if(VECTOR(available_od)[i] > 0) VECTOR(vertices)[j++] = i; // we can add at most id vertices max =( j > id)? id: j; // how many edges to add GGEN_CHECK_GSL_DO(k = gsl_rng_uniform_int(r,max)); k = k+1; // choose that many nodes and add edges from them to the new node // cannot fail either igraph_vector_resize(&choice,k); gsl_ran_choose(r,VECTOR(choice),k, VECTOR(vertices),j,sizeof(VECTOR(vertices)[0])); // add a vertex to the graph GGEN_CHECK_IGRAPH(igraph_add_vertices(g,1,NULL)); igraph_vector_resize(&edges,k*2); // be carefull, vcount is the last ID of vertices not vcount +1 for(i = 0; i < k; i++) { VECTOR(edges)[2*i] = VECTOR(choice)[i]; VECTOR(edges)[2*i+1] = vcount; } vcount++; } // in all cases, edges should be added GGEN_CHECK_IGRAPH(igraph_add_edges(g,&edges,NULL)); } ggen_error_clean(1); return g; ggen_error_label: return NULL; }
static void fit_rvine_trees(igraph_t **trees, const gsl_matrix *data, const dml_vine_weight_t weight, const dml_vine_trunc_t trunc, const dml_copula_indeptest_t indeptest, const double indeptest_level, const dml_copula_type_t *types, const size_t types_size, const dml_copula_select_t select, const gsl_rng *rng) { size_t m, n; igraph_t *graph; igraph_vector_t *graph_weight; dml_copula_t *copula; gsl_vector *x; igraph_integer_t e; // Edge id. igraph_integer_t a, aa, ab, b, ba, bb; // Vertex id. gsl_vector *u = NULL, *v = NULL; igraph_integer_t Cea, Ceb; gsl_vector_short *Ue, *Ua, *Ub; size_t k; dml_measure_t *measure; double tree_aic, copula_aic; gsl_permutation *perm, *rank, *u_rank = NULL, *v_rank = NULL; igraph_i_set_attribute_table(&igraph_cattribute_table); m = data->size1; n = data->size2; graph = g_malloc(sizeof(igraph_t)); graph_weight = g_malloc(sizeof(igraph_vector_t)); perm = gsl_permutation_alloc(m); for (k = 0; k < n - 1; k++) { // Tree index. if (k == 0) { igraph_full(graph, n, IGRAPH_UNDIRECTED, IGRAPH_NO_LOOPS); // Assign the observations to the nodes. for (size_t i = 0; i < n; i++) { // Variable and node index. x = gsl_vector_alloc(m); gsl_matrix_get_col(x, data, i); // Results of the h-function of the copula assigned to the // edge that corresponds to this vertex in the previous tree. // h for the h-function with its arguments in order and // hrev for the h-function with its arguments reversed. In the // first tree both are equal to the observations of the // corresponding variable, in the rest of the trees they differ. SETVAP(graph, "h", i, x); SETVAP(graph, "hrev", i, x); gsl_sort_vector_index(perm, x); rank = gsl_permutation_alloc(m); gsl_permutation_inverse(rank, perm); // Ranks of the h and hrev vectors. SETVAP(graph, "hrank", i, rank); SETVAP(graph, "hrevrank", i, rank); } for (e = 0; e < igraph_ecount(graph); e++) { igraph_edge(graph, e, &a, &b); // Variables "connected" by this edge. Ue = gsl_vector_short_calloc(n); gsl_vector_short_set(Ue, a, 1); gsl_vector_short_set(Ue, b, 1); SETEAP(graph, "Ue", e, Ue); // Conditioned set. SETEAN(graph, "Cea", e, a + 1); SETEAN(graph, "Ceb", e, b + 1); Cea = EAN(graph, "Cea", e); Ceb = EAN(graph, "Ceb", e); // Calculate the weight of the edge. u = VAP(graph, "h", a); v = VAP(graph, "h", b); u_rank = VAP(graph, "hrank", a); v_rank = VAP(graph, "hrank", b); // The conditioned set is ordered to make the order of the // arguments in the bivariate copulas unique as suggested in // Czado, C. (2010) Pair-Copula Constructions of Multivariate // Copulas. In Jaworski, P. and Durante, F. and Hardle, W. K. // and Rychlik, T. (eds.) Copula Theory and Its Applications, // Springer-Verlag, 93-109. if (Cea < Ceb) { rvine_set_weight(graph, weight, e, u, v, u_rank, v_rank); } else { rvine_set_weight(graph, weight, e, v, u, v_rank, u_rank); } } } else { igraph_empty(graph, n - k, IGRAPH_UNDIRECTED); // Adding all "possible" edges. for (a = 0; a < igraph_vcount(graph) - 1; a++) { for (b = a + 1; b < igraph_vcount(graph); b++) { igraph_edge(trees[k - 1], a, &aa, &ab); igraph_edge(trees[k - 1], b, &ba, &bb); // Checking the proximity condition. if (aa == ba || aa == bb || ab == ba || ab == bb) { igraph_add_edge(graph, a, b); igraph_get_eid(graph, &e, a, b, IGRAPH_UNDIRECTED, 1); // Variables "connected" by this edge and conditioned set. Ua = EAP(trees[k - 1], "Ue", a); Ub = EAP(trees[k - 1], "Ue", b); Ue = gsl_vector_short_calloc(n); for (size_t i = 0; i < n; i++) { gsl_vector_short_set(Ue, i, gsl_vector_short_get(Ua, i) | gsl_vector_short_get(Ub, i)); if (gsl_vector_short_get(Ua, i) && !gsl_vector_short_get(Ub, i)) { SETEAN(graph, "Cea", e, i + 1); } if (gsl_vector_short_get(Ub, i) && !gsl_vector_short_get(Ua, i)) { SETEAN(graph, "Ceb", e, i + 1); } } SETEAP(graph, "Ue", e, Ue); } } } // Compute pseudo-observations and edge weights. for (a = 0; a < igraph_vcount(graph); a++) { // See the comment in the code for the first tree. SETVAP(graph, "h", a, NULL); SETVAP(graph, "hrev", a, NULL); SETVAP(graph, "hrank", a, NULL); SETVAP(graph, "hrevrank", a, NULL); } for (e = 0; e < igraph_ecount(graph); e++) { igraph_edge(graph, e, &a, &b); Cea = EAN(graph, "Cea", e); Ceb = EAN(graph, "Ceb", e); // Assign u and u_rank. if ((Cea == EAN(trees[k - 1], "Cea", a) && (EAN(trees[k - 1], "Cea", a) < EAN(trees[k - 1], "Ceb", a))) || (Cea != EAN(trees[k - 1], "Cea", a) && (EAN(trees[k - 1], "Cea", a) > EAN(trees[k - 1], "Ceb", a)))) { u = VAP(graph, "h", a); if (u == NULL) { copula = EAP(trees[k - 1], "copula", a); measure = EAP(trees[k - 1], "measure", a); u = gsl_vector_alloc(m); dml_copula_h(copula, measure->x, measure->y, u); SETVAP(graph, "h", a, u); gsl_sort_vector_index(perm, u); rank = gsl_permutation_alloc(m); gsl_permutation_inverse(rank, perm); SETVAP(graph, "hrank", a, rank); } u_rank = VAP(graph, "hrank", a); } if ((Cea == EAN(trees[k - 1], "Cea", a) && (EAN(trees[k - 1], "Cea", a) > EAN(trees[k - 1], "Ceb", a))) || (Cea != EAN(trees[k - 1], "Cea", a) && (EAN(trees[k - 1], "Cea", a) < EAN(trees[k - 1], "Ceb", a)))) { u = VAP(graph, "hrev", a); if (u == NULL) { copula = EAP(trees[k - 1], "copula", a); measure = EAP(trees[k - 1], "measure", a); u = gsl_vector_alloc(m); dml_copula_h(copula, measure->y, measure->x, u); SETVAP(graph, "hrev", a, u); gsl_sort_vector_index(perm, u); rank = gsl_permutation_alloc(m); gsl_permutation_inverse(rank, perm); SETVAP(graph, "hrevrank", a, rank); } u_rank = VAP(graph, "hrevrank", a); } // Assign v and v_rank. if ((Ceb == EAN(trees[k - 1], "Cea", b) && (EAN(trees[k - 1], "Cea", b) < EAN(trees[k - 1], "Ceb", b))) || (Ceb != EAN(trees[k - 1], "Cea", b) && (EAN(trees[k - 1], "Cea", b) > EAN(trees[k - 1], "Ceb", b)))) { v = VAP(graph, "h", b); if (v == NULL) { copula = EAP(trees[k - 1], "copula", b); measure = EAP(trees[k - 1], "measure", b); v = gsl_vector_alloc(m); dml_copula_h(copula, measure->x, measure->y, v); SETVAP(graph, "h", b, v); gsl_sort_vector_index(perm, v); rank = gsl_permutation_alloc(m); gsl_permutation_inverse(rank, perm); SETVAP(graph, "hrank", b, rank); } v_rank = VAP(graph, "hrank", b); } if ((Ceb == EAN(trees[k - 1], "Cea", b) && (EAN(trees[k - 1], "Cea", b) > EAN(trees[k - 1], "Ceb", b))) || (Ceb != EAN(trees[k - 1], "Cea", b) && (EAN(trees[k - 1], "Cea", b) < EAN(trees[k - 1], "Ceb", b)))) { v = VAP(graph, "hrev", b); if (v == NULL) { copula = EAP(trees[k - 1], "copula", b); measure = EAP(trees[k - 1], "measure", b); v = gsl_vector_alloc(m); dml_copula_h(copula, measure->y, measure->x, v); SETVAP(graph, "hrev", b, v); gsl_sort_vector_index(perm, v); rank = gsl_permutation_alloc(m); gsl_permutation_inverse(rank, perm); SETVAP(graph, "hrevrank", b, rank); } v_rank = VAP(graph, "hrevrank", b); } // Set the weight of the edge. The arguments are ordered here. // The order determines the x and y fields of measure. if (Cea < Ceb) { rvine_set_weight(graph, weight, e, u, v, u_rank, v_rank); } else { rvine_set_weight(graph, weight, e, v, u, v_rank, u_rank); } } } // Compute the minimum weight spanning tree. trees[k] = g_malloc(sizeof(igraph_t)); igraph_vector_init(graph_weight, igraph_ecount(graph)); EANV(graph, "weight", graph_weight); igraph_minimum_spanning_tree_prim(graph, trees[k], graph_weight); igraph_vector_destroy(graph_weight); tree_aic = 0; for (e = 0; e < igraph_ecount(trees[k]); e++) { igraph_edge(trees[k], e, &a, &b); Cea = EAN(trees[k], "Cea", e); Ceb = EAN(trees[k], "Ceb", e); measure = EAP(trees[k], "measure", e); // Assign a bivariate copula to the edge. if (Cea < Ceb) { copula = dml_copula_select(measure->x, measure->y, measure, indeptest, indeptest_level, types, types_size, select, rng); // Get information for the truncation of the vine. if (trunc == DML_VINE_TRUNC_AIC) { dml_copula_aic(copula, measure->x, measure->y, &copula_aic); tree_aic += copula_aic; } } else { copula = dml_copula_select(measure->y, measure->x, measure, indeptest, indeptest_level, types, types_size, select, rng); // Get information for the truncation of the vine. if (trunc == DML_VINE_TRUNC_AIC) { dml_copula_aic(copula, measure->y, measure->x, &copula_aic); tree_aic += copula_aic; } } SETEAP(trees[k], "copula", e, copula); } igraph_destroy(graph); // Check if the vine should be truncated. if (trunc == DML_VINE_TRUNC_AIC && tree_aic >= 0) { // Free the memory used for the last tree. rvine_tree_cleanup(trees[k]); for (e = 0; e < igraph_ecount(trees[k]); e++) { copula = EAP(trees[k], "copula", e); dml_copula_free(copula); } igraph_destroy(trees[k]); g_free(trees[k]); trees[k] = NULL; break; } if (k > 0) rvine_tree_cleanup(trees[k - 1]); } // Cleanup the last tree if the vine was completely estimated. // If the vine was truncated, the last tree will be freed in // the function vine_fit_rvine, because the rvine_trees_to_vine // function needs some attributes of its edges. if (k == n - 1) { rvine_tree_cleanup(trees[n - 2]); } g_free(graph_weight); g_free(graph); gsl_permutation_free(perm); }