diff --git a/doc/source/fmpz.rst b/doc/source/fmpz.rst index 00824c4a52..b5826d68d2 100644 --- a/doc/source/fmpz.rst +++ b/doc/source/fmpz.rst @@ -266,6 +266,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/doc/source/mpn_mod.rst b/doc/source/mpn_mod.rst index 7e6ec0fbbf..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) diff --git a/doc/source/nmod_poly.rst b/doc/source/nmod_poly.rst index b72f18996b..96250add11 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/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/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..e722dba9e8 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,55 @@ 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_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)); + } + + _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_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)); + } + + 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,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(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, - state, fmpz_mod_ctx_modulus(ctx)); + 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))); + 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); } @@ -127,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(poly->coeffs, state, fmpz_mod_ctx_modulus(ctx)); + 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_randm(poly->coeffs + k, state, fmpz_mod_ctx_modulus(ctx)); + 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); } @@ -139,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(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_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))); + 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))); + 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))); + 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); } diff --git a/src/mpn_mod.h b/src/mpn_mod.h index 8af7008d00..8c0c5e7f65 100644 --- a/src/mpn_mod.h +++ b/src/mpn_mod.h @@ -126,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); @@ -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/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) { 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) { diff --git a/src/nmod_poly.h b/src/nmod_poly.h index 377200d85f..5ebb1287cd 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) { 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) { diff --git a/src/nmod_vec.h b/src/nmod_vec.h index f2cde311da..ac90fc4115 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); + void _nmod_vec_rand(nn_ptr vec, flint_rand_t state, slong len, nmod_t mod);