From 4cf3226301cf71973aa996401a09979d840d0b5a Mon Sep 17 00:00:00 2001 From: Dimitri LESNOFF Date: Mon, 27 Oct 2025 14:48:34 +0100 Subject: [PATCH 01/15] Add a randunif function to src/nmod_vec --- src/nmod_vec/{randtest.c => rand.c} | 7 +++++++ 1 file changed, 7 insertions(+) rename src/nmod_vec/{randtest.c => rand.c} (84%) 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..79bde0e242 100644 --- a/src/nmod_vec/randtest.c +++ b/src/nmod_vec/rand.c @@ -11,6 +11,13 @@ #include "nmod_vec.h" +void _nmod_vec_randunif(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 48d863f0daa9ac68e442e2158d5d382b57dff3ad Mon Sep 17 00:00:00 2001 From: Dimitri LESNOFF Date: Mon, 27 Oct 2025 14:51:49 +0100 Subject: [PATCH 02/15] Add randtest to the documentation --- doc/source/fmpz.rst | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/doc/source/fmpz.rst b/doc/source/fmpz.rst index 98ee42436e..db940d802c 100644 --- a/doc/source/fmpz.rst +++ b/doc/source/fmpz.rst @@ -255,8 +255,12 @@ 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(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 signed 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) From f30cff0c7475ced3a2b70e2897a4fcb139a22113 Mon Sep 17 00:00:00 2001 From: Dimitri LESNOFF Date: Mon, 27 Oct 2025 16:09:57 +0100 Subject: [PATCH 03/15] Add fmpz_mod_mat random functions and upgrade documentation --- doc/source/fmpz_mod_mat.rst | 13 ++++++++++++- doc/source/nmod_mat.rst | 6 +++++- src/fmpz_mat/randtest.c | 25 +++++++++++++++++++++---- src/fmpz_mod_mat/randfull.c | 21 +++++++++++++++++++++ src/fmpz_mod_mat/randunif.c | 19 +++++++++++++++++++ src/nmod_mat/randomisation.c | 10 ++++++++++ 6 files changed, 88 insertions(+), 6 deletions(-) create mode 100644 src/fmpz_mod_mat/randfull.c create mode 100644 src/fmpz_mod_mat/randunif.c diff --git a/doc/source/fmpz_mod_mat.rst b/doc/source/fmpz_mod_mat.rst index e667b240b0..b778926546 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 between `1` and `m-1` likely to be close to the modulus + of the matrix. This is used to test potential overflow-related bugs. + +.. function:: void fmpz_mod_mat_randunif(fmpz_mod_mat_t mat, flint_rand_t state, const fmpz_mod_ctx_t ctx) + + Sets the element to random numbers between `0` and `m-1` likely to be close to the modulus + of the matrix. This is used to write benchmarks. Windows and concatenation diff --git a/doc/source/nmod_mat.rst b/doc/source/nmod_mat.rst index b1da8f22ca..43e2b7164d 100644 --- a/doc/source/nmod_mat.rst +++ b/doc/source/nmod_mat.rst @@ -196,9 +196,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 between `1` and `m-1` likely to be close to the modulus of the matrix. This is used to test potential overflow-related bugs. +.. function:: void nmod_mat_randunif(nmod_mat_t mat, flint_rand_t state) + + Sets the element to uniformly generated random numbers between `0` and `m-1`. This is used for benchmarks. + .. 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/src/fmpz_mat/randtest.c b/src/fmpz_mat/randtest.c index 1ca4d620b3..1efa3544ea 100644 --- a/src/fmpz_mat/randtest.c +++ b/src/fmpz_mat/randtest.c @@ -15,12 +15,29 @@ 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=0, 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 < len; i++) + { + if (n_randint(state, sparseness)) + *fmpz_mat_entry(mat, i, j) = 0; + else + fmpz_randtest(fmpz_mat_entry(mat, i, j), state, bits); + } + } } 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/fmpz_mod_mat/randunif.c b/src/fmpz_mod_mat/randunif.c new file mode 100644 index 0000000000..e2182ecfbe --- /dev/null +++ b/src/fmpz_mod_mat/randunif.c @@ -0,0 +1,19 @@ +#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); + } + } +} diff --git a/src/nmod_mat/randomisation.c b/src/nmod_mat/randomisation.c index 4dfe4bd52d..274842c925 100644 --- a/src/nmod_mat/randomisation.c +++ b/src/nmod_mat/randomisation.c @@ -24,6 +24,16 @@ 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_randunif(nmod_mat_t mat, flint_rand_t state) +{ + slong i, j; + + for (i = 0; i < mat->r; i++) + for (j = 0; j < mat->c; j++) + nmod_mat_entry(mat, i, j) = n_randint(state, mat->mod.n); +} + void nmod_mat_randops(nmod_mat_t mat, flint_rand_t state, slong count) { From 534cd063af053e3579eb1bd6ad3e5c254393382a Mon Sep 17 00:00:00 2001 From: Dimitri LESNOFF Date: Mon, 27 Oct 2025 16:47:07 +0100 Subject: [PATCH 04/15] Update headers and documentation --- doc/source/nmod_vec.rst | 5 ++++- src/fmpz_mod_mat.h | 4 ++++ src/fmpz_mod_mat/randunif.c | 2 +- src/nmod_mat.h | 1 + src/nmod_vec.h | 2 ++ 5 files changed, 12 insertions(+), 2 deletions(-) diff --git a/doc/source/nmod_vec.rst b/doc/source/nmod_vec.rst index 55c4e6c14d..d8e187407e 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_randunif(nn_ptr vec, flint_rand_t state, slong len, nmod_t mod) + + Sets ``vec`` to a random vector of the given length with entries uniformly generated between ``0`` and ``mod.n-1`` included. + 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_mod_mat.h b/src/fmpz_mod_mat.h index 9cd599ed69..875357f4bc 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_randunif(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/randunif.c b/src/fmpz_mod_mat/randunif.c index e2182ecfbe..a689fe151f 100644 --- a/src/fmpz_mod_mat/randunif.c +++ b/src/fmpz_mod_mat/randunif.c @@ -1,7 +1,7 @@ #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) +void fmpz_mod_mat_randunif(fmpz_mod_mat_t mat, flint_rand_t state, const fmpz_mod_ctx_t ctx) { fmpz* e; slong i, j, r, c; diff --git a/src/nmod_mat.h b/src/nmod_mat.h index 7b5dd92771..4eb5f4e039 100644 --- a/src/nmod_mat.h +++ b/src/nmod_mat.h @@ -106,6 +106,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_randunif(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_vec.h b/src/nmod_vec.h index cb44dbd4cb..1389869ccc 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_randunif(nn_ptr vec, flint_rand_t state, slong len, nmod_t mod); + NMOD_VEC_INLINE void _nmod_vec_zero(nn_ptr vec, slong len) { From 7ab4f133237a5e80bf15f3941555b79a3a3f9900 Mon Sep 17 00:00:00 2001 From: Dimitri LESNOFF Date: Mon, 27 Oct 2025 16:54:34 +0100 Subject: [PATCH 05/15] Change randunif to rand --- src/fmpz_mod_mat.h | 2 +- src/fmpz_mod_mat/randunif.c | 2 +- src/nmod_mat.h | 2 +- src/nmod_mat/randomisation.c | 2 +- src/nmod_vec.h | 2 +- src/nmod_vec/rand.c | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/fmpz_mod_mat.h b/src/fmpz_mod_mat.h index 875357f4bc..15b871dace 100644 --- a/src/fmpz_mod_mat.h +++ b/src/fmpz_mod_mat.h @@ -120,7 +120,7 @@ void fmpz_mod_mat_randtest(fmpz_mod_mat_t mat, flint_rand_t state, const fmpz_mo void fmpz_mod_mat_randfull(fmpz_mod_mat_t mat, flint_rand_t state, const fmpz_mod_ctx_t ctx); -void fmpz_mod_mat_randunif(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); diff --git a/src/fmpz_mod_mat/randunif.c b/src/fmpz_mod_mat/randunif.c index a689fe151f..ddd0e21b82 100644 --- a/src/fmpz_mod_mat/randunif.c +++ b/src/fmpz_mod_mat/randunif.c @@ -1,7 +1,7 @@ #include "fmpz.h" #include "fmpz_mod_mat.h" -void fmpz_mod_mat_randunif(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) { fmpz* e; slong i, j, r, c; diff --git a/src/nmod_mat.h b/src/nmod_mat.h index 4eb5f4e039..487b02d37c 100644 --- a/src/nmod_mat.h +++ b/src/nmod_mat.h @@ -106,7 +106,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_randunif(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 274842c925..09846be245 100644 --- a/src/nmod_mat/randomisation.c +++ b/src/nmod_mat/randomisation.c @@ -25,7 +25,7 @@ nmod_mat_randfull(nmod_mat_t mat, flint_rand_t state) } void -nmod_mat_randunif(nmod_mat_t mat, flint_rand_t state) +nmod_mat_rand(nmod_mat_t mat, flint_rand_t state) { slong i, j; diff --git a/src/nmod_vec.h b/src/nmod_vec.h index 1389869ccc..04db64ddba 100644 --- a/src/nmod_vec.h +++ b/src/nmod_vec.h @@ -47,7 +47,7 @@ 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_randunif(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/rand.c b/src/nmod_vec/rand.c index 79bde0e242..e25d9f55a9 100644 --- a/src/nmod_vec/rand.c +++ b/src/nmod_vec/rand.c @@ -11,7 +11,7 @@ #include "nmod_vec.h" -void _nmod_vec_randunif(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) { slong i; for (i = 0; i < len; i++) From 1fb1e3ec75218eae59c8b9e2bf2842a2526499dd Mon Sep 17 00:00:00 2001 From: Dimitri LESNOFF Date: Mon, 27 Oct 2025 17:32:06 +0100 Subject: [PATCH 06/15] randunif->rand: Change file name --- src/fmpz_mod_mat/{randunif.c => rand.c} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/fmpz_mod_mat/{randunif.c => rand.c} (100%) diff --git a/src/fmpz_mod_mat/randunif.c b/src/fmpz_mod_mat/rand.c similarity index 100% rename from src/fmpz_mod_mat/randunif.c rename to src/fmpz_mod_mat/rand.c From c245cdcc6728289cc39ea88cf9ba80e32373e0e9 Mon Sep 17 00:00:00 2001 From: Dimitri LESNOFF Date: Mon, 27 Oct 2025 17:37:21 +0100 Subject: [PATCH 07/15] Uses fmpz_zero instead of dereferencing --- src/fmpz_mat/randtest.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fmpz_mat/randtest.c b/src/fmpz_mat/randtest.c index 1efa3544ea..86cfdbcddc 100644 --- a/src/fmpz_mat/randtest.c +++ b/src/fmpz_mat/randtest.c @@ -35,7 +35,7 @@ fmpz_mat_randtest(fmpz_mat_t mat, flint_rand_t state, flint_bitcnt_t bits) for (i = 0; i < len; i++) { if (n_randint(state, sparseness)) - *fmpz_mat_entry(mat, i, j) = 0; + fmpz_zero(fmpz_mat_entry(mat, i, j)); else fmpz_randtest(fmpz_mat_entry(mat, i, j), state, bits); } From 2ff76f1f87cda2f559fd34397f928ee7f01acf38 Mon Sep 17 00:00:00 2001 From: Dimitri Lesnoff <54949944+dlesnoff@users.noreply.github.com> Date: Tue, 28 Oct 2025 10:40:15 +0100 Subject: [PATCH 08/15] Add documentation suggestions Co-authored-by: Vincent Neiger --- doc/source/fmpz_mod_mat.rst | 8 ++++---- doc/source/nmod_mat.rst | 4 ++-- doc/source/nmod_vec.rst | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/doc/source/fmpz_mod_mat.rst b/doc/source/fmpz_mod_mat.rst index b778926546..9d3a9d8b40 100644 --- a/doc/source/fmpz_mod_mat.rst +++ b/doc/source/fmpz_mod_mat.rst @@ -100,13 +100,13 @@ Random generation .. 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 between `1` and `m-1` 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 fmpz_mod_mat_randunif(fmpz_mod_mat_t mat, flint_rand_t state, const fmpz_mod_ctx_t ctx) +.. 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 between `0` and `m-1` likely to be close to the modulus - of the matrix. This is used to write benchmarks. + 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 43e2b7164d..33dced7c27 100644 --- a/doc/source/nmod_mat.rst +++ b/doc/source/nmod_mat.rst @@ -196,12 +196,12 @@ Random matrix generation .. function:: void nmod_mat_randfull(nmod_mat_t mat, flint_rand_t state) - Sets the element to random numbers between `1` and `m-1` 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_randunif(nmod_mat_t mat, flint_rand_t state) - Sets the element to uniformly generated random numbers between `0` and `m-1`. This is used for benchmarks. + 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) diff --git a/doc/source/nmod_vec.rst b/doc/source/nmod_vec.rst index d8e187407e..e311d33c6f 100644 --- a/doc/source/nmod_vec.rst +++ b/doc/source/nmod_vec.rst @@ -28,7 +28,7 @@ Random functions .. function:: void _nmod_vec_randunif(nn_ptr vec, flint_rand_t state, slong len, nmod_t mod) - Sets ``vec`` to a random vector of the given length with entries uniformly generated between ``0`` and ``mod.n-1`` included. + Sets ``vec`` to a vector of the given length with entries picked uniformly at random in `[0, mod.n)`. Basic manipulation and comparison From 1baa250f74b3234d9d553e8e17e1b39740690c3d Mon Sep 17 00:00:00 2001 From: Dimitri LESNOFF Date: Tue, 28 Oct 2025 10:54:11 +0100 Subject: [PATCH 09/15] Fix loops in random generation --- src/fmpz_mat/randtest.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/fmpz_mat/randtest.c b/src/fmpz_mat/randtest.c index 86cfdbcddc..bd02c21e4e 100644 --- a/src/fmpz_mat/randtest.c +++ b/src/fmpz_mat/randtest.c @@ -16,7 +16,7 @@ void fmpz_mat_randtest(fmpz_mat_t mat, flint_rand_t state, flint_bitcnt_t bits) { // Adapted from nmod_vec_randtest - slong r, c, i, j=0, len; + slong r, c, i, j, len; slong sparseness; r = mat->r; @@ -32,12 +32,14 @@ fmpz_mat_randtest(fmpz_mat_t mat, flint_rand_t state, flint_bitcnt_t bits) else { sparseness = 1 + n_randint(state, FLINT_MAX(2, len)); - for (i = 0; i < len; i++) + for (i = 0; i < r; i++) { - if (n_randint(state, sparseness)) - fmpz_zero(fmpz_mat_entry(mat, i, j)); - else - fmpz_randtest(fmpz_mat_entry(mat, i, j), state, bits); + 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); + } } } } From 3ce0ff0af416b85b68c5b8e0e67c5ef4599e6350 Mon Sep 17 00:00:00 2001 From: Dimitri LESNOFF Date: Tue, 28 Oct 2025 11:18:44 +0100 Subject: [PATCH 10/15] Fix documentation --- doc/source/fmpz.rst | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/doc/source/fmpz.rst b/doc/source/fmpz.rst index db940d802c..00824c4a52 100644 --- a/doc/source/fmpz.rst +++ b/doc/source/fmpz.rst @@ -255,12 +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 unsigned integer whose absolute value has a number of bits which is random from `0` up to ``bits`` inclusive. - -.. function:: void fmpz_randtest(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 signed 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) From 9a63870fa2332f3c02c2b5bcb7c25e7e4f226958 Mon Sep 17 00:00:00 2001 From: Dimitri LESNOFF Date: Tue, 28 Oct 2025 11:32:17 +0100 Subject: [PATCH 11/15] Uses vec internally --- src/nmod_mat/randomisation.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/nmod_mat/randomisation.c b/src/nmod_mat/randomisation.c index 09846be245..155ed6c4cc 100644 --- a/src/nmod_mat/randomisation.c +++ b/src/nmod_mat/randomisation.c @@ -17,11 +17,10 @@ void nmod_mat_randfull(nmod_mat_t mat, flint_rand_t state) { - slong i, j; + slong i; for (i = 0; i < mat->r; i++) - for (j = 0; j < mat->c; j++) - nmod_mat_entry(mat, i, j) = FLINT_MAX(1, n_randint(state, mat->mod.n)); + _nmod_vec_rand(nmod_mat_row_ptr(mat, i), state, mat->c, mat->mod); } void From ed77486530958f120f9138e9e47683dec8595989 Mon Sep 17 00:00:00 2001 From: Dimitri LESNOFF Date: Tue, 28 Oct 2025 11:35:37 +0100 Subject: [PATCH 12/15] Adds a function to get the modulus --- doc/source/nmod_mat.rst | 6 +++++- src/nmod_mat.h | 11 +++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/doc/source/nmod_mat.rst b/doc/source/nmod_mat.rst index 33dced7c27..a37307ff62 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. diff --git a/src/nmod_mat.h b/src/nmod_mat.h index 487b02d37c..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); From 5440826508ce7a5d39bae42027a2b51e1f4fab9d Mon Sep 17 00:00:00 2001 From: Dimitri Lesnoff <54949944+dlesnoff@users.noreply.github.com> Date: Tue, 28 Oct 2025 14:20:10 +0100 Subject: [PATCH 13/15] Apply suggestions from code review Co-authored-by: Vincent Neiger --- doc/source/nmod_mat.rst | 2 +- doc/source/nmod_vec.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/source/nmod_mat.rst b/doc/source/nmod_mat.rst index a37307ff62..44579a4273 100644 --- a/doc/source/nmod_mat.rst +++ b/doc/source/nmod_mat.rst @@ -203,7 +203,7 @@ Random matrix generation 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_randunif(nmod_mat_t mat, flint_rand_t state) +.. 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. diff --git a/doc/source/nmod_vec.rst b/doc/source/nmod_vec.rst index e311d33c6f..2388f506e6 100644 --- a/doc/source/nmod_vec.rst +++ b/doc/source/nmod_vec.rst @@ -26,7 +26,7 @@ Random functions Sets ``vec`` to a random vector of the given length with entries reduced modulo ``mod.n``. -.. function:: void _nmod_vec_randunif(nn_ptr vec, flint_rand_t state, slong len, nmod_t mod) +.. 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)`. From 8b583924713ec81969db466b241ace15efa18c2c Mon Sep 17 00:00:00 2001 From: Dimitri LESNOFF Date: Tue, 28 Oct 2025 14:23:38 +0100 Subject: [PATCH 14/15] Apply suggestion for nmod_mat_rand(full) Co-authored-by: vneiger --- src/nmod_mat/randomisation.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/nmod_mat/randomisation.c b/src/nmod_mat/randomisation.c index 155ed6c4cc..fe70b721d0 100644 --- a/src/nmod_mat/randomisation.c +++ b/src/nmod_mat/randomisation.c @@ -17,20 +17,17 @@ void nmod_mat_randfull(nmod_mat_t mat, flint_rand_t state) { - slong i; + slong i, j; for (i = 0; i < mat->r; i++) - _nmod_vec_rand(nmod_mat_row_ptr(mat, i), state, mat->c, mat->mod); + for (j = 0; j < mat->c; j++) + 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, j; - - for (i = 0; i < mat->r; i++) - for (j = 0; j < mat->c; j++) - nmod_mat_entry(mat, i, j) = n_randint(state, mat->mod.n); + _nmod_vec_rand(mat->entries, state, mat->r*mat->c, mat->mod); } void From 4afd8c062f51c3b6f5a2be1805b93e96aeb8ecab Mon Sep 17 00:00:00 2001 From: Dimitri LESNOFF Date: Tue, 28 Oct 2025 16:07:10 +0100 Subject: [PATCH 15/15] Make looping over matrices compatible with stride --- src/nmod_mat/randomisation.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/nmod_mat/randomisation.c b/src/nmod_mat/randomisation.c index fe70b721d0..52e9a99c81 100644 --- a/src/nmod_mat/randomisation.c +++ b/src/nmod_mat/randomisation.c @@ -27,7 +27,9 @@ nmod_mat_randfull(nmod_mat_t mat, flint_rand_t state) void nmod_mat_rand(nmod_mat_t mat, flint_rand_t state) { - _nmod_vec_rand(mat->entries, state, mat->r*mat->c, mat->mod); + slong i; + for (i = 0; i < mat->r; i++) + _nmod_vec_rand(nmod_mat_row_ptr(mat, i), state, mat->c, mat->mod); } void @@ -129,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