Bitvector GraphRepresentation::calculateFID(string &source, string &destination) { int vertex_id; Bitvector result(dm->fid_len * 8); igraph_vs_t vs; igraph_vector_ptr_t res; igraph_vector_t to_vector; igraph_vector_t *temp_v; igraph_integer_t eid; /*find the vertex id in the reverse index*/ int from = (*reverse_node_index.find(source)).second; igraph_vector_init(&to_vector, 1); VECTOR(to_vector)[0] = (*reverse_node_index.find(destination)).second; /*initialize the sequence*/ igraph_vs_vector(&vs, &to_vector); /*initialize the vector that contains pointers*/ igraph_vector_ptr_init(&res, 1); temp_v = (igraph_vector_t *) VECTOR(res)[0]; temp_v = (igraph_vector_t *) malloc(sizeof (igraph_vector_t)); VECTOR(res)[0] = temp_v; igraph_vector_init(temp_v, 1); /*run the shortest path algorithm from "from"*/ igraph_get_shortest_paths(&igraph, &res, from, vs, IGRAPH_OUT); /*check the shortest path to each destination*/ temp_v = (igraph_vector_t *) VECTOR(res)[0]; //click_chatter("Shortest path from %s to %s", igraph_cattribute_VAS(&graph, "NODEID", from), igraph_cattribute_VAS(&graph, "NODEID", VECTOR(*temp_v)[igraph_vector_size(temp_v) - 1])); /*now let's "or" the FIDs for each link in the shortest path*/ for (int j = 0; j < igraph_vector_size(temp_v) - 1; j++) { igraph_get_eid(&igraph, &eid, VECTOR(*temp_v)[j], VECTOR(*temp_v)[j + 1], true); //click_chatter("node %s -> node %s", igraph_cattribute_VAS(&graph, "NODEID", VECTOR(*temp_v)[j]), igraph_cattribute_VAS(&graph, "NODEID", VECTOR(*temp_v)[j + 1])); //click_chatter("link: %s", igraph_cattribute_EAS(&graph, "LID", eid)); string LID(igraph_cattribute_EAS(&igraph, "LID", eid), dm->fid_len * 8); for (int k = 0; k < dm->fid_len * 8; k++) { if (LID[k] == '1') { (result)[ dm->fid_len * 8 - k - 1].operator |=(true); } } //click_chatter("FID of the shortest path: %s", result.to_string().c_str()); } /*now for all destinations "or" the internal linkID*/ vertex_id = (*reverse_node_index.find(destination)).second; string iLID(igraph_cattribute_VAS(&igraph, "iLID", vertex_id)); //click_chatter("internal link for node %s: %s", igraph_cattribute_VAS(&graph, "NODEID", vertex_id), iLID.c_str()); for (int k = 0; k < dm->fid_len * 8; k++) { if (iLID[k] == '1') { (result)[ dm->fid_len * 8 - k - 1].operator |=(true); } } igraph_vector_destroy((igraph_vector_t *) VECTOR(res)[0]); igraph_vector_destroy(&to_vector); igraph_vector_ptr_destroy_all(&res); igraph_vs_destroy(&vs); return result; }
void Graph::delEdge(int i, int j) { if (areConnected(i,j)) { igraph_integer_t eid; igraph_es_t es; igraph_get_eid(graph, &eid, i,j,0); es = igraph_ess_1(eid); igraph_delete_edges(graph, es); } }
/** * \ingroup structural * \function igraph_are_connected * \brief Decides whether two vertices are connected * * \param graph The graph object. * \param v1 The first vertex. * \param v2 The second vertex. * \param res Boolean, \c TRUE if there is an edge from * \p v1 to \p v2, \c FALSE otherwise. * \return The error code \c IGRAPH_EINVVID is returned if an invalid * vertex ID is given. * * The function is of course symmetric for undirected graphs. * * </para><para> * Time complexity: O( min(log(d1), log(d2)) ), * d1 is the (out-)degree of \p v1 and d2 is the (in-)degree of \p v2. */ int igraph_are_connected(const igraph_t *graph, igraph_integer_t v1, igraph_integer_t v2, igraph_bool_t *res) { long int nov=igraph_vcount(graph); igraph_integer_t eid=-1; if (v1 < 0 || v2 < 0 || v1 > nov-1 || v2 > nov-1) { IGRAPH_ERROR("are connected", IGRAPH_EINVVID); } igraph_get_eid(graph, &eid, v1, v2, /*directed=*/1, /*error=*/ 0); *res = (eid >=0); return IGRAPH_SUCCESS; }
void TMIgraph::calculateFID(string &source, string &destination, Bitvector &resultFID, unsigned int &numberOfHops) { int vertex_id; igraph_vs_t vs; igraph_vector_ptr_t res; igraph_vector_t to_vector; igraph_vector_t *temp_v; igraph_integer_t eid; /*find the vertex id in the reverse index*/ int from = (*reverse_node_index.find(source)).second; igraph_vector_init(&to_vector, 1); VECTOR(to_vector)[0] = (*reverse_node_index.find(destination)).second; /*initialize the sequence*/ igraph_vs_vector(&vs, &to_vector); /*initialize the vector that contains pointers*/ igraph_vector_ptr_init(&res, 1); temp_v = (igraph_vector_t *) VECTOR(res)[0]; temp_v = (igraph_vector_t *) malloc(sizeof (igraph_vector_t)); VECTOR(res)[0] = temp_v; igraph_vector_init(temp_v, 1); /*run the shortest path algorithm from "from"*/ igraph_get_shortest_paths(&graph, &res, from, vs, IGRAPH_OUT); /*check the shortest path to each destination*/ temp_v = (igraph_vector_t *) VECTOR(res)[0]; /*now let's "or" the FIDs for each link in the shortest path*/ for (int j = 0; j < igraph_vector_size(temp_v) - 1; j++) { igraph_get_eid(&graph, &eid, VECTOR(*temp_v)[j], VECTOR(*temp_v)[j + 1], true); Bitvector *lid = (*edge_LID.find(eid)).second; (resultFID) = (resultFID) | (*lid); } numberOfHops = igraph_vector_size(temp_v); /*now for the destination "or" the internal linkID*/ Bitvector *ilid = (*nodeID_iLID.find(destination)).second; (resultFID) = (resultFID) | (*ilid); //cout << "FID of the shortest path: " << resultFID.to_string() << endl; igraph_vector_destroy((igraph_vector_t *) VECTOR(res)[0]); igraph_vector_destroy(&to_vector); igraph_vector_ptr_destroy_all(&res); igraph_vs_destroy(&vs); }
gdouble tgengraph_getEdgeWeight(TGenGraph* g, TGenAction* srcAction, TGenAction* dstAction) { TGEN_ASSERT(g); /* given choose action, get the weights of the edges connected to it */ gpointer srcKey = tgenaction_getKey(srcAction); igraph_integer_t srcVertexIndex = (igraph_integer_t) GPOINTER_TO_INT(srcKey); gpointer dstKey = tgenaction_getKey(dstAction); igraph_integer_t dstVertexIndex = (igraph_integer_t) GPOINTER_TO_INT(dstKey); igraph_integer_t edgeIndex; gint result = igraph_get_eid(g->graph, &edgeIndex, srcVertexIndex, dstVertexIndex, IGRAPH_DIRECTED, TRUE); if(result != IGRAPH_SUCCESS) { tgen_critical("igraph_get_eid return non-success code %i", result); return FALSE; } gdouble* weight = _tgengraph_getWeight(g, edgeIndex); return (weight != NULL) ? *weight : 0.0; }
/* call-seq: * graph.get_eid(from,to,directed) -> Fixnum * * Returns the edge id of the edge connecting the vertices from and to. * directed is a boolean specifying whether to search for directed edges * in a directed graph. * * Example: * * g = IGraph.new([1,2,3,4],true) * g.get_eid(1,2,true) # returns 1 * */ VALUE cIGraph_get_eid(VALUE self, VALUE from, VALUE to, VALUE directed){ igraph_t *graph; igraph_integer_t eid = 0; int from_i = 0; int to_i = 0; igraph_bool_t directed_b = 0; Data_Get_Struct(self, igraph_t, graph); from_i = cIGraph_get_vertex_id(self,from); to_i = cIGraph_get_vertex_id(self,to); if(directed) directed_b = 1; igraph_get_eid(graph,&eid,from_i,to_i,directed_b); return INT2NUM(eid); }
integer_t Graph::getEid(integer_t source, integer_t target, bool directed, bool error) const { integer_t eid; IGRAPH_TRY(igraph_get_eid(m_pGraph, &eid, source, target, directed, error)); return eid; }
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; }
int igraph_dijkstra_shortest_paths(const igraph_t *graph, igraph_matrix_t *res, const igraph_vs_t from, const igraph_vector_t *wghts, igraph_neimode_t mode) { long int no_of_nodes=igraph_vcount(graph); long int no_of_from; igraph_real_t *shortest; igraph_real_t min,alt; int i, j, uj, included; igraph_integer_t eid, u,v; igraph_vector_t q; igraph_vit_t fromvit; igraph_vector_t neis; IGRAPH_CHECK(igraph_vit_create(graph, from, &fromvit)); IGRAPH_FINALLY(igraph_vit_destroy, &fromvit); no_of_from=IGRAPH_VIT_SIZE(fromvit); if (mode != IGRAPH_OUT && mode != IGRAPH_IN && mode != IGRAPH_ALL) { IGRAPH_ERROR("Invalid mode argument", IGRAPH_EINVMODE); } shortest=calloc(no_of_nodes, sizeof(igraph_real_t)); if (shortest==0) { IGRAPH_ERROR("shortest paths failed", IGRAPH_ENOMEM); } IGRAPH_FINALLY(free, shortest); IGRAPH_CHECK(igraph_matrix_resize(res, no_of_from, no_of_nodes)); igraph_matrix_null(res); for (IGRAPH_VIT_RESET(fromvit), i=0; !IGRAPH_VIT_END(fromvit); IGRAPH_VIT_NEXT(fromvit), i++) { //Start shortest and previous for(j=0;j<no_of_nodes;j++){ shortest[j] = INFINITY; //memset(previous,NAN, no_of_nodes); } shortest[(int)IGRAPH_VIT_GET(fromvit)] = 0; igraph_vector_init_seq(&q,0,no_of_nodes-1); while(igraph_vector_size(&q) != 0){ min = INFINITY; u = no_of_nodes; uj = igraph_vector_size(&q); for(j=0;j<igraph_vector_size(&q);j++){ v = VECTOR(q)[j]; if(shortest[(int)v] < min){ min = shortest[(int)v]; u = v; uj = j; } } if(min == INFINITY) break; igraph_vector_remove(&q,uj); igraph_vector_init(&neis,0); igraph_neighbors(graph,&neis,u,mode); for(j=0;j<igraph_vector_size(&neis);j++){ v = VECTOR(neis)[j]; //v must be in Q included = 0; for(j=0;j<igraph_vector_size(&q);j++){ if(v == VECTOR(q)[j]){ included = 1; break; } } if(!included) continue; igraph_get_eid(graph,&eid,u,v,1); alt = shortest[(int)u] + VECTOR(*wghts)[(int)eid]; if(alt < shortest[(int)v]){ shortest[(int)v] = alt; } } igraph_vector_destroy(&neis); } for(j=0;j<no_of_nodes;j++){ MATRIX(*res,i,j) = shortest[j]; } igraph_vector_destroy(&q); } /* Clean */ free(shortest); igraph_vit_destroy(&fromvit); IGRAPH_FINALLY_CLEAN(2); return 0; }
static PyObject *ignp_fun_propagate(PyObject *self, PyObject *args) { long int num_active = 0; long int num_susc = 1; long int limit = 30; long int i; float lrAct; PyObject* mem_addr_o; long int mem_addr; /* StateTracker Vars */ PyArrayObject *py_trkr; // 'i64' /* By EdgeID */ PyArrayObject *py_tie_r; // 'f32' /* By NodeID */ PyArrayObject *py_act_n; // 'i8' PyArrayObject *py_thr_n; // 'f32' PyArrayObject *py_exp_n; // 'i64' /* By Infection Order*/ PyArrayObject *py_deg; // i64 PyArrayObject *py_nSuc; // i64 PyArrayObject *py_nAct; // i64 PyArrayObject *py_lrAct; // f32 PyArrayObject *py_hom; // i64 PyArrayObject *py_eComp; // i64 PyArrayObject *py_iComp; // i64 PyArrayObject *py_eTri; // i64 PyArrayObject *py_iTri; // i64 PyArrayObject *py_thr; // i32 PyArrayObject *py_exp; // i64 PyArrayObject *py_cTime; // i64 PyObject *g_obj; igraph_t *g; igraph_t gc; long int randID; long int low = 0; long int high = -1; long int ctime = 0; igraph_rng_t *rGen; igraph_vit_t nbr_iter; igraph_vs_t nbr_sel; igraph_integer_t eid; igraph_integer_t vdeg; igraph_integer_t e_comp = 0; igraph_integer_t i_comp = 0; igraph_integer_t e_tri = 0; igraph_integer_t i_tri = 0; int actv_nbr_count; //int res, j; igraph_vector_t temp; //igraph_vector_t actv_nbrs; //PySys_WriteStdout("Parse Started\n"); if (!PyArg_ParseTuple(args, "OO!O!O!O!O!O!O!O!O!O!O!O!O!O!O!O!O!", &g_obj, &PyArray_Type, &py_trkr, // i64 &PyArray_Type, &py_tie_r, // 'f32' &PyArray_Type, &py_act_n, // 'i8' &PyArray_Type, &py_thr_n, // 'i32' &PyArray_Type, &py_exp_n, // 'i64' &PyArray_Type, &py_deg, // i64 &PyArray_Type, &py_nSuc, // i64 &PyArray_Type, &py_nAct, // i64 &PyArray_Type, &py_lrAct, // f32 &PyArray_Type, &py_hom, // i64 &PyArray_Type, &py_eComp, // i64 &PyArray_Type, &py_iComp, // i64 &PyArray_Type, &py_eTri, // i64 &PyArray_Type, &py_iTri, // i64 &PyArray_Type, &py_thr, // i64 &PyArray_Type, &py_exp, // i64 &PyArray_Type, &py_cTime // i64 )) { printf("Parse Failed\n"); Py_RETURN_NONE; } //PySys_WriteStdout("Getting Tracker Vars\n"); num_active = (long) ax_i64(py_trkr, 0); num_susc = (long) ax_i64(py_trkr, 1); limit = (long) ax_i64(py_trkr, 2); mem_addr_o = PyObject_CallMethod(g_obj, "_raw_pointer", "()"); mem_addr = PyInt_AsLong(mem_addr_o); Py_DECREF(mem_addr_o); if (mem_addr == -1) { printf("PyInt to Long Failed"); return NULL; } g = (igraph_t*) mem_addr; //Setup Vars rGen = igraph_rng_default(); //igraph_rng_init(rGen, time(NULL)); high += (long) igraph_vcount(g); //PySys_WriteStdout("Propagate Starting with %li active of target %li with %li open\n", // num_active, limit, num_susc); //Propagate do { // get random node ctime += 1; randID = igraph_rng_get_integer(rGen, low, high); if ( ax_i8(py_act_n, randID) != 1 && ax_i64(py_exp_n, randID)>=ax_i32(py_thr_n, randID) ){ //activate ax_i8(py_act_n,randID) = 1; lrAct = 0; //update nbrs actv_nbr_count = 0; igraph_vs_adj( &nbr_sel, randID, IGRAPH_ALL); igraph_vit_create(g, nbr_sel, &nbr_iter); igraph_vs_size(g, &nbr_sel, &vdeg); igraph_vector_init(&temp, vdeg); while( !IGRAPH_VIT_END(nbr_iter) ){ i = (long int) IGRAPH_VIT_GET(nbr_iter); ax_i64( py_exp_n, i ) += 1; /* update active nbr count and collect id of active */ if ( ax_i8(py_act_n, i) == i ) { VECTOR(temp)[actv_nbr_count]=i; actv_nbr_count += 1; } /* update num_susc */ if ( ax_i8(py_act_n, i) == 0 && \ ax_i32(py_thr_n, i) > (float) (ax_i64(py_exp_n, i)-1) && \ ax_i32(py_thr_n, i) <= (float) ax_i64(py_exp_n, i) ){ /*PySys_WriteStdout("%li < %i <= %li\n", (ax_i64(py_exp_n, i)-1), ax_i32(py_thr_n, i), ax_i64(py_exp_n, i) );*/ num_susc += 1; } /* Get #active long ties */ if ( ax_i8(py_act_n, i) == 1 ){ igraph_get_eid(g, &eid, randID, i, 0, 1); lrAct += ax_f32( py_tie_r, eid )>2 ; } IGRAPH_VIT_NEXT(nbr_iter); } igraph_vit_destroy(&nbr_iter); igraph_vs_destroy(&nbr_sel); //Compute Components (among all and active nbrs) igraph_vs_adj( &nbr_sel, randID, IGRAPH_ALL); igraph_induced_subgraph(g, &gc, nbr_sel, IGRAPH_SUBGRAPH_CREATE_FROM_SCRATCH); igraph_clusters(&gc, NULL, NULL, &e_comp, IGRAPH_WEAK); e_tri = igraph_vcount(&gc); igraph_destroy(&gc); igraph_vs_destroy(&nbr_sel); igraph_induced_subgraph(g, &gc, igraph_vss_vector(&temp), \ IGRAPH_SUBGRAPH_CREATE_FROM_SCRATCH); igraph_clusters(&gc, NULL, NULL, &i_comp, IGRAPH_WEAK); i_tri = igraph_vcount(&gc); //Clean up igraph_destroy(&gc); igraph_vector_destroy(&temp); //PySys_WriteStdout("e_comp: %i, i_comp: %i\n", e_comp, i_comp); //PySys_WriteStdout("e_tri: %i, i_tri: %i\n", e_tri, i_tri); //update tracking vars ax_f32( py_lrAct, num_active ) = (npy_float32) lrAct; ax_i32( py_thr, num_active) = ax_i32(py_thr_n, randID); ax_i64( py_deg, num_active) = (npy_int64) vdeg; ax_i64( py_nSuc, num_active) = (npy_int64) num_susc; ax_i64( py_nAct, num_active) = (npy_int64) num_active; //ax_i64( py_hom, num_active) = (npy_int64) num_susc; ax_i64( py_eComp, num_active) = (npy_int64) e_comp; ax_i64( py_iComp, num_active) = (npy_int64) i_comp; ax_i64( py_eTri, num_active) = (npy_int64) e_tri; ax_i64( py_iTri, num_active) = (npy_int64) i_tri; ax_i64( py_exp, num_active) = ax_i64(py_exp_n, randID); ax_i64( py_cTime, num_active) = (npy_int64) ctime; num_active += 1; } } while( num_susc > num_active && num_active < limit); //PySys_WriteStdout("Propagate Finished with %li active of target %li with %li open\n", // num_active, limit, num_susc); //igraph_rng_destroy(rGen); ax_i64(py_trkr, 0) = (npy_int64) num_active; ax_i64(py_trkr, 1) = (npy_int64) num_susc ; ax_i64(py_trkr, 2) = (npy_int64) limit ; Py_RETURN_NONE; }
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); }
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); }