void acb_dirichlet_jacobi_sum_naive(acb_t res, const dirichlet_group_t G, const dirichlet_char_t chi1, const dirichlet_char_t chi2, slong prec) { ulong k1, k2, m1, m2, g, e, m; ulong * v1, * v2; slong *v; nmod_t expo; acb_t z; v1 = flint_malloc(G->q * sizeof(ulong)); v2 = flint_malloc(G->q * sizeof(ulong)); dirichlet_vec_set_null(v1, G, G->q); dirichlet_chi_vec_loop(v1, G, chi1, G->q); dirichlet_vec_set_null(v2, G, G->q); dirichlet_chi_vec_loop(v2, G, chi2, G->q); nmod_init(&expo, G->expo); m1 = dirichlet_order_char(G, chi1); m2 = dirichlet_order_char(G, chi2); g = m1 * m2 / n_gcd(m1, m2); m = G->expo / g; v = flint_malloc(g * sizeof(slong)); for (e = 0; e < g; e++) v[e] = 0; for (k1 = 2, k2 = G->q - 1; k2 > 1; k1++, k2--) { if (v1[k1] == DIRICHLET_CHI_NULL || v2[k2] == DIRICHLET_CHI_NULL) continue; e = nmod_add(v1[k1], v2[k2], expo) / m; v[e]++; } acb_init(z); acb_unit_root(z, g, prec); acb_dirichlet_si_poly_evaluate(res, v, g, z, prec); acb_clear(z); flint_free(v); flint_free(v2); flint_free(v1); }
mp_limb_t nmod_mat_trace(const nmod_mat_t mat) { mp_limb_t t; slong i, n = nmod_mat_nrows(mat); if (n == 0) return 0; t = nmod_mat_entry(mat, 0, 0); for (i = 1; i < n; i++) t = nmod_add(t, nmod_mat_entry(mat, i, i), mat->mod); return t; }
/* vector of log(k,a)*loga % order in Z/modZ */ void dlog_vec_loop(ulong * v, ulong nv, ulong a, ulong va, nmod_t mod, ulong na, nmod_t order) { ulong x, vx; dlog_vec_fill(v, nv, DLOG_NOT_FOUND); x = 1; vx = 0; do { if (x < nv) v[x] = vx; x = nmod_mul(x, a, mod); vx = nmod_add(vx, va, order); } while (x != 1); for (x = mod.n + 1; x < nv; x++) v[x] = v[x - mod.n]; }
void _nmod_poly_compose_mod_horner(mp_ptr res, mp_srcptr f, long lenf, mp_srcptr g, mp_srcptr h, long lenh, nmod_t mod) { long i, len; mp_ptr t; if (lenh == 1) return; if (lenf == 1) { res[0] = f[0]; return; } if (lenh == 2) { res[0] = _nmod_poly_evaluate_nmod(f, lenf, g[0], mod); return; } len = lenh - 1; i = lenf - 1; t = _nmod_vec_init(len); _nmod_vec_scalar_mul_nmod(res, g, len, f[i], mod); i--; if (i >= 0) res[0] = nmod_add(res[0], f[i], mod); while (i > 0) { i--; _nmod_poly_mulmod(t, res, len, g, len, h, lenh, mod); _nmod_poly_add(res, t, len, f + i, 1, mod); } _nmod_vec_clear(t); }
void _nmod_poly_compose_series_horner(mp_ptr res, mp_srcptr poly1, long len1, mp_srcptr poly2, long len2, long n, nmod_t mod) { if (n == 1) { res[0] = poly1[0]; } else { long i = len1 - 1; long lenr; mp_ptr t = _nmod_vec_init(n); lenr = len2; _nmod_vec_scalar_mul_nmod(res, poly2, len2, poly1[i], mod); i--; res[0] = nmod_add(res[0], poly1[i], mod); while (i > 0) { i--; if (lenr + len2 - 1 < n) { _nmod_poly_mul(t, res, lenr, poly2, len2, mod); lenr = lenr + len2 - 1; } else { _nmod_poly_mullow(t, res, lenr, poly2, len2, n, mod); lenr = n; } _nmod_poly_add(res, t, lenr, poly1 + i, 1, mod); } _nmod_vec_zero(res + lenr, n - lenr); _nmod_vec_clear(t); } }
/*--------------------------------------------------------*/ mp_limb_t nmod_poly_find_root_seed(long ord, long start, nmod_t mod){ long i; for (i = 0; i < mod.n; i++){ mp_limb_t loc = nmod_add(start, i, mod); if (loc == 0) continue; long done = 1; mp_limb_t rho = loc, tmp = 1; long j; for (j = 1; j <= ord; j++){ tmp = nmod_mul(tmp, rho, mod); if (tmp == 1) // invariant: tmp = rho^j done = 0; } if (done == 1) return loc; } return 0; }
/*------------------------------------------------------------*/ void check(int opt){ long i; flint_rand_t state; flint_randinit(state); for (i = 1; i < 1000; i+=10){ mp_limb_t n = 0; while (n < i) n = n_randtest_prime(state, 0); nmod_poly_t P; mp_ptr roots; nmod_poly_t A; nmod_poly_init(P, n); roots = _nmod_vec_init(i); _nmod_vec_randtest(roots, state, i, P->mod); nmod_poly_product_roots_nmod_vec(P, roots, i); nmod_poly_init(A, n); nmod_poly_rand_dense(A, state, i); if (opt == 1){ mp_limb_t tr1 = nmod_poly_trace(A, P); mp_limb_t tr2 = 0; long j; for (j = 0; j < i; j++) tr2 = nmod_add(tr2, nmod_poly_evaluate_nmod(A, roots[j]), P->mod); sage_output_init(P->mod); sage_output_assign_poly(P, "P"); printf("tr1 = %lu\n", tr1); printf("tr2 = %lu\n", tr2); printf("tr1 == tr2\n"); } else{ double t, u; long j; t = util_gettime(); for (j = 0; j < 10000; j++) nmod_poly_trace(A, P); t = util_gettime() - t; nmod_poly_t tmp1, tmp2, tmp3; nmod_poly_init(tmp1, n); nmod_poly_init(tmp2, n); nmod_poly_init(tmp3, n); nmod_poly_rand_dense(tmp1, state, i); nmod_poly_rand_dense(tmp2, state, i); u = util_gettime(); for (j = 0; j < 10000; j++) nmod_poly_mul(tmp3, tmp1, tmp2); u = util_gettime() - u; nmod_poly_clear(tmp1); nmod_poly_clear(tmp2); nmod_poly_clear(tmp3); printf("%lu %f %f\n", i, t, u); } nmod_poly_clear(P); nmod_poly_clear(A); _nmod_vec_clear(roots); } }