Function: random
Section: conversions
C-Name: genrand
Prototype: DG
Help: random({N=2^31}): random object, depending on the type of N.
 Integer between 0 and N-1 (t_INT), int mod N (t_INTMOD), element in a finite
 field (t_FFELT), point on an elliptic curve (ellinit mod p or over a finite
 field).
Description:
 (?int):int    genrand($1)
 (real):real   genrand($1)
 (gen):gen     genrand($1)
Doc:
 returns a random element in various natural sets depending on the
 argument $N$.

 \item \typ{INT}: let $n = |N|-1$; if $N > 0$ returns an integer uniformly
 distributed in $[0, n]$; if $N < 0$ returns an integer uniformly
 distributed in $[-n, n]$. Omitting the argument is
 equivalent to \kbd{random(2\pow31)}.

 \item \typ{REAL}: returns a real number in $[0,1[$ with the same accuracy as
 $N$ (whose mantissa has the same number of significant words).

 \item \typ{INTMOD}: returns a random intmod for the same modulus.

 \item \typ{FFELT}: returns a random element in the same finite field.

 \item \typ{VEC} of length $2$, $N = [a,b]$: returns an integer uniformly
 distributed between $a$ and $b$.

 \item \typ{VEC} generated by \kbd{ellinit} over a finite field $k$
 (coefficients are \typ{INTMOD}s modulo a prime or \typ{FFELT}s): returns a
 ``random'' $k$-rational \emph{affine} point on the curve. More precisely
 if the curve has a single point (at infinity!) we return it; otherwise
 we return an affine point by drawing an abscissa uniformly at
 random until \tet{ellordinate} succeeds. Note that this is definitely not a
 uniform distribution over $E(k)$, but it should be good enough for
 applications.

 \item \typ{POL} return a random polynomial of degree at most the degree of $N$.
 The coefficients are drawn by applying \kbd{random} to the leading
 coefficient of $N$.

 \bprog
 ? random(10)
 %1 = 9
 ? random(Mod(0,7))
 %2 = Mod(1, 7)
 ? a = ffgen(ffinit(3,7), 'a); random(a)
 %3 = a^6 + 2*a^5 + a^4 + a^3 + a^2 + 2*a
 ? E = ellinit([3,7]*Mod(1,109)); random(E)
 %4 = [Mod(103, 109), Mod(10, 109)]
 ? E = ellinit([1,7]*a^0); random(E)
 %5 = [a^6 + a^5 + 2*a^4 + 2*a^2, 2*a^6 + 2*a^4 + 2*a^3 + a^2 + 2*a]
 ? random(Mod(1,7)*x^4)
 %6 = Mod(5, 7)*x^4 + Mod(6, 7)*x^3 + Mod(2, 7)*x^2 + Mod(2, 7)*x + Mod(5, 7)

 @eprog
 These variants all depend on a single internal generator, and are
 independent from your operating system's random number generators.
 A random seed may be obtained via \tet{getrand}, and reset
 using \tet{setrand}: from a given seed, and given sequence of \kbd{random}s,
 the exact same values will be generated. The same seed is used at each
 startup, reseed the generator yourself if this is a problem. Note that
 internal functions also call the random number generator; adding such a
 function call in the middle of your code will change the numbers produced.

 \misctitle{Technical note}
 Up to
 version 2.4 included, the internal generator produced pseudo-random numbers
 by means of linear congruences, which were not well distributed in arithmetic
 progressions. We now
 use Brent's XORGEN algorithm, based on Feedback Shift Registers, see
 \url{https://wwwmaths.anu.edu.au/~brent/random.html}. The generator has period
 $2^{4096}-1$, passes the Crush battery of statistical tests of L'Ecuyer and
 Simard, but is not suitable for cryptographic purposes: one can reconstruct
 the state vector from a small sample of consecutive values, thus predicting
 the entire sequence.

 \misctitle{Parallelism} In multi-threaded programs, each thread has a
 separate generator. They all start in the same \kbd{setrand(1)} state, so
 will all produce the same sequence of pseudo-random numbers although
 the various states are not shared. To avoid this, use \kbd{setrand} to
 provide a different starting state to each thread:
 \bprog
 \\ with 8 threads
 ? parvector(8, i, random()) \\ all 8 threads return the same number
 %1 = [1546275796, 1546275796, ... , 1546275796]
 ? parvector(8, i, random()) \\ ... and again since they are restarted
 %2 = [1546275796, 1546275796, ... , 1546275796]

 ? s = [1..8]; \\ 8 random seeds; we could use vector(8,i,random())
 ? parvector(8, i, setrand(s[i]); random())
 \\ now we get 8 different numbers
 @eprog

Variant:
  Also available: \fun{GEN}{ellrandom}{GEN E} and \fun{GEN}{ffrandom}{GEN a}.
