static inline void rvine_tree_cleanup(igraph_t *tree) { igraph_integer_t e, a; for (a = 0; a < igraph_vcount(tree); a++) { if (VAP(tree, "h", a) != VAP(tree, "hrev", a)) { gsl_vector_free(VAP(tree, "h", a)); gsl_vector_free(VAP(tree, "hrev", a)); gsl_permutation_free(VAP(tree, "hrank", a)); gsl_permutation_free(VAP(tree, "hrevrank", a)); } else if (VAP(tree, "h", a) != NULL) { gsl_vector_free(VAP(tree, "h", a)); gsl_permutation_free(VAP(tree, "hrank", a)); } else { gsl_vector_free(VAP(tree, "hrev", a)); gsl_permutation_free(VAP(tree, "hrevrank", a)); } } DELVAS(tree); for (e = 0; e < igraph_ecount(tree); e++) { gsl_vector_short_free(EAP(tree, "Ue", e)); dml_measure_free(EAP(tree, "measure", e)); } DELEA(tree, "Ue"); DELEA(tree, "weight"); DELEA(tree, "measure"); }
int main() { igraph_t g, g2; FILE *ifile; igraph_vector_t gtypes, vtypes, etypes; igraph_strvector_t gnames, vnames, enames; long int i; igraph_vector_t y; igraph_strvector_t id; char str[20]; /* turn on attribute handling */ igraph_i_set_attribute_table(&igraph_cattribute_table); ifile=fopen("LINKS.NET", "r"); if (ifile==0) { return 10; } igraph_read_graph_pajek(&g, ifile); fclose(ifile); igraph_vector_init(>ypes, 0); igraph_vector_init(&vtypes, 0); igraph_vector_init(&etypes, 0); igraph_strvector_init(&gnames, 0); igraph_strvector_init(&vnames, 0); igraph_strvector_init(&enames, 0); igraph_cattribute_list(&g, &gnames, >ypes, &vnames, &vtypes, &enames, &etypes); /* List attribute names and types */ printf("Graph attributes: "); for (i=0; i<igraph_strvector_size(&gnames); i++) { printf("%s (%i) ", STR(gnames, i), (int)VECTOR(gtypes)[i]); } printf("\n"); printf("Vertex attributes: "); for (i=0; i<igraph_strvector_size(&vnames); i++) { printf("%s (%i) ", STR(vnames, i), (int)VECTOR(vtypes)[i]); } printf("\n"); printf("Edge attributes: "); for (i=0; i<igraph_strvector_size(&enames); i++) { printf("%s (%i) ", STR(enames, i), (int)VECTOR(etypes)[i]); } printf("\n"); print_attributes(&g); /* Copying a graph */ igraph_copy(&g2, &g); print_attributes(&g2); igraph_destroy(&g2); /* Adding vertices */ igraph_add_vertices(&g, 3, 0); print_attributes(&g); /* Adding edges */ igraph_add_edge(&g, 1, 1); igraph_add_edge(&g, 2, 5); igraph_add_edge(&g, 3, 6); print_attributes(&g); /* Deleting vertices */ igraph_delete_vertices(&g, igraph_vss_1(1)); igraph_delete_vertices(&g, igraph_vss_1(4)); print_attributes(&g); /* Deleting edges */ igraph_delete_edges(&g, igraph_ess_1(igraph_ecount(&g)-1)); igraph_delete_edges(&g, igraph_ess_1(0)); print_attributes(&g); /* Set graph attributes */ SETGAN(&g, "id", 10); if (GAN(&g, "id") != 10) { return 11; } SETGAS(&g, "name", "toy"); if (strcmp(GAS(&g, "name"), "toy")) { return 12; } /* Delete graph attributes */ DELGA(&g, "id"); DELGA(&g, "name"); igraph_cattribute_list(&g, &gnames, 0,0,0,0,0); if (igraph_strvector_size(&gnames) != 0) { return 14; } /* Delete vertex attributes */ DELVA(&g, "x"); DELVA(&g, "shape"); DELVA(&g, "xfact"); DELVA(&g, "yfact"); igraph_cattribute_list(&g, 0,0, &vnames, 0,0,0); if (igraph_strvector_size(&vnames) != 2) { return 15; } /* Delete edge attributes */ igraph_cattribute_list(&g, 0,0,0,0,&enames,0); i=igraph_strvector_size(&enames); DELEA(&g, "hook1"); DELEA(&g, "hook2"); DELEA(&g, "label"); igraph_cattribute_list(&g, 0,0,0,0,&enames,0); if (igraph_strvector_size(&enames) != i-3) { return 16; } /* Set vertex attributes */ SETVAN(&g, "y", 0, -1); SETVAN(&g, "y", 1, 2.1); if (VAN(&g, "y", 0) != -1 || VAN(&g, "y", 1) != 2.1) { return 17; } SETVAS(&g, "id", 0, "foo"); SETVAS(&g, "id", 1, "bar"); if (strcmp(VAS(&g, "id", 0), "foo") || strcmp(VAS(&g, "id", 1), "bar")) { return 18; } /* Set edge attributes */ SETEAN(&g, "weight", 2, 100.0); SETEAN(&g, "weight", 0, -100.1); if (EAN(&g, "weight", 2) != 100.0 || EAN(&g, "weight", 0) != -100.1) { return 19; } SETEAS(&g, "color", 2, "RED"); SETEAS(&g, "color", 0, "Blue"); if (strcmp(EAS(&g, "color", 2), "RED") || strcmp(EAS(&g, "color", 0), "Blue")) { return 20; } /* Set vector attributes as vector */ igraph_vector_init(&y, igraph_vcount(&g)); igraph_vector_fill(&y, 1.23); SETVANV(&g, "y", &y); igraph_vector_destroy(&y); for (i=0; i<igraph_vcount(&g); i++) { if (VAN(&g, "y", i) != 1.23) { return 21; } } igraph_vector_init_seq(&y, 0, igraph_vcount(&g)-1); SETVANV(&g, "foobar", &y); igraph_vector_destroy(&y); for (i=0; i<igraph_vcount(&g); i++) { if (VAN(&g, "foobar", i) != i) { return 22; } } igraph_strvector_init(&id, igraph_vcount(&g)); for (i=0; i<igraph_vcount(&g); i++) { snprintf(str, sizeof(str)-1, "%li", i); igraph_strvector_set(&id, i, str); } SETVASV(&g, "foo", &id); igraph_strvector_destroy(&id); for (i=0; i<igraph_vcount(&g); i++) { printf("%s ", VAS(&g, "foo", i)); } printf("\n"); igraph_strvector_init(&id, igraph_vcount(&g)); for (i=0; i<igraph_vcount(&g); i++) { snprintf(str, sizeof(str)-1, "%li", i); igraph_strvector_set(&id, i, str); } SETVASV(&g, "id", &id); igraph_strvector_destroy(&id); for (i=0; i<igraph_vcount(&g); i++) { printf("%s ", VAS(&g, "id", i)); } printf("\n"); /* Set edge attributes as vector */ igraph_vector_init(&y, igraph_ecount(&g)); igraph_vector_fill(&y, 12.3); SETEANV(&g, "weight", &y); igraph_vector_destroy(&y); for (i=0; i<igraph_ecount(&g); i++) { if (EAN(&g, "weight", i) != 12.3) { return 23; } } igraph_vector_init_seq(&y, 0, igraph_ecount(&g)-1); SETEANV(&g, "foobar", &y); igraph_vector_destroy(&y); for (i=0; i<igraph_ecount(&g); i++) { if (VAN(&g, "foobar", i) != i) { return 24; } } igraph_strvector_init(&id, igraph_ecount(&g)); for (i=0; i<igraph_ecount(&g); i++) { snprintf(str, sizeof(str)-1, "%li", i); igraph_strvector_set(&id, i, str); } SETEASV(&g, "foo", &id); igraph_strvector_destroy(&id); for (i=0; i<igraph_ecount(&g); i++) { printf("%s ", EAS(&g, "foo", i)); } printf("\n"); igraph_strvector_init(&id, igraph_ecount(&g)); for (i=0; i<igraph_ecount(&g); i++) { snprintf(str, sizeof(str)-1, "%li", i); igraph_strvector_set(&id, i, str); } SETEASV(&g, "color", &id); igraph_strvector_destroy(&id); for (i=0; i<igraph_ecount(&g); i++) { printf("%s ", EAS(&g, "color", i)); } printf("\n"); /* Delete all remaining attributes */ DELALL(&g); igraph_cattribute_list(&g, &gnames, >ypes, &vnames, &vtypes, &enames, &etypes); if (igraph_strvector_size(&gnames) != 0 || igraph_strvector_size(&vnames) != 0 || igraph_strvector_size(&enames) != 0) { return 25; } /* Destroy */ igraph_vector_destroy(>ypes); igraph_vector_destroy(&vtypes); igraph_vector_destroy(&etypes); igraph_strvector_destroy(&gnames); igraph_strvector_destroy(&vnames); igraph_strvector_destroy(&enames); igraph_destroy(&g); return 0; }
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); }