int main() { slong iter; flint_rand_t state; flint_printf("chi...."); fflush(stdout); flint_randinit(state); for (iter = 0; iter < 10000 * arb_test_multiplier(); iter++) { acb_t zn1, zn2, zn1n2, zn1zn2; dirichlet_group_t G; dirichlet_char_t chi; ulong q, m, n1, n2, iter2; int res; q = 1 + n_randint(state, 1000); dirichlet_group_init(G, q); dirichlet_char_init(chi, G); acb_init(zn1); acb_init(zn2); acb_init(zn1n2); acb_init(zn1zn2); /* check chi(n1) chi(n2) = chi(n1 n2) */ for (iter2 = 0; iter2 < 10; iter2++) { do { m = 1 + n_randint(state, q); } while (n_gcd(q, m) != 1); dirichlet_char_log(chi, G, m); n1 = n_randint(state, 1000); n2 = n_randint(state, 1000); acb_dirichlet_chi(zn1, G, chi, n1, 53); acb_dirichlet_pairing(zn2, G, m, n1, 53); if (!acb_overlaps(zn1, zn2)) { flint_printf("FAIL: overlap\n\n"); flint_printf("q = %wu\n\n", q); flint_printf("m = %wu\n\n", m); flint_printf("n = %wu\n\n", n1); flint_printf("char = "); acb_printd(zn1, 15); flint_printf("\n\n"); flint_printf("pairing = "); acb_printd(zn2, 15); flint_printf("\n\n"); dirichlet_char_print(G, chi); dirichlet_char_log(chi, G, m); flint_printf("log(m) = "); dirichlet_char_print(G, chi); dirichlet_char_log(chi, G, n1); flint_printf("log(n1) = "); dirichlet_char_print(G, chi); flint_abort(); } acb_dirichlet_pairing(zn2, G, m, n2, 53); acb_dirichlet_pairing(zn1n2, G, m, n1 * n2, 53); acb_mul(zn1zn2, zn1, zn2, 53); if (!acb_overlaps(zn1n2, zn1zn2)) { flint_printf("FAIL: overlap\n\n"); flint_printf("q = %wu\n\n", q); flint_printf("m = %wu\n\n", m); flint_printf("n1 = %wu\n\n", n1); flint_printf("n2 = %wu\n\n", n2); flint_printf("zn1 = "); acb_printd(zn1, 15); flint_printf("\n\n"); flint_printf("zn2 = "); acb_printd(zn2, 15); flint_printf("\n\n"); flint_printf("zn1n2 = "); acb_printd(zn1n2, 15); flint_printf("\n\n"); flint_printf("zn1zn2 = "); acb_printd(zn1zn2, 15); flint_printf("\n\n"); flint_abort(); } } if (iter % 10 == 0) { /* check orthogonality */ acb_zero(zn1); n1 = n_randint(state, 1000); for (m = 1; m <= q; m++) { if (n_gcd(q, m) == 1) { acb_dirichlet_pairing(zn2, G, m, n1, 53); acb_add(zn1, zn1, zn2, 53); } } if (n1 % q == 1 % q) res = arb_contains_si(acb_realref(zn1), n_euler_phi(q)) && arb_contains_zero(acb_imagref(zn1)); else res = acb_contains_zero(zn1); if (!res) { flint_printf("FAIL: orthogonality\n\n"); flint_printf("q = %wu\n\n", q); flint_printf("phi = %wu\n\n", n_euler_phi(q)); flint_printf("n1 = %wu\n\n", n1); flint_printf("zn1 = "); acb_printd(zn1, 15); flint_printf("\n\n"); flint_abort(); } } dirichlet_group_clear(G); dirichlet_char_clear(chi); acb_clear(zn1); acb_clear(zn2); acb_clear(zn1n2); acb_clear(zn1zn2); } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; }
int main() { slong iter, bits; flint_rand_t state; flint_printf("properties...."); fflush(stdout); flint_randinit(state); for (bits = 5; bits <= 30; bits += 5) { for (iter = 0; iter < 50; iter++) { dirichlet_group_t G; dirichlet_char_t chi, psi; ulong q, iter2; q = 2 + n_randint(state, 1 << bits); dirichlet_group_init(G, q); dirichlet_char_init(chi, G); dirichlet_char_init(psi, G); /* check number char properties */ for (iter2 = 0; iter2 < 100; iter2++) { ulong m, n; ulong p1, p2, pairing, cm, cn, q2, q3; dirichlet_group_t G2, G3; dirichlet_char_t chi2, chi3; if (iter2 == 50) dirichlet_group_dlog_precompute(G, 5); /* one random character */ do m = n_randint(state, q); while (n_gcd(q, m) > 1); dirichlet_char_log(chi, G, m); p1 = dirichlet_order_ui(G, m); p2 = dirichlet_order_char(G, chi); check_eq(p1, p2, q, m, "order m", "order chi"); p1 = dirichlet_conductor_ui(G, m); p2 = dirichlet_conductor_char(G, chi); check_eq(p1, p2, q, m, "conductor m", "conductor chi"); p1 = dirichlet_parity_ui(G, m); p2 = dirichlet_parity_char(G, chi); check_eq(p1, p2, q, m, "parity m", "parity chi"); p1 = dirichlet_char_is_real(G, chi); p2 = (dirichlet_order_char(G, chi) <= 2); check_eq(p1, p2, q, m, "is_real", "(order <= 2)"); /* check index */ p1 = dirichlet_index_char(G, chi); dirichlet_char_index(psi, G, p1); if (!dirichlet_char_eq_deep(G, chi, psi)) { flint_printf("FAIL: index\n\n"); flint_printf("q = %wu\n\n", q); flint_printf("m = %wu\n\n", m); flint_printf("chi = "); dirichlet_char_print(G, chi); flint_printf("\n\nindex(chi) = %wu\n\n", p1); flint_printf("psi(index) = %wu\n\n", psi->n); flint_printf("psi = "); dirichlet_char_print(G, psi); flint_printf("\n\n"); abort(); } /* lift to higher modulus */ q2 = q * (1 + n_randint(state, 100)); dirichlet_group_init(G2, q2); dirichlet_char_init(chi2, G2); dirichlet_char_lift(chi2, G2, chi, G); p1 = dirichlet_conductor_char(G, chi); p2 = dirichlet_conductor_char(G2, chi2); check_eq(p1, p2, q, m, "conductor chi", "conductor lift"); p1 = dirichlet_order_char(G, chi); p2 = dirichlet_order_char(G2, chi2); check_eq(p1, p2, q, m, "order chi", "order lift"); /* and lower */ dirichlet_char_lower(psi, G, chi2, G2); if (!dirichlet_char_eq_deep(G, chi, psi)) { flint_printf("FAIL: lift and lower back\n\n"); flint_printf("q = %wu\n\nchi = ", q); dirichlet_char_print(G, chi); flint_printf("\n\nq2 = %wu\n\nchi2 = ", q2); dirichlet_char_print(G2, chi2); flint_printf("\n\nq = %wu\n\npsi = ", q); dirichlet_char_print(G, psi); flint_printf("\n\n"); abort(); } q3 = dirichlet_conductor_char(G, chi) * random_divisor(state, G); q3 = n_gcd(q, q3); dirichlet_group_init(G3, q3); dirichlet_char_init(chi3, G3); dirichlet_char_lower(chi3, G3, chi2, G2); p1 = dirichlet_conductor_char(G, chi); p2 = dirichlet_conductor_char(G3, chi3); check_eq(p1, p2, q, m, "conductor chi", "conductor lower"); p1 = dirichlet_order_char(G, chi); p2 = dirichlet_order_char(G3, chi3); check_eq(p1, p2, q, m, "order chi", "order lower"); dirichlet_char_clear(chi3); dirichlet_group_clear(G3); dirichlet_char_clear(chi2); dirichlet_group_clear(G2); /* another random character */ do n = n_randint(state, q); while (n_gcd(q, n) > 1); dirichlet_char_log(psi, G, n); pairing = dirichlet_pairing(G, m, n); cn = dirichlet_chi(G, chi, n); cm = dirichlet_chi(G, psi, m); if (pairing != cn || pairing != cm) { flint_printf("FAIL: pairing\n\n"); flint_printf("q = %wu\n\n", q); flint_printf("m = %wu\n\n", m); flint_printf("n = %wu\n\n", n); flint_printf("chi(m,n) = %wu\n\n", pairing); flint_printf("chi(m)(n) = %wu\n\n", cn); flint_printf("chi(n)(m) = %wu\n\n", cm); abort(); } } dirichlet_group_dlog_clear(G); dirichlet_char_clear(chi); dirichlet_char_clear(psi); dirichlet_group_clear(G); } } flint_randclear(state); flint_cleanup(); flint_printf("PASS\n"); return EXIT_SUCCESS; }