From e6f8dcdfdb13ce0d72f5fe4327de0f150565f432 Mon Sep 17 00:00:00 2001 From: Dimitri LESNOFF Date: Thu, 30 Oct 2025 12:05:00 +0100 Subject: [PATCH 01/11] Add _nmod_vec_rand --- src/nmod_vec.h | 2 ++ src/nmod_vec/randtest.c | 7 +++++++ 2 files changed, 9 insertions(+) diff --git a/src/nmod_vec.h b/src/nmod_vec.h index cb44dbd4cb..2c41c3e8b3 100644 --- a/src/nmod_vec.h +++ b/src/nmod_vec.h @@ -46,6 +46,8 @@ void _nmod_vec_clear(nn_ptr vec) } void _nmod_vec_randtest(nn_ptr vec, flint_rand_t state, slong len, nmod_t mod); +void _nmod_vec_rand(nn_ptr vec, flint_rand_t state, slong len, nmod_t mod); + NMOD_VEC_INLINE void _nmod_vec_zero(nn_ptr vec, slong len) diff --git a/src/nmod_vec/randtest.c b/src/nmod_vec/randtest.c index 950050f27b..e25d9f55a9 100644 --- a/src/nmod_vec/randtest.c +++ b/src/nmod_vec/randtest.c @@ -11,6 +11,13 @@ #include "nmod_vec.h" +void _nmod_vec_rand(nn_ptr vec, flint_rand_t state, slong len, nmod_t mod) +{ + slong i; + for (i = 0; i < len; i++) + vec[i] = n_randint(state, mod.n); +} + void _nmod_vec_randtest(nn_ptr vec, flint_rand_t state, slong len, nmod_t mod) { slong i, sparseness; From 4ea9a57bea3dc5267d64af160b0d021b44bdd9c8 Mon Sep 17 00:00:00 2001 From: Dimitri LESNOFF Date: Wed, 29 Oct 2025 11:55:32 +0100 Subject: [PATCH 02/11] Add nmod_poly rand funcs --- doc/source/nmod_poly.rst | 15 +++++++++++++-- src/nmod_poly.h | 4 ++++ src/nmod_poly/randtest.c | 28 ++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 2 deletions(-) diff --git a/doc/source/nmod_poly.rst b/doc/source/nmod_poly.rst index 3adcc74198..efd505b482 100644 --- a/doc/source/nmod_poly.rst +++ b/doc/source/nmod_poly.rst @@ -217,14 +217,25 @@ Assignment and basic manipulation Randomization -------------------------------------------------------------------------------- +.. function:: void nmod_poly_rand(nmod_poly_t poly, flint_rand_t state, slong len) + + Generates a random polynomial with length up to ``len``. + +.. function:: void nmod_poly_rand_monic(nmod_poly_t poly, flint_rand_t state, slong len) + + Generates a random monic polynomial with length up to ``len``. + +.. function:: void nmod_poly_rand_irreducible(nmod_poly_t poly, flint_rand_t state, slong len) + + Generates a random irreducible polynomial with length up to ``len``. .. function:: void nmod_poly_randtest(nmod_poly_t poly, flint_rand_t state, slong len) - Generates a random polynomial with length up to ``len``. + Generates a random and sparse with increased probability polynomial with length up to ``len``. .. function:: void nmod_poly_randtest_monic(nmod_poly_t poly, flint_rand_t state, slong len) - Generates a random monic polynomial with length ``len``. + Generates a random and sparse with increased probability monic polynomial with length ``len``. .. function:: void nmod_poly_randtest_trinomial(nmod_poly_t poly, flint_rand_t state, slong len) diff --git a/src/nmod_poly.h b/src/nmod_poly.h index ca86f6f92a..226d0830c0 100644 --- a/src/nmod_poly.h +++ b/src/nmod_poly.h @@ -213,6 +213,10 @@ int nmod_poly_is_monic(const nmod_poly_t poly) /* Randomisation ************************************************************/ +void nmod_poly_rand(nmod_poly_t poly, flint_rand_t state, slong len); +void nmod_poly_rand_monic(nmod_poly_t poly, flint_rand_t state, slong len); +void nmod_poly_rand_irreducible(nmod_poly_t poly, flint_rand_t state, slong len); + void nmod_poly_randtest(nmod_poly_t poly, flint_rand_t state, slong len); NMOD_POLY_INLINE diff --git a/src/nmod_poly/randtest.c b/src/nmod_poly/randtest.c index 27eb52160c..cce1ede11a 100644 --- a/src/nmod_poly/randtest.c +++ b/src/nmod_poly/randtest.c @@ -14,6 +14,34 @@ #include "nmod_poly.h" #include "nmod_poly_factor.h" +// Rand functions -> random dense polynomials with high probability +void +nmod_poly_rand(nmod_poly_t poly, flint_rand_t state, slong len) +{ + nmod_poly_fit_length(poly, len); + _nmod_vec_rand(poly->coeffs, state, len, poly->mod); + poly->length = len; + _nmod_poly_normalise(poly); +} + +void +nmod_poly_rand_monic(nmod_poly_t poly, flint_rand_t state, slong len) +{ + nmod_poly_fit_length(poly, len); + _nmod_vec_rand(poly->coeffs, state, len - 1, poly->mod); + poly->coeffs[len - 1] = 1; + poly->length = len; +} + +void +nmod_poly_rand_irreducible(nmod_poly_t poly, flint_rand_t state, slong len) +{ + do { + nmod_poly_rand(poly, state, len); + } while (nmod_poly_is_zero(poly) || !(nmod_poly_is_irreducible(poly))); +} + +// Randtest functions -> dense/sparse polynomials void nmod_poly_randtest(nmod_poly_t poly, flint_rand_t state, slong len) { From 4f0ef9b94acc54c8624fd7c21640cd2a5b14c800 Mon Sep 17 00:00:00 2001 From: Dimitri LESNOFF Date: Wed, 29 Oct 2025 14:23:14 +0100 Subject: [PATCH 03/11] Add nmod_poly_mat rand funcs --- doc/source/nmod_poly_mat.rst | 7 +++++-- src/nmod_poly_mat.h | 1 + src/nmod_poly_mat/rand.c | 11 +++++++++++ 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/doc/source/nmod_poly_mat.rst b/doc/source/nmod_poly_mat.rst index 1979f2243b..7f281015b7 100644 --- a/doc/source/nmod_poly_mat.rst +++ b/doc/source/nmod_poly_mat.rst @@ -138,10 +138,13 @@ Random matrix generation -------------------------------------------------------------------------------- +.. function:: void nmod_poly_mat_rand(nmod_poly_mat_t mat, flint_rand_t state, slong len) + + Generates a matrix of polynomials with uniformly generated coefficients. + .. function:: void nmod_poly_mat_randtest(nmod_poly_mat_t mat, flint_rand_t state, slong len) - This is equivalent to applying ``nmod_poly_randtest`` to all entries - in the matrix. + Generates a matrix of polynomials sparse with an increased probability. It is equivalent to apply ``nmod_poly_randtest`` to all entries in the matrix. .. function:: void nmod_poly_mat_randtest_sparse(nmod_poly_mat_t A, flint_rand_t state, slong len, float density) diff --git a/src/nmod_poly_mat.h b/src/nmod_poly_mat.h index 135cd4d491..a6888d5957 100644 --- a/src/nmod_poly_mat.h +++ b/src/nmod_poly_mat.h @@ -141,6 +141,7 @@ void nmod_poly_mat_one(nmod_poly_mat_t mat); /* Random matrices ***********************************************************/ +void nmod_poly_mat_rand(nmod_poly_mat_t A, flint_rand_t state, slong len); void nmod_poly_mat_randtest(nmod_poly_mat_t mat, flint_rand_t state, slong len); diff --git a/src/nmod_poly_mat/rand.c b/src/nmod_poly_mat/rand.c index 95e28eecd0..5853dc608e 100644 --- a/src/nmod_poly_mat/rand.c +++ b/src/nmod_poly_mat/rand.c @@ -12,6 +12,17 @@ #include "nmod_poly.h" #include "nmod_poly_mat.h" +void +nmod_poly_mat_rand(nmod_poly_mat_t A, flint_rand_t state, slong len) +{ + slong i, j; + + for (i = 0; i < A->r; i++) + for (j = 0; j < A->c; j++) + nmod_poly_rand(nmod_poly_mat_entry(A, i, j), state, len); +} + + void nmod_poly_mat_randtest(nmod_poly_mat_t A, flint_rand_t state, slong len) { From cacfb536e13a84596b9810046140b9b882fb7dc2 Mon Sep 17 00:00:00 2001 From: Dimitri LESNOFF Date: Wed, 29 Oct 2025 15:22:23 +0100 Subject: [PATCH 04/11] Add fmpz_mod_poly_rand, rand_monic, irred funcs The randtest functions are using `randm` which generates positive coefficients in [0, m) range with m the modulus given by the context. The documentation told that the coefficients are randomly signed, so I fixed that. I introduced a `randm_nonzero` function in fmpz to ensure that coefficients are nonzero and replaced all occurences of `randm` in `fmpz_mod_poly_randtest` functions by this new function. Apart from the `rand` function, this introduces a `rand_monic` and a `rand_irreducible` function. --- doc/source/fmpz.rst | 4 +++ doc/source/fmpz_poly.rst | 18 +++++++++- src/fmpz.h | 1 + src/fmpz/rand.c | 6 ++++ src/fmpz_mod_poly.h | 9 +++++ src/fmpz_mod_poly/randtest.c | 65 ++++++++++++++++++++++++++++++------ 6 files changed, 92 insertions(+), 11 deletions(-) diff --git a/doc/source/fmpz.rst b/doc/source/fmpz.rst index 98ee42436e..b783348777 100644 --- a/doc/source/fmpz.rst +++ b/doc/source/fmpz.rst @@ -267,6 +267,10 @@ should call :func:`flint_rand_clear` to clean up. Generates a random integer in the range `0` to `m - 1` inclusive. +.. function:: void fmpz_randm_nonzero(fmpz_t f, flint_rand_t state, const fmpz_t m) + + Generates a random integer in the range `1` to `m - 1` inclusive. + .. function:: void fmpz_randtest_mod(fmpz_t f, flint_rand_t state, const fmpz_t m) Generates a random integer in the range `0` to `m - 1` inclusive, with an diff --git a/doc/source/fmpz_poly.rst b/doc/source/fmpz_poly.rst index d984d69bed..ce10915764 100644 --- a/doc/source/fmpz_poly.rst +++ b/doc/source/fmpz_poly.rst @@ -284,12 +284,28 @@ Assignment and basic manipulation Randomisation -------------------------------------------------------------------------------- +.. function:: void fmpz_mod_poly_rand(fmpz_mod_poly_t f, flint_rand_t state, slong len, const fmpz_mod_ctx_t ctx) + + Sets `f` to a random polynomial with up to the given length and where + each coefficient has up to the given number of bits. The coefficients + are uniformly generated random numbers in `[0, n)`, where `n` is the modulus given by the context `ctx`. + +.. function:: void fmpz_mod_poly_rand_monic(fmpz_mod_poly_t f, flint_rand_t state, slong len, const fmpz_mod_ctx_t ctx) + + Sets `f` to a random monic polynomial with up to the given length and where + each coefficient has up to the given number of bits. The coefficients + are uniformly generated random numbers in `[0, n)`, where `n` is the modulus given by the context `ctx`. + +.. function:: void fmpz_mod_poly_rand_irreducible(fmpz_mod_poly_t f, flint_rand_t state, slong len, const fmpz_mod_ctx_t ctx) + + Sets `f` to a random irreducible polynomial with up to the given length and where each coefficient has up to the given number of bits. The coefficients + are uniformly generated random numbers in `[0, n)`, where `n` is the modulus given by the context `ctx`. .. function:: void fmpz_poly_randtest(fmpz_poly_t f, flint_rand_t state, slong len, flint_bitcnt_t bits) Sets `f` to a random polynomial with up to the given length and where each coefficient has up to the given number of bits. The coefficients - are signed randomly. + are random numbers in `[1, n)`, where `n` is the modulus given by the context `ctx`. .. function:: void fmpz_poly_randtest_unsigned(fmpz_poly_t f, flint_rand_t state, slong len, flint_bitcnt_t bits) diff --git a/src/fmpz.h b/src/fmpz.h index c8a1c59d43..c3c21a4d42 100644 --- a/src/fmpz.h +++ b/src/fmpz.h @@ -112,6 +112,7 @@ int _fmpz_is_canonical(const fmpz_t x); void fmpz_randbits_unsigned(fmpz_t f, flint_rand_t state, flint_bitcnt_t bits); void fmpz_randbits(fmpz_t f, flint_rand_t state, flint_bitcnt_t bits); void fmpz_randm(fmpz_t f, flint_rand_t state, const fmpz_t m); +void fmpz_randm_nonzero(fmpz_t f, flint_rand_t state, const fmpz_t m); void fmpz_randtest(fmpz_t f, flint_rand_t state, flint_bitcnt_t bits); void fmpz_randtest_unsigned(fmpz_t f, flint_rand_t state, flint_bitcnt_t bits); void fmpz_randtest_not_zero(fmpz_t f, flint_rand_t state, flint_bitcnt_t bits); diff --git a/src/fmpz/rand.c b/src/fmpz/rand.c index dfdedce336..b629dd0aa8 100644 --- a/src/fmpz/rand.c +++ b/src/fmpz/rand.c @@ -71,6 +71,12 @@ fmpz_randm(fmpz_t f, flint_rand_t state, const fmpz_t m) } } +void fmpz_randm_nonzero(fmpz_t f, flint_rand_t state, const fmpz_t m) { + fmpz_randm(f, state, m); + if (fmpz_is_zero(f)) + fmpz_one(f); +} + void fmpz_randprime(fmpz_t f, flint_rand_t state, flint_bitcnt_t bits, int proved) { if (bits <= FLINT_BITS) diff --git a/src/fmpz_mod_poly.h b/src/fmpz_mod_poly.h index dc245cd3ae..53b388abbb 100644 --- a/src/fmpz_mod_poly.h +++ b/src/fmpz_mod_poly.h @@ -134,6 +134,15 @@ int fmpz_mod_poly_is_canonical(const fmpz_mod_poly_t A, const fmpz_mod_ctx_t ctx /* Randomisation ************************************************************/ +void fmpz_mod_poly_rand(fmpz_mod_poly_t f, flint_rand_t state, + slong len, const fmpz_mod_ctx_t ctx); + +void fmpz_mod_poly_rand_monic(fmpz_mod_poly_t f, + flint_rand_t state, slong len, const fmpz_mod_ctx_t ctx); + +void fmpz_mod_poly_rand_irreducible(fmpz_mod_poly_t f, + flint_rand_t state, slong len, const fmpz_mod_ctx_t ctx); + void fmpz_mod_poly_randtest(fmpz_mod_poly_t f, flint_rand_t state, slong len, const fmpz_mod_ctx_t ctx); diff --git a/src/fmpz_mod_poly/randtest.c b/src/fmpz_mod_poly/randtest.c index 97b2830f51..8397a853af 100644 --- a/src/fmpz_mod_poly/randtest.c +++ b/src/fmpz_mod_poly/randtest.c @@ -17,7 +17,7 @@ #include "fmpz_mod_poly.h" #include "fmpz_mod_poly_factor.h" -void fmpz_mod_poly_randtest(fmpz_mod_poly_t f, flint_rand_t state, slong len, +void fmpz_mod_poly_rand(fmpz_mod_poly_t f, flint_rand_t state, slong len, const fmpz_mod_ctx_t ctx) { slong i; @@ -31,7 +31,7 @@ void fmpz_mod_poly_randtest(fmpz_mod_poly_t f, flint_rand_t state, slong len, _fmpz_mod_poly_normalise(f); } -void fmpz_mod_poly_randtest_monic(fmpz_mod_poly_t f, flint_rand_t state, +void fmpz_mod_poly_rand_monic(fmpz_mod_poly_t f, flint_rand_t state, slong len, const fmpz_mod_ctx_t ctx) { slong i; @@ -48,6 +48,51 @@ void fmpz_mod_poly_randtest_monic(fmpz_mod_poly_t f, flint_rand_t state, _fmpz_mod_poly_set_length(f, len); } +void fmpz_mod_poly_rand_irreducible(fmpz_mod_poly_t f, flint_rand_t state, + slong len, const fmpz_mod_ctx_t ctx) +{ + if (len == 0) + { + flint_throw(FLINT_ERROR, "Exception (fmpz_mod_poly_randtest_irreducible). len == 0.\n"); + } + + do { + fmpz_mod_poly_rand(f, state, len, ctx); + } while (fmpz_mod_poly_is_zero(f, ctx) || + !fmpz_mod_poly_is_irreducible(f, ctx)); +} + +void fmpz_mod_poly_randtest(fmpz_mod_poly_t f, flint_rand_t state, slong len, + const fmpz_mod_ctx_t ctx) +{ + slong i; + + fmpz_mod_poly_fit_length(f, len, ctx); + + for (i = 0; i < len; i++) + fmpz_randm_nonzero(f->coeffs + i, state, fmpz_mod_ctx_modulus(ctx)); + + _fmpz_mod_poly_set_length(f, len); + _fmpz_mod_poly_normalise(f); +} + +void fmpz_mod_poly_randtest_monic(fmpz_mod_poly_t f, flint_rand_t state, + slong len, const fmpz_mod_ctx_t ctx) +{ + slong i; + + FLINT_ASSERT(len > 0); + + fmpz_mod_poly_fit_length(f, len, ctx); + + for (i = 0; i < len - 1; i++) + fmpz_randm_nonzero(f->coeffs + i, state, fmpz_mod_ctx_modulus(ctx)); + + fmpz_one(f->coeffs + len - 1); + + _fmpz_mod_poly_set_length(f, len); +} + static void fmpz_mod_poly_randtest_monic_sparse(fmpz_mod_poly_t poly, flint_rand_t state, slong len, slong nonzero, const fmpz_mod_ctx_t ctx) @@ -56,9 +101,9 @@ fmpz_mod_poly_randtest_monic_sparse(fmpz_mod_poly_t poly, flint_rand_t state, fmpz_mod_poly_fit_length(poly, len, ctx); _fmpz_vec_zero(poly->coeffs, len); - fmpz_randm(poly->coeffs + 0, state, fmpz_mod_ctx_modulus(ctx)); + fmpz_randm_nonzero(poly->coeffs + 0, state, fmpz_mod_ctx_modulus(ctx)); for (i = 1; i < nonzero; i++) - fmpz_randm(poly->coeffs + n_randint(state, len - 1) + 1, + fmpz_randm_nonzero(poly->coeffs + n_randint(state, len - 1) + 1, state, fmpz_mod_ctx_modulus(ctx)); fmpz_set_ui(poly->coeffs + len - 1, 1); _fmpz_mod_poly_set_length(poly, len); @@ -127,9 +172,9 @@ void fmpz_mod_poly_randtest_trinomial(fmpz_mod_poly_t poly, ulong k; fmpz_mod_poly_fit_length(poly, len, ctx); _fmpz_vec_zero(poly->coeffs, len); - fmpz_randm(poly->coeffs, state, fmpz_mod_ctx_modulus(ctx)); + fmpz_randm_nonzero(poly->coeffs, state, fmpz_mod_ctx_modulus(ctx)); k = (n_randtest(state) % (len - 2)) + 1; - fmpz_randm(poly->coeffs + k, state, fmpz_mod_ctx_modulus(ctx)); + fmpz_randm_nonzero(poly->coeffs + k, state, fmpz_mod_ctx_modulus(ctx)); fmpz_one(poly->coeffs + len - 1); _fmpz_mod_poly_set_length(poly, len); } @@ -139,10 +184,10 @@ void fmpz_mod_poly_randtest_pentomial(fmpz_mod_poly_t poly, { fmpz_mod_poly_fit_length(poly, len, ctx); _fmpz_vec_zero(poly->coeffs, len); - fmpz_randm(poly->coeffs, state, fmpz_mod_ctx_modulus(ctx)); - fmpz_randm(poly->coeffs + 1, state, fmpz_mod_ctx_modulus(ctx)); - fmpz_randm(poly->coeffs + 2, state, fmpz_mod_ctx_modulus(ctx)); - fmpz_randm(poly->coeffs + 3, state, fmpz_mod_ctx_modulus(ctx)); + fmpz_randm_nonzero(poly->coeffs, state, fmpz_mod_ctx_modulus(ctx)); + fmpz_randm_nonzero(poly->coeffs + 1, state, fmpz_mod_ctx_modulus(ctx)); + fmpz_randm_nonzero(poly->coeffs + 2, state, fmpz_mod_ctx_modulus(ctx)); + fmpz_randm_nonzero(poly->coeffs + 3, state, fmpz_mod_ctx_modulus(ctx)); fmpz_one(poly->coeffs + len - 1); _fmpz_mod_poly_set_length(poly, len); } From bb5d986536e7b567dce420b71e7a63a32fa52819 Mon Sep 17 00:00:00 2001 From: Dimitri LESNOFF Date: Wed, 29 Oct 2025 16:37:54 +0100 Subject: [PATCH 05/11] Add fmpz_mod_vec_rand --- doc/source/fmpz_mod_vec.rst | 9 ++++++++- src/fmpz_mod_vec.h | 2 ++ src/fmpz_mod_vec/rand.c | 10 ++++++++++ 3 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 src/fmpz_mod_vec/rand.c diff --git a/doc/source/fmpz_mod_vec.rst b/doc/source/fmpz_mod_vec.rst index dd6902b76e..abd08d652a 100644 --- a/doc/source/fmpz_mod_vec.rst +++ b/doc/source/fmpz_mod_vec.rst @@ -8,7 +8,7 @@ Conversions .. function:: void _fmpz_mod_vec_set_fmpz_vec(fmpz * A, const fmpz * B, slong len, const fmpz_mod_ctx_t ctx) - Set the `fmpz_mod_vec` `(A, len)` to the `fmpz_vec` `(B, len)` after + Set the `fmpz_{mod}_{vec}` `(A, len)` to the `fmpz_{vec}` `(B, len)` after reduction of each entry modulo the modulus.. Arithmetic @@ -61,3 +61,10 @@ Multiplication .. function:: void _fmpz_mod_vec_mul(fmpz * A, const fmpz * B, const fmpz * C, slong len, const fmpz_mod_ctx_t ctx) Set `(A, len)` the pointwise multiplication of `(B, len)` and `(C, len)`. + +Random functions +-------------------------------------------------------------------------------- + +.. function:: void _fmpz_mod_vec_rand(fmpz * A, flint_rand_t state, slong len, const fmpz_mod_ctx_t ctx) + + Sets ``vec`` to a vector of the given length with entries picked uniformly at random in `[0, mod.n)`. diff --git a/src/fmpz_mod_vec.h b/src/fmpz_mod_vec.h index 50afb1b88a..3af73e5c4d 100644 --- a/src/fmpz_mod_vec.h +++ b/src/fmpz_mod_vec.h @@ -55,6 +55,8 @@ void _fmpz_mod_vec_dot(fmpz_t d, const fmpz * A, const fmpz * B, void _fmpz_mod_vec_dot_rev(fmpz_t r, const fmpz * a, const fmpz * b, slong len, const fmpz_mod_ctx_t ctx); +void _fmpz_mod_vec_rand(fmpz *A, flint_rand_t state, slong len, const fmpz_mod_ctx_t ctx); + #ifdef __cplusplus } #endif diff --git a/src/fmpz_mod_vec/rand.c b/src/fmpz_mod_vec/rand.c new file mode 100644 index 0000000000..70c3549e2d --- /dev/null +++ b/src/fmpz_mod_vec/rand.c @@ -0,0 +1,10 @@ +#include "fmpz.h" +#include "fmpz_mod.h" +#include "fmpz_mod_vec.h" + +void _fmpz_mod_vec_rand(fmpz *A, flint_rand_t state, slong len, const fmpz_mod_ctx_t ctx) +{ + slong i; + for (i = 0; i < len; i++) + fmpz_randm(A + i, state, fmpz_mod_ctx_modulus(ctx)); +} From 400598aff3282544f95a69824477d28f68271a9f Mon Sep 17 00:00:00 2001 From: Dimitri LESNOFF Date: Wed, 29 Oct 2025 16:39:23 +0100 Subject: [PATCH 06/11] Add a rand function to mpn_mod --- doc/source/mpn_mod.rst | 1 + src/mpn_mod/ring.c | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/doc/source/mpn_mod.rst b/doc/source/mpn_mod.rst index 7e6ec0fbbf..b3a6857272 100644 --- a/doc/source/mpn_mod.rst +++ b/doc/source/mpn_mod.rst @@ -109,6 +109,7 @@ Basic operations and arithmetic int mpn_mod_set_mpn(nn_ptr res, nn_srcptr x, slong xn, gr_ctx_t ctx) int mpn_mod_set_fmpz(nn_ptr res, const fmpz_t x, gr_ctx_t ctx) int mpn_mod_set_other(nn_ptr res, gr_ptr v, gr_ctx_t v_ctx, gr_ctx_t ctx) + int mpn_mod_rand(nn_ptr res, flint_rand_t state, gr_ctx_t ctx) int mpn_mod_randtest(nn_ptr res, flint_rand_t state, gr_ctx_t ctx) int mpn_mod_write(gr_stream_t out, nn_srcptr x, gr_ctx_t ctx) int mpn_mod_get_fmpz(fmpz_t res, nn_srcptr x, gr_ctx_t ctx) diff --git a/src/mpn_mod/ring.c b/src/mpn_mod/ring.c index e822705371..5a0baae9b6 100644 --- a/src/mpn_mod/ring.c +++ b/src/mpn_mod/ring.c @@ -202,6 +202,18 @@ mpn_mod_set_other(nn_ptr res, gr_ptr v, gr_ctx_t v_ctx, gr_ctx_t ctx) return gr_generic_set_other(res, v, v_ctx, ctx); } +int +mpn_mod_rand(nn_ptr res, flint_rand_t state, gr_ctx_t ctx) +{ + fmpz_t t; + fmpz_init(t); + fmpz_set_ui_array(t, MPN_MOD_CTX_MODULUS(ctx), MPN_MOD_CTX_NLIMBS(ctx)); + fmpz_randm(t, state, t); + GR_IGNORE(mpn_mod_set_fmpz(res, t, ctx)); + fmpz_clear(t); + return GR_SUCCESS; +} + int mpn_mod_randtest(nn_ptr res, flint_rand_t state, gr_ctx_t ctx) { From 9060505154313a2d1705504e14168d6d827d6cad Mon Sep 17 00:00:00 2001 From: Dimitri LESNOFF Date: Wed, 29 Oct 2025 17:39:36 +0100 Subject: [PATCH 07/11] Add mpn_mod_vec_rand func --- src/mpn_mod.h | 2 ++ src/mpn_mod/vec.c | 13 +++++++++++++ 2 files changed, 15 insertions(+) diff --git a/src/mpn_mod.h b/src/mpn_mod.h index 8af7008d00..01adc4f8b5 100644 --- a/src/mpn_mod.h +++ b/src/mpn_mod.h @@ -67,6 +67,7 @@ mpn_mod_ctx_set_is_field(gr_ctx_t ctx, truth_t is_field) int gr_ctx_init_mpn_mod(gr_ctx_t ctx, const fmpz_t n); int _gr_ctx_init_mpn_mod(gr_ctx_t ctx, nn_srcptr n, slong nlimbs); +int mpn_mod_rand(nn_ptr res, flint_rand_t state, gr_ctx_t ctx); void gr_ctx_init_mpn_mod_randtest(gr_ctx_t ctx, flint_rand_t state); int mpn_mod_ctx_write(gr_stream_t out, gr_ctx_t ctx); @@ -191,6 +192,7 @@ int mpn_mod_div(nn_ptr res, nn_srcptr x, nn_srcptr y, gr_ctx_t ctx); int _mpn_mod_vec_zero(nn_ptr res, slong len, gr_ctx_t ctx); int _mpn_mod_vec_clear(nn_ptr FLINT_UNUSED(res), slong FLINT_UNUSED(len), gr_ctx_t FLINT_UNUSED(ctx)); int _mpn_mod_vec_set(nn_ptr res, nn_srcptr x, slong len, gr_ctx_t ctx); +int _mpn_mod_vec_rand(nn_ptr res, flint_rand_t state, slong len, gr_ctx_t ctx); void _mpn_mod_vec_swap(nn_ptr vec1, nn_ptr vec2, slong len, gr_ctx_t ctx); int _mpn_mod_vec_neg(nn_ptr res, nn_srcptr x, slong len, gr_ctx_t ctx); int _mpn_mod_vec_add(nn_ptr res, nn_srcptr x, nn_srcptr y, slong len, gr_ctx_t ctx); diff --git a/src/mpn_mod/vec.c b/src/mpn_mod/vec.c index a01c42b9ea..4d3d8d5286 100644 --- a/src/mpn_mod/vec.c +++ b/src/mpn_mod/vec.c @@ -32,6 +32,19 @@ _mpn_mod_vec_set(nn_ptr res, nn_srcptr x, slong len, gr_ctx_t ctx) return GR_SUCCESS; } +int +_mpn_mod_vec_rand(nn_ptr res, flint_rand_t state, slong len, gr_ctx_t ctx) +{ + slong n = MPN_MOD_CTX_NLIMBS(ctx); + slong i; + + for (i = 0; i < len; i++) + if (mpn_mod_rand(res + i * n, state, ctx) != GR_SUCCESS) + return GR_UNABLE; + + return GR_SUCCESS; +} + void _mpn_mod_vec_swap(nn_ptr vec1, nn_ptr vec2, slong len, gr_ctx_t ctx) { From 59f5c7d794c80911c7cab49f0cf1001fa13a2bf0 Mon Sep 17 00:00:00 2001 From: Dimitri LESNOFF Date: Wed, 29 Oct 2025 19:13:29 +0100 Subject: [PATCH 08/11] Revert "Add fmpz_mod_vec_rand" I added _fmpz_mod_vec_rand with the intent to use it in _mpn_mod_vec_rand but did not use it in the end. This reverts commit f98e52c300d6b6f0a3a54792c4744450dc05f712. --- doc/source/fmpz_mod_vec.rst | 9 +-------- src/fmpz_mod_vec.h | 2 -- src/fmpz_mod_vec/rand.c | 10 ---------- 3 files changed, 1 insertion(+), 20 deletions(-) delete mode 100644 src/fmpz_mod_vec/rand.c diff --git a/doc/source/fmpz_mod_vec.rst b/doc/source/fmpz_mod_vec.rst index abd08d652a..dd6902b76e 100644 --- a/doc/source/fmpz_mod_vec.rst +++ b/doc/source/fmpz_mod_vec.rst @@ -8,7 +8,7 @@ Conversions .. function:: void _fmpz_mod_vec_set_fmpz_vec(fmpz * A, const fmpz * B, slong len, const fmpz_mod_ctx_t ctx) - Set the `fmpz_{mod}_{vec}` `(A, len)` to the `fmpz_{vec}` `(B, len)` after + Set the `fmpz_mod_vec` `(A, len)` to the `fmpz_vec` `(B, len)` after reduction of each entry modulo the modulus.. Arithmetic @@ -61,10 +61,3 @@ Multiplication .. function:: void _fmpz_mod_vec_mul(fmpz * A, const fmpz * B, const fmpz * C, slong len, const fmpz_mod_ctx_t ctx) Set `(A, len)` the pointwise multiplication of `(B, len)` and `(C, len)`. - -Random functions --------------------------------------------------------------------------------- - -.. function:: void _fmpz_mod_vec_rand(fmpz * A, flint_rand_t state, slong len, const fmpz_mod_ctx_t ctx) - - Sets ``vec`` to a vector of the given length with entries picked uniformly at random in `[0, mod.n)`. diff --git a/src/fmpz_mod_vec.h b/src/fmpz_mod_vec.h index 3af73e5c4d..50afb1b88a 100644 --- a/src/fmpz_mod_vec.h +++ b/src/fmpz_mod_vec.h @@ -55,8 +55,6 @@ void _fmpz_mod_vec_dot(fmpz_t d, const fmpz * A, const fmpz * B, void _fmpz_mod_vec_dot_rev(fmpz_t r, const fmpz * a, const fmpz * b, slong len, const fmpz_mod_ctx_t ctx); -void _fmpz_mod_vec_rand(fmpz *A, flint_rand_t state, slong len, const fmpz_mod_ctx_t ctx); - #ifdef __cplusplus } #endif diff --git a/src/fmpz_mod_vec/rand.c b/src/fmpz_mod_vec/rand.c deleted file mode 100644 index 70c3549e2d..0000000000 --- a/src/fmpz_mod_vec/rand.c +++ /dev/null @@ -1,10 +0,0 @@ -#include "fmpz.h" -#include "fmpz_mod.h" -#include "fmpz_mod_vec.h" - -void _fmpz_mod_vec_rand(fmpz *A, flint_rand_t state, slong len, const fmpz_mod_ctx_t ctx) -{ - slong i; - for (i = 0; i < len; i++) - fmpz_randm(A + i, state, fmpz_mod_ctx_modulus(ctx)); -} From eafe4cf4bf11d5b62f4ec58747729db6d06bb021 Mon Sep 17 00:00:00 2001 From: Dimitri LESNOFF Date: Mon, 3 Nov 2025 14:45:44 +0100 Subject: [PATCH 09/11] Replace randm_non_zero by randtest calls --- src/fmpz_mod_poly/randtest.c | 41 ++++++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/src/fmpz_mod_poly/randtest.c b/src/fmpz_mod_poly/randtest.c index 8397a853af..2048568979 100644 --- a/src/fmpz_mod_poly/randtest.c +++ b/src/fmpz_mod_poly/randtest.c @@ -69,8 +69,10 @@ void fmpz_mod_poly_randtest(fmpz_mod_poly_t f, flint_rand_t state, slong len, fmpz_mod_poly_fit_length(f, len, ctx); - for (i = 0; i < len; i++) - fmpz_randm_nonzero(f->coeffs + i, state, fmpz_mod_ctx_modulus(ctx)); + for (i = 0; i < len; i++) { + fmpz_randtest_unsigned(f->coeffs + i, state, fmpz_bits(fmpz_mod_ctx_modulus(ctx) + 1)); + fmpz_mod(f->coeffs + i, f->coeffs + i, fmpz_mod_ctx_modulus(ctx)); + } _fmpz_mod_poly_set_length(f, len); _fmpz_mod_poly_normalise(f); @@ -85,8 +87,10 @@ void fmpz_mod_poly_randtest_monic(fmpz_mod_poly_t f, flint_rand_t state, fmpz_mod_poly_fit_length(f, len, ctx); - for (i = 0; i < len - 1; i++) - fmpz_randm_nonzero(f->coeffs + i, state, fmpz_mod_ctx_modulus(ctx)); + for (i = 0; i < len - 1; i++) { + fmpz_randtest_unsigned(f->coeffs + i, state, fmpz_bits(fmpz_mod_ctx_modulus(ctx) + 1)); + fmpz_mod(f->coeffs + i, f->coeffs + i, fmpz_mod_ctx_modulus(ctx)); + } fmpz_one(f->coeffs + len - 1); @@ -101,10 +105,13 @@ fmpz_mod_poly_randtest_monic_sparse(fmpz_mod_poly_t poly, flint_rand_t state, fmpz_mod_poly_fit_length(poly, len, ctx); _fmpz_vec_zero(poly->coeffs, len); - fmpz_randm_nonzero(poly->coeffs + 0, state, fmpz_mod_ctx_modulus(ctx)); - for (i = 1; i < nonzero; i++) - fmpz_randm_nonzero(poly->coeffs + n_randint(state, len - 1) + 1, - state, fmpz_mod_ctx_modulus(ctx)); + fmpz_randtest_unsigned(poly->coeffs + 0, state, fmpz_bits(fmpz_mod_ctx_modulus(ctx) + 1)); + fmpz_mod(poly->coeffs + 0, poly->coeffs + 0, fmpz_mod_ctx_modulus(ctx)); + for (i = 1; i < nonzero; i++) { + ulong random_idx = n_randint(state, len - 1); + fmpz_randtest_unsigned(poly->coeffs + random_idx + 1, state, fmpz_bits(fmpz_mod_ctx_modulus(ctx) + 1)); + fmpz_mod(poly->coeffs + random_idx + 1, poly->coeffs + random_idx + 1, fmpz_bits(fmpz_mod_ctx_modulus(ctx))); + } fmpz_set_ui(poly->coeffs + len - 1, 1); _fmpz_mod_poly_set_length(poly, len); } @@ -172,9 +179,11 @@ void fmpz_mod_poly_randtest_trinomial(fmpz_mod_poly_t poly, ulong k; fmpz_mod_poly_fit_length(poly, len, ctx); _fmpz_vec_zero(poly->coeffs, len); - fmpz_randm_nonzero(poly->coeffs, state, fmpz_mod_ctx_modulus(ctx)); + fmpz_randtest_unsigned(poly->coeffs, state, fmpz_bits(fmpz_mod_ctx_modulus(ctx) + 1)); + fmpz_mod(poly->coeffs, poly->coeffs, fmpz_mod_ctx_modulus(ctx)); k = (n_randtest(state) % (len - 2)) + 1; - fmpz_randm_nonzero(poly->coeffs + k, state, fmpz_mod_ctx_modulus(ctx)); + fmpz_randtest_unsigned(poly->coeffs + k, state, fmpz_bits(fmpz_mod_ctx_modulus(ctx) + 1)); + fmpz_mod(poly->coeffs + k, poly->coeffs + k, fmpz_mod_ctx_modulus(ctx)); fmpz_one(poly->coeffs + len - 1); _fmpz_mod_poly_set_length(poly, len); } @@ -184,10 +193,14 @@ void fmpz_mod_poly_randtest_pentomial(fmpz_mod_poly_t poly, { fmpz_mod_poly_fit_length(poly, len, ctx); _fmpz_vec_zero(poly->coeffs, len); - fmpz_randm_nonzero(poly->coeffs, state, fmpz_mod_ctx_modulus(ctx)); - fmpz_randm_nonzero(poly->coeffs + 1, state, fmpz_mod_ctx_modulus(ctx)); - fmpz_randm_nonzero(poly->coeffs + 2, state, fmpz_mod_ctx_modulus(ctx)); - fmpz_randm_nonzero(poly->coeffs + 3, state, fmpz_mod_ctx_modulus(ctx)); + fmpz_randtest_unsigned(poly->coeffs, state, fmpz_bits(fmpz_mod_ctx_modulus(ctx) + 1)); + fmpz_mod(poly->coeffs, poly->coeffs, fmpz_mod_ctx_modulus(ctx)); + fmpz_randtest_unsigned(poly->coeffs + 1, state, fmpz_bits(fmpz_mod_ctx_modulus(ctx) + 1)); + fmpz_mod(poly->coeffs + 1, poly->coeffs + 1, fmpz_mod_ctx_modulus(ctx)); + fmpz_randtest_unsigned(poly->coeffs + 2, state, fmpz_bits(fmpz_mod_ctx_modulus(ctx) + 1)); + fmpz_mod(poly->coeffs + 2, poly->coeffs + 2, fmpz_mod_ctx_modulus(ctx)); + fmpz_randtest_unsigned(poly->coeffs + 3, state, fmpz_bits(fmpz_mod_ctx_modulus(ctx) + 1)); + fmpz_mod(poly->coeffs + 3, poly->coeffs + 3, fmpz_mod_ctx_modulus(ctx)); fmpz_one(poly->coeffs + len - 1); _fmpz_mod_poly_set_length(poly, len); } From 4dff27e1a3f8af7d63ac5e3097099b3040951d23 Mon Sep 17 00:00:00 2001 From: Dimitri LESNOFF Date: Mon, 3 Nov 2025 16:17:26 +0100 Subject: [PATCH 10/11] Fix documentation of mpn_mod --- doc/source/mpn_mod.rst | 6 +++++- src/mpn_mod.h | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/doc/source/mpn_mod.rst b/doc/source/mpn_mod.rst index b3a6857272..85dc3b75a8 100644 --- a/doc/source/mpn_mod.rst +++ b/doc/source/mpn_mod.rst @@ -94,6 +94,11 @@ Context objects Basic operations and arithmetic ------------------------------------------------------------------------------- + +.. function:: int mpn_mod_rand(nn_ptr res, flint_rand_t state, gr_ctx_t ctx) + + Generates a coefficient uniformly between `0` and `MPN_MOD_CTX_MODULUS(ctx)` exclusive. + .. function:: int mpn_mod_ctx_write(gr_stream_t out, gr_ctx_t ctx) void mpn_mod_ctx_clear(gr_ctx_t ctx) truth_t mpn_mod_ctx_is_field(gr_ctx_t ctx) @@ -109,7 +114,6 @@ Basic operations and arithmetic int mpn_mod_set_mpn(nn_ptr res, nn_srcptr x, slong xn, gr_ctx_t ctx) int mpn_mod_set_fmpz(nn_ptr res, const fmpz_t x, gr_ctx_t ctx) int mpn_mod_set_other(nn_ptr res, gr_ptr v, gr_ctx_t v_ctx, gr_ctx_t ctx) - int mpn_mod_rand(nn_ptr res, flint_rand_t state, gr_ctx_t ctx) int mpn_mod_randtest(nn_ptr res, flint_rand_t state, gr_ctx_t ctx) int mpn_mod_write(gr_stream_t out, nn_srcptr x, gr_ctx_t ctx) int mpn_mod_get_fmpz(fmpz_t res, nn_srcptr x, gr_ctx_t ctx) diff --git a/src/mpn_mod.h b/src/mpn_mod.h index 01adc4f8b5..8c0c5e7f65 100644 --- a/src/mpn_mod.h +++ b/src/mpn_mod.h @@ -67,7 +67,6 @@ mpn_mod_ctx_set_is_field(gr_ctx_t ctx, truth_t is_field) int gr_ctx_init_mpn_mod(gr_ctx_t ctx, const fmpz_t n); int _gr_ctx_init_mpn_mod(gr_ctx_t ctx, nn_srcptr n, slong nlimbs); -int mpn_mod_rand(nn_ptr res, flint_rand_t state, gr_ctx_t ctx); void gr_ctx_init_mpn_mod_randtest(gr_ctx_t ctx, flint_rand_t state); int mpn_mod_ctx_write(gr_stream_t out, gr_ctx_t ctx); @@ -127,6 +126,7 @@ int mpn_mod_neg_one(nn_ptr res, gr_ctx_t ctx); int mpn_mod_set_mpn(nn_ptr res, nn_srcptr x, slong xn, gr_ctx_t ctx); int mpn_mod_set_fmpz(nn_ptr res, const fmpz_t x, gr_ctx_t ctx); int mpn_mod_set_other(nn_ptr res, gr_ptr v, gr_ctx_t v_ctx, gr_ctx_t ctx); +int mpn_mod_rand(nn_ptr res, flint_rand_t state, gr_ctx_t ctx); int mpn_mod_randtest(nn_ptr res, flint_rand_t state, gr_ctx_t ctx); int mpn_mod_write(gr_stream_t out, nn_srcptr x, gr_ctx_t ctx); From 716a13e00f8d41c9c2da7ba9bc7cc9c5283dfc1b Mon Sep 17 00:00:00 2001 From: Dimitri LESNOFF Date: Mon, 3 Nov 2025 17:15:40 +0100 Subject: [PATCH 11/11] Remove +1 to uint pointers --- src/fmpz_mod_poly/randtest.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/fmpz_mod_poly/randtest.c b/src/fmpz_mod_poly/randtest.c index 2048568979..e722dba9e8 100644 --- a/src/fmpz_mod_poly/randtest.c +++ b/src/fmpz_mod_poly/randtest.c @@ -70,7 +70,7 @@ void fmpz_mod_poly_randtest(fmpz_mod_poly_t f, flint_rand_t state, slong len, fmpz_mod_poly_fit_length(f, len, ctx); for (i = 0; i < len; i++) { - fmpz_randtest_unsigned(f->coeffs + i, state, fmpz_bits(fmpz_mod_ctx_modulus(ctx) + 1)); + fmpz_randtest_unsigned(f->coeffs + i, state, fmpz_bits(fmpz_mod_ctx_modulus(ctx))); fmpz_mod(f->coeffs + i, f->coeffs + i, fmpz_mod_ctx_modulus(ctx)); } @@ -88,7 +88,7 @@ void fmpz_mod_poly_randtest_monic(fmpz_mod_poly_t f, flint_rand_t state, fmpz_mod_poly_fit_length(f, len, ctx); for (i = 0; i < len - 1; i++) { - fmpz_randtest_unsigned(f->coeffs + i, state, fmpz_bits(fmpz_mod_ctx_modulus(ctx) + 1)); + fmpz_randtest_unsigned(f->coeffs + i, state, fmpz_bits(fmpz_mod_ctx_modulus(ctx))); fmpz_mod(f->coeffs + i, f->coeffs + i, fmpz_mod_ctx_modulus(ctx)); } @@ -105,11 +105,11 @@ fmpz_mod_poly_randtest_monic_sparse(fmpz_mod_poly_t poly, flint_rand_t state, fmpz_mod_poly_fit_length(poly, len, ctx); _fmpz_vec_zero(poly->coeffs, len); - fmpz_randtest_unsigned(poly->coeffs + 0, state, fmpz_bits(fmpz_mod_ctx_modulus(ctx) + 1)); + fmpz_randtest_unsigned(poly->coeffs + 0, state, fmpz_bits(fmpz_mod_ctx_modulus(ctx))); fmpz_mod(poly->coeffs + 0, poly->coeffs + 0, fmpz_mod_ctx_modulus(ctx)); for (i = 1; i < nonzero; i++) { ulong random_idx = n_randint(state, len - 1); - fmpz_randtest_unsigned(poly->coeffs + random_idx + 1, state, fmpz_bits(fmpz_mod_ctx_modulus(ctx) + 1)); + fmpz_randtest_unsigned(poly->coeffs + random_idx + 1, state, fmpz_bits(fmpz_mod_ctx_modulus(ctx))); fmpz_mod(poly->coeffs + random_idx + 1, poly->coeffs + random_idx + 1, fmpz_bits(fmpz_mod_ctx_modulus(ctx))); } fmpz_set_ui(poly->coeffs + len - 1, 1); @@ -179,10 +179,10 @@ void fmpz_mod_poly_randtest_trinomial(fmpz_mod_poly_t poly, ulong k; fmpz_mod_poly_fit_length(poly, len, ctx); _fmpz_vec_zero(poly->coeffs, len); - fmpz_randtest_unsigned(poly->coeffs, state, fmpz_bits(fmpz_mod_ctx_modulus(ctx) + 1)); + fmpz_randtest_unsigned(poly->coeffs, state, fmpz_bits(fmpz_mod_ctx_modulus(ctx))); fmpz_mod(poly->coeffs, poly->coeffs, fmpz_mod_ctx_modulus(ctx)); k = (n_randtest(state) % (len - 2)) + 1; - fmpz_randtest_unsigned(poly->coeffs + k, state, fmpz_bits(fmpz_mod_ctx_modulus(ctx) + 1)); + fmpz_randtest_unsigned(poly->coeffs + k, state, fmpz_bits(fmpz_mod_ctx_modulus(ctx))); fmpz_mod(poly->coeffs + k, poly->coeffs + k, fmpz_mod_ctx_modulus(ctx)); fmpz_one(poly->coeffs + len - 1); _fmpz_mod_poly_set_length(poly, len); @@ -193,13 +193,13 @@ void fmpz_mod_poly_randtest_pentomial(fmpz_mod_poly_t poly, { fmpz_mod_poly_fit_length(poly, len, ctx); _fmpz_vec_zero(poly->coeffs, len); - fmpz_randtest_unsigned(poly->coeffs, state, fmpz_bits(fmpz_mod_ctx_modulus(ctx) + 1)); + fmpz_randtest_unsigned(poly->coeffs, state, fmpz_bits(fmpz_mod_ctx_modulus(ctx))); fmpz_mod(poly->coeffs, poly->coeffs, fmpz_mod_ctx_modulus(ctx)); - fmpz_randtest_unsigned(poly->coeffs + 1, state, fmpz_bits(fmpz_mod_ctx_modulus(ctx) + 1)); + fmpz_randtest_unsigned(poly->coeffs + 1, state, fmpz_bits(fmpz_mod_ctx_modulus(ctx))); fmpz_mod(poly->coeffs + 1, poly->coeffs + 1, fmpz_mod_ctx_modulus(ctx)); - fmpz_randtest_unsigned(poly->coeffs + 2, state, fmpz_bits(fmpz_mod_ctx_modulus(ctx) + 1)); + fmpz_randtest_unsigned(poly->coeffs + 2, state, fmpz_bits(fmpz_mod_ctx_modulus(ctx))); fmpz_mod(poly->coeffs + 2, poly->coeffs + 2, fmpz_mod_ctx_modulus(ctx)); - fmpz_randtest_unsigned(poly->coeffs + 3, state, fmpz_bits(fmpz_mod_ctx_modulus(ctx) + 1)); + fmpz_randtest_unsigned(poly->coeffs + 3, state, fmpz_bits(fmpz_mod_ctx_modulus(ctx))); fmpz_mod(poly->coeffs + 3, poly->coeffs + 3, fmpz_mod_ctx_modulus(ctx)); fmpz_one(poly->coeffs + len - 1); _fmpz_mod_poly_set_length(poly, len);