diff --git a/doc/source/fmpz.rst b/doc/source/fmpz.rst index 98ee42436e..00824c4a52 100644 --- a/doc/source/fmpz.rst +++ b/doc/source/fmpz.rst @@ -255,8 +255,7 @@ should call :func:`flint_rand_clear` to clean up. .. function:: void fmpz_randtest_unsigned(fmpz_t f, flint_rand_t state, flint_bitcnt_t bits) void fmpz_randtest(fmpz_t f, flint_rand_t state, flint_bitcnt_t bits) - Generates a random integer whose absolute value has a number of bits which - is random from `0` up to ``bits`` inclusive. + Generates a random (unsigned) integer whose absolute value has a number of bits which is random from `0` up to ``bits`` inclusive. .. function:: void fmpz_randtest_not_zero(fmpz_t f, flint_rand_t state, flint_bitcnt_t bits) diff --git a/doc/source/fmpz_mod_mat.rst b/doc/source/fmpz_mod_mat.rst index e667b240b0..9d3a9d8b40 100644 --- a/doc/source/fmpz_mod_mat.rst +++ b/doc/source/fmpz_mod_mat.rst @@ -95,7 +95,18 @@ Random generation .. function:: void fmpz_mod_mat_randtest(fmpz_mod_mat_t mat, flint_rand_t state, const fmpz_mod_ctx_t ctx) Generate a random matrix with the existing dimensions and entries in - `[0, n)` where ``n`` is the modulus. + `[0, n)` where ``n`` is the modulus. A sparse matrix is + generated with increased probability. + +.. function:: void fmpz_mod_mat_randfull(fmpz_mod_mat_t mat, flint_rand_t state, const fmpz_mod_ctx_t ctx) + + Sets the element to random numbers in `[0, n)`, likely to be close to the modulus ``n`` + of the matrix. This is used to test potential overflow-related bugs. + +.. function:: void fmpz_mod_mat_rand(fmpz_mod_mat_t mat, flint_rand_t state, const fmpz_mod_ctx_t ctx) + + Sets the element to random numbers in `[0, n)`, likely to be close to the modulus ``n`` + of the matrix. Windows and concatenation diff --git a/doc/source/nmod_mat.rst b/doc/source/nmod_mat.rst index b1da8f22ca..44579a4273 100644 --- a/doc/source/nmod_mat.rst +++ b/doc/source/nmod_mat.rst @@ -76,7 +76,11 @@ Memory management Swaps two matrices by swapping the individual entries rather than swapping the contents of the structs. -.. function:: void nmod_mat_set_mod(nmod_mat_t mat, ulong n); +.. function:: nmod_t nmod_mat_mod(const nmod_mat_t mat) + + Returns the modulus of a matrix. + +.. function:: void nmod_mat_set_mod(nmod_mat_t mat, ulong n) Sets the modulus of an already initialized matrix ``mat`` to be `n`. Row and column dimensions are unchanged, and allocated memory is unaffected. @@ -196,9 +200,13 @@ Random matrix generation .. function:: void nmod_mat_randfull(nmod_mat_t mat, flint_rand_t state) - Sets the element to random numbers likely to be close to the modulus + Sets the element to random numbers in `[0, n)`, likely to be close to the modulus ``n`` of the matrix. This is used to test potential overflow-related bugs. +.. function:: void nmod_mat_rand(nmod_mat_t mat, flint_rand_t state) + + Sets the element to uniformly generated random numbers in `[0, n)`, where `n` is the modulus of the matrix. + .. function:: int nmod_mat_randpermdiag(nmod_mat_t mat, flint_rand_t state, nn_srcptr diag, slong n) Sets ``mat`` to a random permutation of the diagonal matrix diff --git a/doc/source/nmod_vec.rst b/doc/source/nmod_vec.rst index 55c4e6c14d..2388f506e6 100644 --- a/doc/source/nmod_vec.rst +++ b/doc/source/nmod_vec.rst @@ -26,6 +26,10 @@ Random functions Sets ``vec`` to a random vector of the given length with entries reduced modulo ``mod.n``. +.. function:: void _nmod_vec_rand(nn_ptr vec, flint_rand_t state, slong len, nmod_t mod) + + Sets ``vec`` to a vector of the given length with entries picked uniformly at random in `[0, mod.n)`. + Basic manipulation and comparison -------------------------------------------------------------------------------- @@ -224,4 +228,3 @@ performed at the very end of the computation. Same specification as ``_nmod_vec_dot_bound_limbs``, but uses the additional input ``params`` to reduce the amount of computations; for correctness ``params`` must have been computed for the specified ``len`` and ``mod``. - diff --git a/src/fmpz_mat/randtest.c b/src/fmpz_mat/randtest.c index 1ca4d620b3..bd02c21e4e 100644 --- a/src/fmpz_mat/randtest.c +++ b/src/fmpz_mat/randtest.c @@ -15,12 +15,31 @@ void fmpz_mat_randtest(fmpz_mat_t mat, flint_rand_t state, flint_bitcnt_t bits) { - slong r, c, i, j; + // Adapted from nmod_vec_randtest + slong r, c, i, j, len; + slong sparseness; r = mat->r; c = mat->c; + len = r*c; - for (i = 0; i < r; i++) - for (j = 0; j < c; j++) - fmpz_randtest(fmpz_mat_entry(mat, i, j), state, bits); + if (n_randint(state, 2)) + { + for (i = 0; i < r; i++) + for (j = 0; j < c; j++) + fmpz_randtest(fmpz_mat_entry(mat, i, j), state, bits); + } + else + { + sparseness = 1 + n_randint(state, FLINT_MAX(2, len)); + for (i = 0; i < r; i++) + { + for (j = 0; j < c; j++) { + if (n_randint(state, sparseness)) + fmpz_zero(fmpz_mat_entry(mat, i, j)); + else + fmpz_randtest(fmpz_mat_entry(mat, i, j), state, bits); + } + } + } } diff --git a/src/fmpz_mod_mat.h b/src/fmpz_mod_mat.h index 9cd599ed69..15b871dace 100644 --- a/src/fmpz_mod_mat.h +++ b/src/fmpz_mod_mat.h @@ -118,6 +118,10 @@ FMPZ_MOD_MAT_INLINE void _fmpz_mod_mat_reduce(fmpz_mod_mat_t mat, const fmpz_mod void fmpz_mod_mat_randtest(fmpz_mod_mat_t mat, flint_rand_t state, const fmpz_mod_ctx_t ctx); +void fmpz_mod_mat_randfull(fmpz_mod_mat_t mat, flint_rand_t state, const fmpz_mod_ctx_t ctx); + +void fmpz_mod_mat_rand(fmpz_mod_mat_t mat, flint_rand_t state, const fmpz_mod_ctx_t ctx); + void fmpz_mod_mat_randrank(fmpz_mod_mat_t mat, flint_rand_t state, slong rank, const fmpz_mod_ctx_t ctx); void fmpz_mod_mat_randtril(fmpz_mod_mat_t mat, flint_rand_t state, int unit, const fmpz_mod_ctx_t ctx); diff --git a/src/fmpz_mod_mat/rand.c b/src/fmpz_mod_mat/rand.c new file mode 100644 index 0000000000..ddd0e21b82 --- /dev/null +++ b/src/fmpz_mod_mat/rand.c @@ -0,0 +1,19 @@ +#include "fmpz.h" +#include "fmpz_mod_mat.h" + +void fmpz_mod_mat_rand(fmpz_mod_mat_t mat, flint_rand_t state, const fmpz_mod_ctx_t ctx) +{ + fmpz* e; + slong i, j, r, c; + r = fmpz_mod_mat_nrows(mat, ctx); + c = fmpz_mod_mat_nrows(mat, ctx); + + for (i = 0; i < r; i++) + { + for (j = 0; j < c; j++) + { + e = fmpz_mod_mat_entry(mat, i, j); + fmpz_randm(e, state, ctx->n); + } + } +} diff --git a/src/fmpz_mod_mat/randfull.c b/src/fmpz_mod_mat/randfull.c new file mode 100644 index 0000000000..77b3a72ed3 --- /dev/null +++ b/src/fmpz_mod_mat/randfull.c @@ -0,0 +1,21 @@ +#include "fmpz.h" +#include "fmpz_mod_mat.h" + +void fmpz_mod_mat_randfull(fmpz_mod_mat_t mat, flint_rand_t state, const fmpz_mod_ctx_t ctx) +{ + fmpz* e; + slong i, j, r, c; + r = fmpz_mod_mat_nrows(mat, ctx); + c = fmpz_mod_mat_nrows(mat, ctx); + + for (i = 0; i < r; i++) + { + for (j = 0; j < c; j++) + { + e = fmpz_mod_mat_entry(mat, i, j); + fmpz_randm(e, state, ctx->n); + if (fmpz_cmp_ui(e, 0)) + fmpz_one(e); + } + } +} diff --git a/src/nmod_mat.h b/src/nmod_mat.h index 7b5dd92771..c6a5412b3e 100644 --- a/src/nmod_mat.h +++ b/src/nmod_mat.h @@ -40,6 +40,11 @@ ulong * nmod_mat_entry_ptr(const nmod_mat_t mat, slong i, slong j) return &nmod_mat_entry(mat, i, j); } +NMOD_MAT_INLINE +ulong * nmod_mat_row_ptr(const nmod_mat_t mat, slong i) +{ + return &nmod_mat_entry(mat, i, 0); +} /* See inlines.c */ NMOD_MAT_INLINE @@ -56,6 +61,12 @@ slong nmod_mat_ncols(const nmod_mat_t mat) void nmod_mat_set_mod(nmod_mat_t mat, ulong n); +NMOD_MAT_INLINE +nmod_t nmod_mat_mod(const nmod_mat_t mat) +{ + return mat->mod; +} + /* Memory management */ void nmod_mat_init(nmod_mat_t mat, slong rows, slong cols, ulong n); void nmod_mat_init_set(nmod_mat_t mat, const nmod_mat_t src); @@ -106,6 +117,7 @@ void nmod_mat_concat_vertical(nmod_mat_t res, /* Random matrix generation */ void nmod_mat_randtest(nmod_mat_t mat, flint_rand_t state); void nmod_mat_randfull(nmod_mat_t mat, flint_rand_t state); +void nmod_mat_rand(nmod_mat_t mat, flint_rand_t state); int nmod_mat_randpermdiag(nmod_mat_t mat, flint_rand_t state, nn_srcptr diag, slong n); void nmod_mat_randrank(nmod_mat_t, flint_rand_t state, slong rank); diff --git a/src/nmod_mat/randomisation.c b/src/nmod_mat/randomisation.c index 4dfe4bd52d..52e9a99c81 100644 --- a/src/nmod_mat/randomisation.c +++ b/src/nmod_mat/randomisation.c @@ -24,6 +24,14 @@ nmod_mat_randfull(nmod_mat_t mat, flint_rand_t state) nmod_mat_entry(mat, i, j) = FLINT_MAX(1, n_randint(state, mat->mod.n)); } +void +nmod_mat_rand(nmod_mat_t mat, flint_rand_t state) +{ + slong i; + for (i = 0; i < mat->r; i++) + _nmod_vec_rand(nmod_mat_row_ptr(mat, i), state, mat->c, mat->mod); +} + void nmod_mat_randops(nmod_mat_t mat, flint_rand_t state, slong count) { @@ -123,7 +131,9 @@ nmod_mat_randrank(nmod_mat_t mat, flint_rand_t state, slong rank) void nmod_mat_randtest(nmod_mat_t mat, flint_rand_t state) { - _nmod_vec_randtest(mat->entries, state, mat->r * mat->c, mat->mod); + slong i; + for (i = 0; i < mat->r; i++) + _nmod_vec_randtest(nmod_mat_row_ptr(mat, i), state, mat->c, mat->mod); } void diff --git a/src/nmod_vec.h b/src/nmod_vec.h index cb44dbd4cb..04db64ddba 100644 --- a/src/nmod_vec.h +++ b/src/nmod_vec.h @@ -47,6 +47,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/rand.c similarity index 84% rename from src/nmod_vec/randtest.c rename to src/nmod_vec/rand.c index 950050f27b..e25d9f55a9 100644 --- a/src/nmod_vec/randtest.c +++ b/src/nmod_vec/rand.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;