Exemplo n.º 1
0
void
acb_modular_elliptic_e(acb_t res, const acb_t m, long prec)
{
    if (acb_is_zero(m))
    {
        acb_const_pi(res, prec);
        acb_mul_2exp_si(res, res, -1);
    }
    else if (acb_is_one(m))
    {
        acb_one(res);
    }
    else
    {
        acb_struct t[2];

        acb_init(t + 0);
        acb_init(t + 1);

        acb_modular_elliptic_k_cpx(t, m, 2, prec);
        acb_mul(t + 1, t + 1, m, prec);
        acb_mul_2exp_si(t + 1, t + 1, 1);
        acb_add(t, t, t + 1, prec);
        acb_sub_ui(t + 1, m, 1, prec);
        acb_mul(res, t, t + 1, prec);
        acb_neg(res, res);

        acb_clear(t + 0);
        acb_clear(t + 1);
    }
}
Exemplo n.º 2
0
void
acb_hurwitz_zeta(acb_t z, const acb_t s, const acb_t a, slong prec)
{
    if (acb_is_one(a) && acb_is_int(s) &&
        arf_cmpabs_2exp_si(arb_midref(acb_realref(s)), FLINT_BITS - 1) < 0)
    {
        acb_zeta_si(z, arf_get_si(arb_midref(acb_realref(s)), ARF_RND_DOWN), prec);
        return;
    }

    _acb_poly_zeta_cpx_series(z, s, a, 0, 1, prec);
}
Exemplo n.º 3
0
void acb_hypgeom_beta_lower(acb_t res,
                            const acb_t a, const acb_t b, const acb_t z, int regularized, slong prec)
{
    acb_t t, u;

    if (acb_is_zero(z) && arb_is_positive(acb_realref(a)))
    {
        acb_zero(res);
        return;
    }

    if (acb_is_one(z) && arb_is_positive(acb_realref(b)))
    {
        if (regularized)
            acb_one(res);
        else
            acb_beta(res, a, b, prec);
        return;
    }

    acb_init(t);
    acb_init(u);

    acb_sub_ui(t, b, 1, prec);
    acb_neg(t, t);
    acb_add_ui(u, a, 1, prec);

    if (regularized)
    {
        acb_hypgeom_2f1(t, a, t, u, z, 1, prec);

        acb_add(u, a, b, prec);
        acb_gamma(u, u, prec);
        acb_mul(t, t, u, prec);
        acb_rgamma(u, b, prec);
        acb_mul(t, t, u, prec);
    }
    else
    {
        acb_hypgeom_2f1(t, a, t, u, z, 0, prec);
        acb_div(t, t, a, prec);
    }

    acb_pow(u, z, a, prec);
    acb_mul(t, t, u, prec);

    acb_set(res, t);

    acb_clear(t);
    acb_clear(u);
}
Exemplo n.º 4
0
/* compose by poly2 = a*x^n + c, no aliasing; n >= 1 */
void
_acb_poly_compose_axnc(acb_ptr res, acb_srcptr poly1, slong len1,
    const acb_t c, const acb_t a, slong n, slong prec)
{
    slong i;

    _acb_vec_set_round(res, poly1, len1, prec);
    /* shift by c (c = 0 case will be fast) */
    _acb_poly_taylor_shift(res, c, len1, prec);

    /* multiply by powers of a */
    if (!acb_is_one(a))
    {
        if (acb_equal_si(a, -1))
        {
            for (i = 1; i < len1; i += 2)
                acb_neg(res + i, res + i);
        }
        else if (len1 == 2)
        {
            acb_mul(res + 1, res + 1, a, prec);
        }
        else
        {
            acb_t t;
            acb_init(t);
            acb_set(t, a);

            for (i = 1; i < len1; i++)
            {
                acb_mul(res + i, res + i, t, prec);
                if (i + 1 < len1)
                    acb_mul(t, t, a, prec);
            }

            acb_clear(t);
        }
    }

    /* stretch */
    for (i = len1 - 1; i >= 1 && n > 1; i--)
    {
        acb_swap(res + i * n, res + i);
        _acb_vec_zero(res + (i - 1) * n + 1, n - 1);
    }
}
Exemplo n.º 5
0
Arquivo: acos.c Projeto: isuruf/arb
void
acb_acos(acb_t res, const acb_t z, slong prec)
{
    if (acb_is_one(z))
    {
        acb_zero(res);
    }
    else
    {
        acb_t t;
        acb_init(t);
        acb_asin(res, z, prec);
        acb_const_pi(t, prec);
        acb_mul_2exp_si(t, t, -1);
        acb_sub(res, t, res, prec);
        acb_clear(t);
    }
}
Exemplo n.º 6
0
void
acb_dirichlet_l_general(acb_t res, const acb_t s,
    const dirichlet_group_t G, const dirichlet_char_t chi, slong prec)
{
    /* this cutoff is probably too conservative when q is large */
    if (arf_cmp_d(arb_midref(acb_realref(s)), 8 + 0.5 * prec / log(prec)) >= 0)
    {
        acb_dirichlet_l_euler_product(res, s, G, chi, prec);
    }
    else
    {
        slong wp = prec + n_clog(G->phi_q, 2);
        acb_dirichlet_hurwitz_precomp_t pre;
        acb_dirichlet_hurwitz_precomp_init_num(pre, s, acb_is_one(s), G->phi_q, wp);
        acb_dirichlet_l_hurwitz(res, s, pre, G, chi, prec);
        acb_dirichlet_hurwitz_precomp_clear(pre);
    }
}
Exemplo n.º 7
0
static void
_acb_hypgeom_m_1f1(acb_t res, const acb_t a, const acb_t b, const acb_t z, long prec)
{
    if (acb_is_one(a))
    {
        acb_hypgeom_pfq_direct(res, NULL, 0, b, 1, z, -1, prec);
    }
    else
    {
        acb_struct c[3];
        c[0] = *a;
        c[1] = *b;

        acb_init(c + 2);
        acb_one(c + 2);

        acb_hypgeom_pfq_direct(res, c, 1, c + 1, 2, z, -1, prec);

        acb_clear(c + 2);
    }
}
Exemplo n.º 8
0
void
acb_acosh(acb_t res, const acb_t z, slong prec)
{
    if (acb_is_one(z))
    {
        acb_zero(res);
    }
    else
    {
        acb_t t, u;
        acb_init(t);
        acb_init(u);

        acb_add_ui(t, z, 1, prec);
        acb_sub_ui(u, z, 1, prec);
        acb_sqrt(t, t, prec);
        acb_sqrt(u, u, prec);
        acb_mul(t, t, u, prec);
        acb_add(t, t, z, prec);

        if (!arb_is_zero(acb_imagref(z)))
        {
            acb_log(res, t, prec);
        }
        else
        {
            /* pure imaginary on (-1,1) */
            arb_abs(acb_realref(u), acb_realref(z));
            arb_one(acb_imagref(u));
            acb_log(res, t, prec);
            if (arb_lt(acb_realref(u), acb_imagref(u)))
                arb_zero(acb_realref(res));
        }

        acb_clear(t);
        acb_clear(u);
    }
}
Exemplo n.º 9
0
void
_acb_poly_taylor_shift_horner(acb_ptr poly, const acb_t c, slong n, slong prec)
{
    slong i, j;

    if (acb_is_one(c))
    {
        for (i = n - 2; i >= 0; i--)
            for (j = i; j < n - 1; j++)
                acb_add(poly + j, poly + j, poly + j + 1, prec);
    }
    else if (acb_equal_si(c, -1))
    {
        for (i = n - 2; i >= 0; i--)
            for (j = i; j < n - 1; j++)
                acb_sub(poly + j, poly + j, poly + j + 1, prec);
    }
    else if (!acb_is_zero(c))
    {
        for (i = n - 2; i >= 0; i--)
            for (j = i; j < n - 1; j++)
                acb_addmul(poly + j, poly + j + 1, c, prec);
    }
}
Exemplo n.º 10
0
void
acb_hypgeom_chebyshev_t(acb_t res, const acb_t n, const acb_t z, slong prec)
{
    acb_t t;

    if (acb_is_int(n) && 
        arf_cmpabs_2exp_si(arb_midref(acb_realref(n)), FLINT_BITS - 1) < 0)
    {
        slong k = arf_get_si(arb_midref(acb_realref(n)), ARF_RND_DOWN);
        acb_chebyshev_t_ui(res, FLINT_ABS(k), z, prec);
        return;
    }

    if (acb_is_zero(z))
    {
        acb_mul_2exp_si(res, n, -1);
        acb_cos_pi(res, res, prec);
        return;
    }

    if (acb_is_one(z))
    {
        acb_one(res);
        return;
    }

    acb_init(t);
    acb_set_si(t, -1);

    if (acb_equal(t, z))
    {
        acb_cos_pi(res, n, prec);
    }
    else
    {
        acb_sub_ui(t, z, 1, prec);

        if (arf_cmpabs_2exp_si(arb_midref(acb_realref(t)), -2 - prec / 10) < 0 &&
            arf_cmpabs_2exp_si(arb_midref(acb_imagref(t)), -2 - prec / 10) < 0)
        {
            acb_t a, c;

            acb_init(a);
            acb_init(c);

            acb_neg(a, n);
            acb_one(c);
            acb_mul_2exp_si(c, c, -1);
            acb_neg(t, t);
            acb_mul_2exp_si(t, t, -1);
            acb_hypgeom_2f1(res, a, n, c, t, 0, prec);

            acb_clear(a);
            acb_clear(c);
        }
        else if (arb_is_nonnegative(acb_realref(t)))
        {
            acb_acosh(t, z, prec);
            acb_mul(t, t, n, prec);
            acb_cosh(res, t, prec);
        }
        else
        {
            acb_acos(t, z, prec);
            acb_mul(t, t, n, prec);
            acb_cos(res, t, prec);
        }
    }

    acb_clear(t);
}
Exemplo n.º 11
0
void
_acb_poly_zeta_cpx_reflect(acb_ptr t, const acb_t h, const acb_t a, int deflate, slong len, slong prec)
{
    /* use reflection formula */
    if (arf_sgn(arb_midref(acb_realref(h))) < 0 && acb_is_one(a))
    {
        /* zeta(s) = (2*pi)**s * sin(pi*s/2) / pi * gamma(1-s) * zeta(1-s) */
        acb_t pi, hcopy;
        acb_ptr f, s1, s2, s3, s4, u;
        slong i;

        acb_init(pi);
        acb_init(hcopy);
        f = _acb_vec_init(2);
        s1 = _acb_vec_init(len);
        s2 = _acb_vec_init(len);
        s3 = _acb_vec_init(len);
        s4 = _acb_vec_init(len);
        u = _acb_vec_init(len);
        acb_set(hcopy, h);

        acb_const_pi(pi, prec);

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

        /* s2 = sin(pi*s/2) / pi */
        acb_set(f, h);
        acb_one(f + 1);
        acb_mul_2exp_si(f, f, -1);
        acb_mul_2exp_si(f + 1, f + 1, -1);
        _acb_poly_sin_pi_series(s2, f, 2, len, prec);
        _acb_vec_scalar_div(s2, s2, len, pi, prec);

        /* s3 = gamma(1-s) */
        acb_sub_ui(f, hcopy, 1, prec);
        acb_neg(f, f);
        acb_set_si(f + 1, -1);
        _acb_poly_gamma_series(s3, f, 2, len, prec);

        /* s4 = zeta(1-s) */
        acb_sub_ui(f, hcopy, 1, prec);
        acb_neg(f, f);
        _acb_poly_zeta_cpx_series(s4, f, a, 0, len, prec);
        for (i = 1; i < len; i += 2)
            acb_neg(s4 + i, s4 + i);

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

        /* add 1/(1-(s+t)) = 1/(1-s) + t/(1-s)^2 + ... */
        if (deflate)
        {
            acb_sub_ui(u, hcopy, 1, prec);
            acb_neg(u, u);
            acb_inv(u, u, prec);
            for (i = 1; i < len; i++)
                acb_mul(u + i, u + i - 1, u, prec);
            _acb_vec_add(t, t, u, len, prec);
        }

        acb_clear(pi);
        acb_clear(hcopy);
        _acb_vec_clear(f, 2);
        _acb_vec_clear(s1, len);
        _acb_vec_clear(s2, len);
        _acb_vec_clear(s3, len);
        _acb_vec_clear(s4, len);
        _acb_vec_clear(u, len);
    }
    else
    {
        _acb_poly_zeta_cpx_series(t, h, a, deflate, len, prec);
    }
}
Exemplo n.º 12
0
void
_acb_poly_zeta_cpx_series(acb_ptr z, const acb_t s, const acb_t a, int deflate, slong d, slong prec)
{
    ulong M, N;
    slong i, bound_prec;
    mag_t bound;
    arb_ptr vb;
    int is_real, const_is_real;

    if (d < 1)
        return;

    if (!acb_is_finite(s) || !acb_is_finite(a))
    {
        _acb_vec_indeterminate(z, d);
        return;
    }

    if (acb_is_one(s) && deflate && d == 1)
    {
        acb_digamma(z, a, prec);
        acb_neg(z, z);
        if (!acb_is_finite(z))  /* todo: in digamma */
            acb_indeterminate(z);
        return;
    }

    is_real = const_is_real = 0;

    if (acb_is_real(s) && acb_is_real(a))
    {
        if (arb_is_positive(acb_realref(a)))
        {
            is_real = const_is_real = 1;
        }
        else if (arb_is_int(acb_realref(a)) &&
             arb_is_int(acb_realref(s)) &&
             arb_is_nonpositive(acb_realref(s)))
        {
            const_is_real = 1;
        }
    }

    mag_init(bound);
    vb = _arb_vec_init(d);

    bound_prec = 40 + prec / 20;

    _acb_poly_zeta_em_choose_param(bound, &N, &M, s, a, FLINT_MIN(d, 2), prec, bound_prec);
    _acb_poly_zeta_em_bound(vb, s, a, N, M, d, bound_prec);

    _acb_poly_zeta_em_sum(z, s, a, deflate, N, M, d, prec);

    for (i = 0; i < d; i++)
    {
        arb_get_mag(bound, vb + i);
        arb_add_error_mag(acb_realref(z + i), bound);

        if (!is_real && !(i == 0 && const_is_real))
            arb_add_error_mag(acb_imagref(z + i), bound);
    }

    mag_clear(bound);
    _arb_vec_clear(vb, d);
}
Exemplo n.º 13
0
Arquivo: m.c Projeto: argriffing/arb
void
_acb_hypgeom_m_1f1(acb_t res, const acb_t a, const acb_t b, const acb_t z,
    int regularized, slong prec, slong gamma_prec, int kummer)
{
    if (regularized)
    {
        /* Remove singularity */
        if (acb_is_int(b) && arb_is_nonpositive(acb_realref(b)) &&
            arf_cmpabs_2exp_si(arb_midref(acb_realref(b)), 30) < 0)
        {
            acb_t c, d, t, u;
            slong n;

            n = arf_get_si(arb_midref(acb_realref(b)), ARF_RND_DOWN);

            acb_init(c);
            acb_init(d);
            acb_init(t);
            acb_init(u);

            acb_sub(c, a, b, prec);
            acb_add_ui(c, c, 1, prec);

            acb_neg(d, b);
            acb_add_ui(d, d, 2, prec);

            _acb_hypgeom_m_1f1(t, c, d, z, 0, prec, gamma_prec, kummer);

            acb_pow_ui(u, z, 1 - n, prec);
            acb_mul(t, t, u, prec);

            acb_rising_ui(u, a, 1 - n, prec);
            acb_mul(t, t, u, prec);

            arb_fac_ui(acb_realref(u), 1 - n, prec);
            acb_div_arb(res, t, acb_realref(u), prec);

            acb_clear(c);
            acb_clear(d);
            acb_clear(t);
            acb_clear(u);
        }
        else
        {
            acb_t t;
            acb_init(t);
            acb_rgamma(t, b, gamma_prec);
            _acb_hypgeom_m_1f1(res, a, b, z, 0, prec, gamma_prec, kummer);
            acb_mul(res, res, t, prec);
            acb_clear(t);
        }
        return;
    }

    /* Kummer's transformation */
    if (kummer)
    {
        acb_t u, v;
        acb_init(u);
        acb_init(v);

        acb_sub(u, b, a, prec);
        acb_neg(v, z);

        _acb_hypgeom_m_1f1(u, u, b, v, regularized, prec, gamma_prec, 0);
        acb_exp(v, z, prec);
        acb_mul(res, u, v, prec);

        acb_clear(u);
        acb_clear(v);
        return;
    }

    if (acb_is_one(a))
    {
        acb_hypgeom_pfq_direct(res, NULL, 0, b, 1, z, -1, prec);
    }
    else
    {
        acb_struct c[3];
        c[0] = *a;
        c[1] = *b;

        acb_init(c + 2);
        acb_one(c + 2);

        acb_hypgeom_pfq_direct(res, c, 1, c + 1, 2, z, -1, prec);

        acb_clear(c + 2);
    }
}
Exemplo n.º 14
0
void
_acb_poly_zeta_em_sum(acb_ptr z, const acb_t s, const acb_t a, int deflate, ulong N, ulong M, slong d, slong prec)
{
    acb_ptr t, u, v, term, sum;
    acb_t Na, one;
    slong i;

    t = _acb_vec_init(d + 1);
    u = _acb_vec_init(d);
    v = _acb_vec_init(d);
    term = _acb_vec_init(d);
    sum = _acb_vec_init(d);
    acb_init(Na);
    acb_init(one);

    prec += 2 * (FLINT_BIT_COUNT(N) + FLINT_BIT_COUNT(d));
    acb_one(one);

    /* sum 1/(k+a)^(s+x) */
    if (acb_is_one(a) && d <= 3)
        _acb_poly_powsum_one_series_sieved(sum, s, N, d, prec);
    else if (N > 50 && flint_get_num_threads() > 1)
        _acb_poly_powsum_series_naive_threaded(sum, s, a, one, N, d, prec);
    else
        _acb_poly_powsum_series_naive(sum, s, a, one, N, d, prec);

    /* t = 1/(N+a)^(s+x); we might need one extra term for deflation */
    acb_add_ui(Na, a, N, prec);
    _acb_poly_acb_invpow_cpx(t, Na, s, d + 1, prec);

    /* sum += (N+a) * 1/((s+x)-1) * t */
    if (!deflate)
    {
        /* u = (N+a)^(1-(s+x)) */
        acb_sub_ui(v, s, 1, prec);
        _acb_poly_acb_invpow_cpx(u, Na, v, d, prec);

        /* divide by 1/((s-1) + x) */
        acb_sub_ui(v, s, 1, prec);
        acb_div(u, u, v, prec);

        for (i = 1; i < d; i++)
        {
            acb_sub(u + i, u + i, u + i - 1, prec);
            acb_div(u + i, u + i, v, prec);
        }

        _acb_vec_add(sum, sum, u, d, prec);
    }
    /* sum += ((N+a)^(1-(s+x)) - 1) / ((s+x) - 1) */
    else
    {
        /* at s = 1, this becomes (N*t - 1)/x, i.e. just remove one coeff  */
        if (acb_is_one(s))
        {
            for (i = 0; i < d; i++)
                acb_mul(u + i, t + i + 1, Na, prec);
            _acb_vec_add(sum, sum, u, d, prec);
        }
        else
        {
            /* TODO: this is numerically unstable for large derivatives,
                and divides by zero if s contains 1. We want a good
                way to evaluate the power series ((N+a)^y - 1) / y where y has
                nonzero constant term, without doing a division.
                How is this best done? */

            _acb_vec_scalar_mul(t, t, d, Na, prec);
            acb_sub_ui(t + 0, t + 0, 1, prec);
            acb_sub_ui(u + 0, s, 1, prec);
            acb_inv(u + 0, u + 0, prec);
            for (i = 1; i < d; i++)
                acb_mul(u + i, u + i - 1, u + 0, prec);
            for (i = 1; i < d; i += 2)
                acb_neg(u + i, u + i);
            _acb_poly_mullow(v, u, d, t, d, d, prec);
            _acb_vec_add(sum, sum, v, d, prec);
            _acb_poly_acb_invpow_cpx(t, Na, s, d, prec);
        }
    }

    /* sum += u = 1/2 * t */
    _acb_vec_scalar_mul_2exp_si(u, t, d, -WORD(1));
    _acb_vec_add(sum, sum, u, d, prec);

    /* Euler-Maclaurin formula tail */
    if (d < 5 || d < M / 10)
        _acb_poly_zeta_em_tail_naive(u, s, Na, t, M, d, prec);
    else
        _acb_poly_zeta_em_tail_bsplit(u, s, Na, t, M, d, prec);

    _acb_vec_add(z, sum, u, d, prec);

    _acb_vec_clear(t, d + 1);
    _acb_vec_clear(u, d);
    _acb_vec_clear(v, d);
    _acb_vec_clear(term, d);
    _acb_vec_clear(sum, d);
    acb_clear(Na);
    acb_clear(one);
}
Exemplo n.º 15
0
Arquivo: 2f1.c Projeto: argriffing/arb
void
acb_hypgeom_2f1(acb_t res, const acb_t a, const acb_t b,
        const acb_t c, const acb_t z, int flags, slong prec)
{
    int algorithm, regularized;

    regularized = flags & ACB_HYPGEOM_2F1_REGULARIZED;

    if (!acb_is_finite(a) || !acb_is_finite(b) || !acb_is_finite(c) || !acb_is_finite(z))
    {
        acb_indeterminate(res);
        return;
    }

    if (acb_is_zero(z))
    {
        if (regularized)
            acb_rgamma(res, c, prec);
        else
            acb_one(res);
        return;
    }

    if (regularized && acb_is_int(c) && arb_is_nonpositive(acb_realref(c)))
    {
        if ((acb_is_int(a) && arb_is_nonpositive(acb_realref(a)) &&
            arf_cmp(arb_midref(acb_realref(a)), arb_midref(acb_realref(c))) >= 0) ||
            (acb_is_int(b) && arb_is_nonpositive(acb_realref(b)) &&
            arf_cmp(arb_midref(acb_realref(b)), arb_midref(acb_realref(c))) >= 0))
        {
            acb_zero(res);
            return;
        }
    }

    if (regularized && acb_eq(a, c))
    {
        _acb_hypgeom_2f1r_reduced(res, b, c, z, prec);
        return;
    }

    if (regularized && acb_eq(b, c))
    {
        _acb_hypgeom_2f1r_reduced(res, a, c, z, prec);
        return;
    }

    /* polynomial */
    if (acb_is_int(a) && arf_sgn(arb_midref(acb_realref(a))) <= 0 &&
         arf_cmpabs_ui(arb_midref(acb_realref(a)), prec) < 0)
    {
        acb_hypgeom_2f1_direct(res, a, b, c, z, regularized, prec);
        return;
    }

    /* polynomial */
    if (acb_is_int(b) && arf_sgn(arb_midref(acb_realref(b))) <= 0 &&
         arf_cmpabs_ui(arb_midref(acb_realref(b)), prec) < 0)
    {
        acb_hypgeom_2f1_direct(res, a, b, c, z, regularized, prec);
        return;
    }

    /* Try to reduce to a polynomial case using the Pfaff transformation */
    /* TODO: look at flags for integer c-b, c-a here, even when c is nonexact */
    if (acb_is_exact(c))
    {
        acb_t t;
        acb_init(t);

        acb_sub(t, c, b, prec);

        if (acb_is_int(t) && arb_is_nonpositive(acb_realref(t)))
        {
            acb_hypgeom_2f1_transform(res, a, b, c, z, flags, 1, prec);
            acb_clear(t);
            return;
        }

        acb_sub(t, c, a, prec);

        if (acb_is_int(t) && arb_is_nonpositive(acb_realref(t)))
        {
            int f1, f2;

            /* When swapping a, b, also swap the flags. */
            f1 = flags & ACB_HYPGEOM_2F1_AC;
            f2 = flags & ACB_HYPGEOM_2F1_BC;

            flags &= ~ACB_HYPGEOM_2F1_AC;
            flags &= ~ACB_HYPGEOM_2F1_BC;

            if (f1) flags |= ACB_HYPGEOM_2F1_BC;
            if (f2) flags |= ACB_HYPGEOM_2F1_AC;

            acb_hypgeom_2f1_transform(res, b, a, c, z, flags, 1, prec);
            acb_clear(t);
            return;
        }

        acb_clear(t);
    }

    /* special value at z = 1 */
    if (acb_is_one(z))
    {
        acb_t t, u, v;

        acb_init(t);
        acb_init(u);
        acb_init(v);

        acb_sub(t, c, a, prec);
        acb_sub(u, c, b, prec);
        acb_sub(v, t, b, prec);

        if (arb_is_positive(acb_realref(v)))
        {
            acb_rgamma(t, t, prec);
            acb_rgamma(u, u, prec);
            acb_mul(t, t, u, prec);
            acb_gamma(v, v, prec);
            acb_mul(t, t, v, prec);

            if (!regularized)
            {
                acb_gamma(v, c, prec);
                acb_mul(t, t, v, prec);
            }

            acb_set(res, t);
        }
        else
        {
            acb_indeterminate(res);
        }

        acb_clear(t);
        acb_clear(u);
        acb_clear(v);

        return;
    }

    algorithm = acb_hypgeom_2f1_choose(z);

    if (algorithm == 0)
    {
        acb_hypgeom_2f1_direct(res, a, b, c, z, regularized, prec);
    }
    else if (algorithm >= 1 && algorithm <= 5)
    {
        acb_hypgeom_2f1_transform(res, a, b, c, z, flags, algorithm, prec);
    }
    else
    {
        acb_hypgeom_2f1_corner(res, a, b, c, z, regularized, prec);
    }
}
Exemplo n.º 16
0
void
_acb_poly_inv_series(acb_ptr Qinv,
    acb_srcptr Q, slong Qlen, slong len, slong prec)
{
    Qlen = FLINT_MIN(Qlen, len);

    acb_inv(Qinv, Q, prec);

    if (Qlen == 1)
    {
        _acb_vec_zero(Qinv + 1, len - 1);
    }
    else if (len == 2)
    {
        acb_mul(Qinv + 1, Qinv, Qinv, prec);
        acb_mul(Qinv + 1, Qinv + 1, Q + 1, prec);
        acb_neg(Qinv + 1, Qinv + 1);
    }
    else
    {
        slong i, blen;

        /* The basecase algorithm is faster for much larger Qlen or len than
           this, but unfortunately also much less numerically stable. */
        if (Qlen == 2 || len <= 8)
            blen = len;
        else
            blen = FLINT_MIN(len, 4);

        for (i = 1; i < blen; i++)
        {
            acb_dot(Qinv + i, NULL, 1,
                Q + 1, 1, Qinv + i - 1, -1, FLINT_MIN(i, Qlen - 1), prec);
            if (!acb_is_one(Qinv))
                acb_mul(Qinv + i, Qinv + i, Qinv, prec);
        }

        if (len > blen)
        {
            slong Qnlen, Wlen, W2len;
            acb_ptr W;

            W = _acb_vec_init(len);

            NEWTON_INIT(blen, len)
            NEWTON_LOOP(m, n)

            Qnlen = FLINT_MIN(Qlen, n);
            Wlen = FLINT_MIN(Qnlen + m - 1, n);
            W2len = Wlen - m;
            MULLOW(W, Q, Qnlen, Qinv, m, Wlen, prec);
            MULLOW(Qinv + m, Qinv, m, W + m, W2len, n - m, prec);
            _acb_vec_neg(Qinv + m, Qinv + m, n - m);

            NEWTON_END_LOOP
            NEWTON_END

            _acb_vec_clear(W, len);
        }
    }
}