Example #1
0
int main()
{
    slong iter;
    flint_rand_t state;

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

    flint_randinit(state);

    /* test aliasing of c and a */
    for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++)
    {
        acb_t a, b, c;
        slong prec;

        acb_init(a);
        acb_init(b);
        acb_init(c);

        acb_randtest(a, state, 1 + n_randint(state, 200), 10);
        acb_randtest(b, state, 1 + n_randint(state, 200), 10);
        acb_randtest(c, state, 1 + n_randint(state, 200), 10);

        prec = 2 + n_randint(state, 200);

        acb_div(c, a, b, prec);
        acb_div(a, a, b, prec);

        if (!acb_equal(a, c))
        {
            flint_printf("FAIL: aliasing c, a\n\n");
            flint_printf("a = "); acb_print(a); flint_printf("\n\n");
            flint_printf("b = "); acb_print(b); flint_printf("\n\n");
            flint_printf("c = "); acb_print(c); flint_printf("\n\n");
            abort();
        }

        acb_clear(a);
        acb_clear(b);
        acb_clear(c);
    }

    /* test aliasing of c and b */
    for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++)
    {
        acb_t a, b, c;
        slong prec;

        acb_init(a);
        acb_init(b);
        acb_init(c);

        acb_randtest(a, state, 1 + n_randint(state, 200), 10);
        acb_randtest(b, state, 1 + n_randint(state, 200), 10);
        acb_randtest(c, state, 1 + n_randint(state, 200), 10);

        prec = 2 + n_randint(state, 200);

        acb_div(c, a, b, prec);
        acb_div(b, a, b, prec);

        if (!acb_equal(b, c))
        {
            flint_printf("FAIL: aliasing c, b\n\n");
            flint_printf("a = "); acb_print(a); flint_printf("\n\n");
            flint_printf("b = "); acb_print(b); flint_printf("\n\n");
            flint_printf("c = "); acb_print(c); flint_printf("\n\n");
            abort();
        }

        acb_clear(a);
        acb_clear(b);
        acb_clear(c);
    }

    /* test aliasing a, a */
    for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++)
    {
        acb_t a, b, c, d;
        slong prec;

        acb_init(a);
        acb_init(b);
        acb_init(c);
        acb_init(d);

        acb_randtest(a, state, 1 + n_randint(state, 200), 10);
        acb_randtest(b, state, 1 + n_randint(state, 200), 10);
        acb_randtest(c, state, 1 + n_randint(state, 200), 10);

        prec = 2 + n_randint(state, 200);

        acb_set(b, a);
        acb_div(c, a, a, prec);
        acb_div(d, a, b, prec);

        if (!acb_overlaps(c, d))
        {
            flint_printf("FAIL: aliasing a, a\n\n");
            flint_printf("a = "); acb_print(a); flint_printf("\n\n");
            flint_printf("b = "); acb_print(b); flint_printf("\n\n");
            flint_printf("c = "); acb_print(c); flint_printf("\n\n");
            flint_printf("d = "); acb_print(d); flint_printf("\n\n");
            abort();
        }

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

    /* test aliasing a, a, a */
    for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++)
    {
        acb_t a, b, c;
        slong prec;

        acb_init(a);
        acb_init(b);
        acb_init(c);

        acb_randtest(a, state, 1 + n_randint(state, 200), 10);
        acb_randtest(b, state, 1 + n_randint(state, 200), 10);
        acb_randtest(c, state, 1 + n_randint(state, 200), 10);

        prec = 2 + n_randint(state, 200);

        acb_set(b, a);
        acb_div(c, a, b, prec);
        acb_div(a, a, a, prec);

        if (!acb_overlaps(a, c))
        {
            flint_printf("FAIL: aliasing a, a, a\n\n");
            flint_printf("a = "); acb_print(a); flint_printf("\n\n");
            flint_printf("b = "); acb_print(b); flint_printf("\n\n");
            flint_printf("c = "); acb_print(c); flint_printf("\n\n");
            abort();
        }

        acb_clear(a);
        acb_clear(b);
        acb_clear(c);
    }

    /* test (a+b)/c = a/c + b/c */
    for (iter = 0; iter < 100000 * arb_test_multiplier(); iter++)
    {
        acb_t a, b, c, d, e, f;

        acb_init(a);
        acb_init(b);
        acb_init(c);
        acb_init(d);
        acb_init(e);
        acb_init(f);

        acb_randtest(a, state, 1 + n_randint(state, 200), 10);
        acb_randtest(b, state, 1 + n_randint(state, 200), 10);
        acb_randtest(c, state, 1 + n_randint(state, 200), 10);

        acb_add(d, a, b, 2 + n_randint(state, 200));
        acb_div(e, d, c, 2 + n_randint(state, 200));

        acb_div(d, a, c, 2 + n_randint(state, 200));
        acb_div(f, b, c, 2 + n_randint(state, 200));
        acb_add(f, d, f, 2 + n_randint(state, 200));

        if (!acb_overlaps(e, f))
        {
            flint_printf("FAIL: (a+b)/c = a/c + b/c\n\n");
            flint_printf("a = "); acb_print(a); flint_printf("\n\n");
            flint_printf("b = "); acb_print(b); flint_printf("\n\n");
            flint_printf("c = "); acb_print(c); flint_printf("\n\n");
            flint_printf("e = "); acb_print(e); flint_printf("\n\n");
            flint_printf("f = "); acb_print(f); flint_printf("\n\n");
            abort();
        }

        acb_clear(a);
        acb_clear(b);
        acb_clear(c);
        acb_clear(d);
        acb_clear(e);
        acb_clear(f);
    }

    flint_randclear(state);
    flint_cleanup();
    flint_printf("PASS\n");
    return EXIT_SUCCESS;
}
Example #2
0
void
fmpz_poly_complex_roots_squarefree(const fmpz_poly_t poly,
                                   slong initial_prec,
                                   slong target_prec,
                                   slong print_digits)
{
    slong i, j, prec, deg, deg_deflated, isolated, maxiter, deflation;
    acb_poly_t cpoly, cpoly_deflated;
    fmpz_poly_t poly_deflated;
    acb_ptr roots, roots_deflated;
    int removed_zero;

    if (fmpz_poly_degree(poly) < 1)
        return;

    fmpz_poly_init(poly_deflated);
    acb_poly_init(cpoly);
    acb_poly_init(cpoly_deflated);

    /* try to write poly as poly_deflated(x^deflation), possibly multiplied by x */
    removed_zero = fmpz_is_zero(poly->coeffs);
    if (removed_zero)
        fmpz_poly_shift_right(poly_deflated, poly, 1);
    else
        fmpz_poly_set(poly_deflated, poly);
    deflation = fmpz_poly_deflation(poly_deflated);
    fmpz_poly_deflate(poly_deflated, poly_deflated, deflation);

    deg = fmpz_poly_degree(poly);
    deg_deflated = fmpz_poly_degree(poly_deflated);

    flint_printf("searching for %wd roots, %wd deflated\n", deg, deg_deflated);

    roots = _acb_vec_init(deg);
    roots_deflated = _acb_vec_init(deg_deflated);

    for (prec = initial_prec; ; prec *= 2)
    {
        acb_poly_set_fmpz_poly(cpoly_deflated, poly_deflated, prec);
        maxiter = FLINT_MIN(FLINT_MAX(deg_deflated, 32), prec);

        TIMEIT_ONCE_START
        flint_printf("prec=%wd: ", prec);
        isolated = acb_poly_find_roots(roots_deflated, cpoly_deflated,
                                       prec == initial_prec ? NULL : roots_deflated, maxiter, prec);
        flint_printf("%wd isolated roots | ", isolated);
        TIMEIT_ONCE_STOP

        if (isolated == deg_deflated)
        {
            if (!check_accuracy(roots_deflated, deg_deflated, target_prec))
                continue;

            if (deflation == 1)
            {
                _acb_vec_set(roots, roots_deflated, deg_deflated);
            }
            else  /* compute all nth roots */
            {
                acb_t w, w2;

                acb_init(w);
                acb_init(w2);

                acb_unit_root(w, deflation, prec);
                acb_unit_root(w2, 2 * deflation, prec);

                for (i = 0; i < deg_deflated; i++)
                {
                    if (arf_sgn(arb_midref(acb_realref(roots_deflated + i))) > 0)
                    {
                        acb_root_ui(roots + i * deflation,
                                    roots_deflated + i, deflation, prec);
                    }
                    else
                    {
                        acb_neg(roots + i * deflation, roots_deflated + i);
                        acb_root_ui(roots + i * deflation,
                                    roots + i * deflation, deflation, prec);
                        acb_mul(roots + i * deflation,
                                roots + i * deflation, w2, prec);
                    }

                    for (j = 1; j < deflation; j++)
                    {
                        acb_mul(roots + i * deflation + j,
                                roots + i * deflation + j - 1, w, prec);
                    }
                }

                acb_clear(w);
                acb_clear(w2);
            }

            /* by assumption that poly is squarefree, must be just one */
            if (removed_zero)
                acb_zero(roots + deg_deflated * deflation);

            if (!check_accuracy(roots, deg, target_prec))
                continue;

            acb_poly_set_fmpz_poly(cpoly, poly, prec);

            if (!acb_poly_validate_real_roots(roots, cpoly, prec))
                continue;

            for (i = 0; i < deg; i++)
            {
                if (arb_contains_zero(acb_imagref(roots + i)))
                    arb_zero(acb_imagref(roots + i));
            }

            flint_printf("done!\n");
            break;
        }
    }

    if (print_digits != 0)
    {
        _acb_vec_sort_pretty(roots, deg);

        for (i = 0; i < deg; i++)
        {
            acb_printn(roots + i, print_digits, 0);
            flint_printf("\n");
        }
    }

    fmpz_poly_clear(poly_deflated);
    acb_poly_clear(cpoly);
    acb_poly_clear(cpoly_deflated);
    _acb_vec_clear(roots, deg);
    _acb_vec_clear(roots_deflated, deg_deflated);
}
Example #3
0
int main()
{
    slong iter;
    flint_rand_t state;

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

    flint_randinit(state);

    for (iter = 0; iter < 10000; iter++)
    {
        acb_t a, b, a2, b2, z, U1, U2, t, u, M1, M2, am;
        acb_struct bm[2];
        ulong n1, n2;
        slong prec0, prec1, prec2;

        acb_init(a);
        acb_init(b);
        acb_init(a2);
        acb_init(b2);
        acb_init(z);
        acb_init(U1);
        acb_init(U2);
        acb_init(t);
        acb_init(u);
        acb_init(M1);
        acb_init(M2);
        acb_init(am);
        acb_init(bm);
        acb_init(bm + 1);

        if (n_randint(state, 4) == 0)
        {
            n1 = n_randint(state, 200);
            n2 = n_randint(state, 200);
            prec0 = 2 + n_randint(state, 1000);
            prec1 = 2 + n_randint(state, 1000);
            prec2 = 2 + n_randint(state, 1000);
        }
        else
        {
            n1 = n_randint(state, 40);
            n2 = n_randint(state, 40);
            prec0 = 2 + n_randint(state, 300);
            prec1 = 2 + n_randint(state, 300);
            prec2 = 2 + n_randint(state, 300);
        }

        acb_randtest_param(a, state, prec0, 1 + n_randint(state, 20));

        if (n_randint(state, 4) == 0)
            acb_add_ui(b, a, n_randint(state, 10), prec0);
        else
            acb_randtest_param(b, state, prec0, 1 + n_randint(state, 20));

        acb_randtest(z, state, prec0, 1 + n_randint(state, 20));

        /* Test Kummer's transformation */
        acb_sub(a2, a, b, prec0);
        acb_add_ui(a2, a2, 1, prec0);
        acb_sub_ui(b2, b, 2, prec0);
        acb_neg(b2, b2);

        acb_hypgeom_u_asymp(U1, a, b, z, n1, prec1);
        acb_hypgeom_u_asymp(U2, a2, b2, z, n2, prec2);

        if (!acb_overlaps(U1, U2))
        {
            flint_printf("FAIL (Kummer transformation)\n");
            flint_printf("iter = %wd\n", iter);
            flint_printf("a = "); acb_printd(a, 50); flint_printf("\n");
            flint_printf("b = "); acb_printd(b, 50); flint_printf("\n");
            flint_printf("z = "); acb_printd(z, 50); flint_printf("\n");
            flint_printf("n1 = %wd, n2 = %wd, prec1 = %wd, prec2 = %wd\n", n1, n2, prec1, prec2);
            flint_printf("U1 = "); acb_printd(U1, 100); flint_printf("\n");
            flint_printf("U2 = "); acb_printd(U2, 100); flint_printf("\n");
            abort();
        }

        /* Check contiguous relation
            (b-a-1)U(a,b-1,z) + z U(a,b+1,z) + (1-b-z) U(a,b,z) = 0 */
        acb_one(t);
        acb_sub(t, t, b, prec0);
        acb_sub(t, t, z, prec0);
        acb_mul(u, U1, t, prec1);

        acb_add_ui(b2, b, 1, prec0);
        acb_hypgeom_u_asymp(U2, a, b2, z, n2, prec2);
        acb_addmul(u, U2, z, prec1);

        acb_sub_ui(b2, b, 1, prec0);
        acb_hypgeom_u_asymp(U2, a, b2, z, n2, prec2);
        acb_sub(t, b, a, prec0);
        acb_sub_ui(t, t, 1, prec0);
        acb_mul(t, t, U2, prec0);
        acb_add(t, t, u, prec0);

        if (!acb_contains_zero(t))
        {
            flint_printf("FAIL (contiguous relation)\n");
            flint_printf("iter = %wd\n", iter);
            flint_printf("a = "); acb_printd(a, 50); flint_printf("\n");
            flint_printf("b = "); acb_printd(b, 50); flint_printf("\n");
            flint_printf("z = "); acb_printd(z, 50); flint_printf("\n");
            flint_printf("n1 = %wd, n2 = %wd, prec1 = %wd, prec2 = %wd\n", n1, n2, prec1, prec2);
            flint_printf("U1 = "); acb_printd(U1, 100); flint_printf("\n");
            flint_printf("t = "); acb_printd(t, 100); flint_printf("\n");
            abort();
        }

        /* Test U(a,b,z) = gamma(1-b)/gamma(a-b+1) M(a,b,z)
                         + gamma(b-1)/gamma(a) z^(1-b) M(a-b+1,2-b,z) */
        acb_set(am, a);
        acb_set(bm, b);
        acb_one(bm + 1);
        acb_hypgeom_pfq_direct(M1, am, 1, bm, 2, z, n2, prec2);

        acb_sub(am, a, b, prec2);
        acb_add_ui(am, am, 1, prec2);
        acb_sub_ui(bm, b, 2, prec2);
        acb_neg(bm, bm);
        acb_one(bm + 1);
        acb_hypgeom_pfq_direct(M2, am, 1, bm, 2, z, n2, prec2);

        acb_sub(am, a, b, prec2);
        acb_add_ui(am, am, 1, prec2);
        acb_rgamma(am, am, prec2);
        acb_mul(M1, M1, am, prec2);
        acb_sub_ui(am, b, 1, prec2);
        acb_neg(am, am);
        acb_gamma(am, am, prec2);
        acb_mul(M1, M1, am, prec2);

        acb_rgamma(am, a, prec2);
        acb_mul(M2, M2, am, prec2);
        acb_sub_ui(am, b, 1, prec2);
        acb_gamma(am, am, prec2);
        acb_mul(M2, M2, am, prec2);

        acb_sub_ui(am, b, 1, prec2);
        acb_neg(am, am);
        acb_pow(am, z, am, prec2);
        acb_mul(M2, M2, am, prec2);

        acb_add(U2, M1, M2, prec2);

        acb_pow(am, z, a, prec2);
        acb_mul(U2, U2, am, prec2);

        if (!acb_overlaps(U1, U2))
        {
            flint_printf("FAIL (U in terms of M)\n");
            flint_printf("iter = %wd\n", iter);
            flint_printf("a = "); acb_printd(a, 50); flint_printf("\n");
            flint_printf("b = "); acb_printd(b, 50); flint_printf("\n");
            flint_printf("z = "); acb_printd(z, 50); flint_printf("\n");
            flint_printf("n1 = %wd, n2 = %wd, prec1 = %wd, prec2 = %wd\n", n1, n2, prec1, prec2);
            flint_printf("U1 = "); acb_printd(U1, 100); flint_printf("\n");
            flint_printf("U2 = "); acb_printd(U2, 100); flint_printf("\n");
            abort();
        }

        /* Test special value: b = a+1 */
        acb_add_ui(b, a, 1, prec0);
        acb_hypgeom_u_asymp(U1, a, b, z, n1, prec1);
        acb_one(U2);

        if (!acb_overlaps(U1, U2))
        {
            flint_printf("FAIL (special value)\n");
            flint_printf("iter = %wd\n", iter);
            flint_printf("a = "); acb_printd(a, 50); flint_printf("\n");
            flint_printf("b = "); acb_printd(b, 50); flint_printf("\n");
            flint_printf("z = "); acb_printd(z, 50); flint_printf("\n");
            flint_printf("n1 = %wd, n2 = %wd, prec1 = %wd, prec2 = %wd\n", n1, n2, prec1, prec2);
            flint_printf("U1 = "); acb_printd(U1, 100); flint_printf("\n");
            flint_printf("U2 = "); acb_printd(U2, 100); flint_printf("\n");
            abort();
        }

        acb_clear(a);
        acb_clear(b);
        acb_clear(a2);
        acb_clear(b2);
        acb_clear(z);
        acb_clear(U1);
        acb_clear(U2);
        acb_clear(t);
        acb_clear(u);
        acb_clear(M1);
        acb_clear(M2);
        acb_clear(am);
        acb_clear(bm);
        acb_clear(bm + 1);
    }

    flint_randclear(state);
    flint_cleanup();
    flint_printf("PASS\n");
    return EXIT_SUCCESS;
}
Example #4
0
void
acb_hypgeom_2f1_transform_nolimit(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_t ba, ca, cb, cab, ac1, bc1, ab1, ba1, w, t, u, v, s;

    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_nolimit(res, a, b, c, z, 1, which, prec);
        acb_mul(res, res, t, prec);
        acb_clear(t);
        return;
    }

    acb_init(ba);
    acb_init(ca); acb_init(cb); acb_init(cab);
    acb_init(ac1); acb_init(bc1);
    acb_init(ab1); acb_init(ba1);
    acb_init(w); acb_init(t);
    acb_init(u); acb_init(v);
    acb_init(s);

    acb_add_si(s, z, -1, prec);   /* s = 1 - z */
    acb_neg(s, s);

    acb_sub(ba, b, a, prec);      /* ba = b - a */
    acb_sub(ca, c, a, prec);      /* ca = c - a */
    acb_sub(cb, c, b, prec);      /* cb = c - b */
    acb_sub(cab, ca, b, prec);    /* cab = c - a - b */

    acb_add_si(ac1, ca, -1, prec); acb_neg(ac1, ac1); /* ac1 = a - c + 1 */
    acb_add_si(bc1, cb, -1, prec); acb_neg(bc1, bc1); /* bc1 = b - c + 1 */
    acb_add_si(ab1, ba, -1, prec); acb_neg(ab1, ab1); /* ab1 = a - b + 1 */
    acb_add_si(ba1, ba, 1, prec);                     /* ba1 = b - a + 1 */

    /* t = left term, u = right term (DLMF 15.8.1 - 15.8.5) */
    if (which == 2)
    {
        acb_inv(w, z, prec);  /* w = 1/z */
        acb_hypgeom_2f1_direct(t, a, ac1, ab1, w, 1, prec);
        acb_hypgeom_2f1_direct(u, b, bc1, ba1, w, 1, prec);
    }
    else if (which == 3)
    {
        acb_inv(w, s, prec);  /* w = 1/(1-z) */
        acb_hypgeom_2f1_direct(t, a, cb, ab1, w, 1, prec);
        acb_hypgeom_2f1_direct(u, b, ca, ba1, w, 1, prec);
    }
    else if (which == 4)
    {
        acb_set(w, s);                  /* w = 1-z */
        acb_add(v, ac1, b, prec);       /* v = a+b-c+1 */
        acb_hypgeom_2f1_direct(t, a, b, v, w, 1, prec);
        acb_add_si(v, cab, 1, prec);    /* v = c-a-b+1 */
        acb_hypgeom_2f1_direct(u, ca, cb, v, w, 1, prec);
    }
    else if (which == 5)
    {
        acb_inv(w, z, prec);  /* w = 1-1/z */
        acb_neg(w, w);
        acb_add_si(w, w, 1, prec);
        acb_add(v, ac1, b, prec);       /* v = a+b-c+1 */
        acb_hypgeom_2f1_direct(t, a, ac1, v, w, 1, prec);
        acb_add_si(v, cab, 1, prec);    /* v = c-a-b+1 */
        acb_add_si(u, a, -1, prec);     /* u = 1-a */
        acb_neg(u, u);
        acb_hypgeom_2f1_direct(u, ca, u, v, w, 1, prec);
    }
    else
    {
        flint_printf("invalid transformation!\n");
        abort();
    }

    /* gamma factors */
    acb_rgamma(v, a, prec);
    acb_mul(u, u, v, prec);
    acb_rgamma(v, ca, prec);
    acb_mul(t, t, v, prec);

    acb_rgamma(v, b, prec);
    if (which == 2 || which == 3)
        acb_mul(t, t, v, prec);
    else
        acb_mul(u, u, v, prec);

    acb_rgamma(v, cb, prec);
    if (which == 2 || which == 3)
        acb_mul(u, u, v, prec);
    else
        acb_mul(t, t, v, prec);

    if (which == 2 || which == 3)
    {
        if (which == 2)
            acb_neg(s, z);  /* -z, otherwise 1-z since before */

        acb_neg(v, a);
        acb_pow(v, s, v, prec);
        acb_mul(t, t, v, prec);

        acb_neg(v, b);
        acb_pow(v, s, v, prec);
        acb_mul(u, u, v, prec);
    }
    else
    {
        acb_pow(v, s, cab, prec);
        acb_mul(u, u, v, prec);

        if (which == 5)
        {
            acb_neg(v, a);
            acb_pow(v, z, v, prec);
            acb_mul(t, t, v, prec);

            acb_neg(v, ca);
            acb_pow(v, z, v, prec);
            acb_mul(u, u, v, prec);
        }
    }

    acb_sub(t, t, u, prec);

    if (which == 2 || which == 3)
        acb_sin_pi(v, ba, prec);
    else
        acb_sin_pi(v, cab, prec);

    acb_div(t, t, v, prec);
    acb_const_pi(v, prec);
    acb_mul(t, t, v, prec);
    acb_set(res, t);

    acb_clear(ba);
    acb_clear(ca); acb_clear(cb); acb_clear(cab);
    acb_clear(ac1); acb_clear(bc1);
    acb_clear(ab1); acb_clear(ba1);
    acb_clear(w); acb_clear(t);
    acb_clear(u); acb_clear(v);
    acb_clear(s);
}
Example #5
0
void
acb_hypgeom_2f1_transform(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)
{
    if (which == 1)
    {
        acb_t t, u, v;

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

        acb_sub_ui(t, z, 1, prec); /* t = z-1 */
        acb_div(u, z, t, prec); /* u = z/(z-1) */
        acb_neg(t, t);
        acb_neg(v, a);
        acb_pow(t, t, v, prec); /* t = (1-z)^-a */
        acb_sub(v, c, b, prec); /* v = c-b */

        /* We cannot use regularized=1 directly, since if c is a nonnegative
           integer, the transformation formula reads (lhs) * 0 = (rhs) * 0. */
        acb_hypgeom_2f1_direct(u, a, v, c, u, 1, prec);

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

        acb_mul(res, u, t, prec);


        acb_clear(t);
        acb_clear(u);
        acb_clear(v);
    }
    else
    {
        acb_t d;
        acb_init(d);

        if (which == 2 || which == 3)
        {
            acb_sub(d, b, a, prec);
        }
        else
        {
            acb_sub(d, c, a, prec);
            acb_sub(d, d, b, prec);
        }

        if (acb_is_int(d))
            acb_hypgeom_2f1_transform_limit(res, a, b, c, z, regularized, which, prec);
        else
            acb_hypgeom_2f1_transform_nolimit(res, a, b, c, z, regularized, which, prec);

        acb_clear(d);
    }

    if (!acb_is_finite(res))
        acb_indeterminate(res);
}
Example #6
0
File: t-0f1.c Project: isuruf/arb
int main()
{
    long iter;
    flint_rand_t state;

    flint_printf("0f1....");
    fflush(stdout);

    flint_randinit(state);

    for (iter = 0; iter < 2000; iter++)
    {
        acb_t a, z, w1, w2;
        long prec1, prec2;
        int regularized, ebits;

        acb_init(a);
        acb_init(z);
        acb_init(w1);
        acb_init(w2);

        prec1 = 2 + n_randint(state, 700);
        prec2 = 2 + n_randint(state, 700);

        if (n_randint(state, 5) == 0)
            ebits = 100;
        else
            ebits = 10;

        acb_randtest_param(a, state, 1 + n_randint(state, 1000), 1 + n_randint(state, ebits));
        acb_randtest_param(z, state, 1 + n_randint(state, 1000), 1 + n_randint(state, ebits));
        acb_randtest(w1, state, 1 + n_randint(state, 1000), 1 + n_randint(state, ebits));
        acb_randtest(w2, state, 1 + n_randint(state, 1000), 1 + n_randint(state, ebits));
        regularized = n_randint(state, 2);

        switch (n_randint(state, 3))
        {
            case 0:
                acb_hypgeom_0f1_asymp(w1, a, z, regularized, prec1);
                break;
            case 1:
                acb_hypgeom_0f1_direct(w1, a, z, regularized, prec1);
                break;
            default:
                acb_hypgeom_0f1(w1, a, z, regularized, prec1);
        }

        switch (n_randint(state, 3))
        {
            case 0:
                acb_hypgeom_0f1_asymp(w2, a, z, regularized, prec2);
                break;
            case 1:
                acb_hypgeom_0f1_direct(w2, a, z, regularized, prec2);
                break;
            default:
                acb_hypgeom_0f1(w2, a, z, regularized, prec2);
        }

        if (!acb_overlaps(w1, w2))
        {
            flint_printf("FAIL: consistency\n\n");
            flint_printf("regularized = %d\n\n", regularized);
            flint_printf("a = "); acb_printd(a, 30); flint_printf("\n\n");
            flint_printf("z = "); acb_printd(z, 30); flint_printf("\n\n");
            flint_printf("w1 = "); acb_printd(w1, 30); flint_printf("\n\n");
            flint_printf("w2 = "); acb_printd(w2, 30); flint_printf("\n\n");
            abort();
        }

        acb_clear(a);
        acb_clear(z);
        acb_clear(w1);
        acb_clear(w2);
    }

    flint_randclear(state);
    flint_cleanup();
    flint_printf("PASS\n");
    return EXIT_SUCCESS;
}
Example #7
0
int main()
{
    long iter;
    flint_rand_t state;

    printf("lgamma....");
    fflush(stdout);

    flint_randinit(state);

    for (iter = 0; iter < 10000; iter++)
    {
        acb_t a, b, c;
        long prec1, prec2;

        prec1 = 2 + n_randint(state, 500);
        prec2 = prec1 + 30;

        acb_init(a);
        acb_init(b);
        acb_init(c);

        arb_randtest_precise(acb_realref(a), state, 1 + n_randint(state, 1000), 1 + n_randint(state, 10));
        arb_randtest_precise(acb_imagref(a), state, 1 + n_randint(state, 1000), 1 + n_randint(state, 10));

        acb_lgamma(b, a, prec1);

        if (n_randint(state, 4) == 0)
        {
            acb_randtest(c, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 10));
            acb_add(a, a, c, prec1);
            acb_sub(a, a, c, prec1);
        }

        acb_lgamma(c, a, prec2);

        if (!acb_overlaps(b, c))
        {
            printf("FAIL: overlap\n\n");
            printf("a = "); acb_print(a); printf("\n\n");
            printf("b = "); acb_print(b); printf("\n\n");
            printf("c = "); acb_print(c); printf("\n\n");
            abort();
        }

        /* check lgamma(z+1) = lgamma(z) + log(z) */
        acb_log(c, a, prec1);
        acb_add(b, b, c, prec1);

        acb_add_ui(c, a, 1, prec1);
        acb_lgamma(c, c, prec1);

        if (!acb_overlaps(b, c))
        {
            printf("FAIL: functional equation\n\n");
            printf("a = "); acb_print(a); printf("\n\n");
            printf("b = "); acb_print(b); printf("\n\n");
            printf("c = "); acb_print(c); printf("\n\n");
            abort();
        }

        acb_clear(a);
        acb_clear(b);
        acb_clear(c);
    }

    flint_randclear(state);
    flint_cleanup();
    printf("PASS\n");
    return EXIT_SUCCESS;
}
Example #8
0
/* note: z should be exact here */
void acb_lambertw_main(acb_t res, const acb_t z,
                const acb_t ez1, const fmpz_t k, int flags, slong prec)
{
    acb_t w, t, oldw, ew;
    mag_t err;
    slong i, wp, accuracy, ebits, kbits, mbits, wp_initial, extraprec;
    int have_ew;

    acb_init(t);
    acb_init(w);
    acb_init(oldw);
    acb_init(ew);
    mag_init(err);

    /* We need higher precision for large k, large exponents, or very close
       to the branch point at -1/e. todo: we should be recomputing
       ez1 to higher precision when close... */
    acb_get_mag(err, z);
    if (fmpz_is_zero(k) && mag_cmp_2exp_si(err, 0) < 0)
        ebits = 0;
    else
        ebits = fmpz_bits(MAG_EXPREF(err));

    if (fmpz_is_zero(k) || (fmpz_is_one(k) && arb_is_negative(acb_imagref(z)))
                        || (fmpz_equal_si(k, -1) && arb_is_nonnegative(acb_imagref(z))))
    {
        acb_get_mag(err, ez1);
        mbits = -MAG_EXP(err);
        mbits = FLINT_MAX(mbits, 0);
        mbits = FLINT_MIN(mbits, prec);
    }
    else
    {
        mbits = 0;
    }

    kbits = fmpz_bits(k);

    extraprec = FLINT_MAX(ebits, kbits);
    extraprec = FLINT_MAX(extraprec, mbits);

    wp = wp_initial = 40 + extraprec;

    accuracy = acb_lambertw_initial(w, z, ez1, k, wp_initial);
    mag_zero(arb_radref(acb_realref(w)));
    mag_zero(arb_radref(acb_imagref(w)));

    /* We should be able to compute e^w for the final certification
       during the Halley iteration. */
    have_ew = 0;

    for (i = 0; i < 5 + FLINT_BIT_COUNT(prec + extraprec); i++)
    {
        /* todo: should we restart? */
        if (!acb_is_finite(w))
            break;

        wp = FLINT_MIN(3 * accuracy, 1.1 * prec + 10);
        wp = FLINT_MAX(wp, 40);
        wp += extraprec;

        acb_set(oldw, w);
        acb_lambertw_halley_step(t, ew, z, w, wp);

        /* estimate the error (conservatively) */
        acb_sub(w, w, t, wp);
        acb_get_mag(err, w);
        acb_set(w, t);
        acb_add_error_mag(t, err);
        accuracy = acb_rel_accuracy_bits(t);

        if (accuracy > 2 * extraprec)
            accuracy *= 2.9;  /* less conservatively */

        accuracy = FLINT_MIN(accuracy, wp);
        accuracy = FLINT_MAX(accuracy, 0);

        if (accuracy > prec + extraprec)
        {
            /* e^w = e^oldw * e^(w-oldw) */
            acb_sub(t, w, oldw, wp);
            acb_exp(t, t, wp);
            acb_mul(ew, ew, t, wp);
            have_ew = 1;
            break;
        }

        mag_zero(arb_radref(acb_realref(w)));
        mag_zero(arb_radref(acb_imagref(w)));
    }

    wp = FLINT_MIN(3 * accuracy, 1.1 * prec + 10);
    wp = FLINT_MAX(wp, 40);
    wp += extraprec;

    if (acb_lambertw_check_branch(w, k, wp))
    {
        acb_t u, r, eu1;
        mag_t err, rad;

        acb_init(u);
        acb_init(r);
        acb_init(eu1);

        mag_init(err);
        mag_init(rad);

        if (have_ew)
            acb_set(t, ew);
        else
            acb_exp(t, w, wp);
        /* t = w e^w */
        acb_mul(t, t, w, wp);

        acb_sub(r, t, z, wp);

        /* Bound W' on the straight line path between t and z */
        acb_union(u, t, z, wp);

        arb_const_e(acb_realref(eu1), wp);
        arb_zero(acb_imagref(eu1));
        acb_mul(eu1, eu1, u, wp);
        acb_add_ui(eu1, eu1, 1, wp);

        if (acb_lambertw_branch_crossing(u, eu1, k))
        {
            mag_inf(err);
        }
        else
        {
            acb_lambertw_bound_deriv(err, u, eu1, k);
            acb_get_mag(rad, r);
            mag_mul(err, err, rad);
        }

        acb_add_error_mag(w, err);

        acb_set(res, w);

        acb_clear(u);
        acb_clear(r);
        acb_clear(eu1);
        mag_clear(err);
        mag_clear(rad);
    }
    else
    {
        acb_indeterminate(res);
    }

    acb_clear(t);
    acb_clear(w);
    acb_clear(oldw);
    acb_clear(ew);
    mag_clear(err);
}
Example #9
0
void
_acb_lambertw(acb_t res, const acb_t z, const acb_t ez1, const fmpz_t k, int flags, slong prec)
{
    slong goal, ebits, ebits2, ls, lt;
    const fmpz * expo;

    /* Estimated accuracy goal. */
    /* todo: account for exponent bits and bits in k. */
    goal = acb_rel_accuracy_bits(z);
    goal = FLINT_MAX(goal, 10);
    goal = FLINT_MIN(goal, prec);

    /* Handle tiny z directly. For k >= 2, |c_k| <= 4^k / 16. */
    if (fmpz_is_zero(k)
        && arf_cmpabs_2exp_si(arb_midref(acb_realref(z)), -goal / 2) < 0
        && arf_cmpabs_2exp_si(arb_midref(acb_imagref(z)), -goal / 2) < 0)
    {
        mag_t err;
        mag_init(err);
        acb_get_mag(err, z);
        mag_mul_2exp_si(err, err, 2);
        acb_set(res, z);
        acb_submul(res, res, res, prec);
        mag_geom_series(err, err, 3);
        mag_mul_2exp_si(err, err, -4);
        acb_add_error_mag(res, err);
        mag_clear(err);
        return;
    }

    if (arf_cmpabs(arb_midref(acb_realref(z)), arb_midref(acb_imagref(z))) >= 0)
        expo = ARF_EXPREF(arb_midref(acb_realref(z)));
    else
        expo = ARF_EXPREF(arb_midref(acb_imagref(z)));

    ebits = fmpz_bits(expo);

    /* ebits ~= log2(|log(z) + 2 pi i k|) */
    /* ebits2 ~= log2(log(log(z))) */
    ebits = FLINT_MAX(ebits, fmpz_bits(k));
    ebits = FLINT_MAX(ebits, 1) - 1;
    ebits2 = FLINT_BIT_COUNT(ebits);
    ebits2 = FLINT_MAX(ebits2, 1) - 1;

    /* We gain accuracy from the exponent when W ~ log - log log */
    if (fmpz_sgn(expo) > 0 || (fmpz_sgn(expo) < 0 && !fmpz_is_zero(k)))
    {
        goal += ebits - ebits2;
        goal = FLINT_MAX(goal, 10);
        goal = FLINT_MIN(goal, prec);

        /* The asymptotic series with truncation L, M gives us about 
           t - max(2+lt+L*(2+ls), M*(2+lt)) bits of accuracy where
           ls = -ebits, lt = ebits2 - ebits. */
        ls = 2 - ebits;
        lt = 2 + ebits2 - ebits;

        if (ebits - FLINT_MAX(lt + 1*ls, 1*lt) > goal)
        {
            acb_lambertw_asymp(res, z, k, 1, 1, goal);
            acb_set_round(res, res, prec);
            return;
        }
        else if (ebits - FLINT_MAX(lt + 3*ls, 5*lt) > goal)
        {
            acb_lambertw_asymp(res, z, k, 3, 5, goal);
            acb_set_round(res, res, prec);
            return;
        }
    }

    /* Extremely close to the branch point at -1/e, use the series expansion directly. */
    if (acb_lambertw_try_near_branch_point(res, z, ez1, k, flags, goal))
    {
        acb_set_round(res, res, prec);
        return;
    }

    /* compute union of both sides */
    if (acb_lambertw_branch_crossing(z, ez1, k))
    {
        acb_t za, zb, eza1, ezb1;
        fmpz_t kk;

        acb_init(za);
        acb_init(zb);
        acb_init(eza1);
        acb_init(ezb1);
        fmpz_init(kk);

        fmpz_neg(kk, k);

        acb_set(za, z);
        acb_conj(zb, z);
        arb_nonnegative_part(acb_imagref(za), acb_imagref(za));
        arb_nonnegative_part(acb_imagref(zb), acb_imagref(zb));

        acb_set(eza1, ez1);
        acb_conj(ezb1, ez1);
        arb_nonnegative_part(acb_imagref(eza1), acb_imagref(eza1));
        arb_nonnegative_part(acb_imagref(ezb1), acb_imagref(ezb1));

        /* Check series expansion again, because now there is no crossing. */
        if (!acb_lambertw_try_near_branch_point(res, za, eza1, k, flags, goal))
            acb_lambertw_cleared_cut_fix_small(za, za, eza1, k, flags, goal);

        if (!acb_lambertw_try_near_branch_point(res, zb, ezb1, kk, flags, goal))
            acb_lambertw_cleared_cut_fix_small(zb, zb, ezb1, kk, flags, goal);

        acb_conj(zb, zb);
        acb_union(res, za, zb, prec);

        acb_clear(za);
        acb_clear(zb);
        acb_clear(eza1);
        acb_clear(ezb1);
        fmpz_clear(kk);
    }
    else
    {
        acb_lambertw_cleared_cut_fix_small(res, z, ez1, k, flags, goal);
        acb_set_round(res, res, prec);
    }
}
Example #10
0
void
acb_hypgeom_legendre_q(acb_t res, const acb_t n, const acb_t m,
    const acb_t z, int type, slong prec)
{
    if (type == 0)
    {
        /* http://functions.wolfram.com/07.11.26.0033.01 */
        /* todo: simplify the gamma quotients and the sqrt pi factor... */
        acb_t a, b, c, z2, mn, nm, t, u;

        acb_init(a);
        acb_init(b);
        acb_init(c);
        acb_init(z2);
        acb_init(mn);
        acb_init(nm);
        acb_init(t);
        acb_init(u);

        acb_add(mn, m, n, prec); /* mn = m + n */
        acb_sub(nm, n, m, prec); /* nm = n - m */
        acb_mul(z2, z, z, prec); /* z2 = z^2 */

        /* t = 2F1((1-m-n)/2, (n-m)/2+1, 3/2, z^2) */
        acb_sub_ui(a, mn, 1, prec);
        acb_neg(a, a);
        acb_mul_2exp_si(a, a, -1);
        acb_mul_2exp_si(b, nm, -1);
        acb_add_ui(b, b, 1, prec);
        acb_set_ui(c, 3);
        acb_mul_2exp_si(c, c, -1);
        acb_hypgeom_2f1(t, a, b, c, z2, 0, prec);

        /* u = 2F1(-(m+n)/2, (n-m+1)/2, 1/2, z^2) */
        acb_neg(a, mn);
        acb_mul_2exp_si(a, a, -1);
        acb_add_ui(b, nm, 1, prec);
        acb_mul_2exp_si(b, b, -1);
        acb_one(c);
        acb_mul_2exp_si(c, c, -1);
        acb_hypgeom_2f1(u, a, b, c, z2, 0, prec);

        /* a = cospi((m+n)/2) gamma((m+n)/2+1) rgamma((n-m+1)/2) z */
        /* b = sinpi((m+n)/2) gamma((m+n+1)/2) rgamma((n-m)/2+1) / 2 */
        acb_mul_2exp_si(a, mn, -1);
        acb_sin_cos_pi(b, a, a, prec);

        acb_mul_2exp_si(c, mn, -1);
        acb_add_ui(c, c, 1, prec);
        acb_gamma(c, c, prec);
        acb_mul(a, a, c, prec);
        acb_add_ui(c, nm, 1, prec);
        acb_mul_2exp_si(c, c, -1);
        acb_rgamma(c, c, prec);
        acb_mul(a, a, c, prec);
        acb_mul(a, a, z, prec);

        acb_add_ui(c, mn, 1, prec);
        acb_mul_2exp_si(c, c, -1);
        acb_gamma(c, c, prec);
        acb_mul(b, b, c, prec);
        acb_mul_2exp_si(c, nm, -1);
        acb_add_ui(c, c, 1, prec);
        acb_rgamma(c, c, prec);
        acb_mul(b, b, c, prec);
        acb_mul_2exp_si(b, b, -1);

        /* at - bu */
        acb_mul(t, t, a, prec);
        acb_mul(u, u, b, prec);
        acb_sub(t, t, u, prec);

        /* prefactor sqrt(pi) 2^m (1-z^2)^(-m/2) */
        if (!acb_is_zero(m))
        {
            acb_sub_ui(u, z2, 1, prec);
            acb_neg(u, u);
            acb_neg(c, m);
            acb_mul_2exp_si(c, c, -1);
            acb_pow(u, u, c, prec);
            acb_set_ui(c, 2);
            acb_pow(c, c, m, prec);
            acb_mul(u, u, c, prec);
            acb_mul(t, t, u, prec);
        }

        arb_const_sqrt_pi(acb_realref(u), prec);
        acb_mul_arb(t, t, acb_realref(u), prec);

        acb_set(res, t);

        acb_clear(a);
        acb_clear(b);
        acb_clear(c);
        acb_clear(z2);
        acb_clear(mn);
        acb_clear(nm);
        acb_clear(t);
        acb_clear(u);
    }
    else if (type == 1)
    {
        if ((arf_cmpabs_2exp_si(arb_midref(acb_realref(z)), -2) < 0 &&
             arf_cmpabs_2exp_si(arb_midref(acb_imagref(z)), -2) < 0) ||
            !_acb_hypgeom_legendre_q_single_valid(z))
        {
            _acb_hypgeom_legendre_q_double(res, n, m, z, prec);
        }
        else
        {
            _acb_hypgeom_legendre_q_single(res, n, m, z, prec);
        }
    }
    else
    {
        flint_printf("unsupported 'type' %d for legendre q\n", type);
        abort();
    }
}
Example #11
0
void
_acb_hypgeom_legendre_q_double(acb_t res, const acb_t n, const acb_t m,
    const acb_t z, slong prec)
{
    acb_t t, u, v;

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

    if (acb_is_int(m))
    {
        acb_sub_ui(t, z, 1, prec);
        acb_mul_2exp_si(u, m, -1);
        acb_pow(v, t, u, prec);
        acb_neg(t, t);
        acb_neg(u, u);
        acb_pow(t, t, u, prec);
        acb_mul(t, t, v, prec);

        acb_hypgeom_legendre_q(u, n, m, z, 0, prec);
        acb_mul(t, t, u, prec);

        acb_mul_2exp_si(u, m, -1);
        if (!acb_is_int(u))
            acb_neg(t, t);

        acb_sub_ui(u, z, 1, prec);
        acb_sqrt(u, u, prec);
        acb_sub_ui(v, z, 1, prec);
        acb_neg(v, v);
        acb_rsqrt(v, v, prec);
        acb_mul(u, u, v, prec);
        acb_hypgeom_legendre_p(v, n, m, z, 1, prec);
        acb_mul(u, u, v, prec);
        acb_const_pi(v, prec);
        acb_mul(u, u, v, prec);
        acb_mul_2exp_si(u, u, -1);

        acb_sub(res, t, u, prec);
    }
    else
    {
        acb_sub(t, n, m, prec);
        acb_add_ui(t, t, 1, prec);
        acb_mul_2exp_si(u, m, 1);
        acb_rising(t, t, u, prec);
        acb_neg(u, m);
        acb_hypgeom_legendre_p(u, n, u, z, 1, prec);
        acb_mul(t, t, u, prec);

        acb_hypgeom_legendre_p(u, n, m, z, 1, prec);
        acb_sub(t, u, t, prec);

        acb_exp_pi_i(u, m, prec);
        acb_mul(t, t, u, prec);

        acb_sin_pi(u, m, prec);
        acb_div(t, t, u, prec);
        acb_const_pi(u, prec);
        acb_mul(t, t, u, prec);
        acb_mul_2exp_si(t, t, -1);

        acb_set(res, t);
    }

    acb_clear(t);
    acb_clear(u);
    acb_clear(v);
}
Example #12
0
void
_acb_hypgeom_legendre_q_single(acb_t res, const acb_t n, const acb_t m,
    const acb_t z, slong prec)
{
    acb_t a, b, c, z2, t, u;

    acb_init(a);
    acb_init(b);
    acb_init(c);
    acb_init(z2);
    acb_init(t);
    acb_init(u);

    /* invalid in (-1,0) */
    if (!_acb_hypgeom_legendre_q_single_valid(z))
    {
        acb_indeterminate(res);
        return;
    }

    acb_pow_si(z2, z, -2, prec); /* z2 = 1/z^2 */

    /* t = 2F1r((m+n+1)/2, (m+n)/2+1, n+3/2, 1/z^2) */
    acb_add(b, m, n, prec);
    acb_add_ui(a, b, 1, prec);
    acb_mul_2exp_si(a, a, -1);
    acb_mul_2exp_si(b, b, -1);
    acb_add_ui(b, b, 1, prec);
    acb_set_ui(c, 3);
    acb_mul_2exp_si(c, c, -1);
    acb_add(c, c, n, prec);
    acb_hypgeom_2f1(t, a, b, c, z2, 1, prec);

    /* prefactor sqrt(pi) 2^-n (z+1)^(m/2) (z-1)^(m/2) exp(i pi m) */
    /*           (1/2) gamma(m+n+1) z^(-m-n-1) */
    if (!acb_is_zero(m))
    {
        acb_add_ui(z2, z, 1, prec);
        acb_mul_2exp_si(c, m, -1);
        acb_pow(z2, z2, c, prec);
        acb_mul(t, t, z2, prec);

        acb_sub_ui(z2, z, 1, prec);
        acb_mul_2exp_si(c, m, -1);
        acb_pow(z2, z2, c, prec);
        acb_mul(t, t, z2, prec);

        acb_exp_pi_i(z2, m, prec);
        acb_mul(t, t, z2, prec);
    }

    acb_set_ui(z2, 2);
    acb_neg(c, n);
    acb_pow(z2, z2, c, prec);
    acb_mul(t, t, z2, prec);

    acb_add(c, m, n, prec);
    acb_add_ui(c, c, 1, prec);
    acb_gamma(z2, c, prec);
    acb_mul(t, t, z2, prec);

    acb_neg(c, c);
    acb_pow(z2, z, c, prec);
    acb_mul(t, t, z2, prec);

    acb_mul_2exp_si(t, t, -1);

    arb_const_sqrt_pi(acb_realref(u), prec);
    acb_mul_arb(t, t, acb_realref(u), prec);

    acb_set(res, t);

    acb_clear(a);
    acb_clear(b);
    acb_clear(c);
    acb_clear(z2);
    acb_clear(t);
    acb_clear(u);
}
Example #13
0
int main()
{
    slong iter;
    flint_rand_t state;

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

    flint_randinit(state);

    for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++)
    {
        acb_poly_t A;
        acb_poly_t B;
        acb_poly_t C;
        acb_t t;
        acb_ptr roots;
        slong i, deg, isolated;
        slong prec = 10 + n_randint(state, 400);

        acb_init(t);
        acb_poly_init(A);
        acb_poly_init(B);
        acb_poly_init(C);

        do {
            acb_poly_randtest(A, state, 2 + n_randint(state, 15), prec, 5);
        } while (A->length == 0);
        deg = A->length - 1;

        roots = _acb_vec_init(deg);

        isolated = acb_poly_find_roots(roots, A, NULL, 0, prec);

        if (isolated == deg)
        {
            acb_poly_fit_length(B, 1);
            acb_set(B->coeffs, A->coeffs + deg);
            _acb_poly_set_length(B, 1);

            for (i = 0; i < deg; i++)
            {
                acb_poly_fit_length(C, 2);
                acb_one(C->coeffs + 1);
                acb_neg(C->coeffs + 0, roots + i);
                _acb_poly_set_length(C, 2);
                acb_poly_mul(B, B, C, prec);
            }

            if (!acb_poly_contains(B, A))
            {
                flint_printf("FAIL: product does not equal polynomial\n");
                acb_poly_printd(A, 15); flint_printf("\n\n");
                acb_poly_printd(B, 15); flint_printf("\n\n");
                flint_abort();
            }
        }

        for (i = 0; i < isolated; i++)
        {
            acb_poly_evaluate(t, A, roots + i, prec);
            if (!acb_contains_zero(t))
            {
                flint_printf("FAIL: poly(root) does not contain zero\n");
                acb_poly_printd(A, 15); flint_printf("\n\n");
                acb_printd(roots + i, 15); flint_printf("\n\n");
                acb_printd(t, 15); flint_printf("\n\n");
                flint_abort();
            }
        }

        _acb_vec_clear(roots, deg);

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

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

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

    flint_randinit(state);

    /* check test values */
    for (iter = 0; iter < 100; iter++)
    {
        slong i;

        acb_t z, tau, p1, p2;

        acb_init(z);
        acb_init(tau);
        acb_init(p1);
        acb_init(p2);

        for (i = 0; i < NUM_TESTS; i++)
        {
            acb_set_dddd(z, testdata[i][0], 0.0, testdata[i][1], 0.0);
            acb_set_dddd(tau, testdata[i][2], 0.0, testdata[i][3], 0.0);
            acb_set_dddd(p2, testdata[i][4], EPS, testdata[i][5], EPS);

            acb_modular_elliptic_p(p1, z, tau, 2 + n_randint(state, 1000));

            if (!acb_overlaps(p1, p2))
            {
                flint_printf("FAIL (test value)\n");
                flint_printf("tau = "); acb_printd(tau, 15); flint_printf("\n\n");
                flint_printf("z = "); acb_printd(z, 15); flint_printf("\n\n");
                flint_printf("p1 = "); acb_printd(p1, 15); flint_printf("\n\n");
                flint_printf("p2 = "); acb_printd(p2, 15); flint_printf("\n\n");
                abort();
            }
        }

        acb_clear(z);
        acb_clear(tau);
        acb_clear(p1);
        acb_clear(p2);
    }

    /* Test periods */
    for (iter = 0; iter < 2000; iter++)
    {
        acb_t tau, z1, z2, p1, p2;
        slong m, n, e0, prec0, prec1, prec2;

        acb_init(tau);
        acb_init(z1);
        acb_init(z2);
        acb_init(p1);
        acb_init(p2);

        e0 = 1 + n_randint(state, 10);
        prec0 = 2 + n_randint(state, 1000);
        prec1 = 2 + n_randint(state, 1000);
        prec2 = 2 + n_randint(state, 1000);

        acb_randtest(tau, state, prec0, e0);
        if (arf_sgn(arb_midref(acb_imagref(tau))) < 0)
            acb_neg(tau, tau);

        acb_randtest(z1, state, prec0, e0);
        acb_randtest(p1, state, prec0, e0);
        acb_randtest(p2, state, prec0, e0);

        /* z2 = z1 + m + n*tau */
        m = n_randint(state, 10);
        n = n_randint(state, 10);
        acb_add_ui(z2, z1, m, prec0);
        acb_addmul_ui(z2, tau, n, prec0);

        acb_modular_elliptic_p(p1, z1, tau, prec1);
        acb_modular_elliptic_p(p2, z2, tau, prec2);

        if (!acb_overlaps(p1, p2))
        {
            flint_printf("FAIL (overlap)\n");
            flint_printf("tau = "); acb_printd(tau, 15); flint_printf("\n\n");
            flint_printf("z1 = "); acb_printd(z1, 15); flint_printf("\n\n");
            flint_printf("z2 = "); acb_printd(z2, 15); flint_printf("\n\n");
            flint_printf("p1 = "); acb_printd(p1, 15); flint_printf("\n\n");
            flint_printf("p2 = "); acb_printd(p2, 15); flint_printf("\n\n");
            abort();
        }

        acb_modular_elliptic_p(z1, z1, tau, prec1);

        if (!acb_overlaps(z1, p1))
        {
            flint_printf("FAIL (aliasing)\n");
            flint_printf("tau = "); acb_printd(tau, 15); flint_printf("\n\n");
            flint_printf("z1 = "); acb_printd(z1, 15); flint_printf("\n\n");
            flint_printf("p1 = "); acb_printd(p1, 15); flint_printf("\n\n");
            abort();
        }

        acb_clear(tau);
        acb_clear(z1);
        acb_clear(z2);
        acb_clear(p1);
        acb_clear(p2);
    }

    flint_randclear(state);
    flint_cleanup();
    flint_printf("PASS\n");
    return EXIT_SUCCESS;
}
Example #15
0
int main()
{
    long iter;
    flint_rand_t state;

    printf("delta....");
    fflush(stdout);

    flint_randinit(state);

    for (iter = 0; iter < 10000; iter++)
    {
        acb_t tau, z1, z2;
        long e0, prec0, prec1, prec2;

        acb_init(tau);
        acb_init(z1);
        acb_init(z2);

        e0 = 1 + n_randint(state, 10);
        prec0 = 2 + n_randint(state, 1000);
        prec1 = 2 + n_randint(state, 1000);
        prec2 = 2 + n_randint(state, 1000);

        acb_randtest(tau, state, prec0, e0);
        acb_randtest(z1, state, prec0, e0);
        acb_randtest(z2, state, prec0, e0);

        /* compare with eta */
        acb_modular_delta(z1, tau, prec1);

        acb_modular_eta(z2, tau, prec2);
        acb_pow_ui(z2, z2, 24, prec2);

        if (!acb_overlaps(z1, z2))
        {
            printf("FAIL (overlap)\n");
            printf("tau = "); acb_printd(tau, 15); printf("\n\n");
            printf("z1 = "); acb_printd(z1, 15); printf("\n\n");
            printf("z2 = "); acb_printd(z2, 15); printf("\n\n");
            abort();
        }

        acb_modular_delta(tau, tau, prec1);

        if (!acb_overlaps(z1, tau))
        {
            printf("FAIL (aliasing)\n");
            printf("tau = "); acb_printd(tau, 15); printf("\n\n");
            printf("z1 = "); acb_printd(z1, 15); printf("\n\n");
            printf("z2 = "); acb_printd(z2, 15); printf("\n\n");
            abort();
        }

        acb_clear(tau);
        acb_clear(z1);
        acb_clear(z2);
    }

    flint_randclear(state);
    flint_cleanup();
    printf("PASS\n");
    return EXIT_SUCCESS;
}
Example #16
0
void
acb_lambertw_middle(acb_t res, const acb_t z, slong prec)
{
    fmpz_t k;

    if (acb_contains_zero(z))
    {
        acb_indeterminate(res);
        return;
    }

    fmpz_init(k);
    fmpz_set_si(k, -1);

    if (arb_is_positive(acb_imagref(z)))
    {
        acb_lambertw(res, z, k, 0, prec);
    }
    else if (arb_is_negative(acb_imagref(z)))
    {
        acb_conj(res, z);
        acb_lambertw(res, res, k, 0, prec);
        acb_conj(res, res);
    }
    else if (arb_is_negative(acb_realref(z)))
    {
        if (arb_is_nonnegative(acb_imagref(z)))
        {
            acb_lambertw(res, z, k, 0, prec);
        }
        else if (arb_is_negative(acb_imagref(z)))
        {
            acb_conj(res, z);
            acb_lambertw(res, res, k, 0, prec);
            acb_conj(res, res);
        }
        else
        {
            acb_t za, zb;
            acb_init(za);
            acb_init(zb);
            acb_set(za, z);
            acb_conj(zb, z);
            arb_nonnegative_part(acb_imagref(za), acb_imagref(za));
            arb_nonnegative_part(acb_imagref(zb), acb_imagref(zb));
            acb_lambertw(za, za, k, 0, prec);
            acb_lambertw(zb, zb, k, 0, prec);
            acb_conj(zb, zb);
            acb_union(res, za, zb, prec);
            acb_clear(za);
            acb_clear(zb);
        }
    }
    else /* re is positive */
    {
        if (arb_is_positive(acb_imagref(z)))
        {
            acb_lambertw(res, z, k, 0, prec);
        }
        else if (arb_is_nonpositive(acb_imagref(z)))
        {
            acb_conj(res, z);
            acb_lambertw(res, res, k, 0, prec);
            acb_conj(res, res);
        }
        else
        {
            acb_t za, zb;
            acb_init(za);
            acb_init(zb);
            acb_set(za, z);
            acb_conj(zb, z);
            arb_nonnegative_part(acb_imagref(za), acb_imagref(za));
            arb_nonnegative_part(acb_imagref(zb), acb_imagref(zb));
            acb_lambertw(za, za, k, 0, prec);
            acb_lambertw(zb, zb, k, 0, prec);
            acb_conj(zb, zb);
            acb_union(res, za, zb, prec);
            acb_clear(za);
            acb_clear(zb);
        }
    }

    fmpz_clear(k);
}
Example #17
0
int main()
{
    long iter;
    flint_rand_t state;

    printf("det....");
    fflush(stdout);

    flint_randinit(state);

    for (iter = 0; iter < 10000; iter++)
    {
        fmpq_mat_t Q;
        fmpq_t Qdet;
        acb_mat_t A;
        acb_t Adet, imagunit;
        long n, qbits, prec;
        int imaginary;

        n = n_randint(state, 8);
        qbits = 1 + n_randint(state, 100);
        prec = 2 + n_randint(state, 200);
        imaginary = n_randint(state, 2);

        fmpq_mat_init(Q, n, n);
        fmpq_init(Qdet);

        acb_mat_init(A, n, n);
        acb_init(Adet);
        acb_init(imagunit);

        fmpq_mat_randtest(Q, state, qbits);
        fmpq_mat_det(Qdet, Q);

        acb_mat_set_fmpq_mat(A, Q, prec);

        if (imaginary)
        {
            acb_onei(imagunit);
            acb_mat_scalar_mul_acb(A, A, imagunit, prec);
        }

        acb_mat_det(Adet, A, prec);

        if (imaginary)
        {
            acb_onei(imagunit);
            acb_inv(imagunit, imagunit, prec);
            acb_pow_ui(imagunit, imagunit, n, prec);
            acb_mul(Adet, Adet, imagunit, prec);
        }

        if (!acb_contains_fmpq(Adet, Qdet))
        {
            printf("FAIL (containment, iter = %ld)\n", iter);
            printf("n = %ld, prec = %ld\n", n, prec);
            printf("\n");

            printf("Q = \n"); fmpq_mat_print(Q); printf("\n\n");
            printf("Qdet = \n"); fmpq_print(Qdet); printf("\n\n");

            printf("A = \n"); acb_mat_printd(A, 15); printf("\n\n");
            printf("Adet = \n"); acb_printd(Adet, 15); printf("\n\n");
            printf("Adet = \n"); acb_print(Adet); printf("\n\n");

            abort();
        }

        fmpq_mat_clear(Q);
        fmpq_clear(Qdet);
        acb_mat_clear(A);
        acb_clear(Adet);
        acb_clear(imagunit);
    }

    flint_randclear(state);
    flint_cleanup();
    printf("PASS\n");
    return EXIT_SUCCESS;
}
Example #18
0
static void
bsplit(acb_t A1, acb_t B1, acb_t C1,
        acb_srcptr a, slong p,
        acb_srcptr b, slong q,
        const acb_t z,
        slong aa,
        slong bb,
        slong prec,
        int invz)
{
    if (bb - aa == 1)
    {
        slong i;

        if (p == 0)
        {
            if (invz)
                acb_one(A1);
            else
                acb_set(A1, z);
        }
        else
        {
            acb_add_ui(A1, a, aa, prec);

            for (i = 1; i < p; i++)
            {
                acb_add_ui(B1, a + i, aa, prec);
                acb_mul(A1, A1, B1, prec);
            }

            if (!invz)
                acb_mul(A1, A1, z, prec);
        }

        if (q == 0)
        {
            if (invz)
                acb_set(C1, z);
            else
                acb_one(C1);
        }
        else
        {
            acb_add_ui(C1, b, aa, prec);

            for (i = 1; i < q; i++)
            {
                acb_add_ui(B1, b + i, aa, prec);
                acb_mul(C1, C1, B1, prec);
            }

            if (invz)
                acb_mul(C1, C1, z, prec);
        }

        /* acb_set(B1, C1);   but we skip this */
    }
    else
    {
        slong m;

        acb_t A2, B2, C2;

        acb_init(A2);
        acb_init(B2);
        acb_init(C2);

        m = aa + (bb - aa) / 2;

        bsplit(A1, B1, C1, a, p, b, q, z, aa, m, prec, invz);
        bsplit(A2, B2, C2, a, p, b, q, z, m, bb, prec, invz);

        if (bb - m == 1)  /* B2 = C2 */
        {
            if (m - aa == 1)
                acb_add(B2, A1, C1, prec);
            else
                acb_add(B2, A1, B1, prec);

            acb_mul(B1, B2, C2, prec);
        }
        else
        {
            if (m - aa == 1)
                acb_mul(B1, C1, C2, prec);
            else
                acb_mul(B1, B1, C2, prec);

            acb_addmul(B1, A1, B2, prec);
        }

        acb_mul(A1, A1, A2, prec);
        acb_mul(C1, C1, C2, prec);

        acb_clear(A2);
        acb_clear(B2);
        acb_clear(C2);
    }
}
Example #19
0
int main()
{
    slong iter;
    flint_rand_t state;

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

    flint_randinit(state);

    /* test self-consistency */
    for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++)
    {
        acb_t s, s2;
        dirichlet_group_t G;
        dirichlet_char_t chi;
        acb_ptr vec1, vec2;
        slong len1, len2;
        slong prec1, prec2;
        ulong q, k;
        slong i;

        len1 = n_randint(state, 6);
        len2 = n_randint(state, 6);
        prec1 = 2 + n_randint(state, 100);
        prec2 = 2 + n_randint(state, 100);

        do {
            q = 1 + n_randint(state, 30);
        } while (q % 4 == 2);

        dirichlet_group_init(G, q);
        dirichlet_char_init(chi, G);

        do {
            k = n_randint(state, n_euler_phi(q));
            dirichlet_char_index(chi, G, k);
        } while (dirichlet_conductor_char(G, chi) != q);

        acb_init(s);
        acb_init(s2);
        vec1 = _acb_vec_init(len1);
        vec2 = _acb_vec_init(len2);

        acb_randtest(s, state, 2 + n_randint(state, 200), 2);
        acb_randtest(s2, state, 2 + n_randint(state, 200), 2);
        acb_sub(s2, s2, s2, 200);
        acb_add(s2, s, s2, 200);

        acb_dirichlet_hardy_z(vec1, s, G, chi, len1, prec1);
        acb_dirichlet_hardy_z(vec2, s2, G, chi, len2, prec2);

        for (i = 0; i < FLINT_MIN(len1, len2); i++)
        {
            if (!acb_overlaps(vec1 + i, vec2 + i))
            {
                flint_printf("FAIL: overlap\n\n");
                flint_printf("iter = %wd  q = %wu  k = %wu  i = %wd\n\n", iter, q, k, i);
                flint_printf("s = "); acb_printn(s, 50, 0); flint_printf("\n\n");
                flint_printf("r1 = "); acb_printn(vec1 + i, 50, 0); flint_printf("\n\n");
                flint_printf("r2 = "); acb_printn(vec2 + i, 50, 0); flint_printf("\n\n");
                flint_abort();
            }
        }

        if (arb_contains_zero(acb_imagref(s)))
        {
            for (i = 0; i < len1; i++)
            {
                if (!arb_contains_zero(acb_imagref(vec1 + i)))
                {
                    flint_printf("FAIL: real 1\n\n");
                    flint_printf("iter = %wd  q = %wu  k = %wu  i = %wd\n\n", iter, q, k, i);
                    flint_printf("s = "); acb_printn(s, 50, 0); flint_printf("\n\n");
                    flint_printf("r1 = "); acb_printn(vec1 + i, 50, 0); flint_printf("\n\n");
                    flint_abort();
                }
            }
        }

        if (arb_contains_zero(acb_imagref(s2)))
        {
            for (i = 0; i < len2; i++)
            {
                if (!arb_contains_zero(acb_imagref(vec2 + i)))
                {
                    flint_printf("FAIL: real 1\n\n");
                    flint_printf("iter = %wd  q = %wu  k = %wu  i = %wd\n\n", iter, q, k, i);
                    flint_printf("s = "); acb_printn(s, 50, 0); flint_printf("\n\n");
                    flint_printf("r1 = "); acb_printn(vec2 + i, 50, 0); flint_printf("\n\n");
                    flint_abort();
                }
            }
        }

        dirichlet_char_clear(chi);
        dirichlet_group_clear(G);
        acb_clear(s);
        acb_clear(s2);
        _acb_vec_clear(vec1, len1);
        _acb_vec_clear(vec2, len2);
    }

    flint_randclear(state);
    flint_cleanup();
    flint_printf("PASS\n");
    return EXIT_SUCCESS;
}
Example #20
0
void
acb_modular_elliptic_k_cpx(acb_ptr w, const acb_t m, slong len, slong prec)
{
    acb_t t, u, msub1m, m2sub1;
    slong k, n;

    if (len < 1)
        return;

    if (len == 1)
    {
        acb_modular_elliptic_k(w, m, prec);
        return;
    }

    if (acb_is_zero(m))
    {
        acb_const_pi(w, prec);
        acb_mul_2exp_si(w, w, -1);

        for (k = 1; k < len; k++)
        {
            acb_mul_ui(w + k, w + k - 1, (2 * k - 1) * (2 * k - 1), prec);
            acb_div_ui(w + k, w + k, 4 * k * k, prec);
        }

        return;
    }

    acb_init(t);
    acb_init(u);
    acb_init(msub1m);
    acb_init(m2sub1);

    acb_sub_ui(msub1m, m, 1, prec);
    acb_neg(t, msub1m);
    acb_sqrt(t, t, prec);
    acb_mul(msub1m, msub1m, m, prec);

    acb_mul_2exp_si(m2sub1, m, 1);
    acb_sub_ui(m2sub1, m2sub1, 1, prec);

    acb_agm1_cpx(w, t, 2, prec);

    /* pi M'(t) / (4 t M(t)^2) */
    acb_mul(u, w, w, prec);
    acb_mul(t, t, u, prec);
    acb_div(w + 1, w + 1, t, prec);

    acb_const_pi(u, prec);
    acb_mul(w + 1, w + 1, u, prec);
    acb_mul_2exp_si(w + 1, w + 1, -2);

    /* pi / (2 M(t)) */
    acb_const_pi(u, prec);
    acb_div(w, u, w, prec);
    acb_mul_2exp_si(w, w, -1);

    acb_inv(t, msub1m, prec);

    for (k = 2; k < len; k++)
    {
        n = k - 2;

        acb_mul_ui(w + k, w + n, (2 * n + 1) * (2 * n + 1), prec);

        acb_mul(u, w + n + 1, m2sub1, prec);
        acb_addmul_ui(w + k, u, (n + 1) * (n + 1) * 4, prec);

        acb_mul(w + k, w + k, t, prec);
        acb_div_ui(w + k, w + k, 4 * (n + 1) * (n + 2), prec);
        acb_neg(w + k, w + k);
    }

    acb_clear(t);
    acb_clear(u);
    acb_clear(msub1m);
    acb_clear(m2sub1);
}
Example #21
0
int
_acb_poly_validate_real_roots(acb_srcptr roots, acb_srcptr poly, slong len, slong prec)
{
    slong i, deg, num_real;
    arb_ptr real;
    int result;

    deg = len - 1;
    num_real = 0;
    result = 1;

    if (deg <= 1)
        return 1;

    real = _arb_vec_init(deg);

    /* pick out the candidate real roots */
    for (i = 0; i < deg; i++)
    {
        if (arb_contains_zero(acb_imagref(roots + i)))
        {
            arb_set(real + num_real, acb_realref(roots + i));
            num_real++;
        }
    }

    /* number of real roots must be even if the polynomial is even,
       and odd if the polynomial is odd (unless there are repeated roots...
       in which case the input is invalid) */
    if ((num_real % 2) != (deg % 2))
    {
        result = 0;
    }
    else if (num_real > 0)
    {
        int sign_neg_inf, sign_pos_inf, prev_sign;

        acb_t t;
        acb_init(t);

        /* by assumption that the roots are real and isolated, the lead
           coefficient really must be known to be either positive or negative */
        sign_pos_inf = arb_is_positive(acb_realref(poly + deg)) ? 1 : -1;
        sign_neg_inf = (deg % 2) ? -sign_pos_inf : sign_pos_inf;

        /* now we check that there's a sign change between each root */
        _arb_vec_sort_mid(real, num_real);

        prev_sign = sign_neg_inf;

        for (i = 0; i < num_real - 1; i++)
        {
            /* set t to the midpoint between the midpoints */
            arb_zero(acb_imagref(t));
            arf_add(arb_midref(acb_realref(t)),
                arb_midref(real + i), arb_midref(real + i + 1), prec, ARF_RND_DOWN);
            arf_mul_2exp_si(arb_midref(acb_realref(t)), arb_midref(acb_realref(t)), -1);
            mag_zero(arb_radref(acb_realref(t)));

            /* check that this point really is between both intervals (one interval
               could be much wider than the other */
            if (arb_lt(real + i, acb_realref(t)) && arb_lt(acb_realref(t), real + i + 1))
            {
                /* check sign change */
                _acb_poly_evaluate(t, poly, len, t, prec);

                if (prev_sign == 1)
                    result = arb_is_negative(acb_realref(t));
                else
                    result = arb_is_positive(acb_realref(t));

                if (!result)
                    break;

                prev_sign = -prev_sign;
            }
            else
            {
                result = 0;
                break;
            }
        }

        acb_clear(t);
    }

    _arb_vec_clear(real, deg);

    return result;
}
Example #22
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;
}
Example #23
0
void
_acb_hypgeom_2f1_transform_limit(acb_t res, const acb_poly_t a, const acb_poly_t b,
    const acb_poly_t c, const acb_poly_t z, int which, slong prec)
{
    acb_poly_t ba, ca, cb, cab, ac1, bc1, ab1, ba1, w, t, u, v, s;
    acb_t tt;

    acb_poly_init(ba);
    acb_poly_init(ca); acb_poly_init(cb); acb_poly_init(cab);
    acb_poly_init(ac1); acb_poly_init(bc1);
    acb_poly_init(ab1); acb_poly_init(ba1);
    acb_poly_init(w); acb_poly_init(t);
    acb_poly_init(u); acb_poly_init(v);
    acb_poly_init(s);
    acb_init(tt);

    acb_poly_add_si(s, z, -1, prec);   /* s = 1 - z */
    acb_poly_neg(s, s);
    acb_poly_sub(ba, b, a, prec);      /* ba = b - a */
    acb_poly_sub(ca, c, a, prec);      /* ca = c - a */
    acb_poly_sub(cb, c, b, prec);      /* cb = c - b */
    acb_poly_sub(cab, ca, b, prec);    /* cab = c - a - b */
    acb_poly_add_si(ac1, ca, -1, prec); acb_poly_neg(ac1, ac1); /* ac1 = a - c + 1 */
    acb_poly_add_si(bc1, cb, -1, prec); acb_poly_neg(bc1, bc1); /* bc1 = b - c + 1 */
    acb_poly_add_si(ab1, ba, -1, prec); acb_poly_neg(ab1, ab1); /* ab1 = a - b + 1 */
    acb_poly_add_si(ba1, ba, 1, prec);                          /* ba1 = b - a + 1 */

    /* t = left term, u = right term (DLMF 15.8.1 - 15.8.5) */
    if (which == 2)
    {
        acb_poly_inv_series(w, z, 2, prec);  /* w = 1/z */
        acb_hypgeom_2f1_series_direct(t, a, ac1, ab1, w, 1, 2, prec);
        acb_hypgeom_2f1_series_direct(u, b, bc1, ba1, w, 1, 2, prec);
    }
    else if (which == 3)
    {
        acb_poly_inv_series(w, s, 2, prec);  /* w = 1/(1-z) */
        acb_hypgeom_2f1_series_direct(t, a, cb, ab1, w, 1, 2, prec);
        acb_hypgeom_2f1_series_direct(u, b, ca, ba1, w, 1, 2, prec);
    }
    else if (which == 4)
    {
        acb_poly_set(w, s);                  /* w = 1-z */
        acb_poly_add(v, ac1, b, prec);       /* v = a+b-c+1 */
        acb_hypgeom_2f1_series_direct(t, a, b, v, w, 1, 2, prec);
        acb_poly_add_si(v, cab, 1, prec);    /* v = c-a-b+1 */
        acb_hypgeom_2f1_series_direct(u, ca, cb, v, w, 1, 2, prec);
    }
    else if (which == 5)
    {
        acb_poly_inv_series(w, z, 2, prec);  /* w = 1-1/z */
        acb_poly_neg(w, w);
        acb_poly_add_si(w, w, 1, prec);
        acb_poly_add(v, ac1, b, prec);       /* v = a+b-c+1 */
        acb_hypgeom_2f1_series_direct(t, a, ac1, v, w, 1, 2, prec);
        acb_poly_add_si(v, cab, 1, prec);    /* v = c-a-b+1 */
        acb_poly_add_si(u, a, -1, prec);     /* u = 1-a */
        acb_poly_neg(u, u);
        acb_hypgeom_2f1_series_direct(u, ca, u, v, w, 1, 2, prec);
    }
    else
    {
        flint_printf("invalid transformation!\n");
        abort();
    }

    /* gamma factors */
    acb_poly_rgamma_series(v, a, 2, prec);
    acb_poly_mullow(u, u, v, 2, prec);
    acb_poly_rgamma_series(v, ca, 2, prec);
    acb_poly_mullow(t, t, v, 2, prec);

    acb_poly_rgamma_series(v, b, 2, prec);
    if (which == 2 || which == 3)
        acb_poly_mullow(t, t, v, 2, prec);
    else
        acb_poly_mullow(u, u, v, 2, prec);

    acb_poly_rgamma_series(v, cb, 2, prec);
    if (which == 2 || which == 3)
        acb_poly_mullow(u, u, v, 2, prec);
    else
        acb_poly_mullow(t, t, v, 2, prec);

    if (which == 2 || which == 3)
    {
        if (which == 2)
            acb_poly_neg(s, z);  /* -z, otherwise 1-z since before */

        acb_poly_neg(v, a);
        acb_poly_pow_series(v, s, v, 2, prec);
        acb_poly_mullow(t, t, v, 2, prec);

        acb_poly_neg(v, b);
        acb_poly_pow_series(v, s, v, 2, prec);
        acb_poly_mullow(u, u, v, 2, prec);
    }
    else
    {
        acb_poly_pow_series(v, s, cab, 2, prec);
        acb_poly_mullow(u, u, v, 2, prec);

        if (which == 5)
        {
            acb_poly_neg(v, a);
            acb_poly_pow_series(v, z, v, 2, prec);
            acb_poly_mullow(t, t, v, 2, prec);

            acb_poly_neg(v, ca);
            acb_poly_pow_series(v, z, v, 2, prec);
            acb_poly_mullow(u, u, v, 2, prec);
        }
    }

    acb_poly_sub(t, t, u, prec);

    if (which == 2 || which == 3)
        acb_poly_sin_pi_series(v, ba, 2, prec);
    else
        acb_poly_sin_pi_series(v, cab, 2, prec);

    acb_poly_get_coeff_acb(tt, t, 1);
    acb_poly_get_coeff_acb(res, v, 1);
    acb_div(res, tt, res, prec);
    acb_const_pi(tt, prec);
    acb_mul(res, res, tt, prec);

    acb_poly_clear(ba);
    acb_poly_clear(ca); acb_poly_clear(cb); acb_poly_clear(cab);
    acb_poly_clear(ac1); acb_poly_clear(bc1);
    acb_poly_clear(ab1); acb_poly_clear(ba1);
    acb_poly_clear(w); acb_poly_clear(t);
    acb_poly_clear(u); acb_poly_clear(v);
    acb_poly_clear(s);
    acb_clear(tt);
}
Example #24
0
int main()
{
    slong iter;
    flint_rand_t state;

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

    flint_randinit(state);

    for (iter = 0; iter < 3000 * arb_test_multiplier(); iter++)
    {
        acb_t a, b, c;
        slong prec1, prec2;

        prec1 = 2 + n_randint(state, 1000);
        prec2 = prec1 + 30;

        acb_init(a);
        acb_init(b);
        acb_init(c);

        arb_randtest_precise(acb_realref(a), state, 1 + n_randint(state, 1000), 3);
        arb_randtest_precise(acb_imagref(a), state, 1 + n_randint(state, 1000), 3);

        acb_digamma(b, a, prec1);
        acb_digamma(c, a, prec2);

        if (!acb_overlaps(b, c))
        {
            flint_printf("FAIL: overlap\n\n");
            flint_printf("a = "); acb_print(a); flint_printf("\n\n");
            flint_printf("b = "); acb_print(b); flint_printf("\n\n");
            flint_printf("c = "); acb_print(c); flint_printf("\n\n");
            abort();
        }

        acb_set(c, a);
        acb_digamma(c, c, prec2);
        if (!acb_overlaps(b, c))
        {
            flint_printf("FAIL: aliasing\n\n");
            flint_printf("a = "); acb_print(a); flint_printf("\n\n");
            flint_printf("b = "); acb_print(b); flint_printf("\n\n");
            flint_printf("c = "); acb_print(c); flint_printf("\n\n");
            abort();
        }

        /* check digamma(z+1) = digamma(z) + 1/z */
        acb_inv(c, a, prec1);
        acb_add(b, b, c, prec1);
        acb_add_ui(c, a, 1, prec1);
        acb_digamma(c, c, prec1);

        if (!acb_overlaps(b, c))
        {
            flint_printf("FAIL: functional equation\n\n");
            flint_printf("a = "); acb_print(a); flint_printf("\n\n");
            flint_printf("b = "); acb_print(b); flint_printf("\n\n");
            flint_printf("c = "); acb_print(c); flint_printf("\n\n");
            abort();
        }

        acb_clear(a);
        acb_clear(b);
        acb_clear(c);
    }

    flint_randclear(state);
    flint_cleanup();
    flint_printf("PASS\n");
    return EXIT_SUCCESS;
}
Example #25
0
void
acb_elliptic_p_jet(acb_ptr r, const acb_t z, const acb_t tau, slong len, slong prec)
{
    acb_t t01, t02, t03, t04;
    acb_ptr tz1, tz2, tz3, tz4;
    acb_t t;
    int real;
    slong k;

    if (len < 1)
        return;

    if (len == 1)
    {
        acb_elliptic_p(r, z, tau, prec);
        return;
    }

    real = acb_is_real(z) && arb_is_int_2exp_si(acb_realref(tau), -1) &&
                arb_is_positive(acb_imagref(tau));

    acb_init(t);

    acb_init(t01);
    acb_init(t02);
    acb_init(t03);
    acb_init(t04);

    tz1 = _acb_vec_init(len);
    tz2 = _acb_vec_init(len);
    tz3 = _acb_vec_init(len);
    tz4 = _acb_vec_init(len);

    acb_modular_theta_jet(tz1, tz2, tz3, tz4, z, tau, len, prec);

    /* [theta_4(z) / theta_1(z)]^2 */
    _acb_poly_div_series(tz2, tz4, len, tz1, len, len, prec);
    _acb_poly_mullow(tz1, tz2, len, tz2, len, len, prec);

    acb_zero(t);
    acb_modular_theta(t01, t02, t03, t04, t, tau, prec);

    /* [theta_2(0) * theta_3(0)] ^2 */
    acb_mul(t, t02, t03, prec);
    acb_mul(t, t, t, prec);
    _acb_vec_scalar_mul(tz1, tz1, len, t, prec);

    /* - [theta_2(0)^4 + theta_3(0)^4] / 3 */
    acb_pow_ui(t02, t02, 4, prec);
    acb_pow_ui(t03, t03, 4, prec);
    acb_add(t, t02, t03, prec);
    acb_div_ui(t, t, 3, prec);
    acb_sub(tz1, tz1, t, prec);

    /* times pi^2 */
    acb_const_pi(t, prec);
    acb_mul(t, t, t, prec);
    _acb_vec_scalar_mul(r, tz1, len, t, prec);

    if (real)
    {
        for (k = 0; k < len; k++)
            arb_zero(acb_imagref(r + k));
    }

    acb_clear(t);

    acb_clear(t01);
    acb_clear(t02);
    acb_clear(t03);
    acb_clear(t04);

    _acb_vec_clear(tz1, len);
    _acb_vec_clear(tz2, len);
    _acb_vec_clear(tz3, len);
    _acb_vec_clear(tz4, len);
}
Example #26
0
int main()
{
    slong iter;
    flint_rand_t state;

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

    flint_randinit(state);

    /* check exp(A)*exp(c*A) = exp((1+c)*A) */
    for (iter = 0; iter < 500 * arb_test_multiplier(); iter++)
    {
        acb_mat_t A, E, F, EF, G;
        fmpq_mat_t Q;
        acb_t c, d;
        slong n, qbits, prec;

        n = n_randint(state, 5);
        qbits = 2 + n_randint(state, 300);
        prec = 2 + n_randint(state, 300);

        acb_init(c);
        acb_init(d);
        fmpq_mat_init(Q, n, n);
        acb_mat_init(A, n, n);
        acb_mat_init(E, n, n);
        acb_mat_init(F, n, n);
        acb_mat_init(EF, n, n);
        acb_mat_init(G, n, n);

        _fmpq_mat_randtest_for_exp(Q, state, qbits);
        acb_mat_set_fmpq_mat(A, Q, prec);

        acb_mat_exp(E, A, prec);

        acb_randtest(c, state, prec, 10);
        acb_mat_scalar_mul_acb(F, A, c, prec);
        acb_mat_exp(F, F, prec);

        acb_add_ui(d, c, 1, prec);
        acb_mat_scalar_mul_acb(G, A, d, prec);
        acb_mat_exp(G, G, prec);

        acb_mat_mul(EF, E, F, prec);

        if (!acb_mat_overlaps(EF, G))
        {
            flint_printf("FAIL\n\n");
            flint_printf("n = %wd, prec = %wd\n", n, prec);

            flint_printf("c = \n"); acb_printd(c, 15); flint_printf("\n\n");

            flint_printf("A = \n"); acb_mat_printd(A, 15); flint_printf("\n\n");
            flint_printf("E   = \n"); acb_mat_printd(E, 15); flint_printf("\n\n");
            flint_printf("F   = \n"); acb_mat_printd(F, 15); flint_printf("\n\n");
            flint_printf("E*F = \n"); acb_mat_printd(EF, 15); flint_printf("\n\n");
            flint_printf("G   = \n"); acb_mat_printd(G, 15); flint_printf("\n\n");

            flint_abort();
        }

        acb_clear(c);
        acb_clear(d);
        fmpq_mat_clear(Q);
        acb_mat_clear(A);
        acb_mat_clear(E);
        acb_mat_clear(F);
        acb_mat_clear(EF);
        acb_mat_clear(G);
    }

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

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

    flint_randinit(state);

    for (iter = 0; iter < 2000 * arb_test_multiplier(); iter++)
    {
        acb_t a0, a1, b, z, w0, w1, t, u, enz;
        slong prec0, prec1;
        int regularized;

        acb_init(a0);
        acb_init(a1);
        acb_init(b);
        acb_init(z);
        acb_init(w0);
        acb_init(w1);
        acb_init(t);
        acb_init(u);
        acb_init(enz);

        regularized = n_randint(state, 3);

        prec0 = 2 + n_randint(state, 1000);
        prec1 = 2 + n_randint(state, 1000);

        acb_randtest_param(a0, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100));
        acb_randtest(z, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100));
        acb_randtest(w0, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100));
        acb_randtest(w1, state, 1 + n_randint(state, 1000), 1 + n_randint(state, 100));

        acb_add_ui(a1, a0, 1, prec0);

        acb_hypgeom_gamma_lower(w0, a0, z, regularized, prec0);
        acb_hypgeom_gamma_lower(w1, a1, z, regularized, prec1);

        acb_neg(enz, z);
        acb_exp(enz, enz, prec0);

        /* recurrence relations */
        if (regularized == 2)
        {
            /* gamma^{*}(a,z) - exp(-z)/Gamma(a+1) - z gamma^{*}(a+1,z) = 0 */
            /* http://dlmf.nist.gov/8.8.E4 */
            acb_set(t, w0);
            acb_rgamma(u, a1, prec0);
            acb_submul(t, enz, u, prec0);
            acb_submul(t, z, w1, prec0);
        }
        else if (regularized == 1)
        {
            /* P(a,z) - exp(-z) z^a / Gamma(a+1) - P(a+1,z) = 0 */
            /* http://dlmf.nist.gov/8.8.E5 */
            acb_pow(u, z, a0, prec0);
            acb_rgamma(b, a1, prec0);
            acb_mul(u, u, b, prec0);
            acb_sub(t, w0, w1, prec0);
            acb_submul(t, enz, u, prec0);
        }
        else
        {
            /* a gamma(a,z) - exp(-z) z^a - gamma(a+1,z) = 0 */
            /* http://dlmf.nist.gov/8.8.E1 */
            acb_pow(u, z, a0, prec0);
            acb_mul(t, a0, w0, prec0);
            acb_submul(t, enz, u, prec0);
            acb_sub(t, t, w1, prec0);
        }

        if (!acb_contains_zero(t))
        {
            flint_printf("FAIL: recurrence relation\n\n");
            flint_printf("regularized = %d\n\n", regularized);
            flint_printf("a0 = "); acb_printd(a0, 30); flint_printf("\n\n");
            flint_printf("z = ");  acb_printd(z, 30); flint_printf("\n\n");
            flint_printf("w0 = "); acb_printd(w0, 30); flint_printf("\n\n");
            flint_printf("w1 = "); acb_printd(w1, 30); flint_printf("\n\n");
            flint_printf("t = "); acb_printd(t, 30); flint_printf("\n\n");
            abort();
        }

        /* identities relating lower and upper incomplete gamma functions */
        if (regularized == 0 || regularized == 1)
        {
            acb_t u0;
            acb_init(u0);
            acb_hypgeom_gamma_upper(u0, a0, z, regularized, prec0);

            acb_zero(t);

            if (regularized == 1)
            {
                /* P(s,z) + Q(s,z) - 1 = 0 */
                /* http://dlmf.nist.gov/8.2.E5 */
                acb_add(t, w0, u0, prec0);
                acb_sub_ui(t, t, 1, prec0);
            }
            else
            {
                /* gamma(s,z) + Gamma(s,z) - Gamma(s) = 0 */
                /* excludes non-positive integer values of s */
                /* http://dlmf.nist.gov/8.2.E3 */
                if (!acb_is_int(a0) || arb_is_positive(acb_realref(a0)))
                {
                    acb_gamma(b, a0, prec0);
                    acb_add(t, w0, u0, prec0);
                    acb_sub(t, t, b, prec0);
                }
            }

            if (!acb_contains_zero(t))
            {
                flint_printf("FAIL: lower plus upper\n\n");
                flint_printf("regularized = %d\n\n", regularized);
                flint_printf("a0 = "); acb_printd(a0, 30); flint_printf("\n\n");
                flint_printf("z = ");  acb_printd(z, 30); flint_printf("\n\n");
                flint_printf("w0 = "); acb_printd(w0, 30); flint_printf("\n\n");
                flint_printf("w1 = "); acb_printd(w1, 30); flint_printf("\n\n");
                flint_printf("t = "); acb_printd(t, 30); flint_printf("\n\n");
                abort();
            }

            acb_clear(u0);
        }

        acb_clear(a0);
        acb_clear(a1);
        acb_clear(b);
        acb_clear(z);
        acb_clear(w0);
        acb_clear(w1);
        acb_clear(t);
        acb_clear(u);
        acb_clear(enz);
    }

    flint_randclear(state);
    flint_cleanup();
    flint_printf("PASS\n");
    return EXIT_SUCCESS;
}
Example #28
0
int main()
{
    long iter;
    flint_rand_t state;

    printf("root_bound_fujiwara....");
    fflush(stdout);

    flint_randinit(state);

    for (iter = 0; iter < 10000; iter++)
    {
        acb_poly_t a;
        acb_ptr roots;
        acb_t t;
        mag_t mag1, mag2;
        long i, deg, prec;

        prec = 10 + n_randint(state, 400);
        deg = n_randint(state, 10);

        acb_init(t);
        acb_poly_init(a);
        mag_init(mag1);
        mag_init(mag2);
        roots = _acb_vec_init(deg);

        for (i = 0; i < deg; i++)
            acb_randtest(roots + i, state, prec, 1 + n_randint(state, 20));

        acb_poly_product_roots(a, roots, deg, prec);
        acb_randtest(t, state, prec, 1 + n_randint(state, 20));
        _acb_vec_scalar_mul(a->coeffs, a->coeffs, a->length, t, prec);

        acb_poly_root_bound_fujiwara(mag1, a);

        for (i = 0; i < deg; i++)
        {
            acb_get_mag(mag2, roots + i);

            /* acb_get_mag gives an upper bound which due to rounding
               could be larger than mag1, so we pick a slightly
               smaller number */
            mag_mul_ui(mag2, mag2, 10000);
            mag_div_ui(mag2, mag2, 10001);

            if (mag_cmp(mag2, mag1) > 0)
            {
                printf("FAIL\n");
                printf("a = "); acb_poly_printd(a, 15); printf("\n\n");
                printf("root = "); acb_printd(roots + i, 15); printf("\n\n");
                printf("mag1 = "); mag_printd(mag1, 10); printf("\n\n");
                printf("mag2 = "); mag_printd(mag2, 10); printf("\n\n");
                abort();
            }
        }

        _acb_vec_clear(roots, deg);
        acb_clear(t);
        acb_poly_clear(a);
        mag_clear(mag1);
        mag_clear(mag2);
    }

    flint_randclear(state);
    flint_cleanup();
    printf("PASS\n");
    return EXIT_SUCCESS;
}
Example #29
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);
}
Example #30
0
int main()
{
    slong iter;
    flint_rand_t state;

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

    flint_randinit(state);

    for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++)
    {
        acb_t x, y, a, b, c;
        slong prec1, prec2;

        prec1 = 2 + n_randint(state, 1000);
        prec2 = prec1 + 30;

        acb_init(x);
        acb_init(y);
        acb_init(a);
        acb_init(b);
        acb_init(c);

        acb_randtest(x, state, 1 + n_randint(state, 1000), 2 + n_randint(state, 100));

        acb_sin_pi(a, x, prec1);
        acb_sin_pi(b, x, prec2);

        /* check consistency */
        if (!acb_overlaps(a, b))
        {
            flint_printf("FAIL: overlap\n\n");
            flint_printf("x = "); acb_print(x); flint_printf("\n\n");
            flint_printf("a = "); acb_print(a); flint_printf("\n\n");
            flint_printf("b = "); acb_print(b); flint_printf("\n\n");
            abort();
        }

        /* compare with cos */
        arb_const_pi(acb_realref(c), prec1);
        acb_mul_arb(y, x, acb_realref(c), prec1);
        acb_sin(c, y, prec1);

        if (!acb_overlaps(a, c))
        {
            flint_printf("FAIL: functional equation\n\n");
            flint_printf("x = "); acb_print(x); flint_printf("\n\n");
            flint_printf("y = "); acb_print(y); flint_printf("\n\n");
            flint_printf("a = "); acb_print(a); flint_printf("\n\n");
            flint_printf("c = "); acb_print(c); flint_printf("\n\n");
            abort();
        }

        acb_sin_pi(x, x, prec1);

        if (!acb_overlaps(a, x))
        {
            flint_printf("FAIL: aliasing\n\n");
            flint_printf("a = "); acb_print(a); flint_printf("\n\n");
            flint_printf("x = "); acb_print(x); flint_printf("\n\n");
            abort();
        }

        acb_clear(x);
        acb_clear(y);
        acb_clear(a);
        acb_clear(b);
        acb_clear(c);
    }

    flint_randclear(state);
    flint_cleanup();
    flint_printf("PASS\n");
    return EXIT_SUCCESS;
}