Example #1
0
void
arb_addmul(arb_t z, const arb_t x, const arb_t y, slong prec)
{
    mag_t zr, xm, ym;
    int inexact;

    if (arb_is_exact(y))
    {
        arb_addmul_arf(z, x, arb_midref(y), prec);
    }
    else if (arb_is_exact(x))
    {
        arb_addmul_arf(z, y, arb_midref(x), prec);
    }
    else if (ARB_IS_LAGOM(x) && ARB_IS_LAGOM(y) && ARB_IS_LAGOM(z))
    {
        mag_fast_init_set_arf(xm, arb_midref(x));
        mag_fast_init_set_arf(ym, arb_midref(y));

        mag_fast_init_set(zr, arb_radref(z));
        mag_fast_addmul(zr, xm, arb_radref(y));
        mag_fast_addmul(zr, ym, arb_radref(x));
        mag_fast_addmul(zr, arb_radref(x), arb_radref(y));

        inexact = arf_addmul(arb_midref(z), arb_midref(x), arb_midref(y),
            prec, ARF_RND_DOWN);

        if (inexact)
            arf_mag_fast_add_ulp(zr, zr, arb_midref(z), prec);

        *arb_radref(z) = *zr;
    }
    else
    {
        mag_init_set_arf(xm, arb_midref(x));
        mag_init_set_arf(ym, arb_midref(y));

        mag_init_set(zr, arb_radref(z));
        mag_addmul(zr, xm, arb_radref(y));
        mag_addmul(zr, ym, arb_radref(x));
        mag_addmul(zr, arb_radref(x), arb_radref(y));

        inexact = arf_addmul(arb_midref(z), arb_midref(x), arb_midref(y),
            prec, ARF_RND_DOWN);

        if (inexact)
            arf_mag_add_ulp(arb_radref(z), zr, arb_midref(z), prec);
        else
            mag_set(arb_radref(z), zr);

        mag_clear(zr);
        mag_clear(xm);
        mag_clear(ym);
    }
}
Example #2
0
void
arb_addmul_arf(arb_t z, const arb_t x, const arf_t y, slong prec)
{
    mag_t ym;
    int inexact;

    if (arb_is_exact(x))
    {
        inexact = arf_addmul(arb_midref(z), arb_midref(x), y, prec, ARB_RND);

        if (inexact)
            arf_mag_add_ulp(arb_radref(z), arb_radref(z), arb_midref(z), prec);
    }
    else if (ARB_IS_LAGOM(x) && ARF_IS_LAGOM(y) && ARB_IS_LAGOM(z))
    {
        mag_fast_init_set_arf(ym, y);
        mag_fast_addmul(arb_radref(z), ym, arb_radref(x));
        inexact = arf_addmul(arb_midref(z), arb_midref(x), y, prec, ARB_RND);

        if (inexact)
            arf_mag_fast_add_ulp(arb_radref(z), arb_radref(z), arb_midref(z), prec);
    }
    else
    {
        mag_init_set_arf(ym, y);
        mag_addmul(arb_radref(z), ym, arb_radref(x));

        inexact = arf_addmul(arb_midref(z), arb_midref(x), y, prec, ARB_RND);
        if (inexact)
            arf_mag_add_ulp(arb_radref(z), arb_radref(z), arb_midref(z), prec);

        mag_clear(ym);
    }
}
Example #3
0
File: pow.c Project: isuruf/arb
void
arb_pow(arb_t z, const arb_t x, const arb_t y, slong prec)
{
    if (arb_is_zero(y))
    {
        arb_one(z);
        return;
    }

    if (arb_is_zero(x))
    {
        if (arb_is_positive(y))
            arb_zero(z);
        else
            arb_indeterminate(z);
        return;
    }

    if (arb_is_exact(y) && !arf_is_special(arb_midref(x)))
    {
        const arf_struct * ymid = arb_midref(y);

        /* small half-integer or integer */
        if (arf_cmpabs_2exp_si(ymid, BINEXP_LIMIT) < 0 &&
            arf_is_int_2exp_si(ymid, -1))
        {
            fmpz_t e;
            fmpz_init(e);            

            if (arf_is_int(ymid))
            {
                arf_get_fmpz_fixed_si(e, ymid, 0);
                arb_pow_fmpz_binexp(z, x, e, prec);
            }
            else
            {
                arf_get_fmpz_fixed_si(e, ymid, -1);
                arb_sqrt(z, x, prec + fmpz_bits(e));
                arb_pow_fmpz_binexp(z, z, e, prec);
            }

            fmpz_clear(e);
            return;
        }
        else if (arf_is_int(ymid) && arf_sgn(arb_midref(x)) < 0)
        {
            /* use (-x)^n = (-1)^n * x^n to avoid NaNs
               at least at high enough precision */
            int odd = !arf_is_int_2exp_si(ymid, 1);
            _arb_pow_exp(z, x, 1, y, prec);
            if (odd)
                arb_neg(z, z);
            return;
        }
    }

    _arb_pow_exp(z, x, 0, y, prec);
}
Example #4
0
void
arb_sinc(arb_t z, const arb_t x, slong prec)
{
    mag_t c, r;
    mag_init(c);
    mag_init(r);
    mag_set_ui_2exp_si(c, 5, -1);
    arb_get_mag_lower(r, x);
    if (mag_cmp(c, r) < 0)
    {
        /* x is not near the origin */
        _arb_sinc_direct(z, x, prec);
    }
    else if (mag_cmp_2exp_si(arb_radref(x), 1) < 0)
    {
        /* determine error magnitude using the derivative bound */
        if (arb_is_exact(x))
        {
            mag_zero(c);
        }
        else
        {
            _arb_sinc_derivative_bound(r, x);
            mag_mul(c, arb_radref(x), r);
        }

        /* evaluate sinc at the midpoint of x */
        if (arf_is_zero(arb_midref(x)))
        {
            arb_one(z);
        }
        else
        {
            arb_get_mid_arb(z, x);
            _arb_sinc_direct(z, z, prec);
        }

        /* add the error */
        mag_add(arb_radref(z), arb_radref(z), c);
    }
    else
    {
        /* x has a large radius and includes points near the origin */
        arf_zero(arb_midref(z));
        mag_one(arb_radref(z));
    }

    mag_clear(c);
    mag_clear(r);
}
Example #5
0
File: root_ui.c Project: isuruf/arb
void
arb_root_ui_algebraic(arb_t res, const arb_t x, ulong k, slong prec)
{
    mag_t r, msubr, m1k, t;

    if (arb_is_exact(x))
    {
        arb_root_arf(res, arb_midref(x), k, prec);
        return;
    }

    if (!arb_is_nonnegative(x))
    {
        arb_indeterminate(res);
        return;
    }

    mag_init(r);
    mag_init(msubr);
    mag_init(m1k);
    mag_init(t);

    /* x = [m-r, m+r] */
    mag_set(r, arb_radref(x));
    /* m - r */
    arb_get_mag_lower(msubr, x);

    /* m^(1/k) */
    arb_root_arf(res, arb_midref(x), k, prec);

    /* bound for m^(1/k) */
    arb_get_mag(m1k, res);

    /* C = min(1, log(1+r/(m-r))/k) */
    mag_div(t, r, msubr);
    mag_log1p(t, t);
    mag_div_ui(t, t, k);
    if (mag_cmp_2exp_si(t, 0) > 0)
        mag_one(t);

    /* C m^(1/k) */
    mag_mul(t, m1k, t);
    mag_add(arb_radref(res), arb_radref(res), t);

    mag_clear(r);
    mag_clear(msubr);
    mag_clear(m1k);
    mag_clear(t);
}
Example #6
0
File: div.c Project: bluescarni/arb
void
arb_div(arb_t z, const arb_t x, const arb_t y, long prec)
{
    mag_t zr, xm, ym, yl, yw;
    int inexact;

    if (arb_is_exact(y))
    {
        arb_div_arf(z, x, arb_midref(y), prec);
    }
    else if (mag_is_inf(arb_radref(x)) || mag_is_inf(arb_radref(y)))
    {
        arf_div(arb_midref(z), arb_midref(x), arb_midref(y), prec, ARB_RND);
        mag_inf(arb_radref(z));
    }
    else
    {
        mag_init_set_arf(xm, arb_midref(x));
        mag_init_set_arf(ym, arb_midref(y));
        mag_init(zr);
        mag_init(yl);
        mag_init(yw);

        /* (|x|*yrad + |y|*xrad)/(y*(|y|-yrad)) */
        mag_mul(zr, xm, arb_radref(y));
        mag_addmul(zr, ym, arb_radref(x));
        arb_get_mag_lower(yw, y);

        arf_get_mag_lower(yl, arb_midref(y));
        mag_mul_lower(yl, yl, yw);

        mag_div(zr, zr, yl);

        inexact = arf_div(arb_midref(z), arb_midref(x), arb_midref(y), prec, ARB_RND);

        if (inexact)
            arf_mag_add_ulp(arb_radref(z), zr, arb_midref(z), prec);
        else
            mag_swap(arb_radref(z), zr);

        mag_clear(xm);
        mag_clear(ym);
        mag_clear(zr);
        mag_clear(yl);
        mag_clear(yw);
    }
}
Example #7
0
int
arb_contains_arf(const arb_t x, const arf_t y)
{
    if (arf_is_nan(y))
    {
        return arf_is_nan(arb_midref(x));
    }
    else if (arf_is_nan(arb_midref(x)))
    {
        return 1;
    }
    else if (arb_is_exact(x))
    {
        return arf_equal(arb_midref(x), y);
    }
    else
    {
        arf_t t;
        arf_struct tmp[3];
        int result;

        arf_init(t);

        /* y >= xm - xr  <=>  0 >= xm - xr - y */
        arf_init_set_shallow(tmp + 0, arb_midref(x));
        arf_init_neg_mag_shallow(tmp + 1,  arb_radref(x));
        arf_init_neg_shallow(tmp + 2, y);

        arf_sum(t, tmp, 3, MAG_BITS, ARF_RND_DOWN);
        result = (arf_sgn(t) <= 0);

        if (result)
        {
            /* y <= xm + xr  <=>  0 <= xm + xr - y */
            arf_init_set_mag_shallow(tmp + 1,  arb_radref(x));
            arf_sum(t, tmp, 3, MAG_BITS, ARF_RND_DOWN);
            result = (arf_sgn(t) >= 0);
        }

        arf_clear(t);

        return result;
    }
}
Example #8
0
File: div.c Project: bluescarni/arb
void
arb_div_arf(arb_t z, const arb_t x, const arf_t y, long prec)
{
    mag_t zr, ym;
    int inexact;

    if (arf_is_zero(y))
    {
        arb_zero_pm_inf(z);
    }
    else if (arb_is_exact(x))
    {
        inexact = arf_div(arb_midref(z), arb_midref(x), y, prec, ARB_RND);

        if (inexact)
            arf_mag_set_ulp(arb_radref(z), arb_midref(z), prec);
        else
            mag_zero(arb_radref(z));
    }
    else if (mag_is_inf(arb_radref(x)))
    {
        arf_div(arb_midref(z), arb_midref(x), y, prec, ARB_RND);
        mag_inf(arb_radref(z));
    }
    else
    {
        mag_init(ym);
        mag_init(zr);

        arf_get_mag_lower(ym, y);
        mag_div(zr, arb_radref(x), ym);

        inexact = arf_div(arb_midref(z), arb_midref(x), y, prec, ARB_RND);

        if (inexact)
            arf_mag_add_ulp(arb_radref(z), zr, arb_midref(z), prec);
        else
            mag_swap(arb_radref(z), zr);

        mag_clear(ym);
        mag_clear(zr);
    }
}
Example #9
0
void
arb_atan(arb_t z, const arb_t x, slong prec)
{
    if (arb_is_exact(x))
    {
        arb_atan_arf(z, arb_midref(x), prec);
    }
    else
    {
        mag_t t, u;

        mag_init(t);
        mag_init(u);

        arb_get_mag_lower(t, x);

        if (mag_is_zero(t))
        {
            mag_set(t, arb_radref(x));
        }
        else
        {
            mag_mul_lower(t, t, t);
            mag_one(u);
            mag_add_lower(t, t, u);
            mag_div(t, arb_radref(x), t);
        }

        if (mag_cmp_2exp_si(t, 0) > 0)
        {
            mag_const_pi(u);
            mag_min(t, t, u);
        }

        arb_atan_arf(z, arb_midref(x), prec);
        mag_add(arb_radref(z), arb_radref(z), t);

        mag_clear(t);
        mag_clear(u);
    }
}
Example #10
0
File: log.c Project: isuruf/arb
void
arb_log(arb_t y, const arb_t x, slong prec)
{
    if (arb_is_exact(x))
    {
        arb_log_arf(y, arb_midref(x), prec);
    }
    else
    {
        /*
        Let the input be [a-b, a+b]. We require a > b >= 0 (otherwise the
        interval contains zero or a negative number and the logarithm is not
        defined). The error is largest at a-b, and we have

        log(a) - log(a-b) = log(1 + b/(a-b)).
        */
        mag_t err;
        mag_init(err);

        arb_get_mag_lower_nonnegative(err, x);

        if (mag_is_zero(err))
        {
            mag_inf(err);
        }
        else
        {
            mag_div(err, arb_radref(x), err);
            mag_log1p(err, err);
        }

        arb_log_arf(y, arb_midref(x), prec);

        mag_add(arb_radref(y), arb_radref(y), err);
        mag_clear(err);
    }
}
Example #11
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);
}
Example #12
0
void
_acb_poly_powsum_one_series_sieved(acb_ptr z, const acb_t s, slong n, slong len, slong prec)
{
    slong * divisors;
    slong powers_alloc;
    slong i, j, k, ibound, kprev, power_of_two, horner_point;
    int critical_line, integer;

    acb_ptr powers;
    acb_ptr t, u, x;
    acb_ptr p1, p2;
    arb_t logk, v, w;

    critical_line = arb_is_exact(acb_realref(s)) &&
        (arf_cmp_2exp_si(arb_midref(acb_realref(s)), -1) == 0);

    integer = arb_is_zero(acb_imagref(s)) && arb_is_int(acb_realref(s));

    divisors = flint_calloc(n / 2 + 1, sizeof(slong));
    powers_alloc = (n / 6 + 1) * len;
    powers = _acb_vec_init(powers_alloc);

    ibound = n_sqrt(n);
    for (i = 3; i <= ibound; i += 2)
        if (DIVISOR(i) == 0)
            for (j = i * i; j <= n; j += 2 * i)
                DIVISOR(j) = i;

    t = _acb_vec_init(len);
    u = _acb_vec_init(len);
    x = _acb_vec_init(len);
    arb_init(logk);
    arb_init(v);
    arb_init(w);

    power_of_two = 1;
    while (power_of_two * 2 <= n)
        power_of_two *= 2;
    horner_point = n / power_of_two;

    _acb_vec_zero(z, len);

    kprev = 0;
    COMPUTE_POWER(x, 2, kprev);

    for (k = 1; k <= n; k += 2)
    {
        /* t = k^(-s) */
        if (DIVISOR(k) == 0)
        {
            COMPUTE_POWER(t, k, kprev);
        }
        else
        {
            p1 = POWER(DIVISOR(k));
            p2 = POWER(k / DIVISOR(k));

            if (len == 1)
                acb_mul(t, p1, p2, prec);
            else
                _acb_poly_mullow(t, p1, len, p2, len, len, prec);
        }

        if (k * 3 <= n)
            _acb_vec_set(POWER(k), t, len);

        _acb_vec_add(u, u, t, len, prec);

        while (k == horner_point && power_of_two != 1)
        {
            _acb_poly_mullow(t, z, len, x, len, len, prec);
            _acb_vec_add(z, t, u, len, prec);

            power_of_two /= 2;
            horner_point = n / power_of_two;
            horner_point -= (horner_point % 2 == 0);
        }
    }

    _acb_poly_mullow(t, z, len, x, len, len, prec);
    _acb_vec_add(z, t, u, len, prec);

    flint_free(divisors);
    _acb_vec_clear(powers, powers_alloc);
    _acb_vec_clear(t, len);
    _acb_vec_clear(u, len);
    _acb_vec_clear(x, len);
    arb_clear(logk);
    arb_clear(v);
    arb_clear(w);
}
Example #13
0
void
acb_dirichlet_zeta_rs_mid(acb_t res, const acb_t s, slong K, slong prec)
{
    acb_t R1, R2, X, t;
    slong wp;

    if (arf_sgn(arb_midref(acb_imagref(s))) < 0)
    {
        acb_init(t);
        acb_conj(t, s);
        acb_dirichlet_zeta_rs(res, t, K, prec);
        acb_conj(res, res);
        acb_clear(t);
        return;
    }

    acb_init(R1);
    acb_init(R2);
    acb_init(X);
    acb_init(t);

    /* rs_r increases the precision internally */
    wp = prec;

    acb_dirichlet_zeta_rs_r(R1, s, K, wp);

    if (arb_is_exact(acb_realref(s)) &&
        (arf_cmp_2exp_si(arb_midref(acb_realref(s)), -1) == 0))
    {
        acb_conj(R2, R1);
    }
    else
    {
        /* conj(R(conj(1-s))) */
        arb_sub_ui(acb_realref(t), acb_realref(s), 1, 10 * wp);
        arb_neg(acb_realref(t), acb_realref(t));
        arb_set(acb_imagref(t), acb_imagref(s));
        acb_dirichlet_zeta_rs_r(R2, t, K, wp);
        acb_conj(R2, R2);
    }

    if (acb_is_finite(R1) && acb_is_finite(R2))
    {
        wp += 10 + arf_abs_bound_lt_2exp_si(arb_midref(acb_imagref(s)));
        wp = FLINT_MAX(wp, 10);

        /* X = pi^(s-1/2) gamma((1-s)/2) rgamma(s/2)
             = (2 pi)^s rgamma(s) / (2 cos(pi s / 2)) */
        acb_rgamma(X, s, wp);
        acb_const_pi(t, wp);
        acb_mul_2exp_si(t, t, 1);
        acb_pow(t, t, s, wp);
        acb_mul(X, X, t, wp);
        acb_mul_2exp_si(t, s, -1);
        acb_cos_pi(t, t, wp);
        acb_mul_2exp_si(t, t, 1);
        acb_div(X, X, t, wp);

        acb_mul(R2, R2, X, wp);
    }

    /* R1 + X * R2 */
    acb_add(res, R1, R2, prec);

    acb_clear(R1);
    acb_clear(R2);
    acb_clear(X);
    acb_clear(t);
}
Example #14
0
int
arb_get_unique_fmpz(fmpz_t z, const arb_t x)
{
    if (!arb_is_finite(x))
    {
        return 0;
    }
    else if (arb_is_exact(x))
    {
        /* x = b*2^e, e >= 0 */
        if (arf_is_int(arb_midref(x)))
        {
            /* arf_get_fmpz aborts on overflow */
            arf_get_fmpz(z, arb_midref(x), ARF_RND_DOWN);
            return 1;
        }
        else
        {
            return 0;
        }
    }
    /* if the radius is >= 1, there are at least two integers */
    else if (mag_cmp_2exp_si(arb_radref(x), 0) >= 0)
    {
        return 0;
    }
    /* there are 0 or 1 integers if the radius is < 1 */
    else
    {
        fmpz_t a, b, exp;
        int res;

        /* if the midpoint is exactly an integer, it is what we want */
        if (arf_is_int(arb_midref(x)))
        {
            /* arf_get_fmpz aborts on overflow */
            arf_get_fmpz(z, arb_midref(x), ARF_RND_DOWN);
            return 1;
        }

        fmpz_init(a);
        fmpz_init(b);
        fmpz_init(exp);

        /* if the radius is tiny, it can't be an integer */
        arf_bot(a, arb_midref(x));

        if (fmpz_cmp(a, MAG_EXPREF(arb_radref(x))) > 0)
        {
            res = 0;
        }
        else
        {
            arb_get_interval_fmpz_2exp(a, b, exp, x);

            if (COEFF_IS_MPZ(*exp))
            {
                flint_printf("arb_get_unique_fmpz: input too large\n");
                abort();
            }

            if (*exp >= 0)
            {
                res = fmpz_equal(a, b);

                if (res)
                {
                    fmpz_mul_2exp(a, a, *exp);
                    fmpz_mul_2exp(b, b, *exp);
                }
            }
            else
            {
                fmpz_cdiv_q_2exp(a, a, -(*exp));
                fmpz_fdiv_q_2exp(b, b, -(*exp));
                res = fmpz_equal(a, b);
            }

            if (res)
                fmpz_set(z, a);
        }

        fmpz_clear(a);
        fmpz_clear(b);
        fmpz_clear(exp);

        return res;
    }
}