Пример #1
0
void
_fmprb_poly_product_roots(fmprb_ptr poly, fmprb_srcptr xs, long n, long prec)
{
    if (n == 0)
    {
        fmprb_one(poly);
    }
    else if (n == 1)
    {
        fmprb_neg(poly, xs);
        fmprb_one(poly + 1);
    }
    else if (n == 2)
    {
        fmprb_mul(poly, xs + 0, xs + 1, prec);
        fmprb_add(poly + 1, xs + 0, xs + 1, prec);
        fmprb_neg(poly + 1, poly + 1);
        fmprb_one(poly + 2);
    }
    else
    {
        const long m = (n + 1) / 2;
        fmprb_ptr tmp;

        tmp = _fmprb_vec_init(n + 2);

        _fmprb_poly_product_roots(tmp, xs, m, prec);
        _fmprb_poly_product_roots(tmp + m + 1, xs + m, n - m, prec);
        _fmprb_poly_mul_monic(poly, tmp, m + 1, tmp + m + 1, n - m + 1, prec);

        _fmprb_vec_clear(tmp, n + 2);
    }
}
Пример #2
0
Файл: det.c Проект: certik/arb
void
fmprb_mat_det(fmprb_t det, const fmprb_mat_t A, long prec)
{
    long n = fmprb_mat_nrows(A);

    if (n == 0)
    {
        fmprb_one(det);
    }
    else if (n == 1)
    {
        fmprb_set(det, fmprb_mat_entry(A, 0, 0));
    }
    else if (n == 2)
    {
        fmprb_mul(det, fmprb_mat_entry(A, 0, 0), fmprb_mat_entry(A, 1, 1), prec);
        fmprb_submul(det, fmprb_mat_entry(A, 0, 1), fmprb_mat_entry(A, 1, 0), prec);
    }
    else
    {
        fmprb_mat_t T;
        fmprb_mat_init(T, fmprb_mat_nrows(A), fmprb_mat_ncols(A));
        fmprb_mat_set(T, A);
        fmprb_mat_det_inplace(det, T, prec);
        fmprb_mat_clear(T);
    }
}
Пример #3
0
void
bound_K(fmprb_t C, const fmprb_t AN, const fmprb_t B, const fmprb_t T, long wp)
{
    if (fmprb_is_zero(B) || fmprb_is_zero(T))
    {
        fmprb_one(C);
    }
    else
    {
        fmprb_div(C, B, AN, wp);
        /* TODO: atan is dumb, should also bound by pi/2 */
        fmprb_atan(C, C, wp);
        fmprb_mul(C, C, T, wp);
        if (fmprb_is_nonpositive(C))
            fmprb_one(C);
        else
            fmprb_exp(C, C, wp);
    }
}
Пример #4
0
int
sin_x(fmprb_ptr out, const fmprb_t inp, void * params, long order, long prec)
{
    int xlen = FLINT_MIN(2, order);

    fmprb_set(out, inp);
    if (xlen > 1)
        fmprb_one(out + 1);

    _fmprb_poly_sin_series(out, out, xlen, order, prec);

    eval_count++;
    return 0;
}
Пример #5
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);
}
Пример #6
0
void
gamma_rising_fmprb_ui_bsplit_eight(fmprb_t y, const fmprb_t x, ulong n, long prec)
{
    if (n == 0)
    {
        fmprb_one(y);
    }
    else if (n == 1)
    {
        fmprb_set_round(y, x, prec);
    }
    else
    {
        ulong k, a;
        long wp;
        fmprb_t t, u;

        wp = FMPR_PREC_ADD(prec, FLINT_BIT_COUNT(n));

        fmprb_init(t);
        fmprb_init(u);

        if (n >= 8)
        {
            bsplit(t, x, 0, (n / 8) * 8, wp);
            a = (n / 8) * 8;
        }
        else
        {
            fmprb_set(t, x);
            a = 1;
        }

        for (k = a; k < n; k++)
        {
            fmprb_add_ui(u, x, k, wp);
            fmprb_mul(t, t, u, wp);
        }

        fmprb_set_round(y, t, prec);

        fmprb_clear(t);
        fmprb_clear(u);
    }
}
Пример #7
0
int
z_function(fmprb_ptr out, const fmprb_t inp, void * params, long order, long prec)
{
    fmprb_struct x[2];

    fmprb_init(x);
    fmprb_init(x + 1);

    fmprb_set(x, inp);
    fmprb_one(x + 1);

    _fmprb_poly_riemann_siegel_z_series(out, x, FLINT_MIN(2, order), order, prec);

    fmprb_clear(x);
    fmprb_clear(x + 1);

    eval_count++;
    return 0;
}
Пример #8
0
int
sin_1x(fmprb_ptr out, const fmprb_t inp, void * params, long order, long prec)
{
    fmprb_ptr x;
    int xlen = FLINT_MIN(2, order);

    x = _fmprb_vec_init(xlen);

    fmprb_set(x, inp);
    if (xlen > 1)
        fmprb_one(x + 1);

    _fmprb_poly_inv_series(out, x, xlen, order, prec);
    _fmprb_poly_sin_series(out, out, order, order, prec);

    _fmprb_vec_clear(x, xlen);

    eval_count++;
    return 0;
}
Пример #9
0
void
bound_rfac(fmprb_ptr F, const fmpcb_t s, ulong n, long len, long wp)
{
    if (len == 1)
    {
        fmpcb_rfac_abs_ubound2(fmprb_midref(F + 0), s, n, wp);
        fmpr_zero(fmprb_radref(F + 0));
    }
    else
    {
        fmprb_struct sx[2];
        fmprb_init(sx + 0);
        fmprb_init(sx + 1);
        fmpcb_abs(sx + 0, s, wp);
        fmprb_one(sx + 1);
        _fmprb_vec_zero(F, len);
        _fmprb_poly_rising_ui_series(F, sx, 2, n, len, wp);
        fmprb_clear(sx + 0);
        fmprb_clear(sx + 1);
    }
}
Пример #10
0
void
fmprb_hypgeom_sum(fmprb_t P, fmprb_t Q, const hypgeom_t hyp, long n, long prec)
{
    if (n < 1)
    {
        fmprb_zero(P);
        fmprb_one(Q);
    }
    else
    {
        fmprb_t B, T;
        fmprb_init(B);
        fmprb_init(T);
        bsplit_recursive_fmprb(P, Q, B, T, hyp, 0, n, 0, prec);
        if (!fmprb_is_one(B))
            fmprb_mul(Q, Q, B, prec);
        fmprb_swap(P, T);
        fmprb_clear(B);
        fmprb_clear(T);
    }
}
Пример #11
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);
}
Пример #12
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);
}
Пример #13
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);
}
Пример #14
0
void
fmpcb_calc_cauchy_bound(fmprb_t bound, fmpcb_calc_func_t func, void * param,
    const fmpcb_t x, const fmprb_t radius, long maxdepth, long prec)
{
    long i, n, depth, wp;

    fmprb_t pi, theta, v, s1, c1, s2, c2, st, ct;
    fmpcb_t t, u;
    fmprb_t b;

    fmprb_init(pi);
    fmprb_init(theta);
    fmprb_init(v);

    fmprb_init(s1);
    fmprb_init(c1);
    fmprb_init(s2);
    fmprb_init(c2);
    fmprb_init(st);
    fmprb_init(ct);

    fmpcb_init(t);
    fmpcb_init(u);
    fmprb_init(b);

    wp = prec + 20;

    fmprb_const_pi(pi, wp);
    fmprb_zero_pm_inf(b);

    for (depth = 0, n = 16; depth < maxdepth; n *= 2, depth++)
    {
        fmprb_zero(b);

        /* theta = 2 pi / n */
        fmprb_div_ui(theta, pi, n, wp);
        fmprb_mul_2exp_si(theta, theta, 1);

        /* sine and cosine of i*theta and (i+1)*theta */
        fmprb_zero(s1);
        fmprb_one(c1);
        fmprb_sin_cos(st, ct, theta, wp);
        fmprb_set(s2, st);
        fmprb_set(c2, ct);

        for (i = 0; i < n; i++)
        {
            /* sine and cosine of 2 pi ([i,i+1]/n) */

            /* since we use power of two subdivision points, the
               sine and cosine are monotone on each subinterval */
            fmprb_union(fmpcb_realref(t), c1, c2, wp);
            fmprb_union(fmpcb_imagref(t), s1, s2, wp);
            fmpcb_mul_fmprb(t, t, radius, wp);
            fmpcb_add(t, t, x, prec);

            /* next angle */
            fmprb_mul(v, c2, ct, wp);
            fmprb_mul(c1, s2, st, wp);
            fmprb_sub(c1, v, c1, wp);
            fmprb_mul(v, c2, st, wp);
            fmprb_mul(s1, s2, ct, wp);
            fmprb_add(s1, v, s1, wp);
            fmprb_swap(c1, c2);
            fmprb_swap(s1, s2);

            func(u, t, param, 1, prec);
            fmpcb_abs(v, u, prec);
            fmprb_add(b, b, v, prec);
        }

        fmprb_div_ui(b, b, n, prec);

        if (fmprb_is_exact(b) || fmpr_cmp(fmprb_radref(b), fmprb_midref(b)) < 0)
            break;
    }

    fmprb_set(bound, b);

    fmprb_clear(pi);
    fmprb_clear(theta);
    fmprb_clear(v);

    fmpcb_clear(t);
    fmpcb_clear(u);
    fmprb_clear(b);

    fmprb_clear(s1);
    fmprb_clear(c1);
    fmprb_clear(s2);
    fmprb_clear(c2);
    fmprb_clear(st);
    fmprb_clear(ct);
}
Пример #15
0
void
gamma_rising_fmprb_ui_delta(fmprb_t y, const fmprb_t x, ulong n, ulong m, long prec)
{
    fmprb_ptr xs;
    fmprb_t t, u, v;
    ulong i, k, rem;
    fmpz_t c, h;
    fmpz *s, *d;
    long wp;

    if (n == 0)
    {
        fmprb_one(y);
        return;
    }

    if (n == 1)
    {
        fmprb_set_round(y, x, prec);
        return;
    }

    wp = FMPR_PREC_ADD(prec, FLINT_BIT_COUNT(n));

    fmprb_init(t);
    fmprb_init(u);
    fmprb_init(v);
    fmpz_init(c);
    fmpz_init(h);

    if (m == 0)
    {
        ulong m1, m2;
        m1 = 0.2 * pow(wp, 0.4);
        m2 = n_sqrt(n);
        m = FLINT_MIN(m1, m2);
    }

    m = FLINT_MIN(m, n);
    m = FLINT_MAX(m, 1);

    xs = _fmprb_vec_init(m + 1);
    d = _fmpz_vec_init(m * m);
    s = _fmpz_vec_init(m + 1);

    _fmprb_vec_set_powers(xs, x, m + 1, wp);

    rising_difference_polynomial(s, d, m);

    /* tail */
    rem = m;
    while (rem + m <= n)
        rem += m;
    fmprb_one(y);
    for (k = rem; k < n; k++)
    {
        fmprb_add_ui(t, xs + 1, k, wp);
        fmprb_mul(y, y, t, wp);
    }

    /* initial rising factorial */
    fmprb_zero(t);
    for (i = 1; i <= m; i++)
        fmprb_addmul_fmpz(t, xs + i, s + i, wp);

    fmprb_mul(y, y, t, wp);

    /* the leading coefficient is always the same */
    fmprb_mul_fmpz(xs + m - 1, xs + m - 1, d + m - 1 + 0, wp);

    for (k = 0; k + 2 * m <= n; k += m)
    {
        for (i = 0; i < m - 1; i++)
        {
            fmpz_set_ui(h, k);
            _fmpz_poly_evaluate_horner_fmpz(c, d + i * m, m - i, h);

            if (i == 0)
                fmprb_add_fmpz(t, t, c, wp);
            else
                fmprb_addmul_fmpz(t, xs + i, c, wp);
        }

        fmprb_add(t, t, xs + m - 1, wp);
        fmprb_mul(y, y, t, wp);
    }

    fmprb_set_round(y, y, prec);

    fmprb_clear(t);
    fmprb_clear(u);
    fmprb_clear(v);
    _fmprb_vec_clear(xs, m + 1);
    _fmpz_vec_clear(d, m * m);
    _fmpz_vec_clear(s, m + 1);
    fmpz_clear(c);
    fmpz_clear(h);
}
Пример #16
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);
}