Beispiel #1
0
void
arb_fac2_ui(arb_t res, ulong n, long prec)
{
    if (n % 2 == 0)
    {
        arb_fac_ui(res, n / 2, prec);
        arb_mul_2exp_si(res, res, n / 2);
    }
    else
    {
        arb_t t;
        arb_init(t);
        arb_fac2_ui(t, n - 1, prec + 5);
        arb_fac_ui(res, n, prec + 5);
        arb_div(res, res, t, prec);
        arb_clear(t);
    }
}
Beispiel #2
0
void
acb_hypgeom_m(acb_t res, const acb_t a, const acb_t b, const acb_t z, int regularized, long prec)
{
    long m = LONG_MAX;
    long n = LONG_MAX;

    if (acb_is_int(a) &&
            arf_cmpabs_2exp_si(arb_midref(acb_realref(a)), 30) < 0)
    {
        m = arf_get_si(arb_midref(acb_realref(a)), ARF_RND_DOWN);
    }

    if (acb_is_int(b) &&
            arf_cmpabs_2exp_si(arb_midref(acb_realref(b)), 30) < 0)
    {
        n = arf_get_si(arb_midref(acb_realref(b)), ARF_RND_DOWN);
    }

    /* terminating */
    if (m <= 0 && m < n && m > -10 * prec && (n > 0 || !regularized))
    {
        acb_hypgeom_m_1f1(res, a, b, z, regularized, prec);
        return;
    }

    /* large */
    if (acb_hypgeom_u_use_asymp(z, prec))
    {
        acb_hypgeom_m_asymp(res, a, b, z, regularized, prec);
        return;
    }

    /* remove singularity */
    if (n <= 0 && n > -10 * prec && regularized)
    {
        acb_t c, d, t, u;

        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);

        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_hypgeom_m_1f1(res, a, b, z, regularized, prec);
    }
}
Beispiel #3
0
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);
    }
}
void
bernoulli_rev_init(bernoulli_rev_t iter, ulong nmax)
{
    long j;
    fmpz_t t;
    arb_t x;
    arf_t u;
    int round1, round2;
    long wp;

    nmax -= (nmax % 2);
    iter->n = nmax;

    iter->alloc = 0;
    if (nmax < BERNOULLI_REV_MIN)
        return;

    iter->prec = wp = bernoulli_global_prec(nmax);

    iter->max_power = bernoulli_zeta_terms(nmax, iter->prec);
    iter->alloc = iter->max_power + 1;
    iter->powers = _fmpz_vec_init(iter->alloc);
    fmpz_init(iter->pow_error);
    arb_init(iter->prefactor);
    arb_init(iter->two_pi_squared);

    arb_init(x);
    fmpz_init(t);
    arf_init(u);

    /* precompute powers */
    for (j = 3; j <= iter->max_power; j += 2)
    {
        arb_ui_pow_ui(x, j, nmax, bernoulli_power_prec(j, nmax, wp));
        arb_inv(x, x, bernoulli_power_prec(j, nmax, wp));
        round1 = arf_get_fmpz_fixed_si(t, arb_midref(x), -wp);
        fmpz_set(iter->powers + j, t);

        /* error: the radius, plus two roundings */
        arf_set_mag(u, arb_radref(x));
        round2 = arf_get_fmpz_fixed_si(t, u, -wp);
        fmpz_add_ui(t, t, (round1 != 0) + (round2 != 0));
        if (fmpz_cmp(iter->pow_error, t) < 0)
            fmpz_set(iter->pow_error, t);
    }

    /* precompute (2pi)^2 and 2*(n!)/(2pi)^n */
    arb_fac_ui(iter->prefactor, nmax, wp);
    arb_mul_2exp_si(iter->prefactor, iter->prefactor, 1);

    arb_const_pi(x, wp);
    arb_mul_2exp_si(x, x, 1);
    arb_mul(iter->two_pi_squared, x, x, wp);

    arb_pow_ui(x, iter->two_pi_squared, nmax / 2, wp);
    arb_div(iter->prefactor, iter->prefactor, x, wp);

    fmpz_clear(t);
    arb_clear(x);
    arf_clear(u);
}