Esempio n. 1
0
void
bound_I(fmprb_ptr I, const fmprb_t A, const fmprb_t B, const fmprb_t C, long len, long wp)
{
    long k;

    fmprb_t D, Dk, L, T, Bm1;

    fmprb_init(D);
    fmprb_init(Dk);
    fmprb_init(Bm1);
    fmprb_init(T);
    fmprb_init(L);

    fmprb_sub_ui(Bm1, B, 1, wp);
    fmprb_one(L);

    /* T = 1 / (A^Bm1 * Bm1) */
    fmprb_inv(T, A, wp);
    fmprb_pow(T, T, Bm1, wp);
    fmprb_div(T, T, Bm1, wp);

    if (len > 1)
    {
        fmprb_log(D, A, wp);
        fmprb_add(D, D, C, wp);
        fmprb_mul(D, D, Bm1, wp);
        fmprb_set(Dk, D);
    }

    for (k = 0; k < len; k++)
    {
        if (k > 0)
        {
            fmprb_mul_ui(L, L, k, wp);
            fmprb_add(L, L, Dk, wp);
            fmprb_mul(Dk, Dk, D, wp);
        }

        fmprb_mul(I + k, L, T, wp);
        fmprb_div(T, T, Bm1, wp);
    }

    fmprb_clear(D);
    fmprb_clear(Dk);
    fmprb_clear(Bm1);
    fmprb_clear(T);
    fmprb_clear(L);
}
Esempio n. 2
0
/* series of c^(d+x) */
static __inline__ void
_fmprb_poly_pow_cpx(fmprb_ptr res, const fmprb_t c, const fmprb_t d, long trunc, long prec)
{
    long i;
    fmprb_t logc;

    fmprb_init(logc);
    fmprb_log(logc, c, prec);
    fmprb_mul(res + 0, logc, d, prec);
    fmprb_exp(res + 0, res + 0, prec);

    for (i = 1; i < trunc; i++)
    {
        fmprb_mul(res + i, res + i - 1, logc, prec);
        fmprb_div_ui(res + i, res + i, i, prec);
    }

    fmprb_clear(logc);
}
Esempio n. 3
0
void
_fmprb_poly_riemann_siegel_theta_series(fmprb_ptr res,
    fmprb_srcptr h, long hlen, long len, long prec)
{
    fmpcb_ptr s;
    fmprb_t u;
    long i;

    hlen = FLINT_MIN(hlen, len);

    s = _fmpcb_vec_init(len);

    fmprb_init(u);

    /* s = 1/4 + (1/2) i h */
    for (i = 0; i < hlen; i++)
        fmprb_mul_2exp_si(fmpcb_imagref(s + i), h + i, -1);

    fmprb_one(u);
    fmprb_mul_2exp_si(u, u, -2);
    fmprb_add(fmpcb_realref(s), fmpcb_realref(s), u, prec);

    /* log gamma */
    _fmpcb_poly_lgamma_series(s, s, hlen, len, prec);

    /* imaginary part */
    for (i = 0; i < len; i++)
        fmprb_set(res + i, fmpcb_imagref(s + i));

    /* subtract log(pi)/2 * h */
    fmprb_const_pi(u, prec);
    fmprb_log(u, u, prec);
    fmprb_mul_2exp_si(u, u, -1);
    fmprb_neg(u, u);
    _fmprb_vec_scalar_addmul(res, h, hlen, u, prec);

    _fmpcb_vec_clear(s, len);
    fmprb_clear(u);
}
Esempio n. 4
0
long
gamma_taylor_bound_mag(long n)
{
    fmprb_t t, u;
    long v;

    fmprb_init(t);
    fmprb_init(u);

    /* (pi-1) n */
    fmprb_const_pi(t, FMPRB_RAD_PREC);
    fmprb_sub_ui(t, t, 1, FMPRB_RAD_PREC);
    fmprb_mul_ui(t, t, n, FMPRB_RAD_PREC);

    /* (3-5n) log(n/6) */
    fmprb_set_ui(u, n);
    fmprb_div_ui(u, u, 6, FMPRB_RAD_PREC);
    fmprb_log(u, u, FMPRB_RAD_PREC);
    fmprb_mul_si(u, u, 3 - 5*n, FMPRB_RAD_PREC);

    fmprb_add(t, t, u, FMPRB_RAD_PREC);

    /* divide by 6 log(2) */
    fmprb_log_ui(u, 2, FMPRB_RAD_PREC);
    fmprb_mul_ui(u, u, 6, FMPRB_RAD_PREC);
    fmprb_div(t, t, u, FMPRB_RAD_PREC);

    /* upper bound */
    fmpr_add(fmprb_midref(t), fmprb_midref(t), fmprb_radref(t),
        FMPRB_RAD_PREC, FMPR_RND_CEIL);

    v = fmpr_get_si(fmprb_midref(t), FMPR_RND_CEIL);

    fmprb_clear(t);
    fmprb_clear(u);

    return v;
}
Esempio n. 5
0
File: gamma.c Progetto: jwbober/arb
void
fmprb_lgamma(fmprb_t y, const fmprb_t x, long prec)
{
    int reflect;
    long r, n, wp;
    fmprb_t t, u;

    wp = prec + FLINT_BIT_COUNT(prec);

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

    /* log(gamma(x)) = log(gamma(x+r)) - log(rf(x,r)) */
    fmprb_init(t);
    fmprb_init(u);

    fmprb_add_ui(t, x, r, wp);
    gamma_stirling_eval_fmprb(u, t, n, 0, wp);
    gamma_rising_fmprb_ui_bsplit(t, x, r, wp);
    fmprb_log(t, t, wp);
    fmprb_sub(y, u, t, prec);

    fmprb_clear(t);
    fmprb_clear(u);
}
Esempio n. 6
0
void
gamma_stirling_eval_fmprb(fmprb_t s, const fmprb_t z, long nterms, int digamma, long prec)
{
    fmprb_t b, t, logz, zinv, zinv2;
    fmpr_t err;

    long k, term_prec;
    double z_mag, term_mag;

    fmprb_init(b);
    fmprb_init(t);
    fmprb_init(logz);
    fmprb_init(zinv);
    fmprb_init(zinv2);

    fmprb_log(logz, z, prec);
    fmprb_ui_div(zinv, 1UL, z, prec);

    nterms = FLINT_MAX(nterms, 1);

    fmprb_zero(s);

    if (nterms > 1)
    {
        fmprb_mul(zinv2, zinv, zinv, prec);

        z_mag = fmpr_get_d(fmprb_midref(logz), FMPR_RND_UP) * 1.44269504088896;

        for (k = nterms - 1; k >= 1; k--)
        {
            term_mag = bernoulli_bound_2exp_si(2 * k);
            term_mag -= (2 * k - 1) * z_mag;
            term_prec = prec + term_mag;
            term_prec = FLINT_MIN(term_prec, prec);
            term_prec = FLINT_MAX(term_prec, 10);

            if (prec > 2000)
            {
                fmprb_set_round(t, zinv2, term_prec);
                fmprb_mul(s, s, t, term_prec);
            }
            else
                fmprb_mul(s, s, zinv2, term_prec);

            gamma_stirling_coeff(b, k, digamma, term_prec);
            fmprb_add(s, s, b, term_prec);
        }

        if (digamma)
            fmprb_mul(s, s, zinv2, prec);
        else
            fmprb_mul(s, s, zinv, prec);
    }

    /* remainder bound */
    fmpr_init(err);
    gamma_stirling_bound_fmprb(err, z, digamma ? 1 : 0, 1, nterms);
    fmprb_add_error_fmpr(s, err);
    fmpr_clear(err);

    if (digamma)
    {
        fmprb_neg(s, s);
        fmprb_mul_2exp_si(zinv, zinv, -1);
        fmprb_sub(s, s, zinv, prec);
        fmprb_add(s, s, logz, prec);
    }
    else
    {
        /* (z-0.5)*log(z) - z + log(2*pi)/2 */
        fmprb_one(t);
        fmprb_mul_2exp_si(t, t, -1);
        fmprb_sub(t, z, t, prec);
        fmprb_mul(t, logz, t, prec);
        fmprb_add(s, s, t, prec);
        fmprb_sub(s, s, z, prec);
        fmprb_const_log_sqrt2pi(t, prec);
        fmprb_add(s, s, t, prec);
    }

    fmprb_clear(t);
    fmprb_clear(b);
    fmprb_clear(zinv);
    fmprb_clear(zinv2);
    fmprb_clear(logz);
}