Example #1
0
void
arb_hypgeom_coulomb_jet(arb_ptr F, arb_ptr G, const arb_t l, const arb_t eta, const arb_t z, slong len, slong prec)
{
    acb_ptr tmp, tmpF, tmpG;
    slong k;

    if (len <= 0)
        return;

    if (len == 1)
    {
        arb_hypgeom_coulomb(F, G, l, eta, z, prec);
        return;
    }

    tmp = _acb_vec_init(3);
    tmpF = _acb_vec_init(len);
    tmpG = _acb_vec_init(len);

    acb_set_arb(tmp, l);
    acb_set_arb(tmp + 1, eta);
    acb_set_arb(tmp + 2, z);

    acb_hypgeom_coulomb_jet(F ? tmpF : NULL, G ? tmpG : NULL,
        NULL, NULL, tmp, tmp + 1, tmp + 2, len, prec);

    if (F != NULL)
    {
        if (acb_is_real(tmpF))
            for (k = 0; k < len; k++)
                arb_set(F + k, acb_realref(tmpF + k));
        else
            _arb_vec_indeterminate(F, len);
    }

    if (G != NULL)
    {
        if (acb_is_real(tmpG))
            for (k = 0; k < len; k++)
                arb_set(G + k, acb_realref(tmpG + k));
        else
            _arb_vec_indeterminate(G, len);
    }

    _acb_vec_clear(tmpF, len);
    _acb_vec_clear(tmpG, len);
    _acb_vec_clear(tmp, 3);
}
Example #2
0
void
arb_poly_inv_series(arb_poly_t Qinv, const arb_poly_t Q, slong n, slong prec)
{
    if (n == 0)
    {
        arb_poly_zero(Qinv);
        return;
    }

    if (Q->length == 0)
    {
        arb_poly_fit_length(Qinv, n);
        _arb_vec_indeterminate(Qinv->coeffs, n);
        _arb_poly_set_length(Qinv, n);
        return;
    }

    if (Qinv == Q)
    {
        arb_poly_t t;
        arb_poly_init(t);
        arb_poly_inv_series(t, Q, n, prec);
        arb_poly_swap(Qinv, t);
        arb_poly_clear(t);
        return;
    }

    arb_poly_fit_length(Qinv, n);
    _arb_poly_inv_series(Qinv->coeffs, Q->coeffs, Q->length, n, prec);
    _arb_poly_set_length(Qinv, n);
    _arb_poly_normalise(Qinv);
}
Example #3
0
void
arb_poly_sqrt_series(arb_poly_t g, const arb_poly_t h, long n, long prec)
{
    if (n == 0)
    {
        arb_poly_zero(g);
        return;
    }

    if (g == h)
    {
        arb_poly_t t;
        arb_poly_init(t);
        arb_poly_sqrt_series(t, h, n, prec);
        arb_poly_swap(g, t);
        arb_poly_clear(t);
        return;
    }

    arb_poly_fit_length(g, n);
    if (h->length == 0)
        _arb_vec_indeterminate(g->coeffs, n);
    else
        _arb_poly_sqrt_series(g->coeffs, h->coeffs, h->length, n, prec);
    _arb_poly_set_length(g, n);
    _arb_poly_normalise(g);
}
Example #4
0
void
arb_poly_cot_pi_series(arb_poly_t res, const arb_poly_t f, slong len, slong prec)
{
    arb_poly_fit_length(res, len);

    if (f->length == 0 || len == 0)
        _arb_vec_indeterminate(res->coeffs, len);
    else
        _arb_poly_cot_pi_series(res->coeffs, f->coeffs, f->length, len, prec);

    _arb_poly_set_length(res, len);
    _arb_poly_normalise(res);
}
Example #5
0
void
arb_poly_log_series(arb_poly_t res, const arb_poly_t f, slong n, slong prec)
{
    if (n == 0)
    {
        arb_poly_zero(res);
        return;
    }

    arb_poly_fit_length(res, n);
    if (f->length == 0)
        _arb_vec_indeterminate(res->coeffs, n);
    else
        _arb_poly_log_series(res->coeffs, f->coeffs, f->length, n, prec);
    _arb_poly_set_length(res, n);
    _arb_poly_normalise(res);
}
void
arb_poly_div_series(arb_poly_t Q, const arb_poly_t A, const arb_poly_t B, long n, long prec)
{
    if (n == 0)
    {
        arb_poly_zero(Q);
        return;
    }

    if (B->length == 0)
    {
        arb_poly_fit_length(Q, n);
        _arb_vec_indeterminate(Q->coeffs, n);
        _arb_poly_set_length(Q, n);
        return;
    }

    if (A->length == 0)
    {
        arb_poly_zero(Q);
        return;
    }

    if (Q == A || Q == B)
    {
        arb_poly_t t;
        arb_poly_init(t);
        arb_poly_div_series(t, A, B, n, prec);
        arb_poly_swap(Q, t);
        arb_poly_clear(t);
        return;
    }

    arb_poly_fit_length(Q, n);
    _arb_poly_div_series(Q->coeffs, A->coeffs, A->length, B->coeffs, B->length, n, prec);
    _arb_poly_set_length(Q, n);
    _arb_poly_normalise(Q);
}
/* F = 1 + U + U^2 + ... = 1/(1-U) assuming that U[0] is positive;
   indeterminate if not convergent */
static void
arb_poly_geometric_sum(arb_poly_t F, const arb_poly_t U, long len, long prec)
{
    if (U->length == 0)
    {
        arb_poly_one(F);
        return;
    }

    arb_poly_add_si(F, U, -1, prec);
    arb_poly_neg(F, F);

    if (F->length > 0 && arb_is_positive(F->coeffs))
    {
        arb_poly_inv_series(F, F, len, prec);
    }
    else
    {
        arb_poly_fit_length(F, len);
        _arb_vec_indeterminate(F->coeffs, len);
        _arb_poly_set_length(F,  len);
    }
}
/* F = 1 + U + U^2 + U^3 + ... = 1/(1-U)

   U = product of (1 + |A-B|/(|B[0] - |B[1:]|)
       product of (1 / (|B[0] - |B[1:]|))
       * |Z|
*/
void
acb_hypgeom_pfq_series_bound_factor(arb_poly_t F,
    const acb_poly_struct * a, long p,
    const acb_poly_struct * b, long q, 
    const acb_poly_t z,
    long n, long len, long prec)
{
    long i;

    arb_poly_t T, U, V;
    acb_poly_t BN, AB;

    /* not convergent */
    if (p > q)
    {
        arb_poly_fit_length(F, len);
        _arb_vec_indeterminate(F->coeffs, len);
        _arb_poly_set_length(F, len);
        return;
    }

    arb_poly_init(T);
    arb_poly_init(U);
    arb_poly_init(V);

    acb_poly_init(BN);
    acb_poly_init(AB);

    acb_poly_majorant(U, z, prec);

    for (i = 0; i < q; i++)
    {
        acb_poly_add_si(BN, b + i, n, prec);

        if (acb_poly_length(BN) != 0 &&
                arb_is_positive(acb_realref(BN->coeffs)))
        {
            if (i < p)
            {
                /* 1 + |a-b|/reciprocal_majorant(b + n) */
                acb_poly_sub(AB, a + i, b + i, prec);
                acb_poly_majorant(T, AB, prec);
                acb_poly_reciprocal_majorant(V, BN, prec);
                arb_poly_div_series(T, T, V, len, prec);
                arb_poly_add_si(T, T, 1, prec);
                arb_poly_mullow(U, U, T, len, prec);
            }
            else
            {
                acb_poly_reciprocal_majorant(T, BN, prec);
                arb_poly_div_series(U, U, T, len, prec);
            }
        }
        else
        {
            arb_poly_fit_length(U, len);
            _arb_vec_indeterminate(U->coeffs, len);
            _arb_poly_set_length(U,  len);
            break;
        }
    }

    /* F = 1/(1-U) */
    arb_poly_geometric_sum(F, U, len, prec);

    arb_poly_clear(T);
    arb_poly_clear(U);
    arb_poly_clear(V);

    acb_poly_clear(BN);
    acb_poly_clear(AB);
}
void
_arb_poly_zeta_series(arb_ptr res, arb_srcptr h, long hlen, const arb_t a, int deflate, long len, long prec)
{
    long i;
    acb_t cs, ca;
    acb_ptr z;
    arb_ptr t, u;

    if (arb_contains_nonpositive(a))
    {
        _arb_vec_indeterminate(res, len);
        return;
    }

    hlen = FLINT_MIN(hlen, len);

    z = _acb_vec_init(len);
    t = _arb_vec_init(len);
    u = _arb_vec_init(len);
    acb_init(cs);
    acb_init(ca);

    /* use reflection formula */
    if (arf_sgn(arb_midref(h)) < 0 && arb_is_one(a))
    {
        /* zeta(s) = (2*pi)**s * sin(pi*s/2) / pi * gamma(1-s) * zeta(1-s) */
        arb_t pi;
        arb_ptr f, s1, s2, s3, s4;

        arb_init(pi);
        f = _arb_vec_init(2);
        s1 = _arb_vec_init(len);
        s2 = _arb_vec_init(len);
        s3 = _arb_vec_init(len);
        s4 = _arb_vec_init(len);

        arb_const_pi(pi, prec);

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

        /* s2 = sin(pi*s/2) / pi */
        arb_set(f, h);
        arb_one(f + 1);
        arb_mul_2exp_si(f, f, -1);
        arb_mul_2exp_si(f + 1, f + 1, -1);
        _arb_poly_sin_pi_series(s2, f, 2, len, prec);
        _arb_vec_scalar_div(s2, s2, len, pi, prec);

        /* s3 = gamma(1-s) */
        arb_sub_ui(f, h, 1, prec);
        arb_neg(f, f);
        arb_set_si(f + 1, -1);
        _arb_poly_gamma_series(s3, f, 2, len, prec);

        /* s4 = zeta(1-s) */
        arb_sub_ui(f, h, 1, prec);
        arb_neg(f, f);
        acb_set_arb(cs, f);
        acb_one(ca);
        _acb_poly_zeta_cpx_series(z, cs, ca, 0, len, prec);
        for (i = 0; i < len; i++)
            arb_set(s4 + i, acb_realref(z + i));
        for (i = 1; i < len; i += 2)
            arb_neg(s4 + i, s4 + i);

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

        /* add 1/(1-(s+t)) = 1/(1-s) + t/(1-s)^2 + ... */
        if (deflate)
        {
            arb_sub_ui(u, h, 1, prec);
            arb_neg(u, u);
            arb_inv(u, u, prec);
            for (i = 1; i < len; i++)
                arb_mul(u + i, u + i - 1, u, prec);
            _arb_vec_add(t, t, u, len, prec);
        }

        arb_clear(pi);
        _arb_vec_clear(f, 2);
        _arb_vec_clear(s1, len);
        _arb_vec_clear(s2, len);
        _arb_vec_clear(s3, len);
        _arb_vec_clear(s4, len);
    }
    else
    {
        acb_set_arb(cs, h);
        acb_set_arb(ca, a);
        _acb_poly_zeta_cpx_series(z, cs, ca, deflate, len, prec);
        for (i = 0; i < len; i++)
            arb_set(t + i, acb_realref(z + i));
    }

    /* compose with nonconstant part */
    arb_zero(u);
    _arb_vec_set(u + 1, h + 1, hlen - 1);
    _arb_poly_compose_series(res, t, len, u, hlen, len, prec);

    _acb_vec_clear(z, len);
    _arb_vec_clear(t, len);
    _arb_vec_clear(u, len);
    acb_init(cs);
    acb_init(ca);
}
Example #10
0
void
_arb_poly_lgamma_series(arb_ptr res, arb_srcptr h, slong hlen, slong len, slong prec)
{
    int reflect;
    slong r, n, wp;
    arb_t zr;
    arb_ptr t, u;

    if (!arb_is_positive(h))
    {
        _arb_vec_indeterminate(res, len);
        return;
    }

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

    t = _arb_vec_init(len);
    u = _arb_vec_init(len);
    arb_init(zr);

    /* use zeta values at small integers */
    if (arb_is_int(h) && (arf_cmpabs_ui(arb_midref(h), prec / 2) < 0))
    {
        r = arf_get_si(arb_midref(h), ARF_RND_DOWN);

        if (r <= 0)
        {
            _arb_vec_indeterminate(res, len);
            goto cleanup;
        }
        else
        {
            _arb_poly_lgamma_series_at_one(u, len, wp);

            if (r != 1)
            {
                arb_one(zr);
                _log_rising_ui_series(t, zr, r - 1, len, wp);
                _arb_vec_add(u, u, t, len, wp);
            }
        }
    }
    else if (len <= 2)
    {
        arb_lgamma(u, h, wp);
        if (len == 2)
            arb_digamma(u + 1, h, wp);
    }
    else
    {
        /* otherwise use Stirling series */
        arb_gamma_stirling_choose_param(&reflect, &r, &n, h, 0, 0, wp);
        arb_add_ui(zr, h, r, wp);
        _arb_poly_gamma_stirling_eval(u, zr, n, len, wp);

        if (r != 0)
        {
            _log_rising_ui_series(t, h, r, len, wp);
            _arb_vec_sub(u, u, t, len, wp);
        }
    }

    /* compose with nonconstant part */
    arb_zero(t);
    _arb_vec_set(t + 1, h + 1, hlen - 1);
    _arb_poly_compose_series(res, u, len, t, hlen, len, prec);

cleanup:
    arb_clear(zr);
    _arb_vec_clear(t, len);
    _arb_vec_clear(u, len);
}
Example #11
0
void
acb_hypgeom_pfq_series_direct(acb_poly_t res,
    const acb_poly_struct * a, long p,
    const acb_poly_struct * b, long q,
    const acb_poly_t z, int regularized,
    long n, long len, long prec)
{
    acb_poly_t s, t, err;
    arb_poly_t C, T;
    long i;
    int is_real;
    int terminating;

    /* default algorithm to choose number of terms */
    if (n < 0)
    {
        n = acb_hypgeom_pfq_series_choose_n(a, p, b, q, z, len, prec);
    }

    terminating = 0;

    /* check if it terminates due to a root of the numerator */
    for (i = 0; i < p; i++)
    {
        if (acb_poly_length(a + i) == 0 && n > 0)
        {
            terminating = 1;
        }
        else if (acb_poly_length(a + i) == 1)
        {
            acb_srcptr c = acb_poly_get_coeff_ptr(a + i, 0);

            if (acb_is_int(c) && arb_is_negative(acb_realref(c)) &&
                arf_cmpabs_ui(arb_midref(acb_realref(c)), n) < 0)
            {
                terminating = 1;
            }
        }
    }

    /* check if it terminates (to order n) due to z */
    /* the following tests could be made stronger... */
    if (z->length == 0 && n >= 1)
    {
        terminating = 1;
    }
    else if (!terminating && z->length > 0 && acb_is_zero(z->coeffs) && n >= len)
    {
        if (regularized)
        {
            terminating = 1;
        }
        else
        {
            terminating = 1;

            for (i = 0; i < q; i++)
            {
                acb_srcptr c = acb_poly_get_coeff_ptr(b + i, 0);

                if (!arb_is_positive(acb_realref(c)) && acb_contains_int(c))
                    terminating = 0;
            }
        }
    }

    acb_poly_init(s);
    acb_poly_init(t);
    acb_poly_init(err);
    arb_poly_init(C);
    arb_poly_init(T);

    acb_hypgeom_pfq_series_sum_forward(s, t, a, p, b, q, z, regularized, n, len, prec);

    if (!terminating)
    {
        is_real = acb_poly_is_real(z);
        for (i = 0; i < p; i++)
            is_real = is_real && acb_poly_is_real(a + i);
        for (i = 0; i < q; i++)
            is_real = is_real && acb_poly_is_real(b + i);

        acb_poly_majorant(T, t, MAG_BITS);
        acb_hypgeom_pfq_series_bound_factor(C, a, p, b, q, z, n, len, MAG_BITS);

        if (!_arb_vec_is_finite(T->coeffs, T->length) ||
            !_arb_vec_is_finite(C->coeffs, C->length))
        {
            arb_poly_fit_length(T, len);
            _arb_vec_indeterminate(T->coeffs, len);
            _arb_poly_set_length(T, len);
        }
        else
        {
            arb_poly_mullow(T, T, C, len, MAG_BITS);
        }

        /* create polynomial of errors */
        acb_poly_fit_length(err, len);

        for (i = 0; i < FLINT_MIN(len, T->length); i++)
        {
            arb_add_error(acb_realref(err->coeffs + i), T->coeffs + i);
            if (!is_real)
                arb_add_error(acb_imagref(err->coeffs + i), T->coeffs + i);
        }

        _acb_poly_set_length(err, len);
        _acb_poly_normalise(err);

        acb_poly_add(s, s, err, prec);
    }

    acb_poly_set(res, s);

    acb_poly_clear(s);
    acb_poly_clear(t);
    acb_poly_clear(err);
    arb_poly_clear(C);
    arb_poly_clear(T);
}