Exemplo n.º 1
0
void
fmpr_pow_sloppy_fmpz(fmpr_t y, const fmpr_t b, const fmpz_t e,
    long prec, fmpr_rnd_t rnd)
{
    long i, wp, bits;

    if (fmpz_is_zero(e))
    {
        fmpr_set_ui(y, 1UL);
        return;
    }

    if (fmpz_sgn(e) < 0)
    {
        fmpz_t f;
        fmpz_init(f);
        fmpz_neg(f, e);
        fmpr_pow_sloppy_fmpz(y, b, f, prec + 2,
            (rnd == FMPR_RND_FLOOR || rnd == FMPR_RND_DOWN)
            ? FMPR_RND_UP : FMPR_RND_DOWN);
        fmpr_ui_div(y, 1UL, y, prec, rnd);
        fmpz_clear(f);
    }

    if (y == b)
    {
        fmpr_t t;
        fmpr_init(t);
        fmpr_set(t, b);
        fmpr_pow_sloppy_fmpz(y, t, e, prec, rnd);
        fmpr_clear(t);
        return;
    }

    fmpr_set(y, b);

    bits = fmpz_bits(e);
    wp = FMPR_PREC_ADD(prec, bits);

    for (i = bits - 2; i >= 0; i--)
    {
        fmpr_mul(y, y, y, wp, rnd);
        if (fmpz_tstbit(e, i))
            fmpr_mul(y, y, b, wp, rnd);
    }
}
Exemplo n.º 2
0
void _fq_nmod_pow(mp_limb_t *rop, const mp_limb_t *op, slong len, const fmpz_t e, 
                  const fq_nmod_ctx_t ctx)
{
    const slong d = fq_nmod_ctx_degree(ctx);

    if (fmpz_is_zero(e))
    {
        rop[0] = WORD(1);
        _nmod_vec_zero(rop + 1, 2 * d - 1 - 1);
    }
    else if (fmpz_is_one(e))
    {
        _nmod_vec_set(rop, op, len);
        _nmod_vec_zero(rop + len, 2 * d - 1 - len);
    }
    else
    {
        ulong bit;
        mp_limb_t *v = _nmod_vec_init(2 * d - 1);
        mp_limb_t *R, *S, *T;

        _nmod_vec_zero(v, 2 * d - 1);
        _nmod_vec_zero(rop, 2 * d - 1);

        /*
           Set bits to the bitmask with a 1 one place lower than the msb of e
         */

        bit = fmpz_bits(e) - 2;

        /*
           Trial run without any polynomial arithmetic to determine the parity 
           of the number of swaps;  then set R and S accordingly
         */
        
        {
            unsigned int swaps = 0U;
            ulong bit2 = bit;
            if (fmpz_tstbit(e, bit2))
                swaps = ~swaps;
            while (bit2--)
                if (!fmpz_tstbit(e, bit2))
                    swaps = ~swaps;
            
            if (swaps == 0U)
            {
                R = rop;
                S = v;
            }
            else
            {
                R = v;
                S = rop;
            }
        }
        
        /*
           We unroll the first step of the loop, referring to {op, len}
         */

        _nmod_poly_mul(R, op, len, op, len, ctx->mod);
        _fq_nmod_reduce(R, 2 * len - 1, ctx);

        if (fmpz_tstbit(e, bit))
        {
            _nmod_poly_mul(S, R, d, op, len, ctx->mod);
            _fq_nmod_reduce(S, d + len - 1, ctx);
            T = R;
            R = S;
            S = T;
        }

        while (bit--)
        {
            if (fmpz_tstbit(e, bit))
            {
                _nmod_poly_mul(S, R, d, R, d, ctx->mod);
                _fq_nmod_reduce(S, 2 * d - 1, ctx);
                _nmod_poly_mul(R, S, d, op, len, ctx->mod);
                _fq_nmod_reduce(R, d + len - 1, ctx);
            }
            else
            {
                _nmod_poly_mul(S, R, d, R, d, ctx->mod);
                _fq_nmod_reduce(S, 2 * d - 1, ctx);
                T = R;
                R = S;
                S = T;
            }
        }

        _nmod_vec_clear(v);
    }
}
Exemplo n.º 3
0
void
acb_pow_fmpz_binexp(acb_t y, const acb_t b, const fmpz_t e, long prec)
{
    long i, wp, bits;

    if (-2L <= *e && *e <= 4L)
    {
        if (*e == 0L)
        {
            acb_one(y);
        }
        else if (*e == 1L)
        {
            acb_set_round(y, b, prec);
        }
        else if (*e == -1L)
        {
            acb_inv(y, b, prec);
        }
        else if (*e == 2L)
        {
            acb_mul(y, b, b, prec);
        }
        else if (*e == 3L)
        {
            acb_cube(y, b, prec);
        }
        else if (*e == 4L)
        {
            acb_mul(y, b, b, prec);
            acb_mul(y, y, y, prec);
        }
        else
        {
            acb_inv(y, b, prec);
            acb_mul(y, y, y, prec);
        }
        return;
    }

    if (fmpz_sgn(e) < 0)
    {
        fmpz_t f;
        fmpz_init(f);
        fmpz_neg(f, e);
        acb_pow_fmpz_binexp(y, b, f, prec + 2);
        acb_inv(y, y, prec);
        fmpz_clear(f);
        return;
    }

    if (!COEFF_IS_MPZ(*e) && ((*e) % 3 == 0))
    {
        fmpz e3 = (*e) / 3;
        acb_pow_fmpz_binexp(y, b, &e3, prec);
        acb_cube(y, y, prec);
        return;
    }

    if (y == b)
    {
        acb_t t;
        acb_init(t);
        acb_set(t, b);
        acb_pow_fmpz_binexp(y, t, e, prec);
        acb_clear(t);
        return;
    }

    acb_set(y, b);

    bits = fmpz_bits(e);
    wp = ARF_PREC_ADD(prec, bits);

    for (i = bits - 2; i >= 0; i--)
    {
        acb_mul(y, y, y, wp);
        if (fmpz_tstbit(e, i))
            acb_mul(y, y, b, wp);
    }
}
Exemplo n.º 4
0
Arquivo: fib.c Projeto: argriffing/arb
void arb_fib_fmpz(arb_t f, const fmpz_t n, slong prec)
{
    arb_t t, u;
    slong wp, sign, i;

    if (fmpz_sgn(n) < 0)
    {
        fmpz_t m;
        fmpz_init(m);
        fmpz_neg(m, n);
        arb_fib_fmpz(f, m, prec);
        if (fmpz_is_even(m))
            arb_neg(f, f);
        fmpz_clear(m);
        return;
    }

    if (fmpz_cmp_ui(n, 4) <= 0)
    {
        ulong x = fmpz_get_ui(n);
        arb_set_ui(f, x - (x > 1));
        return;
    }

    wp = ARF_PREC_ADD(prec, 3 * fmpz_bits(n));

    arb_init(u);
    arb_init(t);
    arb_set_ui(f, UWORD(1));
    arb_set_ui(u, UWORD(1));
    sign = -1;

    for (i = fmpz_flog_ui(n, UWORD(2)) - 1; i > 0; i--)
    {
        arb_mul(t, f, f, wp);
        arb_add(f, f, u, wp);
        arb_mul_2exp_si(f, f, -1);
        arb_mul(f, f, f, wp);
        arb_mul_2exp_si(f, f, 1);
        arb_submul_ui(f, t, 3, wp);
        arb_sub_si(f, f, 2 * sign, wp);
        arb_mul_ui(u, t, 5, wp);
        arb_add_si(u, u, 2 * sign, wp);
        sign = 1;

        if (fmpz_tstbit(n, i))
        {
            arb_set(t, f);
            arb_add(f, f, u, wp);
            arb_mul_2exp_si(f, f, -1);
            arb_mul_2exp_si(t, t, 1);
            arb_add(u, f, t, wp);
            sign = -1;
        }
    }

    if (fmpz_tstbit(n, 0))
    {
        arb_add(f, f, u, wp);
        arb_mul_2exp_si(f, f, -1);
        arb_mul(f, f, u, wp);
        arb_sub_si(f, f, sign, prec);
    }
    else
    {
        arb_mul(f, f, u, prec);
    }

    arb_clear(u);
    arb_clear(t);
}