Skip to content

Commit 27e44f6

Browse files
dlesnoffvneiger
andauthored
Fmpz mod mat and nmod mat randomisation functions (#2430)
* Add a rand (uniform) function to src/nmod_vec * Add documentation * Add fmpz_mod_mat random functions and improve documentation * Adds a function to get the modulus of an nmod mat * Fix nmod mat randtest: make looping over matrices compatible with stride --------- Co-authored-by: Vincent Neiger <vneiger@users.noreply.github.com>
1 parent c6147f4 commit 27e44f6

File tree

12 files changed

+126
-11
lines changed

12 files changed

+126
-11
lines changed

doc/source/fmpz.rst

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -255,8 +255,7 @@ should call :func:`flint_rand_clear` to clean up.
255255
.. function:: void fmpz_randtest_unsigned(fmpz_t f, flint_rand_t state, flint_bitcnt_t bits)
256256
void fmpz_randtest(fmpz_t f, flint_rand_t state, flint_bitcnt_t bits)
257257

258-
Generates a random integer whose absolute value has a number of bits which
259-
is random from `0` up to ``bits`` inclusive.
258+
Generates a random (unsigned) integer whose absolute value has a number of bits which is random from `0` up to ``bits`` inclusive.
260259

261260
.. function:: void fmpz_randtest_not_zero(fmpz_t f, flint_rand_t state, flint_bitcnt_t bits)
262261

doc/source/fmpz_mod_mat.rst

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,18 @@ Random generation
9696
.. function:: void fmpz_mod_mat_randtest(fmpz_mod_mat_t mat, flint_rand_t state, const fmpz_mod_ctx_t ctx)
9797

9898
Generate a random matrix with the existing dimensions and entries in
99-
`[0, n)` where ``n`` is the modulus.
99+
`[0, n)` where ``n`` is the modulus. A sparse matrix is
100+
generated with increased probability.
101+
102+
.. function:: void fmpz_mod_mat_randfull(fmpz_mod_mat_t mat, flint_rand_t state, const fmpz_mod_ctx_t ctx)
103+
104+
Sets the element to random numbers in `[0, n)`, likely to be close to the modulus ``n``
105+
of the matrix. This is used to test potential overflow-related bugs.
106+
107+
.. function:: void fmpz_mod_mat_rand(fmpz_mod_mat_t mat, flint_rand_t state, const fmpz_mod_ctx_t ctx)
108+
109+
Sets the element to random numbers in `[0, n)`, likely to be close to the modulus ``n``
110+
of the matrix.
100111

101112

102113
Windows and concatenation

doc/source/nmod_mat.rst

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,11 @@ Memory management
7575
Swaps two matrices by swapping the individual entries rather than swapping
7676
the contents of the structs.
7777

78-
.. function:: void nmod_mat_set_mod(nmod_mat_t mat, ulong n);
78+
.. function:: nmod_t nmod_mat_mod(const nmod_mat_t mat)
79+
80+
Returns the modulus of a matrix.
81+
82+
.. function:: void nmod_mat_set_mod(nmod_mat_t mat, ulong n)
7983

8084
Sets the modulus of an already initialized matrix ``mat`` to be `n`. Row
8185
and column dimensions are unchanged, and allocated memory is unaffected.
@@ -195,9 +199,13 @@ Random matrix generation
195199

196200
.. function:: void nmod_mat_randfull(nmod_mat_t mat, flint_rand_t state)
197201

198-
Sets the element to random numbers likely to be close to the modulus
202+
Sets the element to random numbers in `[0, n)`, likely to be close to the modulus ``n``
199203
of the matrix. This is used to test potential overflow-related bugs.
200204

205+
.. function:: void nmod_mat_rand(nmod_mat_t mat, flint_rand_t state)
206+
207+
Sets the element to uniformly generated random numbers in `[0, n)`, where `n` is the modulus of the matrix.
208+
201209
.. function:: int nmod_mat_randpermdiag(nmod_mat_t mat, flint_rand_t state, nn_srcptr diag, slong n)
202210

203211
Sets ``mat`` to a random permutation of the diagonal matrix

doc/source/nmod_vec.rst

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ Random functions
2626
Sets ``vec`` to a random vector of the given length with entries
2727
reduced modulo ``mod.n``.
2828

29+
.. function:: void _nmod_vec_rand(nn_ptr vec, flint_rand_t state, slong len, nmod_t mod)
30+
31+
Sets ``vec`` to a vector of the given length with entries picked uniformly at random in `[0, mod.n)`.
32+
2933

3034
Basic manipulation and comparison
3135
--------------------------------------------------------------------------------
@@ -231,4 +235,3 @@ performed at the very end of the computation.
231235
Same specification as ``_nmod_vec_dot_bound_limbs``, but uses the additional
232236
input ``params`` to reduce the amount of computations; for correctness
233237
``params`` must have been computed for the specified ``len`` and ``mod``.
234-

src/fmpz_mat/randtest.c

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,31 @@
1515
void
1616
fmpz_mat_randtest(fmpz_mat_t mat, flint_rand_t state, flint_bitcnt_t bits)
1717
{
18-
slong r, c, i, j;
18+
// Adapted from nmod_vec_randtest
19+
slong r, c, i, j, len;
20+
slong sparseness;
1921

2022
r = mat->r;
2123
c = mat->c;
24+
len = r*c;
2225

23-
for (i = 0; i < r; i++)
24-
for (j = 0; j < c; j++)
25-
fmpz_randtest(fmpz_mat_entry(mat, i, j), state, bits);
26+
if (n_randint(state, 2))
27+
{
28+
for (i = 0; i < r; i++)
29+
for (j = 0; j < c; j++)
30+
fmpz_randtest(fmpz_mat_entry(mat, i, j), state, bits);
31+
}
32+
else
33+
{
34+
sparseness = 1 + n_randint(state, FLINT_MAX(2, len));
35+
for (i = 0; i < r; i++)
36+
{
37+
for (j = 0; j < c; j++) {
38+
if (n_randint(state, sparseness))
39+
fmpz_zero(fmpz_mat_entry(mat, i, j));
40+
else
41+
fmpz_randtest(fmpz_mat_entry(mat, i, j), state, bits);
42+
}
43+
}
44+
}
2645
}

src/fmpz_mod_mat.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,10 @@ FMPZ_MOD_MAT_INLINE void _fmpz_mod_mat_reduce(fmpz_mod_mat_t mat, const fmpz_mod
118118

119119
void fmpz_mod_mat_randtest(fmpz_mod_mat_t mat, flint_rand_t state, const fmpz_mod_ctx_t ctx);
120120

121+
void fmpz_mod_mat_randfull(fmpz_mod_mat_t mat, flint_rand_t state, const fmpz_mod_ctx_t ctx);
122+
123+
void fmpz_mod_mat_rand(fmpz_mod_mat_t mat, flint_rand_t state, const fmpz_mod_ctx_t ctx);
124+
121125
void fmpz_mod_mat_randrank(fmpz_mod_mat_t mat, flint_rand_t state, slong rank, const fmpz_mod_ctx_t ctx);
122126

123127
void fmpz_mod_mat_randtril(fmpz_mod_mat_t mat, flint_rand_t state, int unit, const fmpz_mod_ctx_t ctx);

src/fmpz_mod_mat/rand.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#include "fmpz.h"
2+
#include "fmpz_mod_mat.h"
3+
4+
void fmpz_mod_mat_rand(fmpz_mod_mat_t mat, flint_rand_t state, const fmpz_mod_ctx_t ctx)
5+
{
6+
fmpz* e;
7+
slong i, j, r, c;
8+
r = fmpz_mod_mat_nrows(mat, ctx);
9+
c = fmpz_mod_mat_nrows(mat, ctx);
10+
11+
for (i = 0; i < r; i++)
12+
{
13+
for (j = 0; j < c; j++)
14+
{
15+
e = fmpz_mod_mat_entry(mat, i, j);
16+
fmpz_randm(e, state, ctx->n);
17+
}
18+
}
19+
}

src/fmpz_mod_mat/randfull.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#include "fmpz.h"
2+
#include "fmpz_mod_mat.h"
3+
4+
void fmpz_mod_mat_randfull(fmpz_mod_mat_t mat, flint_rand_t state, const fmpz_mod_ctx_t ctx)
5+
{
6+
fmpz* e;
7+
slong i, j, r, c;
8+
r = fmpz_mod_mat_nrows(mat, ctx);
9+
c = fmpz_mod_mat_nrows(mat, ctx);
10+
11+
for (i = 0; i < r; i++)
12+
{
13+
for (j = 0; j < c; j++)
14+
{
15+
e = fmpz_mod_mat_entry(mat, i, j);
16+
fmpz_randm(e, state, ctx->n);
17+
if (fmpz_cmp_ui(e, 0))
18+
fmpz_one(e);
19+
}
20+
}
21+
}

src/nmod_mat.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,11 @@ ulong * nmod_mat_entry_ptr(const nmod_mat_t mat, slong i, slong j)
4040
return &nmod_mat_entry(mat, i, j);
4141
}
4242

43+
NMOD_MAT_INLINE
44+
ulong * nmod_mat_row_ptr(const nmod_mat_t mat, slong i)
45+
{
46+
return &nmod_mat_entry(mat, i, 0);
47+
}
4348
/* See inlines.c */
4449

4550
NMOD_MAT_INLINE
@@ -56,6 +61,12 @@ slong nmod_mat_ncols(const nmod_mat_t mat)
5661

5762
void nmod_mat_set_mod(nmod_mat_t mat, ulong n);
5863

64+
NMOD_MAT_INLINE
65+
nmod_t nmod_mat_mod(const nmod_mat_t mat)
66+
{
67+
return mat->mod;
68+
}
69+
5970
/* Memory management */
6071
void nmod_mat_init(nmod_mat_t mat, slong rows, slong cols, ulong n);
6172
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,
106117
/* Random matrix generation */
107118
void nmod_mat_randtest(nmod_mat_t mat, flint_rand_t state);
108119
void nmod_mat_randfull(nmod_mat_t mat, flint_rand_t state);
120+
void nmod_mat_rand(nmod_mat_t mat, flint_rand_t state);
109121
int nmod_mat_randpermdiag(nmod_mat_t mat, flint_rand_t state,
110122
nn_srcptr diag, slong n);
111123
void nmod_mat_randrank(nmod_mat_t, flint_rand_t state, slong rank);

src/nmod_mat/randomisation.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,14 @@ nmod_mat_randfull(nmod_mat_t mat, flint_rand_t state)
2424
nmod_mat_entry(mat, i, j) = FLINT_MAX(1, n_randint(state, mat->mod.n));
2525
}
2626

27+
void
28+
nmod_mat_rand(nmod_mat_t mat, flint_rand_t state)
29+
{
30+
slong i;
31+
for (i = 0; i < mat->r; i++)
32+
_nmod_vec_rand(nmod_mat_row_ptr(mat, i), state, mat->c, mat->mod);
33+
}
34+
2735
void
2836
nmod_mat_randops(nmod_mat_t mat, flint_rand_t state, slong count)
2937
{
@@ -123,7 +131,9 @@ nmod_mat_randrank(nmod_mat_t mat, flint_rand_t state, slong rank)
123131
void
124132
nmod_mat_randtest(nmod_mat_t mat, flint_rand_t state)
125133
{
126-
_nmod_vec_randtest(mat->entries, state, mat->r * mat->c, mat->mod);
134+
slong i;
135+
for (i = 0; i < mat->r; i++)
136+
_nmod_vec_randtest(nmod_mat_row_ptr(mat, i), state, mat->c, mat->mod);
127137
}
128138

129139
void

0 commit comments

Comments
 (0)