Beispiel #1
0
void
fmprb_mul_main_naive(fmprb_t z, const fmprb_t x, const fmprb_t y, slong prec)
{
    if (fmpr_is_pos_inf(fmprb_radref(x)) || fmpr_is_pos_inf(fmprb_radref(y)))
    {
        fmpr_mul(fmprb_midref(z), fmprb_midref(x), fmprb_midref(y), prec, FMPR_RND_DOWN);
        fmpr_pos_inf(fmprb_radref(z));
    }
    else
    {
        fmpr_t t, u;
        slong r;

        fmpr_init(t);
        fmpr_init(u);

        /* (x+a)*(y+b) = x*y + x*b + y*a + a*b*/

        fmpr_mul(t, fmprb_midref(x), fmprb_radref(y), FMPRB_RAD_PREC, FMPR_RND_UP);
        fmpr_abs(t, t);

        fmpr_mul(u, fmprb_midref(y), fmprb_radref(x), FMPRB_RAD_PREC, FMPR_RND_UP);
        fmpr_abs(u, u);

        fmpr_add(t, t, u, FMPRB_RAD_PREC, FMPR_RND_UP);
        fmpr_addmul(t, fmprb_radref(x), fmprb_radref(y), FMPRB_RAD_PREC, FMPR_RND_UP);

        r = fmpr_mul(fmprb_midref(z), fmprb_midref(x), fmprb_midref(y), prec, FMPR_RND_DOWN);
        fmpr_add_error_result(fmprb_radref(z), t,
            fmprb_midref(z), r, FMPRB_RAD_PREC, FMPR_RND_UP);

        fmpr_clear(t);
        fmpr_clear(u);
    }
}
Beispiel #2
0
static slong _fmpr_sub_special(fmpr_t z, const fmpr_t x, const fmpr_t y, slong prec, fmpr_rnd_t rnd)
{
    if (fmpr_is_zero(x))
    {
        return fmpr_neg_round(z, y, prec, rnd);
    }
    else if (fmpr_is_zero(y))
    {
        return fmpr_set_round(z, x, prec, rnd);
    }
    else if (fmpr_is_nan(x) || fmpr_is_nan(y)
        || (fmpr_is_pos_inf(x) && fmpr_is_pos_inf(y))
        || (fmpr_is_neg_inf(x) && fmpr_is_neg_inf(y)))
    {
        fmpr_nan(z);
        return FMPR_RESULT_EXACT;
    }
    else if (fmpr_is_special(x))
    {
        fmpr_set(z, x);
        return FMPR_RESULT_EXACT;
    }
    else
    {
        fmpr_neg(z, y);
        return FMPR_RESULT_EXACT;
    }
}
Beispiel #3
0
int
fmpr_get_mpfr(mpfr_t x, const fmpr_t y, mpfr_rnd_t rnd)
{
    int r;

    if (fmpr_is_special(y))
    {
        if (fmpr_is_zero(y)) mpfr_set_zero(x, 0);
        else if (fmpr_is_pos_inf(y)) mpfr_set_inf(x, 1);
        else if (fmpr_is_neg_inf(y)) mpfr_set_inf(x, -1);
        else mpfr_set_nan(x);
        r = 0;
    }
    else if (COEFF_IS_MPZ(*fmpr_expref(y)))
    {
        flint_printf("exception: exponent too large to convert to mpfr");
        abort();
    }
    else
    {
        if (!COEFF_IS_MPZ(*fmpr_manref(y)))
#if defined(__MINGW64__) 
            r = mpfr_set_sj_2exp(x, *fmpr_manref(y), *fmpr_expref(y), rnd);
#else
            r = mpfr_set_si_2exp(x, *fmpr_manref(y), *fmpr_expref(y), rnd);
#endif
        else
            r = mpfr_set_z_2exp(x, COEFF_TO_PTR(*fmpr_manref(y)), *fmpr_expref(y), rnd);

        if (!mpfr_regular_p(x))
        {
            flint_printf("exception: exponent too large to convert to mpfr");
            abort();
        }
    }
Beispiel #4
0
void
fmprb_mul_fmpr_naive(fmprb_t z, const fmprb_t x, const fmpr_t y, slong prec)
{
    /* (x+a) * y = x*y + y*a */
    if (fmpr_is_pos_inf(fmprb_radref(x)))
    {
        fmpr_mul(fmprb_midref(z), fmprb_midref(x), y, prec, FMPR_RND_DOWN);
        fmpr_pos_inf(fmprb_radref(z));
    }
    else if (fmpr_is_zero(fmprb_radref(x)))
    {
        slong r;

        r = fmpr_mul(fmprb_midref(z), fmprb_midref(x), y, prec, FMPR_RND_DOWN);
        fmpr_set_error_result(fmprb_radref(z), fmprb_midref(z), r);
    }
    else
    {
        slong r;

        fmpr_mul(fmprb_radref(z), fmprb_radref(x), y, FMPRB_RAD_PREC, FMPR_RND_UP);
        fmpr_abs(fmprb_radref(z), fmprb_radref(z));

        r = fmpr_mul(fmprb_midref(z), fmprb_midref(x), y, prec, FMPR_RND_DOWN);
        fmpr_add_error_result(fmprb_radref(z), fmprb_radref(z),
            fmprb_midref(z), r, FMPRB_RAD_PREC, FMPR_RND_UP);
    }
}
Beispiel #5
0
slong
fmpr_rsqrt(fmpr_t y, const fmpr_t x, slong prec, fmpr_rnd_t rnd)
{
    slong r;

    if (fmpr_is_special(x))
    {
        if (fmpr_is_zero(x))
            fmpr_pos_inf(y);
        else if (fmpr_is_pos_inf(x))
            fmpr_zero(y);
        else
            fmpr_nan(y);

        return FMPR_RESULT_EXACT;
    }

    if (fmpr_sgn(x) < 0)
    {
        fmpr_nan(y);
        return FMPR_RESULT_EXACT;
    }

    /* special case: 4^n */
    if (fmpz_is_one(fmpr_manref(x)) && fmpz_is_even(fmpr_expref(x)))
    {
        r = fmpr_set_round(y, x, prec, rnd);
        fmpz_tdiv_q_2exp(fmpr_expref(y), fmpr_expref(y), 1);
        fmpz_neg(fmpr_expref(y), fmpr_expref(y));
        return r;
    }

    {
        fmpr_t t;
        fmpz_t e;

        fmpr_init(t);
        fmpz_init(e);

        fmpz_neg(e, fmpr_expref(x));
        if (fmpz_is_odd(e))
            fmpz_add_ui(e, e, 1);
        fmpr_mul_2exp_fmpz(t, x, e);

        CALL_MPFR_FUNC(r, mpfr_rec_sqrt, y, t, prec, rnd);

        fmpz_tdiv_q_2exp(e, e, 1);
        fmpr_mul_2exp_fmpz(y, y, e);

        fmpr_clear(t);
        fmpz_clear(e);

        return r;
    }
}
Beispiel #6
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));
    }
}
Beispiel #7
0
int
fmpr_cmp(const fmpr_t x, const fmpr_t y)
{
    int res, xsign, ysign;
    fmpr_t t;

    if (fmpr_equal(x, y))
        return 0;

    if (fmpr_is_special(x) || fmpr_is_special(y))
    {
        if (fmpr_is_nan(x) || fmpr_is_nan(y))
            return 0;
        if (fmpr_is_zero(y)) return fmpr_sgn(x);
        if (fmpr_is_zero(x)) return -fmpr_sgn(y);
        if (fmpr_is_pos_inf(x)) return 1;
        if (fmpr_is_neg_inf(y)) return 1;
        return -1;
    }

    xsign = fmpr_sgn(x);
    ysign = fmpr_sgn(y);

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

    /* Reduces to integer comparison if bottom exponents are the same */
    if (fmpz_equal(fmpr_expref(x), fmpr_expref(y)))
        return fmpz_cmp(fmpr_manref(x), fmpr_manref(y)) < 0 ? -1 : 1;

    /* TODO: compare position of top exponents to avoid subtraction */

    fmpr_init(t);
    fmpr_sub(t, x, y, 2, FMPR_RND_DOWN);
    res = fmpr_sgn(t);
    fmpr_clear(t);

    return res;
}
Beispiel #8
0
void
fmprb_sqrtpos(fmprb_t z, const fmprb_t x, slong prec)
{
    if (!fmprb_is_finite(x))
    {
        if (fmpr_is_zero(fmprb_radref(x)) && fmpr_is_pos_inf(fmprb_midref(x)))
            fmprb_pos_inf(z);
        else
            fmprb_zero_pm_inf(z);
    }
    else if (fmprb_contains_nonpositive(x))
    {
        fmpr_t t;
        fmpr_init(t);
        fmpr_add(t, fmprb_midref(x), fmprb_radref(x),
            FMPRB_RAD_PREC, FMPR_RND_CEIL);
        if (fmpr_sgn(t) <= 0)
        {
            fmprb_zero(z);
        }
        else
        {
            fmpr_sqrt(t, t, FMPRB_RAD_PREC, FMPR_RND_CEIL);
            fmpr_mul_2exp_si(t, t, -1);
            fmpr_set(fmprb_midref(z), t);
            fmpr_set(fmprb_radref(z), t);
        }
        fmpr_clear(t);
    }
    else
    {
        fmprb_sqrt(z, x, prec);
    }

    fmprb_nonnegative_part(z, z, prec);
}
Beispiel #9
0
static void
_fmprb_gamma(fmprb_t y, const fmprb_t x, long prec, int inverse)
{
    int reflect;
    long r, n, wp;
    fmprb_t t, u, v;

    if (fmprb_is_exact(x))
    {
        const fmpr_struct * mid = fmprb_midref(x);

        if (fmpr_is_special(mid))
        {
            if (!inverse && fmpr_is_pos_inf(mid))
            {
                fmprb_set(y, x);
            }
            else if (fmpr_is_nan(mid) || fmpr_is_neg_inf(mid) || !inverse)
            {
                fmpr_nan(fmprb_midref(y));
                fmpr_pos_inf(fmprb_radref(y));
            }
            else
            {
                fmprb_zero(y);
            }
            return;
        }
        else
        {
            const fmpz exp = *fmpr_expref(mid);
            const fmpz man = *fmpr_manref(mid);

            /* fast gamma(n), gamma(n/2) or gamma(n/4) */
            if (!COEFF_IS_MPZ(exp) && (exp >= -2) &&
                ((double) fmpz_bits(&man) + exp < prec))
            {
                fmpq_t a;
                fmpq_init(a);
                fmpr_get_fmpq(a, mid);
                fmprb_gamma_fmpq(y, a, prec + 2 * inverse);
                if (inverse)
                    fmprb_ui_div(y, 1, y, prec);
                fmpq_clear(a);
                return;
            }
        }
    }

    wp = prec + FLINT_BIT_COUNT(prec);

    gamma_stirling_choose_param_fmprb(&reflect, &r, &n, x, 1, 0, wp);

    fmprb_init(t);
    fmprb_init(u);
    fmprb_init(v);

    if (reflect)
    {
        /* gamma(x) = (rf(1-x, r) * pi) / (gamma(1-x+r) sin(pi x)) */
        fmprb_sub_ui(t, x, 1, wp);
        fmprb_neg(t, t);
        gamma_rising_fmprb_ui_bsplit(u, t, r, wp);
        fmprb_const_pi(v, wp);
        fmprb_mul(u, u, v, wp);
        fmprb_add_ui(t, t, r, wp);
        gamma_stirling_eval_fmprb(v, t, n, 0, wp);
        fmprb_exp(v, v, wp);
        fmprb_sin_pi(t, x, wp);
        fmprb_mul(v, v, t, wp);
    }
    else
    {
        /* gamma(x) = gamma(x+r) / rf(x,r) */
        fmprb_add_ui(t, x, r, wp);
        gamma_stirling_eval_fmprb(u, t, n, 0, wp);
        fmprb_exp(u, u, prec);
        gamma_rising_fmprb_ui_bsplit(v, x, r, wp);
    }

    if (inverse)
        fmprb_div(y, v, u, prec);
    else
        fmprb_div(y, u, v, prec);

    fmprb_clear(t);
    fmprb_clear(u);
    fmprb_clear(v);
}