예제 #1
0
파일: pow_ui.c 프로젝트: isuruf/arb
void
arb_mat_pow_ui(arb_mat_t B, const arb_mat_t A, ulong exp, slong prec)
{
    slong d = arb_mat_nrows(A);

    if (exp <= 2 || d <= 1)
    {
        if (exp == 0 || d == 0)
        {
            arb_mat_one(B);
        }
        else if (d == 1)
        {
            arb_pow_ui(arb_mat_entry(B, 0, 0),
                 arb_mat_entry(A, 0, 0), exp, prec);
        }
        else if (exp == 1)
        {
            arb_mat_set(B, A);
        }
        else if (exp == 2)
        {
            arb_mat_sqr(B, A, prec);
        }
    }
    else
    {
        arb_mat_t T, U;
        slong i;

        arb_mat_init(T, d, d);
        arb_mat_set(T, A);
        arb_mat_init(U, d, d);

        for (i = ((slong) FLINT_BIT_COUNT(exp)) - 2; i >= 0; i--)
        {
            arb_mat_sqr(U, T, prec);

            if (exp & (WORD(1) << i))
                arb_mat_mul(T, U, A, prec);
            else
                arb_mat_swap(T, U);
        }

        arb_mat_swap(B, T);
        arb_mat_clear(T);
        arb_mat_clear(U);
    }
}
예제 #2
0
파일: lu.c 프로젝트: bluescarni/arb
int
arb_mat_lu(long * P, arb_mat_t LU, const arb_mat_t A, long prec)
{
    arb_t d, e;
    arb_ptr * a;
    long i, j, m, n, r, row, col;
    int result;

    m = arb_mat_nrows(A);
    n = arb_mat_ncols(A);

    result = 1;

    if (m == 0 || n == 0)
        return result;

    arb_mat_set(LU, A);

    a = LU->rows;

    row = col = 0;
    for (i = 0; i < m; i++)
        P[i] = i;

    arb_init(d);
    arb_init(e);

    while (row < m && col < n)
    {
        r = arb_mat_find_pivot_partial(LU, row, m, col);

        if (r == -1)
        {
            result = 0;
            break;
        }
        else if (r != row)
            arb_mat_swap_rows(LU, P, row, r);

        arb_set(d, a[row] + col);

        for (j = row + 1; j < m; j++)
        {
            arb_div(e, a[j] + col, d, prec);
            arb_neg(e, e);
            _arb_vec_scalar_addmul(a[j] + col,
                a[row] + col, n - col, e, prec);
            arb_zero(a[j] + col);
            arb_neg(a[j] + row, e);
        }

        row++;
        col++;
    }

    arb_clear(d);
    arb_clear(e);

    return result;
}
예제 #3
0
/* Calculate the likelihood, storing many intermediate calculations. */
void
evaluate_site_lhood(arb_t lhood,
        arb_mat_struct *lhood_node_vectors,
        arb_mat_struct *lhood_edge_vectors,
        const arb_mat_struct *base_node_vectors,
        const root_prior_t r, const arb_struct *equilibrium,
        const arb_mat_struct *transition_matrices,
        const csr_graph_struct *g,
        const int *preorder, int node_count, slong prec)
{
    int u, a, b, idx;
    int start, stop;
    arb_mat_struct *nmat, *nmatb, *emat;
    const arb_mat_struct *tmat;

    for (u = 0; u < node_count; u++)
    {
        a = preorder[node_count - 1 - u];
        nmat = lhood_node_vectors + a;
        start = g->indptr[a];
        stop = g->indptr[a+1];

        /* initialize the state vector for node a */
        arb_mat_set(nmat, base_node_vectors + a);

        /* create all of the state vectors on edges outgoing from this node */
        for (idx = start; idx < stop; idx++)
        {
            b = g->indices[idx];
            /*
             * At this point (a, b) is an edge from node a to node b
             * in a post-order traversal of edges of the tree.
             */
            tmat = transition_matrices + idx;
            nmatb = lhood_node_vectors + b;
            /*
             * Update vectors on edges if requested,
             * otherwise avoid using temporary vectors on edges.
             * In either case, lhood node vectors are updated.
             */
            if (lhood_edge_vectors)
            {
                emat = lhood_edge_vectors + idx;
                _arb_mat_mul_stochastic(emat, tmat, nmatb, prec);
                arb_mat_mul_entrywise(nmat, nmat, emat, prec);
            }
            else
            {
                _prune_update_prob(nmat, nmat, tmat, nmatb, prec);
            }
        }
    }

    /* Report the sum of state entries associated with the root. */
    int root_node_index = preorder[0];
    nmat = lhood_node_vectors + root_node_index;
    root_prior_expectation(lhood, r, nmat, equilibrium, prec);
}
예제 #4
0
void
cross_site_ws_update_with_edge_rates(cross_site_ws_t w,
        const model_and_data_t m, const arb_struct *edge_rates, slong prec)
{
    w->prec = prec;

    /* update rate mixture */
    rate_mixture_summarize(
            w->rate_mix_prior, w->rate_mix_rates, w->rate_mix_expect,
            m->rate_mixture, prec);

    /* update the equilibrium if necessary, ignoring diagonal entries */
    if (model_and_data_uses_equilibrium(m))
    {
        _arb_vec_rate_matrix_equilibrium(w->equilibrium, m->mat, prec);
    }

    /* update the unscaled rate matrix, and zero the diagonal */
    arb_mat_set(w->rate_matrix, m->mat);
    _arb_mat_zero_diagonal(w->rate_matrix);

    /* update the rate divisor, optionally using the equilibrium */
    _update_rate_divisor(w, m, prec);

    /*
     * Scale the rate matrix according to the rate divisor.
     * Each rate matrix associated with a specific rate category
     * and branch will need to be further scaled.
     */
    arb_mat_scalar_div_arb(w->rate_matrix,
            w->rate_matrix, w->rate_divisor, prec);

    /* update the diagonal of the rate matrix */
    _arb_update_rate_matrix_diagonal(w->rate_matrix, prec);

    /* optionally set edge rates */
    if (edge_rates)
    {
        _arb_vec_set(w->edge_rates, edge_rates, w->edge_count);
    }

    /* update the transition probability matrices */
    _update_transition_matrices(w, prec);
}
예제 #5
0
void
arb_mat_solve_cho_precomp(arb_mat_t X,
    const arb_mat_t L, const arb_mat_t B, slong prec)
{
    slong i, j, c, n, m;

    n = arb_mat_nrows(X);
    m = arb_mat_ncols(X);

    arb_mat_set(X, B);

    for (c = 0; c < m; c++)
    {
        /* solve Ly = b */
        for (i = 0; i < n; i++)
        {
            for (j = 0; j < i; j++)
            {
                arb_submul(arb_mat_entry(X, i, c),
                    arb_mat_entry(L, i, j), arb_mat_entry(X, j, c), prec);
            }
            arb_div(arb_mat_entry(X, i, c), arb_mat_entry(X, i, c),
                arb_mat_entry(L, i, i), prec);
        }

        /* solve Ux = y */
        for (i = n - 1; i >= 0; i--)
        {
            for (j = i + 1; j < n; j++)
            {
                arb_submul(arb_mat_entry(X, i, c),
                    arb_mat_entry(L, j, i), arb_mat_entry(X, j, c), prec);
            }
            arb_div(arb_mat_entry(X, i, c), arb_mat_entry(X, i, c),
                arb_mat_entry(L, i, i), prec);
        }
    }
}
예제 #6
0
static int
_spd_inv(arb_mat_t X, const arb_mat_t A, slong prec)
{
    slong n;
    arb_mat_t L;
    int result;

    n = arb_mat_nrows(A);
    arb_mat_init(L, n, n);
    arb_mat_set(L, A);

    if (_arb_mat_ldl_inplace(L, prec))
    {
        arb_mat_inv_ldl_precomp(X, L, prec);
        result = 1;
    }
    else
    {
        result = 0;
    }

    arb_mat_clear(L);
    return result;
}
예제 #7
0
파일: arb_extras.c 프로젝트: jwbober/ntlib
int arb_mat_jacobi(arb_mat_t D, arb_mat_t P, const arb_mat_t A, slong prec) {
    //
    // Given a d x d real symmetric matrix A, compute an orthogonal matrix
    // P and a diagonal D such that A = P D P^t = P D P^(-1).
    //
    // D should have already been initialized as a d x 1 matrix, and Pp
    // should have already been initialized as a d x d matrix.
    //
    // If the eigenvalues can be certified as unique, then a nonzero int is
    // returned, and the eigenvectors should have reasonable error bounds. If
    // the eigenvalues cannot be certified as unique, then some of the
    // eigenvectors will have infinite error radius.

#define B(i,j) arb_mat_entry(B, i, j)
#define D(i) arb_mat_entry(D, i, 0)
#define P(i,j) arb_mat_entry(P, i, j)
    int dim = arb_mat_nrows(A);
    if(dim == 1) {
        arb_mat_set(D, A);
        arb_mat_one(P);
        return 0;
    }
    arb_mat_t B;
    arb_mat_init(B, dim, dim);

    arf_t * B1 = (arf_t*)malloc(dim * sizeof(arf_t));
    arf_t * B2 = (arf_t*)malloc(dim * sizeof(arf_t));
    arf_t * row_max = (arf_t*)malloc((dim - 1) * sizeof(arf_t));
    int * row_max_indices = (int*)malloc((dim - 1) * sizeof(int));

    for(int k = 0; k < dim; k++) {
        arf_init(B1[k]);
        arf_init(B2[k]);
    }
    for(int k = 0; k < dim - 1; k++) {
        arf_init(row_max[k]);
    }

    arf_t x1, x2;
    arf_init(x1);
    arf_init(x2);

    arf_t Gii, Gij, Gji, Gjj;
    arf_init(Gii);
    arf_init(Gij);
    arf_init(Gji);
    arf_init(Gjj);

    arb_mat_set(B, A);
    arb_mat_one(P);

    for(int i = 0; i < dim - 1; i++) {
        for(int j = i + 1; j < dim; j++) {
            arf_abs(x1, arb_midref(B(i,j)));
            if(arf_cmp(row_max[i], x1) < 0) {
                arf_set(row_max[i], x1);
                row_max_indices[i] = j;
            }
        }
    }


    int finished = 0;

    while(!finished) {
        arf_zero(x1);
        int i = 0;
        int j = 0;
        for(int k = 0; k < dim - 1; k++) {
            if(arf_cmp(x1, row_max[k]) < 0) {
                arf_set(x1, row_max[k]);
                i = k;
            }
        }
        j = row_max_indices[i];

        slong bound = arf_abs_bound_lt_2exp_si(x1);
        if(bound < -prec * .9) {
            finished = 1;
            break;
        }
        else {
            //printf("%ld\n", arf_abs_bound_lt_2exp_si(x1));
            //arb_mat_printd(B, 10);
            //printf("\n");
        }

        arf_twobytwo_diag(Gii, Gij, arb_midref(B(i,i)), arb_midref(B(i,j)), arb_midref(B(j,j)), 2*prec);
        arf_neg(Gji, Gij);
        arf_set(Gjj, Gii);

        //printf("%d %d\n", i, j);
        //arf_printd(Gii, 100);
        //printf(" ");
        //arf_printd(Gij, 100);
        //printf("\n");
        if(arf_is_zero(Gij)) {  // If this happens, we're
            finished = 1;       // not going to do any better
            break;              // without increasing the precision.
        }

        for(int k = 0; k < dim; k++) {
            arf_mul(B1[k], Gii, arb_midref(B(i,k)), prec, ARF_RND_NEAR);
            arf_addmul(B1[k], Gji, arb_midref(B(j,k)), prec, ARF_RND_NEAR);

            arf_mul(B2[k], Gij, arb_midref(B(i,k)), prec, ARF_RND_NEAR);
            arf_addmul(B2[k], Gjj, arb_midref(B(j,k)), prec, ARF_RND_NEAR);
        }
        for(int k = 0; k < dim; k++) {
            arf_set(arb_midref(B(i,k)), B1[k]);
            arf_set(arb_midref(B(j,k)), B2[k]);
        }
        for(int k = 0; k < dim; k++) {
            arf_mul(B1[k], Gii, arb_midref(B(k,i)), prec, ARF_RND_NEAR);
            arf_addmul(B1[k], Gji, arb_midref(B(k,j)), prec, ARF_RND_NEAR);

            arf_mul(B2[k], Gij, arb_midref(B(k,i)), prec, ARF_RND_NEAR);
            arf_addmul(B2[k], Gjj, arb_midref(B(k,j)), prec, ARF_RND_NEAR);
        }
        for(int k = 0; k < dim; k++) {
            arf_set(arb_midref(B(k,i)), B1[k]);
            arf_set(arb_midref(B(k,j)), B2[k]);
        }

        for(int k = 0; k < dim; k++) {
            arf_mul(B1[k], Gii, arb_midref(P(k,i)), prec, ARF_RND_NEAR);
            arf_addmul(B1[k], Gji, arb_midref(P(k,j)), prec, ARF_RND_NEAR);

            arf_mul(B2[k], Gij, arb_midref(P(k,i)), prec, ARF_RND_NEAR);
            arf_addmul(B2[k], Gjj, arb_midref(P(k,j)), prec, ARF_RND_NEAR);
        }
        for(int k = 0; k < dim; k++) {
            arf_set(arb_midref(P(k,i)), B1[k]);
            arf_set(arb_midref(P(k,j)), B2[k]);
        }

        if(i < dim - 1)
            arf_set_ui(row_max[i], 0);
        if(j < dim - 1)
            arf_set_ui(row_max[j], 0);

        // Update the max in any row where the maximum
        // was in a column that changed.
        for(int k = 0; k < dim - 1; k++) {
            if(row_max_indices[k] == j || row_max_indices[k] == i) {
                arf_abs(row_max[k], arb_midref(B(k,k+1)));
                row_max_indices[k] = k+1;
                for(int l = k+2; l < dim; l++) {
                    arf_abs(x1, arb_midref(B(k,l)));
                    if(arf_cmp(row_max[k], x1) < 0) {
                        arf_set(row_max[k], x1);
                        row_max_indices[k] = l;
                    }
                }
            }
        }

        // Update the max in the ith row.
        for(int k = i + 1; k < dim; k++) {
            arf_abs(x1, arb_midref(B(i, k)));
            if(arf_cmp(row_max[i], x1) < 0) {
                arf_set(row_max[i], x1);
                row_max_indices[i] = k;
            }
        }

        // Update the max in the jth row.
        for(int k = j + 1; k < dim; k++) {
            arf_abs(x1, arb_midref(B(j, k)));
            if(arf_cmp(row_max[j], x1) < 0) {
                arf_set(row_max[j], x1);
                row_max_indices[j] = k;
            }
        }

        // Go through column i to see if any of
        // the new entries are larger than the
        // max of their row.
        for(int k = 0; k < i; k++) {
            if(k == dim) continue;
            arf_abs(x1, arb_midref(B(k, i)));
            if(arf_cmp(row_max[k], x1) < 0) {
                arf_set(row_max[k], x1);
                row_max_indices[k] = i;
            }
        }

        // And then column j.
        for(int k = 0; k < j; k++) {
            if(k == dim) continue;
            arf_abs(x1, arb_midref(B(k, j)));
            if(arf_cmp(row_max[k], x1) < 0) {
                arf_set(row_max[k], x1);
                row_max_indices[k] = j;
            }
        }
    }

    for(int k = 0; k < dim; k++) {
        arb_set(D(k), B(k,k));
        arb_set_exact(D(k));
    }

    // At this point we've done that diagonalization and all that remains is
    // to certify the correctness and compute error bounds.

    arb_mat_t e;

    arb_t error_norms[dim];
    for(int k = 0; k < dim; k++) arb_init(error_norms[k]);

    arb_mat_init(e, dim, 1);

    arb_t z1, z2;
    arb_init(z1);
    arb_init(z2);
    for(int j = 0; j < dim; j++) {
        arb_mat_set(B, A);
        for(int k = 0; k < dim; k++) {
            arb_sub(B(k, k), B(k, k), D(j), prec);
        }
        for(int k = 0; k < dim; k++) {
            arb_set(arb_mat_entry(e, k, 0), P(k, j));
        }
        arb_mat_L2norm(z2, e, prec);
        arb_mat_mul(e, B, e, prec);
        arb_mat_L2norm(error_norms[j], e, prec);

        arb_div(z2, error_norms[j], z2, prec); // and now z1 is an upper bound for the
                                               // error in the eigenvalue
        arb_add_error(D(j), z2);
    }

    int unique_eigenvalues = 1;
    for(int j = 0; j < dim; j++) {
        if(j == 0) {
            arb_sub(z1, D(j), D(1), prec);
        }
        else {
            arb_sub(z1, D(j), D(0), prec);
        }
        arb_get_abs_lbound_arf(x1, z1, prec);
        for(int k = 1; k < dim; k++) {
            if(k == j) continue;
            arb_sub(z1, D(j), D(k), prec);
            arb_get_abs_lbound_arf(x2, z1, prec);
            if(arf_cmp(x2, x1) < 0) {
                arf_set(x1, x2);
            }
        }
        if(arf_is_zero(x1)) {
            unique_eigenvalues = 0;
        }
        arb_div_arf(z1, error_norms[j], x1, prec);
        for(int k = 0; k < dim; k++) {
            arb_add_error(P(k, j), z1);
        }
    }

    arb_mat_clear(e);
    arb_clear(z1);
    arb_clear(z2);
    for(int k = 0; k < dim; k++) arb_clear(error_norms[k]);

    arf_clear(x1);
    arf_clear(x2);
    arb_mat_clear(B);
    for(int k = 0; k < dim; k++) {
        arf_clear(B1[k]);
        arf_clear(B2[k]);
    }
    for(int k = 0; k < dim - 1; k++) {
        arf_clear(row_max[k]);
    }
    arf_clear(Gii);
    arf_clear(Gij);
    arf_clear(Gji);
    arf_clear(Gjj);
    free(B1);
    free(B2);
    free(row_max);
    free(row_max_indices);

    if(unique_eigenvalues) return 0;
    else return 1;
#undef B
#undef D
#undef P
}
예제 #8
0
파일: exp.c 프로젝트: wbhart/arb
/* evaluates the truncated Taylor series (assumes no aliasing) */
void
_arb_mat_exp_taylor(arb_mat_t S, const arb_mat_t A, slong N, slong prec)
{
    if (N == 1)
    {
        arb_mat_one(S);
    }
    else if (N == 2)
    {
        arb_mat_one(S);
        arb_mat_add(S, S, A, prec);
    }
    else if (N == 3)
    {
        arb_mat_t T;
        arb_mat_init(T, arb_mat_nrows(A), arb_mat_nrows(A));
        arb_mat_mul(T, A, A, prec);
        arb_mat_scalar_mul_2exp_si(T, T, -1);
        arb_mat_add(S, A, T, prec);
        arb_mat_one(T);
        arb_mat_add(S, S, T, prec);
        arb_mat_clear(T);
    }
    else
    {
        slong i, lo, hi, m, w, dim;
        arb_mat_struct * pows;
        arb_mat_t T, U;
        fmpz_t c, f;

        dim = arb_mat_nrows(A);
        m = n_sqrt(N);
        w = (N + m - 1) / m;

        fmpz_init(c);
        fmpz_init(f);
        pows = flint_malloc(sizeof(arb_mat_t) * (m + 1));
        arb_mat_init(T, dim, dim);
        arb_mat_init(U, dim, dim);

        for (i = 0; i <= m; i++)
        {
            arb_mat_init(pows + i, dim, dim);
            if (i == 0)
                arb_mat_one(pows + i);
            else if (i == 1)
                arb_mat_set(pows + i, A);
            else
                arb_mat_mul(pows + i, pows + i - 1, A, prec);
        }

        arb_mat_zero(S);
        fmpz_one(f);

        for (i = w - 1; i >= 0; i--)
        {
            lo = i * m;
            hi = FLINT_MIN(N - 1, lo + m - 1);

            arb_mat_zero(T);
            fmpz_one(c);

            while (hi >= lo)
            {
                arb_mat_scalar_addmul_fmpz(T, pows + hi - lo, c, prec);
                if (hi != 0)
                    fmpz_mul_ui(c, c, hi);
                hi--;
            }

            arb_mat_mul(U, pows + m, S, prec);
            arb_mat_scalar_mul_fmpz(S, T, f, prec);
            arb_mat_add(S, S, U, prec);
            fmpz_mul(f, f, c);
        }

        arb_mat_scalar_div_fmpz(S, S, f, prec);

        fmpz_clear(c);
        fmpz_clear(f);
        for (i = 0; i <= m; i++)
            arb_mat_clear(pows + i);
        flint_free(pows);
        arb_mat_clear(T);
        arb_mat_clear(U);
    }
}
예제 #9
0
int main()
{
    slong iter;
    flint_rand_t state;

    flint_printf("mul_entrywise....");
    fflush(stdout);

    flint_randinit(state);

    for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++)
    {
        slong m, n, qbits1, qbits2, rbits1, rbits2, rbits3;
        fmpq_mat_t A, B, C;
        arb_mat_t a, b, c, d;

        qbits1 = 2 + n_randint(state, 200);
        qbits2 = 2 + n_randint(state, 200);
        rbits1 = 2 + n_randint(state, 200);
        rbits2 = 2 + n_randint(state, 200);
        rbits3 = 2 + n_randint(state, 200);

        m = n_randint(state, 10);
        n = n_randint(state, 10);

        fmpq_mat_init(A, m, n);
        fmpq_mat_init(B, m, n);
        fmpq_mat_init(C, m, n);

        arb_mat_init(a, m, n);
        arb_mat_init(b, m, n);
        arb_mat_init(c, m, n);
        arb_mat_init(d, m, n);

        fmpq_mat_randtest(A, state, qbits1);
        fmpq_mat_randtest(B, state, qbits2);
        _fmpq_mat_mul_entrywise(C, A, B);

        arb_mat_set_fmpq_mat(a, A, rbits1);
        arb_mat_set_fmpq_mat(b, B, rbits2);
        arb_mat_mul_entrywise(c, a, b, rbits3);

        if (!arb_mat_contains_fmpq_mat(c, C))
        {
            flint_printf("FAIL\n\n");
            flint_printf("m = %wd, n = %wd, bits3 = %wd\n", m, n, rbits3);

            flint_printf("A = "); fmpq_mat_print(A); flint_printf("\n\n");
            flint_printf("B = "); fmpq_mat_print(B); flint_printf("\n\n");
            flint_printf("C = "); fmpq_mat_print(C); flint_printf("\n\n");

            flint_printf("a = "); arb_mat_printd(a, 15); flint_printf("\n\n");
            flint_printf("b = "); arb_mat_printd(b, 15); flint_printf("\n\n");
            flint_printf("c = "); arb_mat_printd(c, 15); flint_printf("\n\n");

            abort();
        }

        /* test aliasing with a */
        if (arb_mat_nrows(a) == arb_mat_nrows(c) &&
            arb_mat_ncols(a) == arb_mat_ncols(c))
        {
            arb_mat_set(d, a);
            arb_mat_mul_entrywise(d, d, b, rbits3);
            if (!arb_mat_equal(d, c))
            {
                flint_printf("FAIL (aliasing 1)\n\n");
                abort();
            }
        }

        /* test aliasing with b */
        if (arb_mat_nrows(b) == arb_mat_nrows(c) &&
            arb_mat_ncols(b) == arb_mat_ncols(c))
        {
            arb_mat_set(d, b);
            arb_mat_mul_entrywise(d, a, d, rbits3);
            if (!arb_mat_equal(d, c))
            {
                flint_printf("FAIL (aliasing 2)\n\n");
                abort();
            }
        }

        fmpq_mat_clear(A);
        fmpq_mat_clear(B);
        fmpq_mat_clear(C);

        arb_mat_clear(a);
        arb_mat_clear(b);
        arb_mat_clear(c);
        arb_mat_clear(d);
    }

    flint_randclear(state);
    flint_cleanup();
    flint_printf("PASS\n");
    return EXIT_SUCCESS;
}