Пример #1
0
void
acb_hypgeom_pfq_sum_bs_invz(acb_t s, acb_t t,
    acb_srcptr a, slong p, acb_srcptr b, slong q, const acb_t z, slong n, slong prec)
{
    acb_t u, v, w;

    if (n < 4)
    {
        acb_init(u);
        acb_inv(u, z, prec);
        acb_hypgeom_pfq_sum_forward(s, t, a, p, b, q, u, n, prec);
        acb_clear(u);
        return;
    }

    acb_init(u);
    acb_init(v);
    acb_init(w);

    bsplit(u, v, w, a, p, b, q, z, 0, n, prec, 1);

    acb_div(t, u, w, prec);
    acb_div(s, v, w, prec);

    acb_clear(u);
    acb_clear(v);
    acb_clear(w);
}
Пример #2
0
int main()
{
    slong iter;
    flint_rand_t state;

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

    flint_randinit(state);

    for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++)
    {
        acb_ptr a, b;
        acb_t z, s1, s2, t1, t2;
        slong i, p, q, n, prec1, prec2;

        p = n_randint(state, 5);
        q = n_randint(state, 5);
        n = n_randint(state, 300);
        prec1 = 2 + n_randint(state, 500);
        prec2 = 2 + n_randint(state, 500);

        acb_init(z);
        acb_init(s1);
        acb_init(s2);
        acb_init(t1);
        acb_init(t2);

        acb_randtest_special(z, state, 1 + n_randint(state, 500), 1 + n_randint(state, 100));
        acb_randtest_special(s1, state, 1 + n_randint(state, 500), 1 + n_randint(state, 100));
        acb_randtest_special(t1, state, 1 + n_randint(state, 500), 1 + n_randint(state, 100));
        acb_randtest_special(s2, state, 1 + n_randint(state, 500), 1 + n_randint(state, 100));
        acb_randtest_special(t2, state, 1 + n_randint(state, 500), 1 + n_randint(state, 100));

        a = _acb_vec_init(p);
        b = _acb_vec_init(q);

        for (i = 0; i < p; i++)
            acb_randtest(a + i, state, 1 + n_randint(state, 100), 1 + n_randint(state, 10));
        for (i = 0; i < q; i++)
            acb_randtest(b + i, state, 1 + n_randint(state, 100), 1 + n_randint(state, 10));

        acb_hypgeom_pfq_sum_forward(s1, t1, a, p, b, q, z, n, prec1);
        acb_hypgeom_pfq_sum_rs(s2, t2, a, p, b, q, z, n, prec2);

        if (!acb_overlaps(s1, s2) || !acb_overlaps(t1, t2))
        {
            flint_printf("FAIL: overlap\n\n");
            flint_printf("z = "); acb_print(a); flint_printf("\n\n");
            flint_printf("s1 = "); acb_print(s1); flint_printf("\n\n");
            flint_printf("s2 = "); acb_print(s2); flint_printf("\n\n");
            flint_printf("t1 = "); acb_print(t1); flint_printf("\n\n");
            flint_printf("t2 = "); acb_print(t2); flint_printf("\n\n");
            flint_abort();
        }

        _acb_vec_clear(a, p);
        _acb_vec_clear(b, q);

        acb_clear(z);
        acb_clear(s1);
        acb_clear(s2);
        acb_clear(t1);
        acb_clear(t2);
    }

    flint_randclear(state);
    flint_cleanup();
    flint_printf("PASS\n");
    return EXIT_SUCCESS;
}
Пример #3
0
void
acb_hypgeom_pfq_sum_fme(acb_t s, acb_t t,
    acb_srcptr a, slong p, acb_srcptr b, slong q,
    const acb_t z, slong n, slong prec)
{
    acb_poly_t A, B, C;
    acb_ptr ks, As, Bs, Cs;
    acb_t u, v;
    acb_ptr * tree;
    slong i, k, m, w;

    /* we compute to n-1 instead of n to avoid dividing by 0 in the
       denominator when computing a hypergeometric polynomial
       that terminates right before a pole */
    if (n > 4)
    {
        m = n_sqrt(n - 1) / 4;  /* tuning parameter */
        w = (n - 1) / FLINT_MAX(m, 1);
    }
    else
    {
        m = w = 0;
    }

    if (m < 1 || w < 1 || p > 3 || q > 3)
    {
        acb_hypgeom_pfq_sum_forward(s, t, a, p, b, q, z, n, prec);
        return;
    }

    acb_poly_init(A);
    acb_poly_init(B);
    acb_poly_init(C);

    acb_init(u);
    acb_init(v);

    ks = _acb_vec_init(w);
    As = _acb_vec_init(w);
    Bs = _acb_vec_init(w);
    Cs = _acb_vec_init(w);

    bsplit(A, B, C, a, p, b, q, z, 0, m, prec);

    for (i = 0; i < w; i++)
        acb_set_ui(ks + i, i * m);

    tree = _acb_poly_tree_alloc(w);
    _acb_poly_tree_build(tree, ks, w, prec);
    _acb_poly_evaluate_vec_fast_precomp(As, A->coeffs, A->length, tree, w, prec);
    _acb_poly_evaluate_vec_fast_precomp(Bs, B->coeffs, B->length, tree, w, prec);
    _acb_poly_evaluate_vec_fast_precomp(Cs, C->coeffs, C->length, tree, w, prec);
    _acb_poly_tree_free(tree, w);

    /* todo: use binary splitting here for improved numerical stability */
    for (i = 1; i < w; i++)
    {
        acb_mul(Cs, Cs, Bs + i, prec);
        acb_addmul(Cs, As, Cs + i, prec);
        acb_mul(As, As, As + i, prec);
        acb_mul(Bs, Bs, Bs + i, prec);
    }

    acb_div(s, Cs, Bs, prec);
    acb_div(t, As, Bs, prec);

    for (k = w * m; k < n && !acb_is_zero(t); k++)
    {
        acb_add(s, s, t, prec);

        if (p > 0)
        {
            acb_add_ui(u, a, k, prec);

            for (i = 1; i < p; i++)
            {
                acb_add_ui(v, a + i, k, prec);
                acb_mul(u, u, v, prec);
            }

            acb_mul(t, t, u, prec);
        }

        if (q > 0)
        {
            acb_add_ui(u, b, k, prec);

            for (i = 1; i < q; i++)
            {
                acb_add_ui(v, b + i, k, prec);
                acb_mul(u, u, v, prec);
            }

            acb_div(t, t, u, prec);
        }

        acb_mul(t, t, z, prec);
    }

    acb_clear(u);
    acb_clear(v);

    _acb_vec_clear(ks, w);
    _acb_vec_clear(As, w);
    _acb_vec_clear(Bs, w);
    _acb_vec_clear(Cs, w);

    acb_poly_clear(A);
    acb_poly_clear(B);
    acb_poly_clear(C);
}