Пример #1
0
Файл: ui.c Проект: certik/arb
void
zeta_ui(fmprb_t x, ulong n, long prec)
{
    if (n == 0)
    {
        fmprb_set_si(x, -1);
        fmprb_mul_2exp_si(x, x, -1);
    }
    else if (n == 1)
    {
        printf("exception: zeta_ui(1)\n");
        abort();
    }
    /* fast detection of asymptotic case */
    else if (n > 0.7 * prec)
    {
        zeta_ui_asymp(x, n, prec);
    }
    else
    {
        /* even */
        if (n % 2 == 0)
        {
            if (((prec < 10000) && (n < 40 + 0.11*prec)) ||
                ((prec >= 10000) && (arith_bernoulli_number_size(n) * 0.9 < prec)))
            {
                zeta_ui_bernoulli(x, n, prec);
            }
            else
            {
                zeta_ui_euler_product(x, n, prec);
            }
        }
        else
        {
            if (n == 3)
            {
                zeta_apery_bsplit(x, prec);
            }
            else if (n < prec * 0.0006)
            {
                /* small odd n, extremely high precision */
                zeta_ui_borwein_bsplit(x, n, prec);
            }
            else if (prec > 20 && n > 6 && n > 0.4 * pow(prec, 0.8))
            {
                /* large n */
                zeta_ui_euler_product(x, n, prec);
            }
            else
            {
                /* fallback */
                zeta_ui_vec_borwein(x, n, 1, 0, prec);
            }
        }
    }
}
Пример #2
0
void
fmprb_si_pow_ui(fmprb_t y, long b, ulong e, long prec)
{
    fmprb_t t;
    fmprb_init(t);
    fmprb_set_si(t, b);
    fmprb_pow_ui(y, t, e, prec);
    fmprb_clear(t);
}
Пример #3
0
Файл: add.c Проект: isuruf/arb
void
fmprb_add_si(fmprb_t z, const fmprb_t x, slong y, slong prec)
{
    fmprb_t t;
    fmprb_init(t);
    fmprb_set_si(t, y);
    fmprb_add(z, x, t, prec);
    fmprb_clear(t);
}
Пример #4
0
void
fmprb_sub_si(fmprb_t z, const fmprb_t x, long y, long prec)
{
    fmprb_t t;
    fmprb_init(t);
    fmprb_set_si(t, y);
    fmprb_sub(z, x, t, prec);
    fmprb_clear(t);
}
Пример #5
0
static __inline__ void
zeta_coeff_k(zeta_bsplit_t S, long k, long n, long s)
{
    fmprb_set_si(S->D, 2 * (n + k));
    fmprb_mul_si(S->D, S->D, n - k, FMPR_PREC_EXACT);
    fmprb_set_si(S->Q1, k + 1);
    fmprb_mul_si(S->Q1, S->Q1, 2*k + 1, FMPR_PREC_EXACT);

    if (k == 0)
    {
        fmprb_zero(S->A);
        fmprb_one(S->Q2);
    }
    else
    {
        fmprb_set_si(S->A, k % 2 ? 1 : -1);
        fmprb_mul(S->A, S->A, S->Q1, FMPR_PREC_EXACT);
        fmprb_ui_pow_ui(S->Q2, k, s, FMPR_PREC_EXACT);
    }

    fmprb_mul(S->Q3, S->Q1, S->Q2, FMPR_PREC_EXACT);
    fmprb_zero(S->B);
    fmprb_set(S->C, S->Q1);
}
Пример #6
0
Файл: det.c Проект: certik/arb
void
fmprb_mat_det_inplace(fmprb_t det, fmprb_mat_t A, long prec)
{
    long i, n, sign, rank;

    n = fmprb_mat_nrows(A);
    rank = fmprb_mat_gauss_partial(A, prec);
    sign = (rank < 0) ? -1 : 1;
    rank = FLINT_ABS(rank);

    fmprb_set_si(det, sign);
    for (i = 0; i < rank; i++)
        fmprb_mul(det, det, fmprb_mat_entry(A, i, i), prec);

    /* bound unreduced part using Hadamard's inequality */
    if (rank < n)
    {
        fmpr_t t;
        fmprb_t d;

        fmpr_init(t);
        fmprb_init(d);

        fmpr_one(fmprb_radref(d));

        for (i = rank; i < n; i++)
        {
            fmprb_vec_get_fmpr_2norm_squared_bound(t, A->rows[i] + rank, 
                n - rank, FMPRB_RAD_PREC);
            fmpr_mul(fmprb_radref(d), fmprb_radref(d), t, FMPRB_RAD_PREC, FMPR_RND_UP);
        }

        fmpr_sqrt(fmprb_radref(d), fmprb_radref(d), FMPRB_RAD_PREC, FMPR_RND_UP);
        fmprb_mul(det, det, d, prec);

        fmprb_clear(d);
        fmpr_clear(t);
    }
}
Пример #7
0
void
_fmprb_poly_zeta_series(fmprb_ptr res, fmprb_srcptr h, long hlen, const fmprb_t a, int deflate, long len, long prec)
{
    long i;
    fmpcb_t cs, ca;
    fmpcb_ptr z;
    fmprb_ptr t, u;

    if (fmprb_contains_nonpositive(a))
    {
        _fmprb_vec_indeterminate(res, len);
        return;
    }

    hlen = FLINT_MIN(hlen, len);

    z = _fmpcb_vec_init(len);
    t = _fmprb_vec_init(len);
    u = _fmprb_vec_init(len);
    fmpcb_init(cs);
    fmpcb_init(ca);

    /* use reflection formula */
    if (fmpr_sgn(fmprb_midref(h)) < 0 && fmprb_is_one(a))
    {
        /* zeta(s) = (2*pi)**s * sin(pi*s/2) / pi * gamma(1-s) * zeta(1-s) */
        fmprb_t pi;
        fmprb_ptr f, s1, s2, s3, s4;

        fmprb_init(pi);
        f = _fmprb_vec_init(2);
        s1 = _fmprb_vec_init(len);
        s2 = _fmprb_vec_init(len);
        s3 = _fmprb_vec_init(len);
        s4 = _fmprb_vec_init(len);

        fmprb_const_pi(pi, prec);

        /* s1 = (2*pi)**s */
        fmprb_mul_2exp_si(pi, pi, 1);
        _fmprb_poly_pow_cpx(s1, pi, h, len, prec);
        fmprb_mul_2exp_si(pi, pi, -1);

        /* s2 = sin(pi*s/2) / pi */
        fmprb_mul_2exp_si(pi, pi, -1);
        fmprb_mul(f, pi, h, prec);
        fmprb_set(f + 1, pi);
        fmprb_mul_2exp_si(pi, pi, 1);
        _fmprb_poly_sin_series(s2, f, 2, len, prec);
        _fmprb_vec_scalar_div(s2, s2, len, pi, prec);

        /* s3 = gamma(1-s) */
        fmprb_sub_ui(f, h, 1, prec);
        fmprb_neg(f, f);
        fmprb_set_si(f + 1, -1);
        _fmprb_poly_gamma_series(s3, f, 2, len, prec);

        /* s4 = zeta(1-s) */
        fmprb_sub_ui(f, h, 1, prec);
        fmprb_neg(f, f);
        fmpcb_set_fmprb(cs, f);
        fmpcb_one(ca);
        zeta_series(z, cs, ca, 0, len, prec);
        for (i = 0; i < len; i++)
            fmprb_set(s4 + i, fmpcb_realref(z + i));
        for (i = 1; i < len; i += 2)
            fmprb_neg(s4 + i, s4 + i);

        _fmprb_poly_mullow(u, s1, len, s2, len, len, prec);
        _fmprb_poly_mullow(s1, s3, len, s4, len, len, prec);
        _fmprb_poly_mullow(t, u, len, s1, len, len, prec);

        /* add 1/(1-(s+t)) = 1/(1-s) + t/(1-s)^2 + ... */
        if (deflate)
        {
            fmprb_sub_ui(u, h, 1, prec);
            fmprb_neg(u, u);
            fmprb_ui_div(u, 1, u, prec);
            for (i = 1; i < len; i++)
                fmprb_mul(u + i, u + i - 1, u, prec);
            _fmprb_vec_add(t, t, u, len, prec);
        }

        fmprb_clear(pi);
        _fmprb_vec_clear(f, 2);
        _fmprb_vec_clear(s1, len);
        _fmprb_vec_clear(s2, len);
        _fmprb_vec_clear(s3, len);
        _fmprb_vec_clear(s4, len);
    }
    else
    {
        fmpcb_set_fmprb(cs, h);
        fmpcb_set_fmprb(ca, a);
        zeta_series(z, cs, ca, deflate, len, prec);
        for (i = 0; i < len; i++)
            fmprb_set(t + i, fmpcb_realref(z + i));
    }

    /* compose with nonconstant part */
    fmprb_zero(u);
    _fmprb_vec_set(u + 1, h + 1, hlen - 1);
    _fmprb_poly_compose_series(res, t, len, u, hlen, len, prec);

    _fmpcb_vec_clear(z, len);
    _fmprb_vec_clear(t, len);
    _fmprb_vec_clear(u, len);
    fmpcb_init(cs);
    fmpcb_init(ca);
}
Пример #8
0
void
_fmprb_poly_rgamma_series(fmprb_ptr res, fmprb_srcptr h, long hlen, long len, long prec)
{
    int reflect;
    long i, rflen, r, n, wp;
    fmprb_ptr t, u, v;
    fmprb_struct f[2];

    hlen = FLINT_MIN(hlen, len);
    wp = prec + FLINT_BIT_COUNT(prec);

    t = _fmprb_vec_init(len);
    u = _fmprb_vec_init(len);
    v = _fmprb_vec_init(len);
    fmprb_init(f);
    fmprb_init(f + 1);

    /* use zeta values at small integers */
    if (fmprb_is_int(h) && (fmpr_cmpabs_ui(fmprb_midref(h), prec / 2) < 0))
    {
        r = fmpr_get_si(fmprb_midref(h), FMPR_RND_DOWN);

        gamma_lgamma_series_at_one(u, len, wp);

        _fmprb_vec_neg(u, u, len);
        _fmprb_poly_exp_series(t, u, len, len, wp);

        if (r == 1)
        {
            _fmprb_vec_swap(v, t, len);
        }
        else if (r <= 0)
        {
            fmprb_set(f, h);
            fmprb_one(f + 1);
            rflen = FLINT_MIN(len, 2 - r);
            _fmprb_poly_rising_ui_series(u, f, FLINT_MIN(2, len), 1 - r, rflen, wp);
            _fmprb_poly_mullow(v, t, len, u, rflen, len, wp);
        }
        else
        {
            fmprb_one(f);
            fmprb_one(f + 1);
            rflen = FLINT_MIN(len, r);
            _fmprb_poly_rising_ui_series(v, f, FLINT_MIN(2, len), r - 1, rflen, wp);

            /* TODO: use div_series? */
            _fmprb_poly_inv_series(u, v, rflen, len, wp);
            _fmprb_poly_mullow(v, t, len, u, len, len, wp);
        }
    }
    else
    {
        /* otherwise use Stirling series */
        gamma_stirling_choose_param_fmprb(&reflect, &r, &n, h, 1, 0, wp);

        /* rgamma(h) = (gamma(1-h+r) sin(pi h)) / (rf(1-h, r) * pi), h = h0 + t*/
        if (reflect)
        {
            /* u = gamma(r+1-h) */
            fmprb_sub_ui(f, h, r + 1, wp);
            fmprb_neg(f, f);
            gamma_stirling_eval_fmprb_series(t, f, n, len, wp);
            _fmprb_poly_exp_series(u, t, len, len, wp);
            for (i = 1; i < len; i += 2)
                fmprb_neg(u + i, u + i);

            /* v = sin(pi x) */
            fmprb_const_pi(f + 1, wp);
            fmprb_mul(f, h, f + 1, wp);
            _fmprb_poly_sin_series(v, f, 2, len, wp);

            _fmprb_poly_mullow(t, u, len, v, len, len, wp);

            /* rf(1-h,r) * pi */
            if (r == 0)
            {
                fmprb_const_pi(u, wp);
                _fmprb_vec_scalar_div(v, t, len, u, wp);
            }
            else
            {
                fmprb_sub_ui(f, h, 1, wp);
                fmprb_neg(f, f);
                fmprb_set_si(f + 1, -1);
                rflen = FLINT_MIN(len, r + 1);
                _fmprb_poly_rising_ui_series(v, f, FLINT_MIN(2, len), r, rflen, wp);
                fmprb_const_pi(u, wp);
                _fmprb_vec_scalar_mul(v, v, rflen, u, wp);

                /* divide by rising factorial */
                /* TODO: might better to use div_series, when it has a good basecase */
                _fmprb_poly_inv_series(u, v, rflen, len, wp);
                _fmprb_poly_mullow(v, t, len, u, len, len, wp);
            }
        }
        else
        {
            /* rgamma(h) = rgamma(h+r) rf(h,r) */
            if (r == 0)
            {
                fmprb_add_ui(f, h, r, wp);
                gamma_stirling_eval_fmprb_series(t, f, n, len, wp);
                _fmprb_vec_neg(t, t, len);
                _fmprb_poly_exp_series(v, t, len, len, wp);
            }
            else
            {
                fmprb_set(f, h);
                fmprb_one(f + 1);
                rflen = FLINT_MIN(len, r + 1);
                _fmprb_poly_rising_ui_series(t, f, FLINT_MIN(2, len), r, rflen, wp);

                fmprb_add_ui(f, h, r, wp);
                gamma_stirling_eval_fmprb_series(v, f, n, len, wp);
                _fmprb_vec_neg(v, v, len);
                _fmprb_poly_exp_series(u, v, len, len, wp);

                _fmprb_poly_mullow(v, u, len, t, rflen, len, wp);
            }
        }
    }

    /* compose with nonconstant part */
    fmprb_zero(t);
    _fmprb_vec_set(t + 1, h + 1, hlen - 1);
    _fmprb_poly_compose_series(res, v, len, t, hlen, len, prec);

    fmprb_clear(f);
    fmprb_clear(f + 1);
    _fmprb_vec_clear(t, len);
    _fmprb_vec_clear(u, len);
    _fmprb_vec_clear(v, len);
}