Example #1
0
int
fmpz_mat_solve_cramer(fmpz_mat_t X, fmpz_t den,
                            const fmpz_mat_t A, const fmpz_mat_t B)
{
    long i, dim = fmpz_mat_nrows(A);

    if (dim == 0)
    {
        fmpz_one(den);
        return 1;
    }
    else if (dim == 1)
    {
        fmpz_set(den, fmpz_mat_entry(A, 0, 0));

        if (fmpz_is_zero(den))
            return 0;

        if (!fmpz_mat_is_empty(B))
            _fmpz_vec_set(X->rows[0], B->rows[0], fmpz_mat_ncols(B));
        return 1;
    }
    else if (dim == 2)
    {
        fmpz_t t, u;

        _fmpz_mat_det_cofactor_2x2(den, A->rows);

        if (fmpz_is_zero(den))
            return 0;

        fmpz_init(t);
        fmpz_init(u);

        for (i = 0; i < fmpz_mat_ncols(B); i++)
        {
            fmpz_mul   (t, fmpz_mat_entry(A, 1, 1), fmpz_mat_entry(B, 0, i));
            fmpz_submul(t, fmpz_mat_entry(A, 0, 1), fmpz_mat_entry(B, 1, i));
            fmpz_mul   (u, fmpz_mat_entry(A, 0, 0), fmpz_mat_entry(B, 1, i));
            fmpz_submul(u, fmpz_mat_entry(A, 1, 0), fmpz_mat_entry(B, 0, i));

            fmpz_swap(fmpz_mat_entry(X, 0, i), t);
            fmpz_swap(fmpz_mat_entry(X, 1, i), u);
        }

        fmpz_clear(t);
        fmpz_clear(u);

        return 1;
    }
    else if (dim == 3)
    {
        return _fmpz_mat_solve_cramer_3x3(X, den, A, B);
    }
    else
    {
        printf("Exception: fmpz_mat_solve_cramer: dim > 3 not implemented");
        abort();
    }
}
Example #2
0
void padic_val_fac(fmpz_t rop, const fmpz_t op, const fmpz_t p)
{
    fmpz_t t, q, pow;

    if (fmpz_sgn(op) <= 0)
    {
        printf("Exception (padic_val_fac).  op is non-positive.\n");
        abort();
    }

    fmpz_init(t);
    fmpz_init(q);
    fmpz_init(pow);
    fmpz_one(pow);

    do 
    {
        fmpz_mul(pow, pow, p);
        fmpz_fdiv_q(q, op, pow);
        fmpz_add(t, t, q);
    }
    while (!fmpz_is_zero(q));

    fmpz_swap(rop, t);
    fmpz_clear(t);
    fmpz_clear(q);
    fmpz_clear(pow);
}
Example #3
0
slong
hypgeom_root_norm(const fmpz_poly_t P)
{
    slong res, i, p;
    fmpz_t t, A;

    fmpz_init(A);
    fmpz_init(t);

    p = fmpz_poly_degree(P);

    fmpz_zero(A);

    for (i = 1; i <= p; i++)
    {
        fmpz_cdiv_abs_q(t, P->coeffs + p - i, P->coeffs + p);
        fmpz_root(t, t, i);
        fmpz_add_ui(t, t, 1);

        if (fmpz_cmp(t, A) > 0)
            fmpz_swap(t, A);
    }

    if (!fmpz_fits_si(A))
        abort();

    res = fmpz_get_si(A);

    fmpz_clear(A);
    fmpz_clear(t);

    return res;
}
Example #4
0
int _fmprb_poly_mid_get_hull(fmpz_t bot_exp, fmpz_t top_exp, fmprb_srcptr A, long lenA)
{
    long i;
    fmpz_t t;
    int have_nonzero = 0;

    fmpz_init(t);
    fmpz_zero(bot_exp);
    fmpz_zero(top_exp);

    for (i = 0; i < lenA; i++)
    {
        if (fmpr_is_normal(fmprb_midref(A + i)))
        {
            if (!have_nonzero)
            {
                have_nonzero = 1;
                fmpr_get_bot_exp(bot_exp, fmprb_midref(A + i));
                fmpr_get_top_exp(top_exp, fmprb_midref(A + i));
            }
            else
            {
                fmpr_get_bot_exp(t, fmprb_midref(A + i));
                if (fmpz_cmp(t, bot_exp) < 0)
                    fmpz_swap(t, bot_exp);

                fmpr_get_top_exp(t, fmprb_midref(A + i));
                if (fmpz_cmp(t, top_exp) > 0)
                    fmpz_swap(t, top_exp);
            }
        }
        else if (!fmpr_is_zero(fmprb_midref(A + i)))
        {
            printf("exception: inf or nan encountered in polynomial\n");
            abort();
        }
    }

    fmpz_clear(t);
    return have_nonzero;
}
Example #5
0
static __inline__ 
long _zeta_function(const fmpz_t p, long a, 
    long n, long d)
{
    const long b = gmc_basis_size(n, d);
    long i, N;

    fmpz_t f, g, max;

    fmpz_init(f);
    fmpz_init(g);
    fmpz_init(max);

    if (n == 3 && fmpz_cmp_ui(p, 2) != 0)
    {
        fmpz_bin_uiui(f, d-1, 3);
        fmpz_bin_uiui(g, b, b / 2);
        fmpz_mul_ui(g, g, 2);
        N = a * (*f) + fmpz_clog(g, p);
    }
    else if (n % 2L == 0)  /* n even implies b even */
    {
        fmpz_bin_uiui(f, b, b / 2);
        fmpz_pow_ui(g, p, (a * (b / 2) * (n - 1) + 1) / 2);
        fmpz_mul(f, f, g);
        fmpz_mul_ui(f, f, 2);

        N = fmpz_flog(f, p) + 1;
    }
    else
    {
        for (i = b / 2; i <= b; i++)
        {
            fmpz_bin_uiui(f, b, i);
            fmpz_pow_ui(g, p, (a * i * (n - 1) + 1) / 2);
            fmpz_mul(f, f, g);
            fmpz_mul_ui(f, f, 2);

            if (fmpz_cmp(max, f) < 0)
                fmpz_swap(max, f);
        }

        N = fmpz_flog(max, p) + 1;
    }

    fmpz_clear(f);
    fmpz_clear(g);
    fmpz_clear(max);

    return N;
}
Example #6
0
void
fmpz_poly_evaluate_horner_fmpz(fmpz_t res, const fmpz_poly_t f, const fmpz_t a)
{
    if (res == a)
    {
        fmpz_t t;
        fmpz_init(t);
        _fmpz_poly_evaluate_horner_fmpz(t, f->coeffs, f->length, a);
        fmpz_swap(res, t);
        fmpz_clear(t);
    }
    else
        _fmpz_poly_evaluate_horner_fmpz(res, f->coeffs, f->length, a);
}
Example #7
0
void
_fmpz_mod_poly_shift_right(fmpz * res, const fmpz * poly, long len, long n)
{
    long i;

    /* Copy in forward order to avoid writing over unshifted coefficients */
    if (res != poly)
    {
        for (i = 0; i < len - n; i++)
            fmpz_set(res + i, poly + n + i);
    }
    else
    {
        for (i = 0; i < len - n; i++)
            fmpz_swap(res + i, res + n + i);
    }

}
Example #8
0
void fmpz_mod_poly_evaluate_fmpz(fmpz_t res, 
                                 const fmpz_mod_poly_t poly, const fmpz_t a)
{
    if (res == a)
    {
        fmpz_t t;

        fmpz_init(t);
        _fmpz_mod_poly_evaluate_fmpz(t, poly->coeffs, poly->length, 
                                     a, &(poly->p));
        fmpz_swap(res, t);
        fmpz_clear(t);
    }
    else
    {
        _fmpz_mod_poly_evaluate_fmpz(res, poly->coeffs, poly->length, 
                                     a, &(poly->p));
    }
}
Example #9
0
static __inline__ void
_mag_vec_get_fmpz_2exp_blocks(fmpz * coeffs,
                              double * dblcoeffs, fmpz * exps, slong * blocks, const fmpz_t scale,
                              arb_srcptr x, mag_srcptr xm, slong len)
{
    fmpz_t top, bot, t, b, v, block_top, block_bot;
    slong i, j, s, block, bits, maxheight;
    int in_zero;
    mag_srcptr cur;

    fmpz_init(top);
    fmpz_init(bot);
    fmpz_init(t);
    fmpz_init(b);
    fmpz_init(v);
    fmpz_init(block_top);
    fmpz_init(block_bot);

    blocks[0] = 0;
    block = 0;
    in_zero = 1;

    maxheight = ALPHA * MAG_BITS + BETA;
    if (maxheight > DOUBLE_BLOCK_MAX_HEIGHT)
        abort();

    for (i = 0; i < len; i++)
    {
        cur = (x == NULL) ? (xm + i) : arb_radref(x + i);

        /* Skip (must be zero, since we assume there are no Infs/NaNs). */
        if (mag_is_special(cur))
            continue;

        /* Bottom and top exponent of current number */
        bits = MAG_BITS;
        fmpz_set(top, MAG_EXPREF(cur));
        fmpz_submul_ui(top, scale, i);
        fmpz_sub_ui(bot, top, bits);

        /* Extend current block. */
        if (in_zero)
        {
            fmpz_swap(block_top, top);
            fmpz_swap(block_bot, bot);
        }
        else
        {
            fmpz_max(t, top, block_top);
            fmpz_min(b, bot, block_bot);
            fmpz_sub(v, t, b);

            /* extend current block */
            if (fmpz_cmp_ui(v, maxheight) < 0)
            {
                fmpz_swap(block_top, t);
                fmpz_swap(block_bot, b);
            }
            else  /* start new block */
            {
                /* write exponent for previous block */
                fmpz_set(exps + block, block_bot);

                block++;
                blocks[block] = i;

                fmpz_swap(block_top, top);
                fmpz_swap(block_bot, bot);
            }
        }

        in_zero = 0;
    }

    /* write exponent for last block */
    fmpz_set(exps + block, block_bot);

    /* end marker */
    blocks[block + 1] = len;

    /* write the block data */
    for (i = 0; blocks[i] != len; i++)
    {
        for (j = blocks[i]; j < blocks[i + 1]; j++)
        {
            cur = (x == NULL) ? (xm + j) : arb_radref(x + j);

            if (mag_is_special(cur))
            {
                fmpz_zero(coeffs + j);
                dblcoeffs[j] = 0.0;
            }
            else
            {
                mp_limb_t man;
                double c;

                man = MAG_MAN(cur);

                /* TODO: only write and use doubles when block is short? */

                /* Divide by 2^(scale * j) */
                fmpz_mul_ui(t, scale, j);
                fmpz_sub(t, MAG_EXPREF(cur), t);

                fmpz_sub_ui(t, t, MAG_BITS); /* bottom exponent */
                s = _fmpz_sub_small(t, exps + i);

                if (s < 0) abort(); /* Bug catcher */

                fmpz_set_ui(coeffs + j, man);
                fmpz_mul_2exp(coeffs + j, coeffs + j, s);
                c = man;
                c = ldexp(c, s - DOUBLE_BLOCK_SHIFT);
                if (c < 1e-150 || c > 1e150) /* Bug catcher */
                    abort();
                dblcoeffs[j] = c;
            }
        }
    }

    fmpz_clear(top);
    fmpz_clear(bot);
    fmpz_clear(t);
    fmpz_clear(b);
    fmpz_clear(v);
    fmpz_clear(block_top);
    fmpz_clear(block_bot);
}
Example #10
0
static __inline__ void
_arb_vec_get_fmpz_2exp_blocks(fmpz * coeffs, fmpz * exps,
                              slong * blocks, const fmpz_t scale, arb_srcptr x, slong len, slong prec)
{
    fmpz_t top, bot, t, b, v, block_top, block_bot;
    slong i, j, s, block, bits, maxheight;
    int in_zero;

    fmpz_init(top);
    fmpz_init(bot);
    fmpz_init(t);
    fmpz_init(b);
    fmpz_init(v);
    fmpz_init(block_top);
    fmpz_init(block_bot);

    blocks[0] = 0;
    block = 0;
    in_zero = 1;

    if (prec == ARF_PREC_EXACT)
        maxheight = ARF_PREC_EXACT;
    else
        maxheight = ALPHA * prec + BETA;

    for (i = 0; i < len; i++)
    {
        bits = arf_bits(arb_midref(x + i));

        /* Skip (must be zero, since we assume there are no Infs/NaNs). */
        if (bits == 0)
            continue;

        /* Bottom and top exponent of current number */
        fmpz_set(top, ARF_EXPREF(arb_midref(x + i)));
        fmpz_submul_ui(top, scale, i);
        fmpz_sub_ui(bot, top, bits);

        /* Extend current block. */
        if (in_zero)
        {
            fmpz_swap(block_top, top);
            fmpz_swap(block_bot, bot);
        }
        else
        {
            fmpz_max(t, top, block_top);
            fmpz_min(b, bot, block_bot);
            fmpz_sub(v, t, b);

            /* extend current block */
            if (fmpz_cmp_ui(v, maxheight) < 0)
            {
                fmpz_swap(block_top, t);
                fmpz_swap(block_bot, b);
            }
            else  /* start new block */
            {
                /* write exponent for previous block */
                fmpz_set(exps + block, block_bot);

                block++;
                blocks[block] = i;

                fmpz_swap(block_top, top);
                fmpz_swap(block_bot, bot);
            }
        }

        in_zero = 0;
    }

    /* write exponent for last block */
    fmpz_set(exps + block, block_bot);

    /* end marker */
    blocks[block + 1] = len;

    /* write the block data */
    for (i = 0; blocks[i] != len; i++)
    {
        for (j = blocks[i]; j < blocks[i + 1]; j++)
        {
            if (arf_is_special(arb_midref(x + j)))
            {
                fmpz_zero(coeffs + j);
            }
            else
            {
                /* TODO: make this a single operation */
                arf_get_fmpz_2exp(coeffs + j, bot, arb_midref(x + j));

                fmpz_mul_ui(t, scale, j);
                fmpz_sub(t, bot, t);
                s = _fmpz_sub_small(t, exps + i);
                if (s < 0) abort(); /* Bug catcher */
                fmpz_mul_2exp(coeffs + j, coeffs + j, s);
            }
        }
    }

    fmpz_clear(top);
    fmpz_clear(bot);
    fmpz_clear(t);
    fmpz_clear(b);
    fmpz_clear(v);
    fmpz_clear(block_top);
    fmpz_clear(block_bot);
}
void
_fmpq_poly_revert_series_lagrange_fast(fmpz * Qinv, fmpz_t den,
                                    const fmpz * Q, const fmpz_t Qden, slong n)
{
    slong i, j, k, m;
    fmpz *R, *Rden, *S, *T, *dens, *tmp;
    fmpz_t Sden, Tden, t;

    if (fmpz_is_one(Qden) && (n > 1) && fmpz_is_pm1(Q + 1))
    {
        _fmpz_poly_revert_series(Qinv, Q, n);
        fmpz_one(den);
        return;
    }

    if (n <= 2)
    {
        fmpz_zero(Qinv);
        if (n == 2)
        {
            fmpz_set(Qinv + 1, Qden);
            fmpz_set(den, Q + 1);
            _fmpq_poly_canonicalise(Qinv, den, 2);
        }
        return;
    }

    m = n_sqrt(n);

    fmpz_init(t);
    dens = _fmpz_vec_init(n);
    R = _fmpz_vec_init((n - 1) * m);
    S = _fmpz_vec_init(n - 1);
    T = _fmpz_vec_init(n - 1);
    Rden = _fmpz_vec_init(m);
    fmpz_init(Sden);
    fmpz_init(Tden);

    fmpz_zero(Qinv);
    fmpz_one(dens);

    _fmpq_poly_inv_series(Ri(1), Rdeni(1), Q + 1, Qden, n - 1);
    _fmpq_poly_canonicalise(Ri(1), Rdeni(1), n - 1);

    for (i = 2; i <= m; i++)
    {
        _fmpq_poly_mullow(Ri(i), Rdeni(i), Ri(i-1), Rdeni(i-1), n - 1,
                Ri(1), Rdeni(1), n - 1, n - 1);
        _fmpq_poly_canonicalise(Ri(i), Rdeni(i), n - 1);
    }

    for (i = 1; i < m; i++)
    {
        fmpz_set(Qinv + i, Ri(i) + i - 1);
        fmpz_mul_ui(dens + i, Rdeni(i), i);
    }

    _fmpz_vec_set(S, Ri(m), n - 1);
    fmpz_set(Sden, Rdeni(m));

    for (i = m; i < n; i += m)
    {
        fmpz_set(Qinv + i, S + i - 1);
        fmpz_mul_ui(dens + i, Sden, i);

        for (j = 1; j < m && i + j < n; j++)
        {
            fmpz_mul(t, S + 0, Ri(j) + i + j - 1);

            for (k = 1; k <= i + j - 1; k++)
                fmpz_addmul(t, S + k, Ri(j) + i + j - 1 - k);

            fmpz_set(Qinv + i + j, t);
            fmpz_mul(dens + i + j, Sden, Rdeni(j));
            fmpz_mul_ui(dens + i + j, dens + i + j, i + j);
        }

        if (i + 1 < n)
        {
            _fmpq_poly_mullow(T, Tden, S, Sden, n - 1,
                Ri(m), Rdeni(m), n - 1, n - 1);
            _fmpq_poly_canonicalise(T, Tden, n - 1);
            fmpz_swap(Tden, Sden);
            tmp = S; S = T; T = tmp;
        }
    }

    _set_vec(Qinv, den, Qinv, dens, n);
    _fmpq_poly_canonicalise(Qinv, den, n);

    fmpz_clear(t);
    _fmpz_vec_clear(dens, n);
    _fmpz_vec_clear(R, (n - 1) * m);
    _fmpz_vec_clear(S, n - 1);
    _fmpz_vec_clear(T, n - 1);
    _fmpz_vec_clear(Rden, m);
    fmpz_clear(Sden);
    fmpz_clear(Tden);
}
Example #12
0
void
_fmpq_poly_revert_series_lagrange(fmpz * Qinv, fmpz_t den,
                            const fmpz * Q, const fmpz_t Qden, long n)
{
    long i;
    fmpz *R, *S, *T, *dens, *tmp;
    fmpz_t Rden, Sden, Tden;

    if (fmpz_is_one(Qden) && (n > 1) && fmpz_is_pm1(Q + 1))
    {
        _fmpz_poly_revert_series(Qinv, Q, n);
        fmpz_one(den);
    }
    else if (n <= 2)
    {
        fmpz_zero(Qinv);
        if (n == 2)
        {
            fmpz_set(Qinv + 1, Qden);
            fmpz_set(den, Q + 1);
            _fmpq_poly_canonicalise(Qinv, den, 2);
        }
    }
    else
    {
        dens = _fmpz_vec_init(n);
        R = _fmpz_vec_init(n - 1);
        S = _fmpz_vec_init(n - 1);
        T = _fmpz_vec_init(n - 1);
        fmpz_init(Rden);
        fmpz_init(Sden);
        fmpz_init(Tden);

        fmpz_zero(Qinv);
        fmpz_one(dens);
        fmpz_set(Qinv + 1, Qden);
        fmpz_set(dens + 1, Q + 1);

        _fmpq_poly_inv_series(R, Rden, Q + 1, Qden, n - 1);
        _fmpq_poly_canonicalise(R, Rden, n - 1);

        _fmpz_vec_set(S, R, n - 1);
        fmpz_set(Sden, Rden);

        for (i = 2; i < n; i++)
        {
            _fmpq_poly_mullow(T, Tden, S, Sden, n - 1, R, Rden, n - 1, n - 1);
            _fmpq_poly_canonicalise(T, Tden, n - 1);
            fmpz_set(Qinv + i, T + i - 1);
            fmpz_mul_ui(dens + i, Tden, i);
            tmp = S; S = T; T = tmp;
            fmpz_swap(Sden, Tden);
        }

        _set_vec(Qinv, den, Qinv, dens, n);
        _fmpq_poly_canonicalise(Qinv, den, n);

        _fmpz_vec_clear(R, n - 1);
        _fmpz_vec_clear(S, n - 1);
        _fmpz_vec_clear(T, n - 1);
        _fmpz_vec_clear(dens, n);
        fmpz_clear(Rden);
        fmpz_clear(Sden);
        fmpz_clear(Tden);
    }
}
Example #13
0
int
_fmpz_mat_solve_cramer_3x3(fmpz_mat_t X, fmpz_t den,
    const fmpz_mat_t A, const fmpz_mat_t B)
{
    fmpz_t t15, t16, t17;
    int success;

    fmpz_init(t15);
    fmpz_init(t16);
    fmpz_init(t17);

    fmpz_mul(t17, AA(1,0), AA(2,1));
    fmpz_submul(t17, AA(1,1), AA(2,0));

    fmpz_mul(t16, AA(1,2), AA(2,0));
    fmpz_submul(t16, AA(1,0), AA(2,2));

    fmpz_mul(t15, AA(1,1), AA(2,2));
    fmpz_submul(t15, AA(1,2), AA(2,1));

    fmpz_mul   (den, t15, AA(0,0));
    fmpz_addmul(den, t16, AA(0,1));
    fmpz_addmul(den, t17, AA(0,2));

    success = !fmpz_is_zero(den);

    if (success)
    {
        fmpz_t t12, t13, t14, x0, x1, x2;
        long i, n = fmpz_mat_ncols(B);

        fmpz_init(t12);
        fmpz_init(t13);
        fmpz_init(t14);
        fmpz_init(x0);
        fmpz_init(x1);
        fmpz_init(x2);

        for (i = 0; i < n; i++)
        {
            fmpz_mul(t14, AA(2,0), BB(1,i));
            fmpz_submul(t14, AA(1,0), BB(2,i));

            fmpz_mul(t13, AA(2,1), BB(1,i));
            fmpz_submul(t13, AA(1,1), BB(2,i));

            fmpz_mul(t12, AA(2,2), BB(1,i));
            fmpz_submul(t12, AA(1,2), BB(2,i));

            fmpz_mul   (x0, t15, BB(0,i));
            fmpz_addmul(x0, t13, AA(0,2));
            fmpz_submul(x0, t12, AA(0,1));

            fmpz_mul   (x1, t16, BB(0,i));
            fmpz_addmul(x1, t12, AA(0,0));
            fmpz_submul(x1, t14, AA(0,2));

            fmpz_mul   (x2, t17, BB(0,i));
            fmpz_addmul(x2, t14, AA(0,1));
            fmpz_submul(x2, t13, AA(0,0));

            fmpz_swap(XX(0,i), x0);
            fmpz_swap(XX(1,i), x1);
            fmpz_swap(XX(2,i), x2);
        }

        fmpz_clear(t12);
        fmpz_clear(t13);
        fmpz_clear(t14);
        fmpz_clear(x0);
        fmpz_clear(x1);
        fmpz_clear(x2);
    }

    fmpz_clear(t15);
    fmpz_clear(t16);
    fmpz_clear(t17);

    return success;
}
Example #14
0
static void dsum_2(
    fmpz_t rop, 
    const fmpz *dinv, const fmpz *mu, long M, const long *C, long lenC, 
    const fmpz_t a, long ui, long vi, long n, long d, long N)
{
    const fmpz_t P = {2L};
    const long m0  = (2 * (ui + 1) - (vi + 1)) / d;
    const long u   = ui + 1;

    long m, r;
    fmpz_t apow, f0, f1, f2, g;

    fmpz_init(apow);
    fmpz_init(f0);
    fmpz_init(f1);
    fmpz_init(f2);
    fmpz_init(g);

    fmpz_zero(rop);

    for (m = m0; m <= M; m += 2)
    {
        /* Note that r = 0 in the first iteration */
        r = m / 2;

        switch (r)
        {
          case 0:
            fmpz_one(f2);
            break;
          case 1:
            fmpz_one(f1);
            fmpz_set_ui(f2, u);
            break;
          case 5:
            fmpz_swap(f1, f2);
            fmpz_set_ui(f2, (u * (u + d) * (u + 2*d) * (u + 3*d) * (u + 4*d)) 
                / ((m0 == 0) ? 4 : 8));
            break;
          default:
            fmpz_swap(f0, f1);
            fmpz_swap(f1, f2);
            fmpz_mul_ui(f2, f0, ((u + (r-2)*d) * (u + (r-1)*d)) / 2);
            fmpz_fdiv_r_2exp(f2, f2, N);
        }

        if (r == 0)
        {
            fmpz_one(apow);
        }
        else
        {
            fmpz_mul(apow, apow, a);
            fmpz_fdiv_r_2exp(apow, apow, N);
        }

        /*
            g = a_i^r f_{r} d^{-r} \mu_m
              = h * f2 * dinv[r] * mu[m]
         */

        fmpz_mul(g, f2, dinv + r);
        fmpz_fdiv_r_2exp(g, g, N);
        fmpz_mul(g, g, apow);
        fmpz_fdiv_r_2exp(g, g, N);
        fmpz_mul(g, g, mu + m);
        fmpz_fdiv_r_2exp(g, g, N);

        fmpz_add(rop, rop, g);
    }

    fmpz_fdiv_r_2exp(rop, rop, N);

    fmpz_clear(apow);
    fmpz_clear(f0);
    fmpz_clear(f1);
    fmpz_clear(f2);
    fmpz_clear(g);
}
Example #15
0
slong
fmpr_div(fmpr_t z, const fmpr_t x, const fmpr_t y, slong prec, fmpr_rnd_t rnd)
{
    if (fmpr_is_special(x) || fmpr_is_special(y))
    {
        _fmpr_div_special(z, x, y);
        return FMPR_RESULT_EXACT;
    }

    /* division by power of two <=> shift exponents */
    if (fmpz_is_pm1(fmpr_manref(y)))
    {
        if (fmpz_is_one(fmpr_manref(y)))
            fmpz_set(fmpr_manref(z), fmpr_manref(x));
        else
            fmpz_neg(fmpr_manref(z), fmpr_manref(x));
        fmpz_sub(fmpr_expref(z), fmpr_expref(x), fmpr_expref(y));
        return _fmpr_normalise(fmpr_manref(z), fmpr_expref(z), prec, rnd);
    }
    else
    {
        slong xbits, ybits, extra, extra_pad, extra_control;
        int negative;
        fmpz_t t, u;

        /* todo: work out exact needed shift */
        xbits = fmpz_bits(fmpr_manref(x));
        ybits = fmpz_bits(fmpr_manref(y));

        extra = prec - xbits + ybits;
        extra = FLINT_MAX(extra, 0);

        extra_pad = 32;
        extra_control = 24;
        extra += extra_pad;

        fmpz_init(t);
        fmpz_init(u);

        fmpz_mul_2exp(t, fmpr_manref(x), extra);
        fmpz_tdiv_q(u, t, fmpr_manref(y));

        if (low_bits_are_zero(u, extra_control))
        {
            fmpz_t v;
            fmpz_init(v);
            fmpz_mul(v, u, fmpr_manref(y));

            negative = fmpz_sgn(fmpr_manref(x)) != fmpz_sgn(fmpr_manref(y));

            if (!fmpz_equal(t, v))
            {
                if (negative)
                    fmpz_sub_ui(u, u, 1);
                else
                    fmpz_add_ui(u, u, 1);
            }

            fmpz_clear(v);
        }

        fmpz_swap(fmpr_manref(z), u);

        fmpz_clear(t);
        fmpz_clear(u);

        fmpz_sub(fmpr_expref(z), fmpr_expref(x), fmpr_expref(y));
        fmpz_sub_ui(fmpr_expref(z), fmpr_expref(z), extra);

        return _fmpr_normalise(fmpr_manref(z), fmpr_expref(z), prec, rnd);
    }
}