int main() {
  
  igraph_t g, tree;
  igraph_vector_t eb, edges;
  long int i;
  
  igraph_small(&g, 0, IGRAPH_UNDIRECTED, 
	       0,  1,  0,  2,  0,  3,  0,  4,  0,  5,
	       0,  6,  0,  7,  0,  8,  0, 10,  0, 11,
	       0, 12,  0, 13,  0, 17,  0, 19,  0, 21,
	       0, 31,  1,  2,  1,  3,  1,  7,  1, 13,
	       1, 17,  1, 19,  1, 21,  1, 30,  2,  3,
	       2,  7,  2,  8,  2,  9,  2, 13,  2, 27,
	       2, 28,  2, 32,  3,  7,  3, 12,  3, 13,
	       4,  6,  4, 10,  5,  6,  5, 10,  5, 16,
	       6, 16,  8, 30,  8, 32,  8, 33,  9, 33,
	       13, 33, 14, 32, 14, 33, 15, 32, 15, 33,
	       18, 32, 18, 33, 19, 33, 20, 32, 20, 33,
	       22, 32, 22, 33, 23, 25, 23, 27, 23, 29,
	       23, 32, 23, 33, 24, 25, 24, 27, 24, 31,
	       25, 31, 26, 29, 26, 33, 27, 33, 28, 31,
	       28, 33, 29, 32, 29, 33, 30, 32, 30, 33,
	       31, 32, 31, 33, 32, 33,
	       -1);
  
  igraph_vector_init(&eb, igraph_ecount(&g));
  igraph_edge_betweenness(&g, &eb, IGRAPH_UNDIRECTED, /*weights=*/ 0);
  for (i=0; i<igraph_vector_size(&eb); i++) {
    VECTOR(eb)[i] = -VECTOR(eb)[i];
  }

  igraph_minimum_spanning_tree_prim(&g, &tree, &eb);
  igraph_write_graph_edgelist(&tree, stdout);

  igraph_vector_init(&edges, 0);
  igraph_minimum_spanning_tree(&g, &edges, &eb);
  igraph_vector_print(&edges);
  igraph_vector_destroy(&edges);

  igraph_destroy(&tree);
  igraph_destroy(&g);
  igraph_vector_destroy(&eb);
  
  return 0;
}
Exemplo n.º 2
0
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);
}