示例#1
0
文件: bessel_k.c 项目: isuruf/arb
void
acb_hypgeom_bessel_k_0f1(acb_t res, const acb_t nu, const acb_t z, slong prec)
{
    if (acb_is_int(nu))
    {
        acb_poly_t nux, zx, rx;

        acb_poly_init(nux);
        acb_poly_init(zx);
        acb_poly_init(rx);

        acb_poly_set_coeff_acb(nux, 0, nu);
        acb_poly_set_coeff_si(nux, 1, 1);
        acb_poly_set_acb(zx, z);

        acb_hypgeom_bessel_k_0f1_series(rx, nux, zx, 1, prec);

        acb_poly_get_coeff_acb(res, rx, 0);

        acb_poly_clear(nux);
        acb_poly_clear(zx);
        acb_poly_clear(rx);
    }
    else
    {
        acb_t t, u, v, w;
        acb_struct b[2];

        acb_init(t);
        acb_init(u);
        acb_init(v);
        acb_init(w);
        acb_init(b + 0);
        acb_init(b + 1);

        /* u = 0F1(1+nu), v = 0F1(1-nu) */
        acb_mul(t, z, z, prec);
        acb_mul_2exp_si(t, t, -2);
        acb_add_ui(b, nu, 1, prec);
        acb_one(b + 1);
        acb_hypgeom_pfq_direct(u, NULL, 0, b, 2, t, -1, prec);
        acb_sub_ui(b, nu, 1, prec);
        acb_neg(b, b);
        acb_hypgeom_pfq_direct(v, NULL, 0, b, 2, t, -1, prec);

        /* v = v * gamma(nu) / (z/2)^nu */
        acb_mul_2exp_si(t, z, -1);
        acb_pow(t, t, nu, prec);
        acb_gamma(w, nu, prec);
        acb_mul(v, v, w, prec);
        acb_div(v, v, t, prec);

        /* u = u * t * pi / (gamma(nu) * nu * sin(pi nu)) */
        acb_mul(u, u, t, prec);
        acb_const_pi(t, prec);
        acb_mul(u, u, t, prec);
        acb_sin_pi(t, nu, prec);
        acb_mul(t, t, w, prec);
        acb_mul(t, t, nu, prec);
        acb_div(u, u, t, prec);

        acb_sub(res, v, u, prec);
        acb_mul_2exp_si(res, res, -1);

        acb_clear(t);
        acb_clear(u);
        acb_clear(v);
        acb_clear(w);
        acb_clear(b + 0);
        acb_clear(b + 1);
    }
}
示例#2
0
int main()
{
    slong iter;
    flint_rand_t state;

    flint_printf("binomial_transform....");
    fflush(stdout);

    flint_randinit(state);

    for (iter = 0; iter < 500 * arb_test_multiplier(); iter++)
    {
        acb_poly_t a, b, c, d;
        slong j, n, prec;

        acb_poly_init(a);
        acb_poly_init(b);
        acb_poly_init(c);
        acb_poly_init(d);

        n = n_randint(state, 20);
        prec = 2 + n_randint(state, 200);

        acb_poly_randtest(a, state, n, prec, 10);
        acb_poly_randtest(b, state, n, prec, 10);
        acb_poly_randtest(c, state, n, prec, 10);

        /* check self-inversion property */
        acb_poly_binomial_transform(b, a, n, prec);
        acb_poly_binomial_transform(c, b, n, prec);

        acb_poly_set(d, a);
        acb_poly_truncate(d, n);

        if (!acb_poly_contains(c, d))
        {
            flint_printf("FAIL (containment)\n\n");
            flint_printf("n = %wd, prec = %wd\n\n", n, prec);

            flint_printf("a: "); acb_poly_printd(a, 15); flint_printf("\n\n");
            flint_printf("b: "); acb_poly_printd(b, 15); flint_printf("\n\n");
            flint_printf("c: "); acb_poly_printd(c, 15); flint_printf("\n\n");
            flint_printf("d: "); acb_poly_printd(d, 15); flint_printf("\n\n");

            abort();
        }

        acb_poly_set(d, a);
        acb_poly_binomial_transform(d, d, n, prec);
        if (!acb_poly_equal(d, b))
        {
            flint_printf("FAIL (aliasing)\n\n");

            flint_printf("a: "); acb_poly_printd(a, 15); flint_printf("\n\n");
            flint_printf("b: "); acb_poly_printd(b, 15); flint_printf("\n\n");
            flint_printf("d: "); acb_poly_printd(d, 15); flint_printf("\n\n");

            abort();
        }

        /* compare with power series operations */
        acb_poly_zero(d);
        for (j = 1; j < n; j++)
            acb_poly_set_coeff_si(d, j, -1);
        acb_poly_compose_series(c, a, d, n, prec);
        for (j = 0; j < n; j++)
            acb_poly_set_coeff_si(d, j, 1);
        acb_poly_mullow(c, c, d, n, prec);

        if (!acb_poly_overlaps(b, c))
        {
            flint_printf("FAIL (power series)\n\n");

            flint_printf("a: "); acb_poly_printd(a, 15); flint_printf("\n\n");
            flint_printf("b: "); acb_poly_printd(b, 15); flint_printf("\n\n");
            flint_printf("c: "); acb_poly_printd(c, 15); flint_printf("\n\n");

            abort();
        }

        acb_poly_clear(a);
        acb_poly_clear(b);
        acb_poly_clear(c);
        acb_poly_clear(d);
    }

    flint_randclear(state);
    flint_cleanup();
    flint_printf("PASS\n");
    return EXIT_SUCCESS;
}
示例#3
0
int main()
{
    slong iter;
    flint_rand_t state;

    flint_printf("lgamma_series....");
    fflush(stdout);

    flint_randinit(state);

    /* special accuracy test case */
    {
        acb_poly_t a;
        acb_t c;

        acb_init(c);
        acb_poly_init(a);

        arb_set_str(acb_realref(c), "-20.25", 53);
        arb_set_str(acb_imagref(c), "1e1000", 53);

        acb_poly_set_coeff_acb(a, 0, c);
        acb_poly_set_coeff_si(a, 1, 1);

        acb_poly_lgamma_series(a, a, 3, 53);

        if (acb_rel_accuracy_bits(a->coeffs) < 40 ||
            acb_rel_accuracy_bits(a->coeffs + 1) < 40 ||
            acb_rel_accuracy_bits(a->coeffs + 2) < 40)
        {
            flint_printf("FAIL: accuracy (reflection formula)\n\n");
            acb_poly_printd(a, 15); flint_printf("\n\n");
            abort();
        }

        acb_poly_clear(a);
        acb_clear(c);
    }

    for (iter = 0; iter < 500 * arb_test_multiplier(); iter++)
    {
        slong m, n1, n2, rbits1, rbits2, rbits3;
        acb_poly_t a, b, c, d;

        rbits1 = 2 + n_randint(state, 200);
        rbits2 = 2 + n_randint(state, 200);
        rbits3 = 2 + n_randint(state, 200);

        m = 1 + n_randint(state, 30);
        n1 = 1 + n_randint(state, 30);
        n2 = 1 + n_randint(state, 30);

        acb_poly_init(a);
        acb_poly_init(b);
        acb_poly_init(c);
        acb_poly_init(d);

        acb_poly_randtest(a, state, m, rbits1, 10);
        acb_poly_randtest(b, state, m, rbits1, 10);
        acb_poly_randtest(c, state, m, rbits1, 10);

        acb_poly_lgamma_series(b, a, n1, rbits2);
        acb_poly_lgamma_series(c, a, n2, rbits3);

        acb_poly_set(d, b);
        acb_poly_truncate(d, FLINT_MIN(n1, n2));
        acb_poly_truncate(c, FLINT_MIN(n1, n2));

        if (!acb_poly_overlaps(c, d))
        {
            flint_printf("FAIL\n\n");
            flint_printf("n1 = %wd, n2 = %wd, bits2 = %wd, bits3 = %wd\n", n1, n2, rbits2, rbits3);

            flint_printf("a = "); acb_poly_printd(a, 15); flint_printf("\n\n");
            flint_printf("b = "); acb_poly_printd(b, 15); flint_printf("\n\n");
            flint_printf("c = "); acb_poly_printd(c, 15); flint_printf("\n\n");

            abort();
        }

        /* check loggamma(a) + log(a) = loggamma(a+1) */
        acb_poly_log_series(c, a, n1, rbits2);
        acb_poly_add(c, b, c, rbits2);

        acb_poly_set(d, a);
        acb_add_ui(d->coeffs, d->coeffs, 1, rbits2);
        acb_poly_lgamma_series(d, d, n1, rbits2);

        if (!acb_poly_overlaps(c, d))
        {
            flint_printf("FAIL (functional equation)\n\n");

            flint_printf("a = "); acb_poly_printd(a, 15); flint_printf("\n\n");
            flint_printf("b = "); acb_poly_printd(b, 15); flint_printf("\n\n");
            flint_printf("c = "); acb_poly_printd(c, 15); flint_printf("\n\n");
            flint_printf("d = "); acb_poly_printd(d, 15); flint_printf("\n\n");

            abort();
        }

        acb_poly_lgamma_series(a, a, n1, rbits2);
        if (!acb_poly_overlaps(a, b))
        {
            flint_printf("FAIL (aliasing)\n\n");
            abort();
        }

        acb_poly_clear(a);
        acb_poly_clear(b);
        acb_poly_clear(c);
        acb_poly_clear(d);
    }

    flint_randclear(state);
    flint_cleanup();
    flint_printf("PASS\n");
    return EXIT_SUCCESS;
}
示例#4
0
void
acb_hypgeom_2f1_transform_limit(acb_t res, const acb_t a, const acb_t b,
    const acb_t c, const acb_t z, int regularized, int which, slong prec)
{
    acb_poly_t aa, bb, cc, zz;
    acb_t t;

    if (acb_contains_zero(z) || !acb_is_finite(z))
    {
        acb_indeterminate(res);
        return;
    }

    if (arb_contains_si(acb_realref(z), 1) && arb_contains_zero(acb_imagref(z)))
    {
        acb_indeterminate(res);
        return;
    }

    if (!regularized)
    {
        acb_init(t);
        acb_gamma(t, c, prec);
        acb_hypgeom_2f1_transform_limit(res, a, b, c, z, 1, which, prec);
        acb_mul(res, res, t, prec);
        acb_clear(t);
        return;
    }

    acb_poly_init(aa);
    acb_poly_init(bb);
    acb_poly_init(cc);
    acb_poly_init(zz);
    acb_init(t);

    acb_poly_set_acb(aa, a);
    acb_poly_set_acb(bb, b);
    acb_poly_set_acb(cc, c);
    acb_poly_set_acb(zz, z);

    if (which == 2 || which == 3)
    {
        acb_sub(t, b, a, prec);
        acb_poly_set_coeff_si(aa, 1, 1);

        /* prefer b-a nonnegative (either is correct) to avoid
           expensive operations in the hypergeometric series */
        if (arb_is_nonnegative(acb_realref(t)))
            _acb_hypgeom_2f1_transform_limit(res, aa, bb, cc, zz, which, prec);
        else
            _acb_hypgeom_2f1_transform_limit(res, bb, aa, cc, zz, which, prec);
    }
    else
    {
        acb_poly_set_coeff_si(aa, 1, 1);
        _acb_hypgeom_2f1_transform_limit(res, aa, bb, cc, zz, which, prec);
    }

    acb_poly_clear(aa);
    acb_poly_clear(bb);
    acb_poly_clear(cc);
    acb_poly_clear(zz);
    acb_clear(t);
}
示例#5
0
void
acb_hypgeom_u_1f1(acb_t res, const acb_t a, const acb_t b, const acb_t z, long prec)
{
    if (acb_is_int(b))
    {
        acb_poly_t aa, bb, zz;

        acb_poly_init(aa);
        acb_poly_init(bb);
        acb_poly_init(zz);

        acb_poly_set_acb(aa, a);
        acb_poly_set_coeff_acb(bb, 0, b);
        acb_poly_set_coeff_si(bb, 1, 1);
        acb_poly_set_acb(zz, z);

        acb_hypgeom_u_1f1_series(zz, aa, bb, zz, 1, prec);
        acb_poly_get_coeff_acb(res, zz, 0);

        acb_poly_clear(aa);
        acb_poly_clear(bb);
        acb_poly_clear(zz);
    }
    else
    {
        acb_t t, u, v;
        acb_struct aa[3];

        acb_init(t);
        acb_init(u);
        acb_init(v);
        acb_init(aa + 0);
        acb_init(aa + 1);
        acb_init(aa + 2);

        acb_set(aa, a);
        acb_set(aa + 1, b);
        acb_one(aa + 2);
        acb_hypgeom_pfq_direct(u, aa, 1, aa + 1, 2, z, -1, prec);
        acb_sub(aa, a, b, prec);
        acb_add_ui(aa, aa, 1, prec);
        acb_sub_ui(aa + 1, b, 2, prec);
        acb_neg(aa + 1, aa + 1);
        acb_hypgeom_pfq_direct(v, aa, 1, aa + 1, 2, z, -1, prec);

        acb_sub_ui(aa + 1, b, 1, prec);

        /* rgamma(a-b+1) * gamma(1-b) * u */
        acb_rgamma(t, aa, prec);
        acb_mul(u, u, t, prec);
        acb_neg(t, aa + 1);
        acb_gamma(t, t, prec);
        acb_mul(u, u, t, prec);

        /* rgamma(a) * gamma(b-1) * z^(1-b) * v */
        acb_rgamma(t, a, prec);
        acb_mul(v, v, t, prec);
        acb_gamma(t, aa + 1, prec);
        acb_mul(v, v, t, prec);
        acb_neg(t, aa + 1);
        acb_pow(t, z, t, prec);
        acb_mul(v, v, t, prec);

        acb_add(res, u, v, prec);

        acb_clear(t);
        acb_clear(u);
        acb_clear(v);
        acb_clear(aa + 0);
        acb_clear(aa + 1);
        acb_clear(aa + 2);
    }
}