Exemple #1
0
int
arf_add(arf_ptr z, arf_srcptr x, arf_srcptr y, slong prec, arf_rnd_t rnd)
{
    mp_size_t xn, yn;
    mp_srcptr xptr, yptr;
    slong shift;

    if (arf_is_special(x) || arf_is_special(y))
    {
        return arf_add_special(z, x, y, prec, rnd);
    }

    shift = _fmpz_sub_small(ARF_EXPREF(x), ARF_EXPREF(y));

    if (shift < 0)
    {
        arf_srcptr __t;
        __t = x; x = y; y = __t;
        shift = -shift;
    }

    ARF_GET_MPN_READONLY(xptr, xn, x);
    ARF_GET_MPN_READONLY(yptr, yn, y);

    return _arf_add_mpn(z, xptr, xn, ARF_SGNBIT(x), ARF_EXPREF(x),
                           yptr, yn, ARF_SGNBIT(y), shift, prec, rnd);
}
Exemple #2
0
int
arf_equal(const arf_t x, const arf_t y)
{
    mp_size_t n;

    if (x == y)
        return 1;

    if (ARF_XSIZE(x) != ARF_XSIZE(y))
        return 0;

    if (!fmpz_equal(ARF_EXPREF(x), ARF_EXPREF(y)))
        return 0;

    n = ARF_SIZE(x);

    if (n == 0)
        return 1;

    if (n == 1)
        return ARF_NOPTR_D(x)[0] == ARF_NOPTR_D(y)[0];

    if (n == 2)
        return (ARF_NOPTR_D(x)[0] == ARF_NOPTR_D(y)[0] &&
                ARF_NOPTR_D(x)[1] == ARF_NOPTR_D(y)[1]);

    return mpn_cmp(ARF_PTR_D(x), ARF_PTR_D(y), n) == 0;
}
Exemple #3
0
int _arf_are_close(const arf_t x, const arf_t y, long prec)
{
    fmpz_t xb, yb;
    fmpz_t delta;
    int result;

    fmpz_init(xb);
    fmpz_init(yb);
    fmpz_init(delta);

    arf_bot(xb, x);
    arf_bot(yb, y);

    if (fmpz_cmp(ARF_EXPREF(x), ARF_EXPREF(y)) >= 0)
        fmpz_sub(delta, xb, ARF_EXPREF(y));
    else
        fmpz_sub(delta, yb, ARF_EXPREF(x));

    fmpz_sub_ui(delta, delta, 64);
    result = (fmpz_cmp_ui(delta, prec) < 0);

    fmpz_clear(xb);
    fmpz_clear(yb);
    fmpz_clear(delta);

    return result;
}
Exemple #4
0
int
arf_set_round(arf_t y, const arf_t x, slong prec, arf_rnd_t rnd)
{
    if (arf_is_special(x))
    {
        arf_set(y, x);
        return 0;
    }
    else
    {
        int inexact;
        slong fix;
        mp_size_t xn;
        mp_srcptr xptr;

        if (y == x)
        {
            mp_ptr xtmp;
            TMP_INIT;

            ARF_GET_MPN_READONLY(xptr, xn, x);

            /* exact */
            if (xn * FLINT_BITS <= prec)
                return 0;

            if ((xn - 1) * FLINT_BITS < prec)
            {
                /* exact */
                if ((xptr[0] << (prec - (xn-1) *  FLINT_BITS)) == 0)
                    return 0;
            }

            /* inexact */
            TMP_START;
            xtmp = TMP_ALLOC(xn * sizeof(mp_limb_t));
            flint_mpn_copyi(xtmp, xptr, xn);
            inexact = _arf_set_round_mpn(y, &fix, xtmp, xn, ARF_SGNBIT(x), prec, rnd);
            _fmpz_add_fast(ARF_EXPREF(y), ARF_EXPREF(x), fix);

            TMP_END;
            return inexact;
        }
        else
        {
            ARF_GET_MPN_READONLY(xptr, xn, x);
            inexact = _arf_set_round_mpn(y, &fix, xptr, xn,
                ARF_SGNBIT(x), prec, rnd);
            _fmpz_add_fast(ARF_EXPREF(y), ARF_EXPREF(x), fix);
            return inexact;
        }
    }
}
Exemple #5
0
Fichier : sub.c Projet : isuruf/arb
int
arf_sub_si(arf_ptr z, arf_srcptr x, slong y, slong prec, arf_rnd_t rnd)
{
    mp_size_t xn, yn;
    mp_srcptr xptr, yptr;
    mp_limb_t ytmp;
    int xsgnbit, ysgnbit;
    fmpz yexp;
    slong shift;

    if (y == 0)
    {
        return arf_set_round(z, x, prec, rnd);
    }
    else if (arf_is_special(x))
    {
        if (arf_is_zero(x))
        {
            arf_set_si(z, y);
            return arf_neg_round(z, z, prec, rnd);
        }
        else
        {
            arf_set(z, x);
            return 0;
        }
    }

    ysgnbit = (y < 0);
    if (ysgnbit)
        ytmp = -y;
    else
        ytmp = y;
    yptr = &ytmp;
    yn = 1;
    yexp = FLINT_BITS;
    ysgnbit ^= 1;

    shift = _fmpz_sub_small(ARF_EXPREF(x), &yexp);

    xsgnbit = ARF_SGNBIT(x);
    ARF_GET_MPN_READONLY(xptr, xn, x);

    if (shift >= 0)
        return _arf_add_mpn(z, xptr, xn, xsgnbit, ARF_EXPREF(x),
                               yptr, yn, ysgnbit, shift, prec, rnd);
    else
        return _arf_add_mpn(z, yptr, yn, ysgnbit, &yexp,
                               xptr, xn, xsgnbit, -shift, prec, rnd);
}
Exemple #6
0
int
_arf_add_eps(arf_t s, const arf_t x, int sgn, long prec, arf_rnd_t rnd)
{
    arf_t t;
    long bits;

    bits = arf_bits(x);

    if (bits == 0)
    {
        printf("_arf_add_eps\n");
        abort();
    }

    bits = FLINT_MAX(bits, prec) + 10;

    arf_init(t);
    arf_set_si(t, sgn);
    arf_mul_2exp_fmpz(t, t, ARF_EXPREF(x));
    arf_mul_2exp_si(t, t, -bits);
    arf_add(s, x, t, prec, rnd);
    arf_clear(t);

    return 1;
}
Exemple #7
0
Fichier : log.c Projet : isuruf/arb
void
arb_log_arf_huge(arb_t z, const arf_t x, slong prec)
{
    arf_t t;
    arb_t c;
    fmpz_t exp;
    slong wp;

    arf_init(t);
    arb_init(c);
    fmpz_init(exp);

    fmpz_neg(exp, ARF_EXPREF(x));
    arf_mul_2exp_fmpz(t, x, exp);

    wp = prec + 4 - fmpz_bits(exp);
    wp = FLINT_MAX(wp, 4);

    arb_log_arf(z, t, wp);
    arb_const_log2(c, prec + 4);
    arb_submul_fmpz(z, c, exp, prec);

    arf_clear(t);
    arb_clear(c);
    fmpz_clear(exp);
}
Exemple #8
0
int
arf_add_fmpz_2exp(arf_ptr z, arf_srcptr x, const fmpz_t y, const fmpz_t exp, slong prec, arf_rnd_t rnd)
{
    mp_size_t xn, yn;
    mp_srcptr xptr, yptr;
    mp_limb_t ytmp;
    int xsgnbit, ysgnbit, inexact;
    fmpz_t yexp;
    slong shift;

    if (fmpz_is_zero(y))
    {
        return arf_set_round(z, x, prec, rnd);
    }
    else if (arf_is_special(x))
    {
        if (arf_is_zero(x))
        {
            inexact = arf_set_round_fmpz(z, y, prec, rnd);
            arf_mul_2exp_fmpz(z, z, exp);
            return inexact;
        }
        else
        {
            arf_set(z, x);
            return 0;
        }
    }

    FMPZ_GET_MPN_READONLY(ysgnbit, yn, yptr, ytmp, *y)
    fmpz_init(yexp);
    fmpz_add_ui(yexp, exp, yn * FLINT_BITS);
    shift = _fmpz_sub_small(ARF_EXPREF(x), yexp);

    xsgnbit = ARF_SGNBIT(x);
    ARF_GET_MPN_READONLY(xptr, xn, x);

    if (shift >= 0)
        inexact = _arf_add_mpn(z, xptr, xn, xsgnbit, ARF_EXPREF(x),
                               yptr, yn, ysgnbit, shift, prec, rnd);
    else
        inexact = _arf_add_mpn(z, yptr, yn, ysgnbit, yexp,
                               xptr, xn, xsgnbit, -shift, prec, rnd);

    fmpz_clear(yexp);
    return inexact;
}
Exemple #9
0
Fichier : sub.c Projet : isuruf/arb
int
arf_sub_fmpz(arf_ptr z, arf_srcptr x, const fmpz_t y, slong prec, arf_rnd_t rnd)
{
    mp_size_t xn, yn;
    mp_srcptr xptr, yptr;
    mp_limb_t ytmp;
    int xsgnbit, ysgnbit;
    fmpz yexp;
    slong shift;

    if (fmpz_is_zero(y))
    {
        return arf_set_round(z, x, prec, rnd);
    }
    else if (arf_is_special(x))
    {
        if (arf_is_zero(x))
        {
            arf_set_fmpz(z, y);
            return arf_neg_round(z, z, prec, rnd);
        }
        else
        {
            arf_set(z, x);
            return 0;
        }
    }

    FMPZ_GET_MPN_READONLY(ysgnbit, yn, yptr, ytmp, *y)
    yexp = yn * FLINT_BITS;
    shift = _fmpz_sub_small(ARF_EXPREF(x), &yexp);
    ysgnbit ^= 1;

    xsgnbit = ARF_SGNBIT(x);
    ARF_GET_MPN_READONLY(xptr, xn, x);

    if (shift >= 0)
        return _arf_add_mpn(z, xptr, xn, xsgnbit, ARF_EXPREF(x),
                               yptr, yn, ysgnbit, shift, prec, rnd);
    else
        return _arf_add_mpn(z, yptr, yn, ysgnbit, &yexp,
                               xptr, xn, xsgnbit, -shift, prec, rnd);
}
Exemple #10
0
/* atan(x) = x + eps, |eps| < x^3*/
void
arb_atan_eps(arb_t z, const arf_t x, slong prec)
{
    fmpz_t mag;
    fmpz_init(mag);
    fmpz_mul_ui(mag, ARF_EXPREF(x), 3);
    arb_set_arf(z, x);
    arb_set_round(z, z, prec);
    arb_add_error_2exp_fmpz(z, mag);
    fmpz_clear(mag);
}
Exemple #11
0
void
arf_set_fmpr(arf_t y, const fmpr_t x)
{
    if (fmpr_is_special(x))
    {
        if (fmpr_is_zero(x))
            arf_zero(y);
        else if (fmpr_is_pos_inf(x))
            arf_pos_inf(y);
        else if (fmpr_is_neg_inf(x))
            arf_neg_inf(y);
        else
            arf_nan(y);
    }
    else
    {
        arf_set_fmpz(y, fmpr_manref(x));
        fmpz_add_inline(ARF_EXPREF(y), ARF_EXPREF(y), fmpr_expref(x));
    }
}
Exemple #12
0
int
arf_cmpabs(const arf_t x, const arf_t y)
{
    int ec, mc;
    mp_size_t xn, yn;
    mp_srcptr xp, yp;

    if (arf_is_special(x) || arf_is_special(y))
    {
        if (arf_equal(x, y))
            return 0;
        if (arf_is_nan(x) || arf_is_nan(y))
            return 0;
        if (arf_is_zero(x)) return -1;
        if (arf_is_zero(y)) return 1;
        if (arf_is_inf(x)) return arf_is_inf(y) ? 0 : 1;
        if (arf_is_inf(y)) return -1;
        return -1;
    }

    ec = fmpz_cmp(ARF_EXPREF(x), ARF_EXPREF(y));

    if (ec != 0)
        return (ec < 0) ? -1 : 1;

    ARF_GET_MPN_READONLY(xp, xn, x);
    ARF_GET_MPN_READONLY(yp, yn, y);

    if (xn >= yn)
        mc = mpn_cmp(xp + xn - yn, yp, yn);
    else
        mc = mpn_cmp(xp, yp + yn - xn, xn);

    if (mc != 0)
        return (mc < 0) ? -1 : 1;

    if (xn != yn)
        return (xn < yn) ? -1 : 1;

    return 0;
}
Exemple #13
0
int
arf_cmp_2exp_si(const arf_t x, long e)
{
    if (arf_is_special(x))
    {
        if (arf_is_zero(x)) return -1;
        if (arf_is_pos_inf(x)) return 1;
        if (arf_is_neg_inf(x)) return -1;
        return 0;
    }

    if (ARF_SGNBIT(x))
        return -1;

    /* Fast path. */
    if (!COEFF_IS_MPZ(ARF_EXP(x)))
    {
        if (ARF_IS_POW2(x) && (ARF_EXP(x) - 1 == e))
            return 0;
        else
            return (ARF_EXP(x) <= e) ? -1 : 1;
    }

    if (ARF_IS_POW2(x))
    {
        fmpz_t t;
        fmpz_init(t);
        fmpz_one(t);
        fmpz_add_si(t, t, e);
        if (fmpz_equal(ARF_EXPREF(x), t))
        {
            fmpz_clear(t);
            return 0;
        }
        fmpz_clear(t);
    }

    return (fmpz_cmp_si(ARF_EXPREF(x), e) <= 0) ? -1 : 1;
}
Exemple #14
0
Fichier : sub.c Projet : isuruf/arb
int
arf_sub(arf_ptr z, arf_srcptr x, arf_srcptr y, slong prec, arf_rnd_t rnd)
{
    mp_size_t xn, yn;
    mp_srcptr xptr, yptr;
    slong shift;

    if (arf_is_special(x) || arf_is_special(y))
    {
        return arf_sub_special(z, x, y, prec, rnd);
    }

    shift = _fmpz_sub_small(ARF_EXPREF(x), ARF_EXPREF(y));

    ARF_GET_MPN_READONLY(xptr, xn, x);
    ARF_GET_MPN_READONLY(yptr, yn, y);

    if (shift >= 0)
        return _arf_add_mpn(z, xptr, xn, ARF_SGNBIT(x), ARF_EXPREF(x),
                           yptr, yn, ARF_SGNBIT(y) ^ 1, shift, prec, rnd);
    else
        return _arf_add_mpn(z, yptr, yn, ARF_SGNBIT(y) ^ 1, ARF_EXPREF(y),
                           xptr, xn, ARF_SGNBIT(x), -shift, prec, rnd);
}
Exemple #15
0
void
_arb_poly_get_scale(fmpz_t scale, arb_srcptr x, slong xlen,
                    arb_srcptr y, slong ylen)
{
    slong xa, xb, ya, yb, den;

    fmpz_zero(scale);

    /* ignore zeros (and infs/nans!); find the first and last
       finite nonzero entries to determine the scale */
    xa = 0;
    xb = xlen - 1;
    while (xa < xlen && arf_is_special(arb_midref(x + xa))) xa++;
    while (xb > xa && arf_is_special(arb_midref(x + xb))) xb--;

    ya = 0;
    yb = ylen - 1;
    while (ya < ylen && arf_is_special(arb_midref(y + ya))) ya++;
    while (yb > ya && arf_is_special(arb_midref(y + yb))) yb--;

    /* compute average of exponent differences, weighted by the lengths */
    if (xa <= xb && ya <= yb && (xa < xb || ya < yb))
    {
        fmpz_add(scale, scale, ARF_EXPREF(arb_midref(x + xb)));
        fmpz_sub(scale, scale, ARF_EXPREF(arb_midref(x + xa)));
        fmpz_add(scale, scale, ARF_EXPREF(arb_midref(y + yb)));
        fmpz_sub(scale, scale, ARF_EXPREF(arb_midref(y + ya)));

        den = (xb - xa) + (yb - ya);

        /* scale = floor(scale / den + 1/2) = floor((2 scale + den) / (2 den)) */
        fmpz_mul_2exp(scale, scale, 1);
        fmpz_add_ui(scale, scale, den);
        fmpz_fdiv_q_ui(scale, scale, 2 * den);
    }
}
Exemple #16
0
Fichier : log.c Projet : isuruf/arb
/* requires x != 1 */
static void
arf_log_via_mpfr(arf_t z, const arf_t x, slong prec, arf_rnd_t rnd)
{
    mpfr_t xf, zf;
    mp_ptr zptr, tmp;
    mp_srcptr xptr;
    mp_size_t xn, zn, val;
    TMP_INIT;
    TMP_START;

    zn = (prec + FLINT_BITS - 1) / FLINT_BITS;
    tmp = TMP_ALLOC(zn * sizeof(mp_limb_t));

    ARF_GET_MPN_READONLY(xptr, xn, x);

    xf->_mpfr_d = (mp_ptr) xptr;
    xf->_mpfr_prec = xn * FLINT_BITS;
    xf->_mpfr_sign = ARF_SGNBIT(x) ? -1 : 1;
    xf->_mpfr_exp = ARF_EXP(x);

    zf->_mpfr_d = tmp;
    zf->_mpfr_prec = prec;
    zf->_mpfr_sign = 1;
    zf->_mpfr_exp = 0;

    mpfr_set_emin(MPFR_EMIN_MIN);
    mpfr_set_emax(MPFR_EMAX_MAX);

    mpfr_log(zf, xf, arf_rnd_to_mpfr(rnd));

    val = 0;
    while (tmp[val] == 0)
        val++;

    ARF_GET_MPN_WRITE(zptr, zn - val, z);
    flint_mpn_copyi(zptr, tmp + val, zn - val);
    if (zf->_mpfr_sign < 0)
        ARF_NEG(z);

    fmpz_set_si(ARF_EXPREF(z), zf->_mpfr_exp);

    TMP_END;
}
Exemple #17
0
void
arb_const_log2(arb_t res, slong prec)
{
    if (prec < ARB_LOG_TAB2_LIMBS * FLINT_BITS - 16)
    {
        slong exp;

        /* just reading the table is known to give the correct rounding */
        _arf_set_round_mpn(arb_midref(res), &exp, arb_log_log2_tab,
            ARB_LOG_TAB2_LIMBS, 0, prec, ARF_RND_NEAR);
        _fmpz_set_si_small(ARF_EXPREF(arb_midref(res)), exp);

        /* 1/2 ulp error */
        _fmpz_set_si_small(MAG_EXPREF(arb_radref(res)), exp - prec);
        MAG_MAN(arb_radref(res)) = MAG_ONE_HALF;
    }
    else
    {
        arb_const_log2_hypgeom(res, prec);
    }
}
Exemple #18
0
/* atan(x) = pi/2 - eps, eps < 1/x <= 2^(1-mag) */
void
arb_atan_inf_eps(arb_t z, const arf_t x, slong prec)
{
    fmpz_t mag;
    fmpz_init(mag);

    fmpz_neg(mag, ARF_EXPREF(x));
    fmpz_add_ui(mag, mag, 1);

    if (arf_sgn(x) > 0)
    {
        arb_const_pi(z, prec);
    }
    else
    {
        arb_const_pi(z, prec);
        arb_neg(z, z);
    }

    arb_mul_2exp_si(z, z, -1);
    arb_add_error_2exp_fmpz(z, mag);

    fmpz_clear(mag);
}
Exemple #19
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);
}
Exemple #20
0
void
arb_mul_naive(arb_t z, const arb_t x, const arb_t y, slong prec)
{
    arf_t zm_exact, zm_rounded, zr, t, u;

    arf_init(zm_exact);
    arf_init(zm_rounded);
    arf_init(zr);
    arf_init(t);
    arf_init(u);

    arf_mul(zm_exact, arb_midref(x), arb_midref(y), ARF_PREC_EXACT, ARF_RND_DOWN);
    arf_set_round(zm_rounded, zm_exact, prec, ARB_RND);

    /* rounding error */
    if (arf_equal(zm_exact, zm_rounded))
    {
        arf_zero(zr);
    }
    else
    {
        fmpz_t e;
        fmpz_init(e);

        /* more accurate, but not what we are testing
        arf_sub(zr, zm_exact, zm_rounded, MAG_BITS, ARF_RND_UP);
        arf_abs(zr, zr); */

        fmpz_sub_ui(e, ARF_EXPREF(zm_rounded), prec);
        arf_one(zr);
        arf_mul_2exp_fmpz(zr, zr, e);
        fmpz_clear(e);
    }

    /* propagated error */
    if (!arb_is_exact(x))
    {
        arf_set_mag(t, arb_radref(x));
        arf_abs(u, arb_midref(y));
        arf_addmul(zr, t, u, MAG_BITS, ARF_RND_UP);
    }

    if (!arb_is_exact(y))
    {
        arf_set_mag(t, arb_radref(y));
        arf_abs(u, arb_midref(x));
        arf_addmul(zr, t, u, MAG_BITS, ARF_RND_UP);
    }

    if (!arb_is_exact(x) && !arb_is_exact(y))
    {
        arf_set_mag(t, arb_radref(x));
        arf_set_mag(u, arb_radref(y));
        arf_addmul(zr, t, u, MAG_BITS, ARF_RND_UP);
    }

    arf_set(arb_midref(z), zm_rounded);
    arf_get_mag(arb_radref(z), zr);

    arf_clear(zm_exact);
    arf_clear(zm_rounded);
    arf_clear(zr);
    arf_clear(t);
    arf_clear(u);
}
Exemple #21
0
int main()
{
    slong iter, iter2;
    flint_rand_t state;

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

    flint_randinit(state);

    for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++)
    {
        arf_t x, z, v;
        slong y;
        slong prec, r1, r2;
        arf_rnd_t rnd;

        arf_init(x);
        arf_init(z);
        arf_init(v);

        for (iter2 = 0; iter2 < 100; iter2++)
        {
            arf_randtest_special(x, state, 2000, 100);
            y = z_randtest(state);
            arf_randtest_special(z, state, 2000, 100);
            arf_set(v, z);

            prec = 2 + n_randint(state, 2000);

            if (n_randint(state, 10) == 0 &&
                fmpz_bits(ARF_EXPREF(x)) < 10 &&
                fmpz_bits(ARF_EXPREF(z)) < 10)
            {
                prec = ARF_PREC_EXACT;
            }

            switch (n_randint(state, 5))
            {
                case 0:  rnd = ARF_RND_DOWN; break;
                case 1:  rnd = ARF_RND_UP; break;
                case 2:  rnd = ARF_RND_FLOOR; break;
                case 3:  rnd = ARF_RND_CEIL; break;
                default: rnd = ARF_RND_NEAR; break;
            }

            switch (n_randint(state, 2))
            {
            case 0:
                r1 = arf_addmul_si(z, x, y, prec, rnd);
                r2 = arf_addmul_si_naive(v, x, y, prec, rnd);
                if (!arf_equal(z, v) || r1 != r2)
                {
                    flint_printf("FAIL!\n");
                    flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd);
                    flint_printf("x = "); arf_print(x); flint_printf("\n\n");
                    flint_printf("y = %wd", y); flint_printf("\n\n");
                    flint_printf("z = "); arf_debug(z); flint_printf("\n\n");
                    flint_printf("v = "); arf_debug(v); flint_printf("\n\n");
                    flint_printf("r1 = %wd, r2 = %wd\n", r1, r2);
                    abort();
                }
                break;

            default:
                r2 = arf_addmul_si_naive(v, v, y, prec, rnd);
                r1 = arf_addmul_si(z, z, y, prec, rnd);
                if (!arf_equal(v, z) || r1 != r2)
                {
                    flint_printf("FAIL (aliasing)!\n");
                    flint_printf("prec = %wd, rnd = %d\n\n", prec, rnd);
                    flint_printf("y = %wd", y); flint_printf("\n\n");
                    flint_printf("v = "); arf_print(v); flint_printf("\n\n");
                    flint_printf("z = "); arf_print(z); flint_printf("\n\n");
                    flint_printf("r1 = %wd, r2 = %wd\n", r1, r2);
                    abort();
                }
                break;
            }
        }

        arf_clear(x);
        arf_clear(z);
        arf_clear(v);
    }

    flint_randclear(state);
    flint_cleanup();
    flint_printf("PASS\n");
    return EXIT_SUCCESS;
}
Exemple #22
0
int
arf_submul_mpz(arf_ptr z, arf_srcptr x, const mpz_t y, slong prec, arf_rnd_t rnd)
{
    mp_size_t xn, yn, zn, tn, alloc;
    mp_srcptr xptr, yptr, zptr;
    mp_ptr tptr, tptr2;
    fmpz_t texp, yexp;
    slong shift;
    int tsgnbit, ysgnbit, inexact;
    ARF_MUL_TMP_DECL

    yn = FLINT_ABS(y->_mp_size);

    if (arf_is_special(x) || yn == 0 || arf_is_special(z))
    {
        if (arf_is_zero(z))
        {
            /* TODO: make more efficient */
            arf_mul_mpz(z, x, y, ARF_PREC_EXACT, rnd);
            return arf_neg_round(z, z, prec, rnd);
        }
        else if (arf_is_finite(x))
        {
            return arf_set_round(z, z, prec, rnd);
        }
        else
        {
            /* todo: speed up */
            arf_t t;
            arf_init(t);
            arf_mul_mpz(t, x, y, ARF_PREC_EXACT, ARF_RND_DOWN);
            inexact = arf_sub(z, z, t, prec, rnd);
            arf_clear(t);
            return inexact;
        }
    }

    ARF_GET_MPN_READONLY(xptr, xn, x);

    yptr = y->_mp_d;
    ysgnbit = (y->_mp_size > 0);
    *yexp = yn * FLINT_BITS;

    ARF_GET_MPN_READONLY(zptr, zn, z);

    fmpz_init(texp);

    tsgnbit = ARF_SGNBIT(x) ^ ysgnbit;

    alloc = tn = xn + yn;
    ARF_MUL_TMP_ALLOC(tptr2, alloc)
    tptr = tptr2;

    ARF_MPN_MUL(tptr, xptr, xn, yptr, yn);

    shift = (tptr[tn - 1] == 0) * FLINT_BITS;
    tn -= (tptr[tn - 1] == 0);

    _fmpz_add2_fast(texp, ARF_EXPREF(x), yexp, -shift);
    shift = _fmpz_sub_small(ARF_EXPREF(z), texp);

    if (shift >= 0)
        inexact = _arf_add_mpn(z, zptr, zn, ARF_SGNBIT(z), ARF_EXPREF(z),
            tptr, tn, tsgnbit, shift, prec, rnd);
    else
        inexact = _arf_add_mpn(z, tptr, tn, tsgnbit, texp,
            zptr, zn, ARF_SGNBIT(z), -shift, prec, rnd);

    ARF_MUL_TMP_FREE(tptr2, alloc)
    fmpz_clear(texp);

    return inexact;
}
Exemple #23
0
int
arf_submul(arf_ptr z, arf_srcptr x, arf_srcptr y, slong prec, arf_rnd_t rnd)
{
    mp_size_t xn, yn, zn, tn, alloc;
    mp_srcptr xptr, yptr, zptr;
    mp_ptr tptr, tptr2;
    fmpz_t texp;
    slong shift;
    int tsgnbit, inexact;
    ARF_MUL_TMP_DECL

    if (arf_is_special(x) || arf_is_special(y) || arf_is_special(z))
    {
        if (arf_is_zero(z))
        {
            return arf_neg_mul(z, x, y, prec, rnd);
        }
        else if (arf_is_finite(x) && arf_is_finite(y))
        {
            return arf_set_round(z, z, prec, rnd);
        }
        else
        {
            /* todo: speed up */
            arf_t t;
            arf_init(t);
            arf_mul(t, x, y, ARF_PREC_EXACT, ARF_RND_DOWN);
            inexact = arf_sub(z, z, t, prec, rnd);
            arf_clear(t);
            return inexact;
        }
    }

    tsgnbit = ARF_SGNBIT(x) ^ ARF_SGNBIT(y) ^ 1;
    ARF_GET_MPN_READONLY(xptr, xn, x);
    ARF_GET_MPN_READONLY(yptr, yn, y);
    ARF_GET_MPN_READONLY(zptr, zn, z);

    fmpz_init(texp);

    _fmpz_add2_fast(texp, ARF_EXPREF(x), ARF_EXPREF(y), 0);
    shift = _fmpz_sub_small(ARF_EXPREF(z), texp);

    alloc = tn = xn + yn;
    ARF_MUL_TMP_ALLOC(tptr2, alloc)
    tptr = tptr2;

    ARF_MPN_MUL(tptr, xptr, xn, yptr, yn);

    tn -= (tptr[0] == 0);
    tptr += (tptr[0] == 0);

    if (shift >= 0)
        inexact = _arf_add_mpn(z, zptr, zn, ARF_SGNBIT(z), ARF_EXPREF(z),
            tptr, tn, tsgnbit, shift, prec, rnd);
    else
        inexact = _arf_add_mpn(z, tptr, tn, tsgnbit, texp,
            zptr, zn, ARF_SGNBIT(z), -shift, prec, rnd);

    ARF_MUL_TMP_FREE(tptr2, alloc)
    fmpz_clear(texp);

    return inexact;
}
Exemple #24
0
void
acb_hypgeom_airy(acb_t ai, acb_t aip, acb_t bi, acb_t bip, const acb_t z, slong prec)
{
    arf_srcptr re, im;
    double x, y, t, zmag, z15, term_est, airy_est, abstol;
    slong n, wp;

    if (!acb_is_finite(z))
    {
        if (ai != NULL) acb_indeterminate(ai);
        if (aip != NULL) acb_indeterminate(aip);
        if (bi != NULL) acb_indeterminate(bi);
        if (bip != NULL) acb_indeterminate(bip);
        return;
    }

    re = arb_midref(acb_realref(z));
    im = arb_midref(acb_imagref(z));
    wp = prec * 1.03 + 15;

    /* tiny input -- use direct method and pick n without underflowing */
    if (arf_cmpabs_2exp_si(re, -64) < 0 && arf_cmpabs_2exp_si(im, -64) < 0)
    {
        if (arf_cmpabs_2exp_si(re, -wp) < 0 && arf_cmpabs_2exp_si(im, -wp) < 0)
        {
            n = 1;  /* very tiny input */
        }
        else
        {
            if (arf_cmpabs(re, im) > 0)
                zmag = fmpz_get_d(ARF_EXPREF(re));
            else
                zmag = fmpz_get_d(ARF_EXPREF(im));
            zmag = (zmag + 1) * (1.0 / LOG2);
            n = wp / (-zmag) + 1;
        }

        acb_hypgeom_airy_direct(ai, aip, bi, bip, z, n, wp);
    }  /* huge input -- use asymptotics and pick n without overflowing */
    else if ((arf_cmpabs_2exp_si(re, 64) > 0 || arf_cmpabs_2exp_si(im, 64) > 0))
    {
        if (arf_cmpabs_2exp_si(re, prec) > 0 || arf_cmpabs_2exp_si(im, prec) > 0)
        {
            n = 1;   /* very huge input */
        }
        else
        {
            x = fmpz_get_d(ARF_EXPREF(re));
            y = fmpz_get_d(ARF_EXPREF(im));
            zmag = (FLINT_MAX(x, y) - 2) * (1.0 / LOG2);
            n = asymp_pick_terms(wp, zmag);
            n = FLINT_MAX(n, 1);
        }

        acb_hypgeom_airy_asymp(ai, aip, bi, bip, z, n, wp);
    }
    else /* moderate input */
    {
        x = arf_get_d(re, ARF_RND_DOWN);
        y = arf_get_d(im, ARF_RND_DOWN);

        zmag = sqrt(x * x + y * y);
        z15 = zmag * sqrt(zmag);

        if (zmag >= 4.0 && (n = asymp_pick_terms(wp, log(zmag))) != -1)
        {
            acb_hypgeom_airy_asymp(ai, aip, bi, bip, z, n, wp);
        }
        else if (zmag <= 1.5)
        {
            t = 3 * (wp * LOG2) / (2 * z15 * EXP1);
            t = (wp * LOG2) / (2 * d_lambertw(t));
            n = FLINT_MAX(t + 1, 2);
            acb_hypgeom_airy_direct(ai, aip, bi, bip, z, n, wp);
        }
        else
        {
            /* estimate largest term: log2(exp(2(z^3/9)^(1/2))) */
            term_est = 0.96179669392597560491 * z15;

            /* estimate the smaller of Ai and Bi */
            airy_est = estimate_airy(x, y, (ai != NULL || aip != NULL));

            /* estimate absolute tolerance and necessary working precision */
            abstol = airy_est - wp;
            wp = wp + term_est - airy_est;
            wp = FLINT_MAX(wp, 10);

            t = 3 * (-abstol * LOG2) / (2 * z15 * EXP1);
            t = (-abstol * LOG2) / (2 * d_lambertw(t));
            n = FLINT_MAX(t + 1, 2);

            if (acb_is_exact(z))
                acb_hypgeom_airy_direct(ai, aip, bi, bip, z, n, wp);
            else
                acb_hypgeom_airy_direct_prop(ai, aip, bi, bip, z, n, wp);
        }
    }

    if (ai != NULL) acb_set_round(ai, ai, prec);
    if (aip != NULL) acb_set_round(aip, aip, prec);
    if (bi != NULL) acb_set_round(bi, bi, prec);
    if (bip != NULL) acb_set_round(bip, bip, prec);
}
Exemple #25
0
void
arb_atan_arf(arb_t z, const arf_t x, slong prec)
{
    if (arf_is_special(x))
    {
        if (arf_is_zero(x))
        {
            arb_zero(z);
        }
        else if (arf_is_pos_inf(x))
        {
            arb_const_pi(z, prec);
            arb_mul_2exp_si(z, z, -1);
        }
        else if (arf_is_neg_inf(x))
        {
            arb_const_pi(z, prec);
            arb_mul_2exp_si(z, z, -1);
            arb_neg(z, z);
        }
        else
        {
            arb_indeterminate(z);
        }
    }
    else if (COEFF_IS_MPZ(*ARF_EXPREF(x)))
    {
        if (fmpz_sgn(ARF_EXPREF(x)) < 0)
            arb_atan_eps(z, x, prec);
        else
            arb_atan_inf_eps(z, x, prec);
    }
    else
    {
        slong exp, wp, wn, N, r;
        mp_srcptr xp;
        mp_size_t xn, tn;
        mp_ptr tmp, w, t, u;
        mp_limb_t p1, q1bits, p2, q2bits, error, error2;
        int negative, inexact, reciprocal;
        TMP_INIT;

        exp = ARF_EXP(x);
        negative = ARF_SGNBIT(x);

        if (exp < -(prec/2) - 2 || exp > prec + 2)
        {
            if (exp < 0)
                arb_atan_eps(z, x, prec);
            else
                arb_atan_inf_eps(z, x, prec);
            return;
        }

        ARF_GET_MPN_READONLY(xp, xn, x);

        /* Special case: +/- 1 (we require |x| != 1 later on) */
        if (exp == 1 && xn == 1 && xp[xn-1] == LIMB_TOP)
        {
            arb_const_pi(z, prec);
            arb_mul_2exp_si(z, z, -2);
            if (negative)
                arb_neg(z, z);
            return;
        }

        /* Absolute working precision (NOT rounded to a limb multiple) */
        wp = prec - FLINT_MIN(0, exp) + 4;

        /* Too high precision to use table */
        if (wp > ARB_ATAN_TAB2_PREC)
        {
            arb_atan_arf_bb(z, x, prec);
            return;
        }

        /* Working precision in limbs */
        wn = (wp + FLINT_BITS - 1) / FLINT_BITS;

        TMP_START;

        tmp = TMP_ALLOC_LIMBS(4 * wn + 3);
        w = tmp;        /* requires wn+1 limbs */
        t = w + wn + 1; /* requires wn+1 limbs */
        u = t + wn + 1; /* requires 2wn+1 limbs */

        /* ----------------------------------------------------------------- */
        /* Convert x or 1/x to a fixed-point number |w| < 1                  */
        /* ----------------------------------------------------------------- */

        if (exp <= 0)  /* |x| < 1 */
        {
            reciprocal = 0;

            /* todo: just zero top */
            flint_mpn_zero(w, wn);

            /* w = x as a fixed-point number */
            error = _arf_get_integer_mpn(w, xp, xn, exp + wn * FLINT_BITS);
        }
        else    /* |x| > 1 */
        {
            slong one_exp, one_limbs, one_bits;
            mp_ptr one;

            reciprocal = 1;

            one_exp = xn * FLINT_BITS + wn * FLINT_BITS - exp;

            flint_mpn_zero(w, wn);

            /* 1/x becomes zero */
            if (one_exp >= FLINT_BITS - 1)
            {
                /* w = 1/x */
                one_limbs = one_exp / FLINT_BITS;
                one_bits = one_exp % FLINT_BITS;

                if (one_limbs + 1 >= xn)
                {
                    one = TMP_ALLOC_LIMBS(one_limbs + 1);
                    flint_mpn_zero(one, one_limbs);
                    one[one_limbs] = UWORD(1) << one_bits;

                    /* todo: only zero necessary part */
                    flint_mpn_zero(w, wn);
                    mpn_tdiv_q(w, one, one_limbs + 1, xp, xn);

                    /* Now w must be < 1 since x > 1 and we rounded down; thus
                       w[wn] must be zero */
                }
            }

            /* todo: moderate powers of two would be exact... */
            error = 1;
        }

        /* ----------------------------------------------------------------- */
        /* Table-based argument reduction                                    */
        /* ----------------------------------------------------------------- */

        /* choose p such that p/q <= x < (p+1)/q */
        if (wp <= ARB_ATAN_TAB1_PREC)
            q1bits = ARB_ATAN_TAB1_BITS;
        else
            q1bits = ARB_ATAN_TAB21_BITS;

        p1 = w[wn-1] >> (FLINT_BITS - q1bits);

        /* atan(w) = atan(p/q) + atan(w2) */
        /* where w2 = (q*w-p)/(q+p*w) */
        if (p1 != 0)
        {
            t[wn] = (UWORD(1) << q1bits) + mpn_mul_1(t, w, wn, p1);
            flint_mpn_zero(u, wn);
            u[2 * wn] = mpn_lshift(u + wn, w, wn, q1bits) - p1;
            mpn_tdiv_q(w, u, 2 * wn + 1, t, wn + 1);
            error++;  /* w2 is computed with 1 ulp error */
        }

        /* Do a second round of argument reduction */
        if (wp <= ARB_ATAN_TAB1_PREC)
        {
            p2 = 0;
        }
        else
        {
            q2bits = ARB_ATAN_TAB21_BITS + ARB_ATAN_TAB22_BITS;
            p2 = w[wn-1] >> (FLINT_BITS - q2bits);

            if (p2 != 0)
            {
                t[wn] = (UWORD(1) << q2bits) + mpn_mul_1(t, w, wn, p2);
                flint_mpn_zero(u, wn);
                u[2 * wn] = mpn_lshift(u + wn, w, wn, q2bits) - p2;
                mpn_tdiv_q(w, u, 2 * wn + 1, t, wn + 1);
                error++;
            }
        }

        /* |w| <= 2^-r */
        r = _arb_mpn_leading_zeros(w, wn);

        /* N >= (wp-r)/(2r) */
        N = (wp - r + (2*r-1)) / (2*r);

        /* Evaluate Taylor series */
        _arb_atan_taylor_rs(t, &error2, w, wn, N, 1);

        /* Taylor series evaluation error */
        error += error2;

        /* Size of output number */
        tn = wn;

        /* First table lookup */
        if (p1 != 0)
        {
            if (wp <= ARB_ATAN_TAB1_PREC)
                mpn_add_n(t, t, arb_atan_tab1[p1] + ARB_ATAN_TAB1_LIMBS - tn, tn);
            else
                mpn_add_n(t, t, arb_atan_tab21[p1] + ARB_ATAN_TAB2_LIMBS - tn, tn);
            error++;
        }

        /* Second table lookup */
        if (p2 != 0)
        {
            mpn_add_n(t, t, arb_atan_tab22[p2] + ARB_ATAN_TAB2_LIMBS - tn, tn);
            error++;
        }

        /* pi/2 - atan(1/x) */
        if (reciprocal)
        {
            t[tn] = LIMB_ONE - mpn_sub_n(t,
                arb_atan_pi2_minus_one + ARB_ATAN_TAB2_LIMBS - tn, t, tn);

            /* result can be >= 1 */
            tn += (t[tn] != 0);

            /* error of pi/2 */
            error++;
        }

        /* The accumulated arithmetic error */
        mag_set_ui_2exp_si(arb_radref(z), error, -wn * FLINT_BITS);

        /* Truncation error from the Taylor series */
        mag_add_ui_2exp_si(arb_radref(z), arb_radref(z), 1, -r*(2*N+1));

        /* Set the midpoint */
        inexact = _arf_set_mpn_fixed(arb_midref(z), t, tn, wn, negative, prec, ARB_RND);
        if (inexact)
            arf_mag_add_ulp(arb_radref(z), arb_radref(z), arb_midref(z), prec);

        TMP_END;
    }
}
Exemple #26
0
int
arf_root(arf_ptr z, arf_srcptr x, ulong k, slong prec, arf_rnd_t rnd)
{
    mp_size_t xn, zn, val;
    mp_srcptr xptr;
    mp_ptr tmp, zptr;
    mpfr_t xf, zf;
    fmpz_t q, r;
    int inexact;

    if (k == 0)
    {
        arf_nan(z);
        return 0;
    }

    if (k == 1)
        return arf_set_round(z, x, prec, rnd);

    if (k == 2)
        return arf_sqrt(z, x, prec, rnd);

    if (arf_is_special(x))
    {
        if (arf_is_neg_inf(x))
            arf_nan(z);
        else
            arf_set(z, x);
        return 0;
    }

    if (ARF_SGNBIT(x))
    {
        arf_nan(z);
        return 0;
    }

    fmpz_init(q);
    fmpz_init(r);

    /* x = m * 2^e where e = qk + r */
    /* x^(1/k) = (m * 2^(qk+r))^(1/k)  */
    /* x^(1/k) = (m * 2^r)^(1/k) * 2^q  */
    fmpz_set_ui(r, k);
    fmpz_fdiv_qr(q, r, ARF_EXPREF(x), r);

    ARF_GET_MPN_READONLY(xptr, xn, x);
    zn = (prec + FLINT_BITS - 1) / FLINT_BITS;

    zf->_mpfr_d = tmp = flint_malloc(zn * sizeof(mp_limb_t));
    zf->_mpfr_prec = prec;
    zf->_mpfr_sign = 1;
    zf->_mpfr_exp = 0;

    xf->_mpfr_d = (mp_ptr) xptr;
    xf->_mpfr_prec = xn * FLINT_BITS;
    xf->_mpfr_sign = 1;
    xf->_mpfr_exp = fmpz_get_ui(r);

    inexact = mpfr_root(zf, xf, k, arf_rnd_to_mpfr(rnd));
    inexact = (inexact != 0);

    val = 0;
    while (tmp[val] == 0)
        val++;

    ARF_GET_MPN_WRITE(zptr, zn - val, z);
    flint_mpn_copyi(zptr, tmp + val, zn - val);

    fmpz_add_si(ARF_EXPREF(z), q, zf->_mpfr_exp);

    flint_free(tmp);
    fmpz_clear(q);
    fmpz_clear(r);

    return inexact;
}
Exemple #27
0
int main()
{
    long iter, iter2;
    flint_rand_t state;

    printf("add_fmpz....");
    fflush(stdout);

    flint_randinit(state);

    for (iter = 0; iter < 10000; iter++)
    {
        arf_t x, z, v;
        fmpz_t y;
        long prec, r1, r2;
        arf_rnd_t rnd;

        arf_init(x);
        arf_init(z);
        arf_init(v);
        fmpz_init(y);

        for (iter2 = 0; iter2 < 100; iter2++)
        {
            arf_randtest_special(x, state, 2000, 10);
            fmpz_randtest(y, state, 2000);
            prec = 2 + n_randint(state, 2000);

            if (n_randint(state, 10) == 0 && fmpz_bits(ARF_EXPREF(x)) < 10)
            {
                prec = ARF_PREC_EXACT;
            }

            switch (n_randint(state, 4))
            {
                case 0:  rnd = ARF_RND_DOWN; break;
                case 1:  rnd = ARF_RND_UP; break;
                case 2:  rnd = ARF_RND_FLOOR; break;
                default: rnd = ARF_RND_CEIL; break;
            }

            switch (n_randint(state, 2))
            {
            case 0:
                r1 = arf_add_fmpz(z, x, y, prec, rnd);
                r2 = arf_add_fmpz_naive(v, x, y, prec, rnd);
                if (!arf_equal(z, v) || r1 != r2)
                {
                    printf("FAIL!\n");
                    printf("prec = %ld, rnd = %d\n\n", prec, rnd);
                    printf("x = "); arf_print(x); printf("\n\n");
                    printf("y = "); fmpz_print(y); printf("\n\n");
                    printf("z = "); arf_print(z); printf("\n\n");
                    printf("v = "); arf_print(v); printf("\n\n");
                    printf("r1 = %ld, r2 = %ld\n", r1, r2);
                    abort();
                }
                break;

            default:
                r2 = arf_add_fmpz_naive(v, x, y, prec, rnd);
                r1 = arf_add_fmpz(x, x, y, prec, rnd);
                if (!arf_equal(x, v) || r1 != r2)
                {
                    printf("FAIL (aliasing)!\n");
                    printf("prec = %ld, rnd = %d\n\n", prec, rnd);
                    printf("x = "); arf_print(x); printf("\n\n");
                    printf("y = "); fmpz_print(y); printf("\n\n");
                    printf("v = "); arf_print(v); printf("\n\n");
                    printf("r1 = %ld, r2 = %ld\n", r1, r2);
                    abort();
                }
                break;
            }
        }

        arf_clear(x);
        arf_clear(z);
        arf_clear(v);
        fmpz_clear(y);
    }

    flint_randclear(state);
    flint_cleanup();
    printf("PASS\n");
    return EXIT_SUCCESS;
}
Exemple #28
0
int main()
{
    slong iter;
    flint_rand_t state;

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

    flint_randinit(state);

    {
        arf_t x, y, z;

        arf_init(x);
        arf_init(y);
        arf_init(z);

        for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++)
        {
            slong bits1, bits2;
            int ret1, ret2;
            mpfr_t g1, g2;
            fmpz_t e;
            arf_rnd_t rnd;

            bits1 = 1 + n_randint(state, 1000);
            bits2 = 2 + n_randint(state, 1000);

            if (n_randint(state, 100) == 0)
                bits2 = ARF_PREC_EXACT;

            switch (n_randint(state, 5))
            {
                case 0: rnd = ARF_RND_DOWN; break;
                case 1: rnd = ARF_RND_UP; break;
                case 2: rnd = ARF_RND_FLOOR; break;
                case 3: rnd = ARF_RND_CEIL; break;
                default: rnd = ARF_RND_NEAR; break;
            }

            fmpz_init(e);
            mpfr_init2(g1, FLINT_MAX(2, bits1));
            mpfr_init2(g2, FLINT_MIN(bits2, 10000));

            if (n_randint(state, 100) == 0)
            {
                arf_clear(x); arf_clear(y); arf_clear(z);
                arf_init(x); arf_init(y); arf_init(z);
            }

            /* dirty output variables */
            if (n_randint(state, 2))
            {
                arf_randtest_special(y, state, 1 + n_randint(state, 1000),
                    1 + n_randint(state, 100));
                arf_randtest_special(z, state, 1 + n_randint(state, 1000),
                    1 + n_randint(state, 100));
            }

            arf_randtest_special(x, state, bits1, 1 + n_randint(state, 10));
            arf_get_mpfr(g1, x, MPFR_RNDD); /* exact */

            /* test large exponents */
            if (n_randint(state, 4) == 0)
                fmpz_randtest(e, state, 1 + n_randint(state, 100));

            if (!arf_is_special(x))
                fmpz_add(ARF_EXPREF(x), ARF_EXPREF(x), e);

            ret1 = arf_set_round(y, x, bits2, rnd);
            ret2 = mpfr_set(g2, g1, arf_rnd_to_mpfr(rnd));
            arf_set_mpfr(z, g2);

            if (!arf_is_special(y))
                fmpz_sub(ARF_EXPREF(y), ARF_EXPREF(y), e);

            if (!arf_equal(y, z) || ((ret1 == ARF_RESULT_EXACT) != (ret2 == 0)))
            {
                flint_printf("FAIL\n\n");
                flint_printf("bits1: %wd\n", bits1);
                flint_printf("bits2: %wd\n", bits2);
                flint_printf("x = "); arf_print(x); flint_printf("\n\n");
                flint_printf("y = "); arf_print(y); flint_printf("\n\n");
                flint_printf("z = "); arf_print(z); flint_printf("\n\n");
                flint_printf("ret1 = %d, ret2 = %d\n\n", ret1, ret2);
                flint_abort();
            }

            if (!arf_is_special(x))
                fmpz_add(ARF_EXPREF(x), ARF_EXPREF(x), e);

            ret1 = arf_set_round(y, x, bits2, rnd);
            arf_set(z, x);
            ret2 = arf_set_round(z, z, bits2, rnd);

            if (!arf_equal(y, z) || ret1 != ret2)
            {
                flint_printf("FAIL (aliasing)\n\n");
                flint_printf("bits1: %wd\n", bits1);
                flint_printf("bits2: %wd\n", bits2);
                flint_printf("x = "); arf_print(x); flint_printf("\n\n");
                flint_printf("y = "); arf_print(y); flint_printf("\n\n");
                flint_printf("z = "); arf_print(z); flint_printf("\n\n");
                flint_printf("ret1 = %d, ret2 = %d\n\n", ret1, ret2);
                flint_abort();
            }

            mpfr_clear(g1);
            mpfr_clear(g2);
            fmpz_clear(e);
        }

        arf_clear(x);
        arf_clear(y);
        arf_clear(z);
    }

    flint_randclear(state);
    flint_cleanup();
    flint_printf("PASS\n");
    return EXIT_SUCCESS;
}
Exemple #29
0
void
arf_get_fmpz(fmpz_t z, const arf_t x, arf_rnd_t rnd)
{
    if (arf_is_special(x))
    {
        if (arf_is_zero(x))
        {
            fmpz_zero(z);
        }
        else
        {
            flint_printf("arf_get_fmpz: cannot convert infinity or nan to integer\n");
            abort();
        }
    }
    else if (COEFF_IS_MPZ(*ARF_EXPREF(x)))
    {
        /* tiny */
        if (fmpz_sgn(ARF_EXPREF(x)) < 0)
        {
            int negative = ARF_SGNBIT(x);

            if (rnd == ARF_RND_NEAR
                    || rnd == ARF_RND_DOWN
                    || (rnd == ARF_RND_FLOOR && !negative)
                    || (rnd == ARF_RND_CEIL && negative))
            {
                fmpz_zero(z);
            }
            else
            {
                fmpz_set_si(z, negative ? -1 : 1);
            }
        }
        else
        {
            flint_printf("arf_get_fmpz: number too large to convert to integer\n");
            abort();
        }
    }
    else
    {
        slong exp;
        int negative, inexact;
        mp_size_t xn, zn;
        mp_srcptr xp;
        __mpz_struct * zz;

        /* TBD: implement efficiently */
        if (rnd == ARF_RND_NEAR)
        {
            fmpr_t t;
            fmpr_init(t);
            arf_get_fmpr(t, x);
            fmpr_get_fmpz(z, t, rnd);
            fmpr_clear(t);
            return;
        }

        exp = ARF_EXP(x);
        negative = ARF_SGNBIT(x);

        /* |x| < 1 */
        if (exp <= 0)
        {
            if (rnd == ARF_RND_DOWN ||
                    (rnd == ARF_RND_FLOOR && !negative) ||
                    (rnd == ARF_RND_CEIL && negative))
            {
                fmpz_zero(z);
            }
            else
            {
                fmpz_set_si(z, negative ? -1 : 1);
            }
            return;
        }

        ARF_GET_MPN_READONLY(xp, xn, x);

        /* |x| < 2^31 or 2^63 (must save 1 bit for rounding up!) */
        if (exp < FLINT_BITS)
        {
            mp_limb_t v, v2;

            v = xp[xn - 1];
            v2 = v >> (FLINT_BITS - exp);
            inexact = (xn > 1) || ((v2 << (FLINT_BITS - exp)) != v);

            if (inexact && rnd != ARF_RND_DOWN)
            {
                if (negative && (rnd == ARF_RND_UP || rnd == ARF_RND_FLOOR))
                    v2++;
                if (!negative && (rnd == ARF_RND_UP || rnd == ARF_RND_CEIL))
                    v2++;
            }

            if (negative)
                fmpz_neg_ui(z, v2);
            else
                fmpz_set_ui(z, v2);

            return;
        }

        /* |x| >= 1 */
        zn = (exp + FLINT_BITS - 1) / FLINT_BITS;
        zz = _fmpz_promote(z);

        if (zz->_mp_alloc < zn)
            mpz_realloc2(zz, zn * FLINT_BITS);

        inexact = _arf_get_integer_mpn(zz->_mp_d, xp, xn, exp);

        zz->_mp_size = negative ? -zn : zn;
        _fmpz_demote_val(z);

        if (inexact && rnd != ARF_RND_DOWN)
        {
            if (negative && (rnd == ARF_RND_UP || rnd == ARF_RND_FLOOR))
                fmpz_sub_ui(z, z, 1);

            if (!negative && (rnd == ARF_RND_UP || rnd == ARF_RND_CEIL))
                fmpz_add_ui(z, z, 1);
        }
    }
Exemple #30
0
int main()
{
    slong iter;
    flint_rand_t state;

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

    flint_randinit(state);

    for (iter = 0; iter < 1000000 * arb_test_multiplier(); iter++)
    {
        arf_t x, y;
        slong prec, fix1, fix2;
        int ret1, ret2, sgnbit;
        mp_limb_t t[2];
        arf_rnd_t rnd;

        prec = 2 + n_randint(state, 1000);

        arf_init(x);
        arf_init(y);

        arf_randtest_special(x, state, 1 + n_randint(state, 200), 1 + n_randint(state, 100));
        arf_randtest_special(y, state, 1 + n_randint(state, 200), 1 + n_randint(state, 100));

        do {
            t[0] = n_randtest(state);
            t[1] = n_randtest(state);
        } while (t[0] == 0 && t[1] == 0);

        sgnbit = n_randint(state, 2);

        switch (n_randint(state, 10))
        {
            case 0: rnd = ARF_RND_DOWN; break;
            case 1: rnd = ARF_RND_UP; break;
            case 2: rnd = ARF_RND_FLOOR; break;
            case 3: rnd = ARF_RND_CEIL; break;
            default: rnd = ARF_RND_NEAR; break;
        }

        if (t[1] != 0)
        {
            ret1 = _arf_set_round_mpn(x, &fix1, t, 2, sgnbit, prec, rnd);
            fmpz_set_si(ARF_EXPREF(x), 2 * FLINT_BITS + fix1);
        }
        else
        {
            ret1 = _arf_set_round_mpn(x, &fix1, t, 1, sgnbit, prec, rnd);
            fmpz_set_si(ARF_EXPREF(x), FLINT_BITS + fix1);
        }

        ret2 = _arf_set_round_uiui(y, &fix2, t[1], t[0], sgnbit, prec, rnd);
        fmpz_set_si(ARF_EXPREF(y), 2 * FLINT_BITS + fix2);

        if (!arf_equal(x, y) || (ret1 != ret2))
        {
            flint_printf("FAIL\n\n");
            flint_printf("prec = %wd", prec); flint_printf("\n\n");
            flint_printf("hi = %wu, lo = %wu\n\n", t[1], t[0]);
            flint_printf("x = "); arf_print(x); flint_printf("\n\n");
            flint_printf("y = "); arf_print(y); flint_printf("\n\n");
            flint_printf("ret1 = %d, ret2 = %d\n\n", ret1, ret2);
            abort();
        }

        arf_clear(x);
        arf_clear(y);
    }

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