int n_is_probabprime_fibonacci(mp_limb_t n) { mp_limb_t m; n_pair_t V; if (FLINT_ABS((mp_limb_signed_t) n) <= 3UL) { if (n >= 2UL) return 1; return 0; } m = (n - n_jacobi(5L, n)) / 2; /* cannot overflow as (5/n) = 0 for n = 2^64-1 */ if (FLINT_BIT_COUNT(n) <= FLINT_D_BITS) { double npre = n_precompute_inverse(n); V = fchain_precomp(m, n, npre); return (n_mulmod_precomp(n - 3UL, V.x, n, npre) == n_mulmod_precomp(2UL, V.y, n, npre)); } else { mp_limb_t ninv = n_preinvert_limb(n); V = fchain2_preinv(m, n, ninv); return (n_mulmod2_preinv(n - 3UL, V.x, n, ninv) == n_mulmod2_preinv(2UL, V.y, n, ninv)); } }
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; }