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

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

    flint_randinit(state);

    /* compare with fmpz_poly */
    for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++)
    {
        slong zbits1, rbits1, rbits2, trunc;
        ulong e;
        fmpz_poly_t A, B;
        acb_poly_t a, b;

        zbits1 = 2 + n_randint(state, 100);
        rbits1 = 2 + n_randint(state, 200);
        rbits2 = 2 + n_randint(state, 200);
        e = n_randint(state, 50);
        trunc = n_randint(state, 40);

        fmpz_poly_init(A);
        fmpz_poly_init(B);

        acb_poly_init(a);
        acb_poly_init(b);

        fmpz_poly_randtest(A, state, 1 + n_randint(state, 10), zbits1);
        fmpz_poly_pow_trunc(B, A, e, trunc);

        acb_poly_set_fmpz_poly(a, A, rbits1);
        acb_poly_pow_ui_trunc_binexp(b, a, e, trunc, rbits2);

        if (!acb_poly_contains_fmpz_poly(b, B))
        {
            flint_printf("FAIL\n\n");
            flint_printf("bits2 = %wd\n", rbits2);
            flint_printf("e = %wu\n", e);
            flint_printf("trunc = %wd\n", trunc);

            flint_printf("A = "); fmpz_poly_print(A); flint_printf("\n\n");
            flint_printf("B = "); fmpz_poly_print(B); flint_printf("\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");

            abort();
        }

        acb_poly_pow_ui_trunc_binexp(a, a, e, trunc, rbits2);
        if (!acb_poly_equal(a, b))
        {
            flint_printf("FAIL (aliasing)\n\n");
            abort();
        }

        fmpz_poly_clear(A);
        fmpz_poly_clear(B);

        acb_poly_clear(a);
        acb_poly_clear(b);
    }

    flint_randclear(state);
    flint_cleanup();
    flint_printf("PASS\n");
    return EXIT_SUCCESS;
}
int main(int argc, char *argv[])
{
    ulong r, s, p, prec, s_prec;
    ulong i, m, lambda, char1, char2;
    fmpz_poly_t eis, eta, eta_r;
    fmpz_t p1, c1, c2, ss1, ss, pp, ppl, pplc;

    // input r, s, and the precision desired
    if (argc == 4) {
        r = atol(argv[1]);
        s = atol(argv[2]);
        prec = atol(argv[3]);
        prec = n_nextprime(prec, 1) - 1;
    }

    if (argc != 4) {
        printf("usage: shimura_coeffs r s n\n");
        return EXIT_FAILURE;
    }

    // Compute the weight of the form f_r_s
    lambda = r / 2 + s;

    //printf("%d\n", lambda);

    // This is the necessary precision of the input
    s_prec = (prec + r) * prec * r / 24;
    //printf("Necessary precision: %d terms\n", s_prec);

    // First compute eta
    //printf("Computing eta\n");
    fmpz_poly_init(eta);
    eta_series(&eta, s_prec);

    // Next compute eta^r
    //printf("Computing eta^%d\n", r);
    fmpz_poly_init(eta_r);
    fmpz_poly_pow_trunc(eta_r, eta, r, s_prec);
    fmpz_poly_clear(eta);

    // Next compute E_s
    //printf("Computing E_%d\n", s);
    
    fmpz_poly_init(eis);
    if(s != 0) {
        eis_series(&eis, s, s_prec);
    }

    //printf("Computing coefficients\n");

    // Instead of computing the product, we will compute each coefficient as
    // needed. This is potentially slower, but saves memory.
    //
    fmpz_init(p1);
    fmpz_init(c1);
    fmpz_init(c2);
    fmpz_init(ss);
    fmpz_init(ss1);

    // compute alpha(p^2*r)
    p = 2;
    m = r*p*p;
    while(p <= prec) {
        fmpz_set_ui(ss1, 0);

        if(s != 0) {
            for(i = r; i <= m; i += 24) {
                if((m - i) % 24 == 0) {
                    fmpz_poly_get_coeff_fmpz(c1, eta_r, (i - r) / 24);
                    fmpz_poly_get_coeff_fmpz(c2, eis, (m - i) / 24);
                    fmpz_addmul(ss1, c1, c2);
                }
            }
        }
        else {
            if((m - r) % 24 == 0)
                fmpz_poly_get_coeff_fmpz(ss1, eta_r, (m - r) / 24);
        }

        /*
        if(p == 199) {
            fmpz_print(ss1);
            printf("\n");
        }
        */

        // compute character X12(p)
        char1 = n_jacobi(12, p);
        
        // compute character ((-1)^(lambda) * n | p)
        if(lambda % 2 == 0) {
            char2 = n_jacobi(r, p);
        }
        else {
            char2 = n_jacobi(-r, p);
        }

        // compute p^(lambda - 1)
        fmpz_set_ui(pp, p);
        fmpz_pow_ui(ppl, pp, lambda - 1);
        fmpz_mul_si(pplc, ppl, char1*char2);

        fmpz_add(ss, ss1, pplc);

        printf("%d:\t", p);
        fmpz_print(ss);
        printf("\n");

        p = n_nextprime(p, 1);
        m = r*p*p;
    }

    fmpz_clear(p1);
    fmpz_clear(c1);
    fmpz_clear(c2);
    fmpz_clear(ss);
    fmpz_clear(ss1);

    return EXIT_SUCCESS;
}