Random numbers
Y=grand(m,n,"bet",A,B)
Y=grand(m,n,"bin",N,p)
Y=grand(m,n,"nbn",N,p)
Y=grand(m,n,"chi", Df)
Y=grand(m,n,"nch",Df,Xnon)
Y=grand(m,n,"exp",Av)
Y=grand(m,n,"f",Dfn,Dfd)
Y=grand(m,n,"nf",Dfn,Dfd,Xnon)
Y=grand(m,n,"gam",shape,scale)
Y=grand(m,n,"nor",Av,Sd)
Y=grand(m,n,"geom", p)
Y=grand(m,n,"poi",mu)
Y=grand(m,n,"def")
Y=grand(m,n,"unf",Low,High)
Y=grand(m,n,"uin",Low,High)
Y=grand(m,n,"lgi")
Y=grand(X,...)
Y=grand(n,"mn",Mean,Cov)
Y=grand(n,"markov",P,x0)
Y=grand(n,"mul",nb,P)
Y=grand(n,"prm",vect)
S=grand("getgen")
grand("setgen",gen)
S=grand("getsd")
grand("setsd",S)
S=grand("phr2sd",phrase)
grand("setcgn",G)
S=grand("getcgn")
grand("initgn",I)
grand("setall",s1,s2,s3,s4)
grand("advnst",K)
:m, n integers, size of the wanted matrix Y : :X a matrix whom only the dimensions (say m-by- n) are used : :Y a m-by- n matrix of doubles, with random entries : :S output of the action (a string or a real column vector) :
This function generates random numbers from various distributions.
The calling sequences:
Y=grand(m,n,"bet",A,B)
Y=grand(m,n,"bin",N,p)
Y=grand(m,n,"nbn",N,p)
Y=grand(m,n,"chi", Df)
Y=grand(m,n,"nch",Df,Xnon)
Y=grand(m,n,"exp",Av)
Y=grand(m,n,"f",Dfn,Dfd)
Y=grand(m,n,"nf",Dfn,Dfd,Xnon)
Y=grand(m,n,"gam",shape,scale)
Y=grand(m,n,"nor",Av,Sd)
Y=grand(m,n,"geom", p)
Y=grand(m,n,"poi",mu)
Y=grand(m,n,"def")
Y=grand(m,n,"unf",Low,High)
Y=grand(m,n,"uin",Low,High)
Y=grand(m,n,"lgi")
produce a m-by- n matrix with random entries.
The calling sequence:
Y=grand(X,...)
where X is a m-by- n matrix, produce the same effect. In this case, only the size of X is used.
The calling sequences:
Y=grand(n,"mn",Mean,Cov)
Y=grand(n,"markov",P,x0)
Y=grand(n,"mul",nb,P)
Y=grand(n,"prm",vect)
produce a m-by- n matrix with random entries, where m is the size of the argument Mean, Cov, P or vect depending on the case (see below for details).
The calling sequences:
S=grand("getgen")
grand("setgen",gen)
S=grand("getsd")
grand("setsd",S)
grand("setcgn",G)
S=grand("getcgn")
grand("initgn",I)
grand("setall",s1,s2,s3,s4)
grand("advnst",K)
configure or quiery the state of the underlying random number generators.
: :uniform (lgi) Y=grand(m,n,”lgi”) returns the basic output of the current generator : random integers following a uniform distribution over :
- [0, 2^32 - 1] for mt, kiss and fsultra;
- [0, 2147483561] for clcg2;
- [0, 2^31 - 2] for clcg4;
- [0, 2^31 - 1] for urand.
:
The user has the possibility to choose between different base generators (which give random integers following the “lgi” distribution, the others being gotten from it).
:
The differents actions common to all the generators, are:
: :action= “setsd” grand(“setsd”,S), grand(“setsd”,s1[,s2,s3,s4]) sets the state of the current base generator (the new seeds) :
- :for mt S is a vector of integers of dim 625 (the first component
- is an index and must be in [1,624], the 624 last ones must be in [0,2^32[) (but must not be all zeros) ; a simpler initialisation may be done with only one integer s1 ( s1 must be in [0,2^32[) ;
- : :for kiss 4 integers s1,s2, s3,s4 in [0,2^32[ must be provided
- ;
- : :for clcg2 2 integers s1 in [1,2147483562] and s2 in
- [1,2147483398] must be given ;
- : :for clcg4 4 integers s1 in [1,2147483646], s2 in
- [1,2147483542], s3 in [1,2147483422], s4 in [1,2147483322] are required ; CAUTION : with clcg4 you set the seeds of the current virtual generator but you may lost the synchronisation between this one and the others virtuals generators (i.e. the sequence generated is not warranty to be non-overlapping with a sequence generated by another virtual generator)=> use instead the “setall” option.
: :for urand 1 integer s1 in [0,2^31[ must be given. : :for fsultra S is a vector of integers of dim 40 (the first
component is an index and must be in [0,37], the 2nd component is a flag (0 or 1), the 3rd component is an integer in [1,2^32[ and the 37 others integers are in [0,2^32[) ; a simpler (and recommanded) initialisation may be done with two integers s1 and s2 in [0,2^32[.:
:
The clcg4 generator may be used as the others generators but it offers the advantage to be split in several ( 101) virtual generators with non-overlapping sequences (when you use a classic generator you may change the initial state (seeds) in order to get another sequence but you are not warranty to get a complete different one). Each virtual generator corresponds to a sequence of 2^72 values which is further split into V=2^31 segments (or blocks) of length W=2^41. For a given virtual generator you have the possibility to return at the beginning of the sequence or at the beginning of the current segment or to go directly at the next segment. You may also change the initial state (seed) of the generator 0 with the “setall” option which then change also the initial state of the other virtual generators so as to get synchronisation, i.e. in function of the new initial state of gen 0 the initial state of gen 1..100 are recomputed so as to get 101 non-overlapping sequences.
: :action= “initgn” grand(“initgn”,I) reinitializes the state of the current virtual generator
:I = -1 sets the state to its initial seed : :I = 0 sets the state to its last (previous) seed (i.e. to the
beginning of the current segment)
- : :I = 1 sets the state to a new seed W values from its last seed
- (i.e. to the beginning of the next segment) and resets the current segment parameters.
:
:
In the following example, we generate random numbers from various distributions and plot the associated histograms.
// Returns a 400-by-800 matrix of random doubles,
// with normal distribution and average 0 and standard deviation 1.
R = grand(400,800,"nor",0,1);
`scf`_();
`histplot`_(10,R);
`xtitle`_("Normal random numbers from grand","X","Frequency");
// Returns a 400-by-800 matrix of random doubles,
// uniform in [0,1).
R = grand(400,800,"def");
`scf`_();
`histplot`_(10,R);
`xtitle`_("Uniform random numbers from grand","X","Frequency");
// Returns a 400-by-800 matrix of random doubles,
// with Poisson distribution and average equal to 5.
R = grand(400,800,"poi",5);
`scf`_();
`histplot`_(10,R);
`xtitle`_("Poisson random numbers from grand","X","Frequency");
In the following example, we generate random numbers from the exponential distribution and then compare the empirical with the theoretical distribution.
lambda=1.6;
N=100000;
X = grand(1,N,"exp",lambda);
`scf`_();
classes = `linspace`_(0,12,25);
`histplot`_(classes,X)
x=`linspace`_(0,12,25);
y = (1/lambda)*`exp`_(-(1/lambda)*x);
`plot`_(x,y,"ro-");
`legend`_(["Empirical" "Theory"]);
`xtitle`_("Exponential random numbers from grand","X","Frequency");
In the following example, we generate random numbers from the gamma distribution and then compare the empirical with the theoretical distribution.
N=10000;
A=10;
B=4;
R=grand(1,N,"gam",A,B);
XS=`gsort`_(R,"g","i")';
PS=(1:N)'/N;
P=`cdfgam`_("PQ",XS,A*`ones`_(XS),B*`ones`_(XS));
`scf`_();
`plot`_(XS,PS,"b-"); // Empirical distribution
`plot`_(XS,P,"r-"); // Theoretical distribution
`legend`_(["Empirical" "Theory"]);
`xtitle`_("Cumulative distribution function of Gamma random numbers","X","F");
In the following example, we generate 10 random integers in the [1,365] interval.
grand(10,1,"uin",1,365)
In the following example, we generate 12 permutations of the [1,2,...,7] set. The 12 permutations are stored column-by-column.
grand(12,"prm",(1:7)')
The pseudo random number generators are based on deterministic sequences. In order to get reproducible simulations, the initial seed of the generator is constant, such that the sequence will remain the same from a session to the other. Hence, by default, the first numbers produced by grand are always the same.
In some situations, we may want to initialize the seed of the generator in order to produce less predictible numbers. In this case, we may initialize the seed with the output of the getdate function:
n=`getdate`_("s");
grand("setsd",n)
An example of the need of the splitting capabilities of clcg4 is as follows. Two statistical techniques are being compared on data of different sizes. The first technique uses bootstrapping and is thought to be as accurate using less data than the second method which employs only brute force. For the first method, a data set of size uniformly distributed between 25 and 50 will be generated. Then the data set of the specified size will be generated and analyzed. The second method will choose a data set size between 100 and 200, generate the data and analyze it. This process will be repeated 1000 times. For variance reduction, we want the random numbers used in the two methods to be the same for each of the 1000 comparisons. But method two will use more random numbers than method one and without this package, synchronization might be difficult. With clcg4, it is a snap. Use generator 0 to obtain the sample size for method one and generator 1 to obtain the data. Then reset the state to the beginning of the current block and do the same for the second method. This assures that the initial data for method two is that used by method one. When both have concluded, advance the block for both generators.