Exemplo n.º 1
0
int main()
{
    slong iter;
    flint_rand_t state;

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

    flint_randinit(state);

    for (iter = 0; iter < 1000 * arb_test_multiplier(); iter++)
    {
        acb_t s, t, u;
        dirichlet_group_t G;
        dirichlet_char_t chi;
        ulong q, k;
        slong prec;

        acb_init(s);
        acb_init(t);
        acb_init(u);

        q = 1 + n_randint(state, 50);
        prec = 2 + n_randint(state, 100);
        k = n_randint(state, n_euler_phi(q));

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

        if (n_randint(state, 2))
            acb_set_si(s, n_randint(state, 50) - 25);
        else
            acb_randtest(s, state, 2 + n_randint(state, 200), 2);

        acb_dirichlet_l_hurwitz(t, s, NULL, G, chi, prec);
        acb_dirichlet_l(u, s, G, chi, prec);

        if (!acb_overlaps(t, u))
        {
            flint_printf("FAIL: overlap\n\n");
            flint_printf("iter = %ld  q = %lu  k = %lu  prec = %ld\n\n", iter, q, k, prec);
            flint_printf("s = "); acb_printn(s, 100, 0); flint_printf("\n\n");
            flint_printf("t = "); acb_printn(t, 100, 0); flint_printf("\n\n");
            flint_printf("u = "); acb_printn(u, 100, 0); flint_printf("\n\n");
            abort();
        }

        dirichlet_char_clear(chi);
        dirichlet_group_clear(G);
        acb_clear(s);
        acb_clear(t);
        acb_clear(u);
    }

    flint_randclear(state);
    flint_cleanup();
    flint_printf("PASS\n");
    return EXIT_SUCCESS;
}
Exemplo n.º 2
0
int main()
{
    slong iter;
    flint_rand_t state;

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

    flint_randinit(state);

    for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++)
    {
        acb_t x, y, z;
        acb_dirichlet_roots_t roots;
        ulong n, k;
        slong prec;
        slong iter2;

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

        acb_init(x);
        acb_init(y);
        acb_init(z);

        acb_dirichlet_roots_init(roots, n, n_randtest(state), prec);
        acb_unit_root(y, n, prec);

        for (iter2 = 0; iter2 <= FLINT_MIN(n, 20); iter2++)
        {
            k = n_randint(state, 2 * n);
            acb_dirichlet_root(x, roots, k, prec);
            acb_pow_ui(z, y, k, prec);

            if (!acb_overlaps(x, z))
            {
                flint_printf("FAIL: overlap\n\n");
                flint_printf("iter = %wd  n = %wu  k = %wu  prec = %wd\n\n", iter, n, k, prec);
                flint_printf("x = "); acb_printn(x, 30, 0); flint_printf("\n\n");
                flint_printf("z = "); acb_printn(z, 30, 0); flint_printf("\n\n");
                flint_abort();
            }
        }

        acb_dirichlet_roots_clear(roots);
        acb_clear(x);
        acb_clear(y);
        acb_clear(z);
    }

    flint_randclear(state);
    flint_cleanup();
    flint_printf("PASS\n");
    return EXIT_SUCCESS;
}
Exemplo n.º 3
0
int main(int argc, char *argv[])
{
    acb_t s, t, a, b;
    mag_t tol;
    slong prec, goal;
    slong N;
    ulong k;
    int integral, ifrom, ito;
    int i, twice, havegoal, havetol;
    acb_calc_integrate_opt_t options;

    ifrom = ito = -1;

    for (i = 1; i < argc; i++)
    {
        if (!strcmp(argv[i], "-i"))
        {
            if (!strcmp(argv[i+1], "all"))
            {
                ifrom = 0;
                ito = NUM_INTEGRALS - 1;
            }
            else
            {
                ifrom = ito = atol(argv[i+1]);
                if (ito < 0 || ito >= NUM_INTEGRALS)
                    flint_abort();
            }
        }
    }

    if (ifrom == -1)
    {
        flint_printf("Compute integrals using acb_calc_integrate.\n");
        flint_printf("Usage: integrals -i n [-prec p] [-tol eps] [-twice] [...]\n\n");
        flint_printf("-i n       - compute integral n (0 <= n <= %d), or \"-i all\"\n", NUM_INTEGRALS - 1);
        flint_printf("-prec p    - precision in bits (default p = 64)\n");
        flint_printf("-goal p    - approximate relative accuracy goal (default p)\n");
        flint_printf("-tol eps   - approximate absolute error goal (default 2^-p)\n");
        flint_printf("-twice     - run twice (to see overhead of computing nodes)\n");
        flint_printf("-heap      - use heap for subinterval queue\n");
        flint_printf("-verbose   - show information\n");
        flint_printf("-verbose2  - show more information\n");
        flint_printf("-deg n     - use quadrature degree up to n\n");
        flint_printf("-eval n    - limit number of function evaluations to n\n");
        flint_printf("-depth n   - limit subinterval queue size to n\n\n");
        flint_printf("Implemented integrals:\n");
        for (integral = 0; integral < NUM_INTEGRALS; integral++)
            flint_printf("I%d = %s\n", integral, descr[integral]);
        flint_printf("\n");
        return 1;
    }

    acb_calc_integrate_opt_init(options);

    prec = 64;
    twice = 0;
    goal = 0;
    havetol = havegoal = 0;

    acb_init(a);
    acb_init(b);
    acb_init(s);
    acb_init(t);
    mag_init(tol);

    for (i = 1; i < argc; i++)
    {
        if (!strcmp(argv[i], "-prec"))
        {
            prec = atol(argv[i+1]);
        }
        else if (!strcmp(argv[i], "-twice"))
        {
            twice = 1;
        }
        else if (!strcmp(argv[i], "-goal"))
        {
            goal = atol(argv[i+1]);
            if (goal < 0)
            {
                flint_printf("expected goal >= 0\n");
                return 1;
            }
            havegoal = 1;
        }
        else if (!strcmp(argv[i], "-tol"))
        {
            arb_t x;
            arb_init(x);
            arb_set_str(x, argv[i+1], 10);
            arb_get_mag(tol, x);
            arb_clear(x);
            havetol = 1;
        }
        else if (!strcmp(argv[i], "-deg"))
        {
            options->deg_limit = atol(argv[i+1]);
        }
        else if (!strcmp(argv[i], "-eval"))
        {
            options->eval_limit = atol(argv[i+1]);
        }
        else if (!strcmp(argv[i], "-depth"))
        {
            options->depth_limit = atol(argv[i+1]);
        }
        else if (!strcmp(argv[i], "-verbose"))
        {
            options->verbose = 1;
        }
        else if (!strcmp(argv[i], "-verbose2"))
        {
            options->verbose = 2;
        }
        else if (!strcmp(argv[i], "-heap"))
        {
            options->use_heap = 1;
        }
    }

    if (!havegoal)
        goal = prec;

    if (!havetol)
        mag_set_ui_2exp_si(tol, 1, -prec);

    for (integral = ifrom; integral <= ito; integral++)
    {
        flint_printf("I%d = %s ...\n", integral, descr[integral]);

        for (i = 0; i < 1 + twice; i++)
        {
            TIMEIT_ONCE_START
            switch (integral)
            {
            case 0:
                acb_set_d(a, 0);
                acb_set_d(b, 100);
                acb_calc_integrate(s, f_sin, NULL, a, b, goal, tol, options, prec);
                break;

            case 1:
                acb_set_d(a, 0);
                acb_set_d(b, 1);
                acb_calc_integrate(s, f_atanderiv, NULL, a, b, goal, tol, options, prec);
                acb_mul_2exp_si(s, s, 2);
                break;

            case 2:
                acb_set_d(a, 0);
                acb_one(b);
                acb_mul_2exp_si(b, b, goal);
                acb_calc_integrate(s, f_atanderiv, NULL, a, b, goal, tol, options, prec);
                arb_add_error_2exp_si(acb_realref(s), -goal);
                acb_mul_2exp_si(s, s, 1);
                break;

            case 3:
                acb_set_d(a, 0);
                acb_set_d(b, 1);
                acb_calc_integrate(s, f_circle, NULL, a, b, goal, tol, options, prec);
                acb_mul_2exp_si(s, s, 2);
                break;

            case 4:
                acb_set_d(a, 0);
                acb_set_d(b, 8);
                acb_calc_integrate(s, f_rump, NULL, a, b, goal, tol, options, prec);
                break;

            case 5:
                acb_set_d(a, 1);
                acb_set_d(b, 101);
                acb_calc_integrate(s, f_floor, NULL, a, b, goal, tol, options, prec);
                break;

            case 6:
                acb_set_d(a, 0);
                acb_set_d(b, 1);
                acb_calc_integrate(s, f_helfgott, NULL, a, b, goal, tol, options, prec);
                break;

            case 7:
                acb_zero(s);

                acb_set_d_d(a, -1.0, -1.0);
                acb_set_d_d(b, 2.0, -1.0);
                acb_calc_integrate(t, f_zeta, NULL, a, b, goal, tol, options, prec);
                acb_add(s, s, t, prec);

                acb_set_d_d(a, 2.0, -1.0);
                acb_set_d_d(b, 2.0, 1.0);
                acb_calc_integrate(t, f_zeta, NULL, a, b, goal, tol, options, prec);
                acb_add(s, s, t, prec);

                acb_set_d_d(a, 2.0, 1.0);
                acb_set_d_d(b, -1.0, 1.0);
                acb_calc_integrate(t, f_zeta, NULL, a, b, goal, tol, options, prec);
                acb_add(s, s, t, prec);

                acb_set_d_d(a, -1.0, 1.0);
                acb_set_d_d(b, -1.0, -1.0);
                acb_calc_integrate(t, f_zeta, NULL, a, b, goal, tol, options, prec);
                acb_add(s, s, t, prec);

                acb_const_pi(t, prec);
                acb_div(s, s, t, prec);
                acb_mul_2exp_si(s, s, -1);
                acb_div_onei(s, s);
                break;

            case 8:
                acb_set_d(a, 0);
                acb_set_d(b, 1);
                acb_calc_integrate(s, f_essing, NULL, a, b, goal, tol, options, prec);
                break;

            case 9:
                acb_set_d(a, 0);
                acb_set_d(b, 1);
                acb_calc_integrate(s, f_essing2, NULL, a, b, goal, tol, options, prec);
                break;

            case 10:
                acb_set_d(a, 0);
                acb_set_d(b, 10000);
                acb_calc_integrate(s, f_factorial1000, NULL, a, b, goal, tol, options, prec);
                break;

            case 11:
                acb_set_d_d(a, 1.0, 0.0);
                acb_set_d_d(b, 1.0, 1000.0);
                acb_calc_integrate(s, f_gamma, NULL, a, b, goal, tol, options, prec);
                break;

            case 12:
                acb_set_d(a, -10.0);
                acb_set_d(b, 10.0);
                acb_calc_integrate(s, f_sin_plus_small, NULL, a, b, goal, tol, options, prec);
                break;

            case 13:
                acb_set_d(a, -1020.0);
                acb_set_d(b, -1010.0);
                acb_calc_integrate(s, f_exp, NULL, a, b, goal, tol, options, prec);
                break;

            case 14:
                acb_set_d(a, 0);
                acb_set_d(b, ceil(sqrt(goal * 0.693147181) + 1.0));
                acb_calc_integrate(s, f_gaussian, NULL, a, b, goal, tol, options, prec);
                acb_mul(b, b, b, prec);
                acb_neg(b, b);
                acb_exp(b, b, prec);
                arb_add_error(acb_realref(s), acb_realref(b));
                break;

            case 15:
                acb_set_d(a, 0.0);
                acb_set_d(b, 1.0);
                acb_calc_integrate(s, f_spike, NULL, a, b, goal, tol, options, prec);
                break;

            case 16:
                acb_set_d(a, 0.0);
                acb_set_d(b, 8.0);
                acb_calc_integrate(s, f_monster, NULL, a, b, goal, tol, options, prec);
                break;

            case 17:
                acb_set_d(a, 0);
                acb_set_d(b, ceil(goal * 0.693147181 + 1.0));
                acb_calc_integrate(s, f_sech, NULL, a, b, goal, tol, options, prec);
                acb_neg(b, b);
                acb_exp(b, b, prec);
                acb_mul_2exp_si(b, b, 1);
                arb_add_error(acb_realref(s), acb_realref(b));
                break;

            case 18:
                acb_set_d(a, 0);
                acb_set_d(b, ceil(goal * 0.693147181 / 3.0 + 2.0));
                acb_calc_integrate(s, f_sech3, NULL, a, b, goal, tol, options, prec);
                acb_neg(b, b);
                acb_mul_ui(b, b, 3, prec);
                acb_exp(b, b, prec);
                acb_mul_2exp_si(b, b, 3);
                acb_div_ui(b, b, 3, prec);
                arb_add_error(acb_realref(s), acb_realref(b));
                break;

            case 19:
                if (goal < 0)
                    abort();
                /* error bound 2^-N (1+N) when truncated at 2^-N */
                N = goal + FLINT_BIT_COUNT(goal);
                acb_one(a);
                acb_mul_2exp_si(a, a, -N);
                acb_one(b);
                acb_calc_integrate(s, f_log_div1p, NULL, a, b, goal, tol, options, prec);
                acb_set_ui(b, N + 1);
                acb_mul_2exp_si(b, b, -N);
                arb_add_error(acb_realref(s), acb_realref(b));
                break;

           case 20:
                if (goal < 0)
                    abort();
                /* error bound (N+1) exp(-N) when truncated at N */
                N = goal + FLINT_BIT_COUNT(goal);
                acb_zero(a);
                acb_set_ui(b, N);
                acb_calc_integrate(s, f_log_div1p_transformed, NULL, a, b, goal, tol, options, prec);
                acb_neg(b, b);
                acb_exp(b, b, prec);
                acb_mul_ui(b, b, N + 1, prec);
                arb_add_error(acb_realref(s), acb_realref(b));
                break;

            case 21:

                acb_zero(s);

                N = 10;

                acb_set_d_d(a, 0.5, -0.5);
                acb_set_d_d(b, 0.5, 0.5);
                acb_calc_integrate(t, f_elliptic_p_laurent_n, &N, a, b, goal, tol, options, prec);
                acb_add(s, s, t, prec);

                acb_set_d_d(a, 0.5, 0.5);
                acb_set_d_d(b, -0.5, 0.5);
                acb_calc_integrate(t, f_elliptic_p_laurent_n, &N, a, b, goal, tol, options, prec);
                acb_add(s, s, t, prec);

                acb_set_d_d(a, -0.5, 0.5);
                acb_set_d_d(b, -0.5, -0.5);
                acb_calc_integrate(t, f_elliptic_p_laurent_n, &N, a, b, goal, tol, options, prec);
                acb_add(s, s, t, prec);

                acb_set_d_d(a, -0.5, -0.5);
                acb_set_d_d(b, 0.5, -0.5);
                acb_calc_integrate(t, f_elliptic_p_laurent_n, &N, a, b, goal, tol, options, prec);
                acb_add(s, s, t, prec);

                acb_const_pi(t, prec);
                acb_div(s, s, t, prec);
                acb_mul_2exp_si(s, s, -1);
                acb_div_onei(s, s);
                break;

            case 22:

                acb_zero(s);

                N = 1000;

                acb_set_d_d(a, 100.0, 0.0);
                acb_set_d_d(b, 100.0, N);
                acb_calc_integrate(t, f_zeta_frac, NULL, a, b, goal, tol, options, prec);
                acb_add(s, s, t, prec);

                acb_set_d_d(a, 100, N);
                acb_set_d_d(b, 0.5, N);
                acb_calc_integrate(t, f_zeta_frac, NULL, a, b, goal, tol, options, prec);
                acb_add(s, s, t, prec);

                acb_div_onei(s, s);
                arb_zero(acb_imagref(s));

                acb_set_ui(t, N);
                acb_dirichlet_hardy_theta(t, t, NULL, NULL, 1, prec);
                acb_add(s, s, t, prec);

                acb_const_pi(t, prec);
                acb_div(s, s, t, prec);
                acb_add_ui(s, s, 1, prec);
                break;

            case 23:
                acb_set_d(a, 0.0);
                acb_set_d(b, 1000.0);
                acb_calc_integrate(s, f_lambertw, NULL, a, b, goal, tol, options, prec);
                break;

            case 24:
                acb_set_d(a, 0.0);
                acb_const_pi(b, prec);
                acb_calc_integrate(s, f_max_sin_cos, NULL, a, b, goal, tol, options, prec);
                break;

            case 25:
                acb_set_si(a, -1);
                acb_set_si(b, 1);
                acb_calc_integrate(s, f_erf_bent, NULL, a, b, goal, tol, options, prec);
                break;

            case 26:
                acb_set_si(a, -10);
                acb_set_si(b, 10);
                acb_calc_integrate(s, f_airy_ai, NULL, a, b, goal, tol, options, prec);
                break;

            case 27:
                acb_set_si(a, 0);
                acb_set_si(b, 10);
                acb_calc_integrate(s, f_horror, NULL, a, b, goal, tol, options, prec);
                break;

            case 28:
                acb_set_d_d(a, -1, -1);
                acb_set_d_d(b, -1, 1);
                acb_calc_integrate(s, f_sqrt, NULL, a, b, goal, tol, options, prec);
                break;

            case 29:
                acb_set_d(a, 0);
                acb_set_d(b, ceil(sqrt(goal * 0.693147181) + 1.0));
                acb_calc_integrate(s, f_gaussian_twist, NULL, a, b, goal, tol, options, prec);
                acb_mul(b, b, b, prec);
                acb_neg(b, b);
                acb_exp(b, b, prec);
                arb_add_error(acb_realref(s), acb_realref(b));
                arb_add_error(acb_imagref(s), acb_realref(b));
                break;

            case 30:
                acb_set_d(a, 0);
                acb_set_d(b, ceil(goal * 0.693147181 + 1.0));
                acb_calc_integrate(s, f_exp_airy, NULL, a, b, goal, tol, options, prec);
                acb_neg(b, b);
                acb_exp(b, b, prec);
                acb_mul_2exp_si(b, b, 1);
                arb_add_error(acb_realref(s), acb_realref(b));
                break;

            case 31:
                acb_zero(a);
                acb_const_pi(b, prec);
                acb_calc_integrate(s, f_sin_cos_frac, NULL, a, b, goal, tol, options, prec);
                break;

            case 32:
                acb_zero(a);
                acb_set_ui(b, 3);
                acb_calc_integrate(s, f_sin_near_essing, NULL, a, b, goal, tol, options, prec);
                break;

            case 33:
                acb_zero(a);
                acb_zero(b);
                k = 3;
                scaled_bessel_select_N(acb_realref(b), k, prec);
                acb_calc_integrate(s, f_scaled_bessel, &k, a, b, goal, tol, options, prec);
                scaled_bessel_tail_bound(acb_realref(a), k, acb_realref(b), prec);
                arb_add_error(acb_realref(s), acb_realref(a));
                break;

            case 34:
                acb_zero(a);
                acb_zero(b);
                k = 15;
                scaled_bessel_select_N(acb_realref(b), k, prec);
                acb_calc_integrate(s, f_scaled_bessel, &k, a, b, goal, tol, options, prec);
                scaled_bessel_tail_bound(acb_realref(a), k, acb_realref(b), prec);
                arb_add_error(acb_realref(s), acb_realref(a));
                break;

            case 35:
                acb_set_d_d(a, -1, -1);
                acb_set_d_d(b, -1, 1);
                acb_calc_integrate(s, f_rsqrt, NULL, a, b, goal, tol, options, prec);
                break;

            default:
                abort();
            }

            TIMEIT_ONCE_STOP
        }
        flint_printf("I%d = ", integral);
        acb_printn(s, 3.333 * prec, 0);
        flint_printf("\n\n");
    }

    acb_clear(a);
    acb_clear(b);
    acb_clear(s);
    acb_clear(t);
    mag_clear(tol);

    flint_cleanup();
    return 0;
}
Exemplo n.º 4
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);
}
Exemplo n.º 5
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;
}