예제 #1
0
파일: addmul.c 프로젝트: argriffing/arb
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);
    }
}
예제 #2
0
void
arb_set_interval_arf(arb_t x, const arf_t a, const arf_t b, slong prec)
{
    arf_t t;
    int inexact;

    if (arf_is_inf(a) && arf_equal(a, b))
    {
        /* [-inf, -inf] or [+inf, +inf] */
        arf_set(arb_midref(x), a);
        mag_zero(arb_radref(x));
        return;
    }

    arf_init(t);
    arf_sub(t, b, a, MAG_BITS, ARF_RND_UP);

    if (arf_sgn(t) < 0)
    {
        flint_printf("exception: arb_set_interval_arf: endpoints not ordered\n");
        abort();
    }

    arf_get_mag(arb_radref(x), t);

    inexact = arf_add(arb_midref(x), a, b, prec, ARB_RND);
    if (inexact)
        arf_mag_add_ulp(arb_radref(x), arb_radref(x), arb_midref(x), prec);

    arb_mul_2exp_si(x, x, -1);

    arf_clear(t);
}
예제 #3
0
파일: arb_extras.c 프로젝트: jwbober/ntlib
void arb_square(arb_t out, const arb_t in, slong prec) {
    mag_mul(arb_radref(out), arb_radref(in), arb_radref(in));
    int inexact = arf_mul(arb_midref(out), arb_midref(in), arb_midref(in), ARB_RND, prec);
    if (inexact)
        arf_mag_add_ulp(arb_radref(out), arb_radref(out), arb_midref(out), prec);

}
예제 #4
0
파일: sqrtpos.c 프로젝트: bluescarni/arb
static __inline__ void
arb_nonnegative_part(arb_t z, const arb_t x, long prec)
{
    if (arb_contains_negative(x))
    {
        arf_t t;
        arf_init(t);

        arf_set_mag(t, arb_radref(x));
        arf_add(arb_midref(z), arb_midref(x), t, MAG_BITS, ARF_RND_CEIL);

        if (arf_sgn(arb_midref(z)) <= 0)
        {
            mag_zero(arb_radref(z));
        }
        else
        {
            arf_mul_2exp_si(arb_midref(z), arb_midref(z), -1);
            arf_get_mag(arb_radref(z), arb_midref(z));

            /* XXX: needed since arf_get_mag is inexact */
            arf_set_mag(arb_midref(z), arb_radref(z));
        }

        arf_clear(t);
    }
    else
    {
        arb_set(z, x);
    }
}
예제 #5
0
void
arb_max(arb_t z, const arb_t x, const arb_t y, slong prec)
{
    arf_t left, right, t, xr, yr;

    if (arf_is_nan(arb_midref(x)) || arf_is_nan(arb_midref(y)))
    {
        arb_indeterminate(z);
        return;
    }

    arf_init(left);
    arf_init(right);
    arf_init(t);

    arf_init_set_mag_shallow(xr, arb_radref(x));
    arf_init_set_mag_shallow(yr, arb_radref(y));

    arf_sub(left, arb_midref(x), xr, prec, ARF_RND_FLOOR);
    arf_sub(t, arb_midref(y), yr, prec, ARF_RND_FLOOR);
    arf_max(left, left, t);

    arf_add(right, arb_midref(x), xr, prec, ARF_RND_CEIL);
    arf_add(t, arb_midref(y), yr, prec, ARF_RND_CEIL);
    arf_max(right, right, t);

    arb_set_interval_arf(z, left, right, prec);

    arf_clear(left);
    arf_clear(right);
    arf_clear(t);
}
예제 #6
0
파일: t-elliptic_p.c 프로젝트: isuruf/arb
static void
acb_set_dddd(acb_t z, double a, double ar, double b, double br)
{
    arf_set_d(arb_midref(acb_realref(z)), a);
    mag_set_d(arb_radref(acb_realref(z)), ar);
    arf_set_d(arb_midref(acb_imagref(z)), b);
    mag_set_d(arb_radref(acb_imagref(z)), br);
}
예제 #7
0
파일: root_ui.c 프로젝트: isuruf/arb
static void
arb_root_arf(arb_t z, const arf_t x, ulong k, slong prec)
{
    int inexact = arf_root(arb_midref(z), x, k, prec, ARB_RND);

    if (inexact)
        arf_mag_set_ulp(arb_radref(z), arb_midref(z), prec);
    else
        mag_zero(arb_radref(z));
}
예제 #8
0
파일: sub.c 프로젝트: argriffing/arb
void
arb_sub_fmpz(arb_t z, const arb_t x, const fmpz_t y, slong prec)
{
    int inexact;
    inexact = arf_sub_fmpz(arb_midref(z), arb_midref(x), y, prec, ARB_RND);
    if (inexact)
        arf_mag_add_ulp(arb_radref(z), arb_radref(x), arb_midref(z), prec);
    else
        mag_set(arb_radref(z), arb_radref(x));
}
예제 #9
0
파일: inv.c 프로젝트: fredrik-johansson/arb
static void
_arb_arf_div_rounded_den_add_err(arb_t res, const arf_t x, const arf_t y, int yinexact, slong prec)
{
    int inexact = arf_div(arb_midref(res), x, y, prec, ARB_RND);

    if (yinexact && !arf_is_special(arb_midref(res)))
        arf_mag_add_ulp(arb_radref(res), arb_radref(res), arb_midref(res), prec - 1);
    else if (inexact)
        arf_mag_add_ulp(arb_radref(res), arb_radref(res), arb_midref(res), prec);
}
예제 #10
0
파일: erf.c 프로젝트: fredrik-johansson/arb
void
acb_hypgeom_erf_propagated_error(mag_t re, mag_t im, const acb_t z)
{
    mag_t x, y;

    mag_init(x);
    mag_init(y);

    /* |exp(-(x+y)^2)| = exp(y^2-x^2) */
    arb_get_mag(y, acb_imagref(z));
    mag_mul(y, y, y);

    arb_get_mag_lower(x, acb_realref(z));
    mag_mul_lower(x, x, x);

    if (mag_cmp(y, x) >= 0)
    {
        mag_sub(re, y, x);
        mag_exp(re, re);
    }
    else
    {
        mag_sub_lower(re, x, y);
        mag_expinv(re, re);
    }

    /* Radius. */
    mag_hypot(x, arb_radref(acb_realref(z)), arb_radref(acb_imagref(z)));
    mag_mul(re, re, x);

    /* 2/sqrt(pi) < 289/256 */
    mag_mul_ui(re, re, 289);
    mag_mul_2exp_si(re, re, -8);

    if (arb_is_zero(acb_imagref(z)))
    {
        /* todo: could bound magnitude even for complex numbers */
        mag_set_ui(y, 2);
        mag_min(re, re, y);

        mag_zero(im);
    }
    else if (arb_is_zero(acb_realref(z)))
    {
        mag_swap(im, re);
        mag_zero(re);
    }
    else
    {
        mag_set(im, re);
    }

    mag_clear(x);
    mag_clear(y);
}
예제 #11
0
void
arb_set_round_fmpz(arb_t y, const fmpz_t x, slong prec)
{
    int inexact;
    inexact = arf_set_round_fmpz(arb_midref(y), x, prec, ARB_RND);

    if (inexact)
        arf_mag_set_ulp(arb_radref(y), arb_midref(y), prec);
    else
        mag_zero(arb_radref(y));
}
예제 #12
0
파일: t-spherical_y.c 프로젝트: isuruf/arb
int main()
{
    flint_printf("spherical_y....");
    fflush(stdout);

    {
        slong i, n, m;
        acb_t z, w, x, y;

        acb_init(z);
        acb_init(w);
        acb_init(x);
        acb_init(y);

        i = 0;

        arb_set_str(acb_realref(x), "0.2", 64);
        arb_set_str(acb_imagref(x), "0.3", 64);
        arb_set_str(acb_realref(y), "0.3", 64);
        arb_set_str(acb_imagref(y), "0.4", 64);

        for (n = -4; n <= 4; n++)
        {
            for (m = -4; m <= 4; m++)
            {
                acb_hypgeom_spherical_y(z, n, m, x, y, 64);

                acb_set_d_d(w, testdata[2 * i], testdata[2 * i + 1]);
                mag_set_d(arb_radref(acb_realref(w)), 1e-13);
                mag_set_d(arb_radref(acb_imagref(w)), 1e-13);

                if (!acb_overlaps(z, w))
                {
                    flint_printf("FAIL: value\n\n");
                    flint_printf("n = %wd, m = %wd\n", n, m);
                    flint_printf("z = "); acb_printd(z, 20); flint_printf("\n\n");
                    flint_printf("w = "); acb_printd(w, 20); flint_printf("\n\n");
                    abort();
                }

                i++;
            }
        }

        acb_clear(z);
        acb_clear(w);
        acb_clear(x);
        acb_clear(y);
    }

    flint_cleanup();
    flint_printf("PASS\n");
    return EXIT_SUCCESS;
}
예제 #13
0
파일: sub.c 프로젝트: argriffing/arb
void
arb_sub(arb_t z, const arb_t x, const arb_t y, slong prec)
{
    int inexact;

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

    mag_add(arb_radref(z), arb_radref(x), arb_radref(y));
    if (inexact)
        arf_mag_add_ulp(arb_radref(z), arb_radref(z), arb_midref(z), prec);
}
예제 #14
0
파일: div.c 프로젝트: bluescarni/arb
void
arb_fmpz_div_fmpz(arb_t z, const fmpz_t x, const fmpz_t y, long prec)
{
    int inexact;

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

    if (inexact)
        arf_mag_set_ulp(arb_radref(z), arb_midref(z), prec);
    else
        mag_zero(arb_radref(z));
}
예제 #15
0
파일: sin_cos_pi.c 프로젝트: bluescarni/arb
void
arb_sin_cos_pi(arb_t s, arb_t c, const arb_t x, long prec)
{
    arb_t t;
    arb_t u;
    fmpz_t v;

    if (arf_cmpabs_2exp_si(arb_midref(x), FLINT_MAX(65536, (4*prec))) > 0)
    {
        arf_zero(arb_midref(s));
        mag_one(arb_radref(s));
        arf_zero(arb_midref(c));
        mag_one(arb_radref(c));
        return;
    }

    arb_init(t);
    arb_init(u);
    fmpz_init(v);

    arb_mul_2exp_si(t, x, 1);
    arf_get_fmpz(v, arb_midref(t), ARF_RND_NEAR);
    arb_sub_fmpz(t, t, v, prec);

    arb_const_pi(u, prec);
    arb_mul(t, t, u, prec);
    arb_mul_2exp_si(t, t, -1);

    switch (fmpz_fdiv_ui(v, 4))
    {
        case 0:
            arb_sin_cos(s, c, t, prec);
            break;
        case 1:
            arb_sin_cos(c, s, t, prec);
            arb_neg(c, c);
            break;
        case 2:
            arb_sin_cos(s, c, t, prec);
            arb_neg(s, s);
            arb_neg(c, c);
            break;
        default:
            arb_sin_cos(c, s, t, prec);
            arb_neg(s, s);
            break;
    }

    fmpz_clear(v);
    arb_clear(t);
    arb_clear(u);
}
예제 #16
0
int check_accuracy(acb_ptr vec, slong len, slong prec)
{
    slong i;

    for (i = 0; i < len; i++)
    {
        if (mag_cmp_2exp_si(arb_radref(acb_realref(vec + i)), -prec) >= 0
                || mag_cmp_2exp_si(arb_radref(acb_imagref(vec + i)), -prec) >= 0)
            return 0;
    }

    return 1;
}
예제 #17
0
/* note: the tmp variable t should have zero radius */
static void
acb_approx_div(acb_t z, const acb_t x, const acb_t y, acb_t t, slong prec)
{
    arf_set(arb_midref(acb_realref(t)), arb_midref(acb_realref(y)));
    arf_set(arb_midref(acb_imagref(t)), arb_midref(acb_imagref(y)));

    acb_inv(t, t, prec);

    mag_zero(arb_radref(acb_realref(t)));
    mag_zero(arb_radref(acb_imagref(t)));

    acb_approx_mul(z, x, t, prec);
}
예제 #18
0
파일: mul.c 프로젝트: isuruf/arb
static void
_acb_mul_slow(acb_t z, const acb_t x, const acb_t y, slong prec)
{
    int inexact;

    mag_t am, bm, cm, dm, er, fr;

    mag_init_set_arf(am, arb_midref(a));
    mag_init_set_arf(bm, arb_midref(b));
    mag_init_set_arf(cm, arb_midref(c));
    mag_init_set_arf(dm, arb_midref(d));

    mag_init(er);
    mag_init(fr);

    mag_addmul(er, am, cr);
    mag_addmul(er, bm, dr);
    mag_addmul(er, cm, ar);
    mag_addmul(er, dm, br);
    mag_addmul(er, ar, cr);
    mag_addmul(er, br, dr);

    mag_addmul(fr, am, dr);
    mag_addmul(fr, bm, cr);
    mag_addmul(fr, cm, br);
    mag_addmul(fr, dm, ar);
    mag_addmul(fr, br, cr);
    mag_addmul(fr, ar, dr);

    inexact = arf_complex_mul(arb_midref(e), arb_midref(f),
                    arb_midref(a), arb_midref(b),
                    arb_midref(c), arb_midref(d), prec, ARB_RND);

    if (inexact & 1)
        arf_mag_add_ulp(arb_radref(e), er, arb_midref(e), prec);
    else
        mag_swap(arb_radref(e), er);

    if (inexact & 2)
        arf_mag_add_ulp(arb_radref(f), fr, arb_midref(f), prec);
    else
        mag_swap(arb_radref(f), fr);

    mag_clear(am);
    mag_clear(bm);
    mag_clear(cm);
    mag_clear(dm);

    mag_clear(er);
    mag_clear(fr);
}
예제 #19
0
파일: sinc.c 프로젝트: argriffing/arb
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);
}
예제 #20
0
/* assumes no aliasing */
slong
acb_lambertw_initial(acb_t res, const acb_t z, const acb_t ez1, const fmpz_t k, slong prec)
{
    /* Handle z very close to 0 on the principal branch. */
    if (fmpz_is_zero(k) && 
            (arf_cmpabs_2exp_si(arb_midref(acb_realref(z)), -20) <= 0 &&
             arf_cmpabs_2exp_si(arb_midref(acb_imagref(z)), -20) <= 0))
    {
        acb_set(res, z);
        acb_submul(res, res, res, prec);
        return 40;  /* could be tightened... */
    }

    /* For moderate input not close to the branch point, compute a double
       approximation as the initial value. */
    if (fmpz_is_zero(k) &&
        arf_cmpabs_2exp_si(arb_midref(acb_realref(z)), 400) < 0 &&
        arf_cmpabs_2exp_si(arb_midref(acb_imagref(z)), 400) < 0 &&
          (arf_cmp_d(arb_midref(acb_realref(z)), -0.37) < 0 ||
           arf_cmp_d(arb_midref(acb_realref(z)), -0.36) > 0 ||
           arf_cmpabs_d(arb_midref(acb_imagref(z)), 0.01) > 0))
    {
        acb_lambertw_principal_d(res, z);
        return 48;
    }

    /* Check if we are close to the branch point at -1/e. */
    if ((fmpz_is_zero(k) || (fmpz_is_one(k) && arb_is_negative(acb_imagref(z)))
                         || (fmpz_equal_si(k, -1) && arb_is_nonnegative(acb_imagref(z))))
        && ((arf_cmpabs_2exp_si(arb_midref(acb_realref(ez1)), -2) <= 0 &&
             arf_cmpabs_2exp_si(arb_midref(acb_imagref(ez1)), -2) <= 0)))
    {
        acb_t t;
        acb_init(t);
        acb_mul_2exp_si(t, ez1, 1);
        mag_zero(arb_radref(acb_realref(t)));
        mag_zero(arb_radref(acb_imagref(t)));
        acb_mul_ui(t, t, 3, prec);
        acb_sqrt(t, t, prec);
        if (!fmpz_is_zero(k))
            acb_neg(t, t);
        acb_lambertw_branchpoint_series(res, t, 0, prec);
        acb_clear(t);
        return 1;  /* todo: estimate */
    }

    acb_lambertw_initial_asymp(res, z, k, prec);
    return 1;  /* todo: estimate */
}
예제 #21
0
파일: root_ui.c 프로젝트: 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);
}
예제 #22
0
int
_arb_poly_newton_step(arb_t xnew, arb_srcptr poly, long len,
    const arb_t x,
    const arb_t convergence_interval,
    const arf_t convergence_factor, long prec)
{
    arf_t err;
    arb_t t, u, v;
    int result;

    arf_init(err);
    arb_init(t);
    arb_init(u);
    arb_init(v);

    arf_set_mag(err, arb_radref(x));
    arf_mul(err, err, err, MAG_BITS, ARF_RND_UP);
    arf_mul(err, err, convergence_factor, MAG_BITS, ARF_RND_UP);

    arf_set(arb_midref(t), arb_midref(x));
    mag_zero(arb_radref(t));

    _arb_poly_evaluate2(u, v, poly, len, t, prec);

    arb_div(u, u, v, prec);
    arb_sub(u, t, u, prec);

    arb_add_error_arf(u, err);

    if (arb_contains(convergence_interval, u) &&
        (mag_cmp(arb_radref(u), arb_radref(x)) < 0))
    {
        arb_swap(xnew, u);
        result = 1;
    }
    else
    {
        arb_set(xnew, x);
        result = 0;
    }

    arb_clear(t);
    arb_clear(u);
    arb_clear(v);
    arf_clear(err);

    return result;
}
예제 #23
0
파일: fprint.c 프로젝트: isuruf/arb
void
arb_fprintd(FILE * file, const arb_t x, slong digits)
{
    arf_fprintd(file, arb_midref(x), FLINT_MAX(digits, 1));
    flint_fprintf(file, " +/- ");
    mag_fprintd(file, arb_radref(x), 5);
}
예제 #24
0
파일: fprint.c 프로젝트: isuruf/arb
void
arb_fprint(FILE * file, const arb_t x)
{
    arf_fprint(file, arb_midref(x));
    flint_fprintf(file, " +/- ");
    mag_fprint(file, arb_radref(x));
}
예제 #25
0
void
acb_lambertw_cleared_cut_fix_small(acb_t res, const acb_t z,
    const acb_t ez1, const fmpz_t k, int flags, slong prec)
{
    acb_t zz, zmid, zmide1;
    arf_t eps;

    acb_init(zz);
    acb_init(zmid);
    acb_init(zmide1);
    arf_init(eps);

    arf_mul_2exp_si(eps, arb_midref(acb_realref(z)), -prec);
    acb_set(zz, z);

    if (arf_sgn(arb_midref(acb_realref(zz))) < 0 &&
        (!fmpz_is_zero(k) || arf_sgn(arb_midref(acb_realref(ez1))) < 0) &&
        arf_cmpabs(arb_midref(acb_imagref(zz)), eps) < 0)
    {
        /* now the value must be in [0,2eps] */
        arf_get_mag(arb_radref(acb_imagref(zz)), eps);
        arf_set_mag(arb_midref(acb_imagref(zz)), arb_radref(acb_imagref(zz)));

        if (arf_sgn(arb_midref(acb_imagref(z))) >= 0)
        {
            acb_lambertw_cleared_cut(res, zz, k, flags, prec);
        }
        else
        {
            fmpz_t kk;
            fmpz_init(kk);
            fmpz_neg(kk, k);
            acb_lambertw_cleared_cut(res, zz, kk, flags, prec);
            acb_conj(res, res);
            fmpz_clear(kk);
        }
    }
    else
    {
        acb_lambertw_cleared_cut(res, zz, k, flags, prec);
    }

    acb_clear(zz);
    acb_clear(zmid);
    acb_clear(zmide1);
    arf_clear(eps);
}
예제 #26
0
static void
arb_supremum(arf_t res, const arb_t x)
{
    if (arf_is_nan(arb_midref(x)))
    {
        arf_nan(res);
    }
    else if (mag_is_inf(arb_radref(x)))
    {
        arf_pos_inf(res);
    }
    else
    {
        arf_set_mag(res, arb_radref(x));
        arf_add(res, res, arb_midref(x), ARF_PREC_EXACT, ARF_RND_CEIL);
    }
}
예제 #27
0
static void
arb_infimum(arf_t res, const arb_t x)
{
    if (arf_is_nan(arb_midref(x)))
    {
        arf_nan(res);
    }
    else if (mag_is_inf(arb_radref(x)))
    {
        arf_neg_inf(res);
    }
    else
    {
        arf_set_mag(res, arb_radref(x));
        arf_sub(res, arb_midref(x), res, ARF_PREC_EXACT, ARF_RND_FLOOR);
    }
}
예제 #28
0
void
arb_get_lbound_arf(arf_t u, const arb_t x, long prec)
{
    arf_t t;
    arf_init_set_mag_shallow(t, arb_radref(x));

    arf_sub(u, arb_midref(x), t, prec, ARF_RND_FLOOR);
}
예제 #29
0
void
arb_zeta_ui_borwein_bsplit(arb_t x, ulong s, slong prec)
{
    zeta_bsplit_t sum;
    mag_t err;
    slong wp, n;

    /* zeta(0) = -1/2 */
    if (s == 0)
    {
        arb_set_si(x, -1);
        arb_mul_2exp_si(x, x, -1);
        return;
    }

    if (s == 1)
    {
        flint_printf("zeta_ui_borwein_bsplit: zeta(1)");
        abort();
    }

    n = prec / ERROR_B + 2;
    wp = prec + 30;

    zeta_bsplit_init(sum);
    zeta_bsplit(sum, 0, n + 1, n, s, 0, wp);

    /*  A/Q3 - B/Q3 / (C/Q1) = (A*C - B*Q1) / (Q3*C)    */
    arb_mul(sum->A, sum->A, sum->C, wp);
    arb_mul(sum->B, sum->B, sum->Q1, wp);
    arb_sub(sum->A, sum->A, sum->B, wp);
    arb_mul(sum->Q3, sum->Q3, sum->C, wp);
    arb_div(sum->C, sum->A, sum->Q3, wp);

    mag_init(err);
    mag_borwein_error(err, n);
    mag_add(arb_radref(sum->C), arb_radref(sum->C), err);
    mag_clear(err);

    /* convert from eta(s) to zeta(s) */
    arb_div_2expm1_ui(x, sum->C, s - 1, wp);
    arb_mul_2exp_si(x, x, s - 1);

    zeta_bsplit_clear(sum);
}
예제 #30
0
void
arb_bernoulli_fmpz(arb_t res, const fmpz_t n, slong prec)
{
    if (fmpz_cmp_ui(n, UWORD_MAX) <= 0)
    {
        if (fmpz_sgn(n) >= 0)
            arb_bernoulli_ui(res, fmpz_get_ui(n), prec);
        else
            arb_zero(res);
    }
    else if (fmpz_is_odd(n))
    {
        arb_zero(res);
    }
    else
    {
        arb_t t;
        slong wp;

        arb_init(t);
        wp = prec + 2 * fmpz_bits(n);

        /* zeta(n) ~= 1 */
        arf_one(arb_midref(res));
        mag_one(arb_radref(res));
        mag_mul_2exp_si(arb_radref(res), arb_radref(res), WORD_MIN);

        /* |B_n| = 2 * n! / (2*pi)^n * zeta(n) */
        arb_gamma_fmpz(t, n, wp);
        arb_mul_fmpz(t, t, n, wp);
        arb_mul(res, res, t, wp);

        arb_const_pi(t, wp);
        arb_mul_2exp_si(t, t, 1);
        arb_pow_fmpz(t, t, n, wp);

        arb_div(res, res, t, prec);
        arb_mul_2exp_si(res, res, 1);

        if (fmpz_fdiv_ui(n, 4) == 0)
            arb_neg(res, res);

        arb_clear(t);
    }
}