ulong dlog_once(ulong b, ulong a, const nmod_t mod, ulong n) { if (b == 1) return 0; if (n < 50) { slong k; ulong ak = 1; for (k = 0; k < n; k++) { if (ak == b) return k; ak = nmod_mul(ak, a, mod); } flint_printf("FAIL[dlog once]: log(%wu,%wu) mod %wu not found (size %wu)\n", b, a, mod.n, n); flint_abort(); return 0; /* dummy return because flint_abort() is not declared noreturn */ } else { ulong l; dlog_precomp_t pre; dlog_precomp_n_init(pre, a, mod.n, n, 1); l = dlog_precomp(pre, b); dlog_precomp_clear(pre); return l; } }
int dirichlet_char_next_primitive(dirichlet_char_t x, const dirichlet_group_t G) { /* update index avoiding multiples of p except for first component if 8|q */ slong k; /* if (G->neven == 2) { x->n = nmod_mul(x->n, G->generators[0], G->mod); x->log[0]++; if (x->log[0] == 1) return 0; x->log[0] = 0; k = 1; } */ for (k = G->num - 1; k >= 0; k--) { #if 1 x->n = nmod_mul(x->n, G->generators[k], G->mod); x->log[k]++; if (x->log[k] % G->P[k].p == 0) { x->n = nmod_mul(x->n, G->generators[k], G->mod); x->log[k]++; } if (x->log[k] < G->P[k].phi.n) break; if (x->log[k] == G->P[k].phi.n) x->n = nmod_mul(x->n, G->generators[k], G->mod); x->log[k] = 1; #else do { x->n = nmod_mul(x->n, G->generators[k], G->mod); x->log[k]++; } while (x->log[k] % G->P[k].p == 0); if (x->log[k] < G->P[k].phi) break; if (x->log[k] == G->P[k].phi) x->n = nmod_mul(x->n, G->generators[k], G->mod); x->log[k] = 1; #endif } /* return last index modified */ return k; }
void _nmod_poly_interpolate_nmod_vec_barycentric(mp_ptr poly, mp_srcptr xs, mp_srcptr ys, slong n, nmod_t mod) { mp_ptr P, Q, w; slong i, j; if (n == 1) { poly[0] = ys[0]; return; } P = _nmod_vec_init(n + 1); Q = _nmod_vec_init(n); w = _nmod_vec_init(n); _nmod_poly_product_roots_nmod_vec(P, xs, n, mod); for (i = 0; i < n; i++) { w[i] = UWORD(1); for (j = 0; j < n; j++) { if (i != j) w[i] = nmod_mul(w[i], nmod_sub(xs[i], xs[j], mod), mod); } w[i] = n_invmod(w[i], mod.n); } _nmod_vec_zero(poly, n); for (i = 0; i < n; i++) { _nmod_poly_div_root(Q, P, n + 1, xs[i], mod); _nmod_vec_scalar_addmul_nmod(poly, Q, n, nmod_mul(w[i], ys[i], mod), mod); } _nmod_vec_clear(P); _nmod_vec_clear(Q); _nmod_vec_clear(w); }
/* 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]; }
ulong dlog_crt_init(dlog_crt_t t, ulong a, ulong mod, ulong n, ulong num) { int k; n_factor_t fac; ulong * M, * u; ulong cost = 0; n_factor_init(&fac); n_factor(&fac, n, 1); t->num = fac.num; nmod_init(&t->mod,mod); nmod_init(&t->n, n); M = t->expo = flint_malloc(t->num * sizeof(ulong)); u = t->crt_coeffs = flint_malloc(t->num * sizeof(ulong)); t->pre = flint_malloc(t->num * sizeof(dlog_precomp_struct)); for (k = 0; k < t->num; k++) { ulong p, e, mk; p = fac.p[k]; e = fac.exp[k]; if (0 && mod % p == 0) { flint_printf("dlog_crt_init: modulus must be prime to order.\n"); abort(); } mk = n_pow(p, e); M[k] = n / mk; u[k] = nmod_mul(M[k], n_invmod(M[k] % mk, mk), t->n); /* depends on the power */ #if 0 flint_printf("[sub-crt -- init for size %wu mod %wu]\n", mk, mod); #endif dlog_precomp_pe_init(t->pre + k, nmod_pow_ui(a, M[k], t->mod), mod, p, e, mk, num); cost += t->pre[k].cost; } #if 0 if (cost > 500) flint_printf("[crt init for size %wu mod %wu -> cost %wu]\n", n,mod,cost); #endif return cost; }
/*--------------------------------------------------------*/ 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; }
int main(void) { slong i; FLINT_TEST_INIT(state); flint_printf("rref...."); fflush(stdout); for (i = 0; i < 1000 * flint_test_multiplier(); i++) { nmod_mat_t A, B, C, D; mp_limb_t mod; slong j, k, m, n, rank1, rank2; slong *perm; int equal; mp_limb_t c; mod = n_randtest_prime(state, 0); m = n_randint(state, 20); n = n_randint(state, 20); perm = _perm_init(2*m); nmod_mat_init(A, m, n, mod); nmod_mat_init(D, 2*m, n, mod); nmod_mat_randtest(A, state); nmod_mat_init_set(B, A); nmod_mat_init_set(C, A); rank1 = nmod_mat_rref(B); if (!check_rref_form(perm, B, rank1)) { flint_printf("FAIL (malformed rref)\n"); nmod_mat_print_pretty(A); flint_printf("\n\n"); nmod_mat_print_pretty(B); flint_printf("\n\n"); abort(); } /* Concatenate the original matrix with the rref, scramble the rows, and check that the rref is the same */ _perm_randtest(perm, 2 * m, state); for (j = 0; j < m; j++) { do { c = n_randint(state, mod); } while (c == 0); for (k = 0; k < n; k++) nmod_mat_entry(D, perm[j], k) = nmod_mul(nmod_mat_entry(A, j, k), c, A->mod); } for (j = 0; j < m; j++) { do { c = n_randint(state, mod); } while (c == 0); for (k = 0; k < n; k++) nmod_mat_entry(D, perm[m + j], k) = nmod_mul(nmod_mat_entry(B, j, k), c, A->mod); } rank2 = nmod_mat_rref(D); equal = (rank1 == rank2); if (equal) { for (j = 0; j < rank2; j++) for (k = 0; k < n; k++) equal = equal && (nmod_mat_entry(B, j, k) == nmod_mat_entry(D, j, k)); for (j = rank2; j < 2 * rank2; j++) for (k = 0; k < n; k++) equal = equal && (nmod_mat_entry(D, j, k) == 0); } if (!equal) { flint_printf("FAIL (rank1 = %wd, rank2 = %wd)!\n", rank1, rank2); nmod_mat_print_pretty(A); flint_printf("\n\n"); nmod_mat_print_pretty(B); flint_printf("\n\n"); nmod_mat_print_pretty(D); flint_printf("\n\n"); abort(); } _perm_clear(perm); nmod_mat_clear(A); nmod_mat_clear(B); nmod_mat_clear(C); nmod_mat_clear(D); } FLINT_TEST_CLEANUP(state); flint_printf("PASS\n"); return 0; }