Random Object Generation

Pseudo-random quantities are used in several Magma algorithms, and may also be generated explicitly by some intrinsics. Throughout the Handbook, the word ‘random’ is used for ‘pseudo-random’.

Since V2.7 (June 2000), Magma contains an implementation of the Monster random number generator of G. Marsaglia [Mar00]. The period of this generator is \(2^{29430} - 2^{27382}\) (approximately \(10^{8859}\)), and passes all of the stringent tests in Marsaglia’s Diehard test suite [Mar95].

Because the generator uses an internal array of machine integers, one ‘seed’ variable does not express the whole state, so the method for setting or getting the generator state is by way of a pair of values: (1) the seed for initializing the array, and (2) the number of steps performed since the initialization.

SetSeed(s, c): RngIntElt, RngIntElt
SetSeed(s): RngIntElt

(Procedure.) Reset the random number generator to have initial seed \(s\) (\(0 \leq s < 2^{32}\)), and advance to step \(c\) (\(0 \leq c < 2^{64})\). If \(c\) is not given, it is taken to be \(0\). Passing -Sn to Magma at startup is equivalent to typing SetSeed(n); after startup.

GetSeed() -> RngIntElt, RngIntElt

Return the initial seed \(s\) used to initialize the random-number generator and also the current step \(c\). This is the complement to the SetSeed function.

Random(S): Str -> Elt

Given a finite set or structure \(S\), return a random element of \(S\).

Random(a, b): RngIntElt, RngIntElt -> RngIntElt

Return a random integer lying in the interval \([a, b]\), where \(a\leq b\).

Random(b): RngIntElt -> RngIntElt

Return a random integer lying in the interval \([0, b]\), where \(b\) is a non-negative integer. Because of the good properties of the underlying Monster generator, calling Random(1) is a good safe way to produce a sequence of random bits.

Example: Restoring a Random State (ex-a0e14a)

Run in calculator (opens in a new tab)

We demonstrate how one can return to a previous random state by the use of GetSeed and SetSeed. We begin with initial seed 1 at step 0 and create a multi-set of 100,000 random integers in the range \([1..4]\).

> SetSeed(1);
> GetSeed();
1 0
> time S := {* Random(1, 4): i in [1..100000] *};
Time: 0.490
> S;
{* 1^^24911, 2^^24893, 3^^25139, 4^^25057 *}

We note the current state by GetSeed, and then print 10 random integers in the range \([1..100]\).

> GetSeed();
1 100000
> [Random(1, 100): i in [1 .. 10]];
[ 85, 41, 43, 69, 66, 61, 63, 31, 84, 11 ]
> GetSeed();
1 100014

We now restart with a different initial seed 23 (again at step 0), and do the same as before, noting the different random integers produced.

> SetSeed(23);
> GetSeed();
23 0
> time S := {* Random(1, 4): i in [1..100000] *};
Time: 0.500
> S;
{* 1^^24962, 2^^24923, 3^^24948, 4^^25167 *}
> GetSeed();
23 100000
> [Random(1, 100): i in [1 .. 10]];
[ 3, 93, 11, 62, 6, 73, 46, 52, 100, 30 ]
> GetSeed();
23 100013

Finally, we restore the random generator state to what it was after the creation of the multi-set for the first seed. We then print the 10 random integers in the range \([1..100]\), and note that they are the same as before.

> SetSeed(1, 100000);
> [Random(1, 100): i in [1 .. 10]];
[ 85, 41, 43, 69, 66, 61, 63, 31, 84, 11 ]
> GetSeed();
1 100014

Run in calculator (opens in a new tab)