\chapter{Random Numbers}
\label{cha:random-array}

%begin{latexonly}
\makeatletter \py@reset \makeatother
%end{latexonly}
\declaremodule[numarray.randomarray]{extension}{numarray.random_array}
\moduleauthor{The numarray team}{numpy@lists.sourceforge.net}
\modulesynopsis{Random Numbers}

\begin{quote}
  The \module{numarray.random_array} module (in conjunction with the
  \module{numarray.random_array.ranlib} submodule) provides a high-level
  interface to ranlib, which provides a good quality C implementation of a
  random-number generator.
\end{quote}

\section{General functions}
\label{sec:RA:general-functions}

\begin{funcdesc}{seed}{x=0, y=0}
   The \function{seed} function takes two integers and sets the two seeds of
   the random number generator to those values. If the default values of 0 are
   used for both \var{x} and \var{y}, then a seed is generated from the current
   time, providing a pseudo-random seed.
\end{funcdesc}

\begin{funcdesc}{get_seed}{}
   This function returns the two seeds used by the current random-number
   generator. It is most often used to find out what seeds the \function{seed}
   function chose at the last iteration.
   \remark{Are there any thread-safety issues?}
\end{funcdesc}

\begin{funcdesc}{random}{shape=[]}
   The \function{random} function takes a \var{shape}, and returns an array of
   \class{Float} numbers between 0.0 and 1.0.  Neither 0.0 nor 1.0 is ever
   returned by this function.  The array is filled from the generator following
   the canonical array organization.
   
   If no argument is specified, the function returns a single floating point
   number, not an array.
   
   \note{See discussion of the \member{flat} attribute in section
      \ref{mem:numarray:flat}.}
\end{funcdesc}

\begin{funcdesc}{uniform}{minimum, maximum, shape=[]}
   The \function{uniform} function returns an array of the specified
   \var{shape} and containing \class{Float} random numbers strictly between
   \var{minimum} and \var{maximum}.
   
   The \var{minimum} and \var{maximum} arguments can be arrays. If this is the
   case, and the output \var{shape} is specified, \var{minimum} and
   \var{maximum} are broadcasted if their dimensions are not equal to
   \var{shape}. If \var{shape} is not specified, the shape of the output is
   equal to the shape of \var{minimum} and \var{maximum} after broadcasting.
   
   If no \var{shape} is specified, and \var{minimum} and \var{maximum} are
   scalars, a single value is returned.
\end{funcdesc}

\begin{funcdesc}{randint}{minimum, maximum, shape=[]}
   The \function{randint} function returns an array of the specified
   \var{shape} and containing random (standard) integers greater than or equal
   to \var{minimum} and strictly less than \var{maximum}. 
   
   The \var{minimum} and \var{maximum} arguments can be arrays. If this is the
   case, and the output \var{shape} is specified, \var{minimum} and
   \var{maximum} are broadcasted if their dimensions are not equal to
   \var{shape}. If \var{shape} is not specified, the shape of the output is
   equal to the shape of \var{minimum} and \var{maximum} after broadcasting.
   
   If no \var{shape} is specified, and \var{minimum} and \var{maximum} are
   scalars, a single value is returned.
\end{funcdesc}

\begin{funcdesc}{permutation}{n}
   The \function{permutation} function returns an array of the integers between
   \code{0} and \code{\var{n}-1}, in an array of shape \code{(n,)} with its
   elements randomly permuted.
\end{funcdesc}




\section{Special random number distributions}
\label{sec:RA:special-distribution}



\subsection{Random floating point number distributions}
\label{sec:RA:float-distribution}

\begin{funcdesc}{beta}{a, b, shape=[]}
   The \function{beta} function returns an array of the specified shape that
   contains \class{Float} numbers $\beta$-distributed with $\alpha$-parameter
   \var{a} and $\beta$-parameter \var{b}. 
   
   The \var{a} and \var{b} arguments can be arrays. If this is the case, and
   the output \var{shape} is specified, \var{a} and \var{b} are broadcasted if
   their dimensions are not equal to \var{shape}. If \var{shape} is not
   specified, the shape of the output is equal to the shape of \var{a} and
   \var{b} after broadcasting.
   
   If no \var{shape} is specified, and \var{a} and \var{b} are
   scalars, a single value is returned.
\end{funcdesc}

\begin{funcdesc}{chi_square}{df, shape=[]}
   The \function{chi_square} function returns an array of the specified
   \var{shape} that contains \class{Float} numbers with the
   $\chi^2$-distribution with \var{df} degrees of freedom.
   
   The \var{df} argument can be an array. If this is the case, and the output
   \var{shape} is specified, \var{df} is broadcasted if its dimensions are not
   equal to \var{shape}. If \var{shape} is not specified, the shape of the
   output is equal to the shape of \var{df}.
   
   If no \var{shape} is specified, and \var{df} is a scalar, a single value is
   returned.
\end{funcdesc}

\begin{funcdesc}{exponential}{mean, shape=[]}
   The \function{exponential} function returns an array of the specified
   \var{shape} that contains \class{Float} numbers exponentially distributed
   with the specified \var{mean}. 
   
   The \var{mean} argument can be an array. If this is the case, and the output
   \var{shape} is specified, \var{mean} is broadcasted if its dimensions are
   not equal to \var{shape}. If \var{shape} is not specified, the shape of the
   output is equal to the shape of \var{mean}.
   
   If no \var{shape} is specified, and \var{mean} is a scalar, a single value
   is returned.
\end{funcdesc}

\begin{funcdesc}{F}{dfn, dfd, shape=[]}
  The \function{F} function returns an array of the specified \var{shape} that
  contains \class{Float} numbers with the F-distribution with \var{dfn} degrees
  of freedom in the numerator and \var{dfd} degrees of freedom in the
  denominator.
   
  The \var{dfn} and \var{dfd} arguments can be arrays. If this is the case, and
  the output \var{shape} is specified, \var{dfn} and \var{dfd} are broadcasted
  if their dimensions are not equal to \var{shape}. If \var{shape} is not
  specified, the shape of the output is equal to the shape of \var{dfn} and
  \var{dfd} after broadcasting.
   
  If no \var{shape} is specified, and \var{dfn} and \var{dfd} are scalars, a
  single value is returned.
\end{funcdesc}

\begin{funcdesc}{gamma}{a, r, shape=[]}
   The \function{gamma} function returns an array of the specified \var{shape}
   that contains \class{Float} numbers $\beta$-distributed with location
   parameter \var{a} and distribution shape parameter \var{r}.
   
   The \var{a} and \var{r} arguments can be arrays. If this is the case, and
   the output \var{shape} is specified, \var{a} and \var{r} are broadcasted if
   their dimensions are not equal to \var{shape}. If \var{shape} is not
   specified, the shape of the output is equal to the shape of \var{a} and
   \var{r} after broadcasting.
   
   If no \var{shape} is specified, and \var{a} and \var{r} are scalars, a
   single value is returned.
\end{funcdesc}

\begin{funcdesc}{multivariate_normal}{mean, covariance, shape=[]}
   The multivariate_normal function takes a one dimensional array argument
   \var{mean} and a two dimensional array argument \var{covariance}. Suppose
   the shape of \var{mean} is \code{(n,)}. Then the shape of \var{covariance}
   must be \code{(n,n)}. The function returns an array of \class{Float}s.
   
   The effect of the \var{shape} parameter is:
   \begin{itemize}
   \item If no \var{shape} is specified, then an array with shape \code{(n,)}
      is returned containing a vector of numbers with a multivariate normal
      distribution with the specified mean and covariance.
   \item If \var{shape} is specified, then an array of such vectors is
      returned.  The shape of the output is \code{shape.append((n,))}. The
      leading indices into the output array select a multivariate normal from
      the array. The final index selects one number from within the
      multivariate normal.
 \end{itemize}
 In either case, the behavior of \function{multivariate_normal} is undefined if
 \var{covariance} is not symmetric and positive definite.
\end{funcdesc}

\begin{funcdesc}{normal}{mean, stddev, shape=[]}
   The \function{normal} function returns an array of the specified \var{shape}
   that contains \class{Float} numbers normally distributed with the specified
   \var{mean} and standard deviation \var{stddev}. 
   
   The \var{mean} and \var{stddev} arguments can be arrays. If this is the
   case, and the output \var{shape} is specified, \var{mean} and \var{stddev}
   are broadcasted if their dimensions are not equal to \var{shape}. If
   \var{shape} is not specified, the shape of the output is equal to the shape
   of \var{mean} and \var{stddev} after broadcasting.
   
   If no \var{shape} is specified, and \var{mean} and \var{stddev} are scalars,
   a single value is returned.
\end{funcdesc}

\begin{funcdesc}{noncentral_chi_square}{df, nonc, shape=[]}
   The \function{noncentral_chi_square} function returns an array of the
   specified \var{shape} that contains \class{Float} numbers with
   the$\chi^2$-distribution with \var{df} degrees of freedom and noncentrality
   parameter \var{nconc}.
   
   The \var{df} and \var{nonc} arguments can be arrays. If this is the case,
   and the output \var{shape} is specified, \var{df} and \var{nonc} are
   broadcasted if their dimensions are not equal to \var{shape}. If \var{shape}
   is not specified, the shape of the output is equal to the shape of \var{df}
   and \var{nonc} after broadcasting.
   
   If no \var{shape} is specified, and \var{df} and \var{nonc} are scalars, a
   single value is returned.
\end{funcdesc}

\begin{funcdesc}{noncentral_F}{dfn, dfd, nconc, shape=[]}
   The \function{noncentral_F} function returns an array of the specified
   \var{shape} that contains \class{Float} numbers with the F-distribution with
   \var{dfn} degrees of freedom in the numerator, \var{dfd} degrees of freedom
   in the denominator, and noncentrality parameter \var{nconc}.
   
   The \var{dfn}, \var{dfd} and \var{nonc} arguments can be arrays. If this is
   the case, and the output \var{shape} is specified, \var{dfn}, \var{dfd} and
   \var{nonc} are broadcasted if their dimensions are not equal to \var{shape}.
   If \var{shape} is not specified, the shape of the output is equal to the
   shape of \var{dfn}, \var{dfd} and \var{nonc} after broadcasting.
   
   If no \var{shape} is specified, and \var{dfn}, \var{dfd} and \var{nonc} are
   scalars, a single value is returned.
\end{funcdesc}

\begin{funcdesc}{standard_normal}{shape=[]}
   The \function{standard_normal} function returns an array of the specified
   \var{shape} that contains \class{Float} numbers normally (Gaussian)
   distributed with mean zero and variance and standard deviation one. 
   
   If no \var{shape} is specified, a single number is returned.
\end{funcdesc}



\subsection{Random integer number distributions }
\label{sec:RA:int-distributions}

\begin{funcdesc}{binomial}{trials, prob, shape=[]}
   The \function{binomial} function returns an array with the specified
   \var{shape} that contains \class{Integer} numbers with the binomial
   distribution with \var{trials} and event probability \var{prob}. In other
   words, each value in the returned array is the number of times an event with
   probability \var{prob} occurred within \var{trials} repeated trials. 
   
   The \var{trials} and \var{prob} arguments can be arrays. If this is the
   case, and the output \var{shape} is specified, \var{trials} and \var{prob}
   are broadcasted if their dimensions are not equal to \var{shape}. If
   \var{shape} is not specified, the shape of the output is equal to the shape
   of \var{trials} and \var{prob} after broadcasting.
   
   If no \var{shape} is specified, and \var{trials} and \var{prob} are scalars,
   a single value is returned.
\end{funcdesc}

\begin{funcdesc}{negative_binomial}{trials, prob, shape=[]}
  The \function{negative_binomial} function returns an array with the specified
  \var{shape} that contains \class{Integer} numbers with the negative binomial
  distribution with \var{trials} and event probability \var{prob}.
   
  The \var{trials} and \var{prob} arguments can be arrays. If this is the case,
  and the output \var{shape} is specified, \var{trials} and \var{prob} are
  broadcasted if their dimensions are not equal to \var{shape}. If \var{shape}
  is not specified, the shape of the output is equal to the shape of
  \var{trials} and \var{prob} after broadcasting.
   
   If no \var{shape} is specified, and \var{trials} and \var{prob} are scalars,
   a single value is returned.
\end{funcdesc}

\begin{funcdesc}{multinomial}{trials, probs, shape=[]}
   The \function{multinomial} function returns an array with that contains
   integer numbers with the multinomial distribution with \var{trials} and
   event probabilities given in \var{probs}.  \var{probs} must be a one
   dimensional array.  There are \code{len(probs)+1} events. \code{probs[i]} is
   the probability of the i-th event for \code{0<=i<len(probs)}. The
   probability of event \code{len(probs)} is \code{1.-Numeric.sum(prob)}.
   
   The function returns an integer array of shape
   \code{shape~+~(len(probs)+1,)}.  If \var{shape} is not specified this is one
   multinomially distributed vector of shape \code{(len(prob)+1,)}.  Otherwise
   each \code{returnarray[i,j,...,:]} is an integer array of shape
   \code{(len(prob)+1,)} containing one multinomially distributed vector.
\end{funcdesc}

\begin{funcdesc}{poisson}{mean, shape=[]}
   The \function{poisson} function returns an array with the specified shape
   that contains \class{Integer} numbers with the Poisson distribution with the
   specified \var{mean}.
   
   The \var{mean} argument can be an array. If this is the case, and the output
   \var{shape} is specified, \var{mean} is broadcasted if its dimensions are
   not equal to \var{shape}. If \var{shape} is not specified, the shape of the
   output is equal to the shape of \var{mean}.
   
   If no \var{shape} is specified, and \var{mean} is a scalar, a single value
   is returned.
\end{funcdesc}



\section{Examples}
\label{sec:examples}

Some example uses of the \module{numarray.random_array} module. \note{Naturally the exact
   output of running these examples will be different each time!} \remark{Make
   sure these examples are correct!}
\begin{verbatim}
>>> from numarray.random_array import *
>>> seed() # Set seed based on current time
>>> print get_seed() # Find out what seeds were used
(897800491, 192000)
>>> print random()
0.0528018975065
>>> print random((5,2))
[[ 0.14833829 0.99031458]
[ 0.7526806 0.09601787]
[ 0.1895229 0.97674777]
[ 0.46134511 0.25420982]
[ 0.66132009 0.24864472]]
>>> print uniform(-1,1,(10,))
[ 0.72168852 -0.75374185 -0.73590945 0.50488248 -0.74462822 0.09293685
-0.65898308 0.9718067 -0.03252475 0.99611011]
>>> print randint(0,100, (12,))
[28 5 96 19 1 32 69 40 56 69 53 44]
>>> print permutation(10)
[4 2 8 9 1 7 3 6 5 0]
>>> seed(897800491, 192000) # resetting the same seeds
>>> print random() # yields the same numbers
0.0528018975065
\end{verbatim}
Most of the functions in this package take zero or more distribution specific
parameters plus an optional \var{shape} parameter. The \var{shape} parameter
gives the shape of the output array:
\begin{verbatim}
>>> from numarray.random_array import *
>>> print standard_normal()
-0.435568600893
>>> print standard_normal(5)
[-1.36134553 0.78617644 -0.45038718 0.18508556 0.05941355]
>>> print standard_normal((5,2))
[[ 1.33448863 -0.10125473]
[ 0.66838062 0.24691346]
[-0.95092064 0.94168913]
[-0.23919107 1.89288616]
[ 0.87651485 0.96400219]]
>>> print normal(7., 4., (5,2)) #mean=7, std. dev.=4
[[ 2.66997623 11.65832615]
[ 6.73916003 6.58162862]
[ 8.47180378 4.30354905]
[ 1.35531998 -2.80886841]
[ 7.07408469 11.39024973]]
>>> print exponential(10., 5) #mean=10
[ 18.03347754 7.11702306 9.8587961 32.49231603 28.55408891]
>>> print beta(3.1, 9.1, 5) # alpha=3.1, beta=9.1
[ 0.1175056 0.17504358 0.3517828 0.06965593 0.43898219]
>>> print chi_square(7, 5) # 7 degrees of freedom (dfs)
[ 11.99046516 3.00741053 4.72235727 6.17056274 8.50756836]
>>> print noncentral_chi_square(7, 3, 5) # 7 dfs, noncentrality 3
[ 18.28332138 4.07550335 16.0425396 9.51192093 9.80156231]
>>> F(5, 7, 5) # 5 and 7 dfs
array([ 0.24693671, 3.76726145, 0.66883826, 0.59169068, 1.90763224])
>>> noncentral_F(5, 7, 3., 5) # 5 and 7 dfs, noncentrality 3
array([ 1.17992553, 0.7500126 , 0.77389943, 9.26798989, 1.35719634])
>>> binomial(32, .5, 5) # 32 trials, prob of an event = .5
array([12, 20, 21, 19, 17])
>>> negative_binomial(32, .5, 5) # 32 trials: prob of an event = .5
array([21, 38, 29, 32, 36])
\end{verbatim}
Two functions that return generate multivariate random numbers (that is, random
vectors with some known relationship between the elements of each vector,
defined by the distribution). They are \function{multivariate_normal} and
\function{multinomial}. For these two functions, the lengths of the leading
axes of the output may be specified. The length of the last axis is determined
by the length of some other parameter.
\begin{verbatim}
>>> multivariate_normal([1,2], [[1,2],[2,1]], [2,3])
array([[[ 0.14157988, 1.46232224],
[-1.11820295, -0.82796288],
[ 1.35251635, -0.2575901 ]],
[[-0.61142141, 1.0230465 ],
[-1.08280948, -0.55567217],
[ 2.49873002, 3.28136372]]])
>>> x = multivariate_normal([10,100], [[1,2],[2,1]], 10000)
>>> x_mean = sum(x)/10000
>>> print x_mean
[ 9.98599893 100.00032416]
>>> x_minus_mean = x - x_mean
>>> cov = matrixmultiply(transpose(x_minus_mean), x_minus_mean) / 9999.
>>> cov
array([[ 2.01737122, 1.00474408],
[ 1.00474408, 2.0009806 ]])
\end{verbatim}
The a priori probabilities for a multinomial distribution must sum to one. The
prior probability argument to \function{multinomial} doesn't give the prior
probability of the last event: it is computed to be one minus the sum of the
others.
\begin{verbatim}
>>> multinomial(16, [.1, .4, .2]) # prior probabilities [.1, .4, .2, .3]
array([2, 7, 1, 6])
>>> multinomial(16, [.1, .4, .2], [2,3]) # output shape [2,3,4]
array([[[ 1, 9, 1, 5],
[ 0, 10, 3, 3],
[ 4, 9, 3, 0]],
[[ 1, 6, 1, 8],
[ 3, 4, 5, 4],
[ 1, 5, 2, 8]]])
\end{verbatim}
Many of the functions accept arrays or sequences for the distribution
arguments. If no \var{shape} argument is given, then the shape of the output is
determined by the shape of the parameter argument. For instance:
\begin{verbatim}
>>> beta([5.0, 50.0], [10.0, 100.])
array([ 0.54379648,  0.35352072])
\end{verbatim}
Broadcasting rules apply if two or more arguments are arrays:
\begin{verbatim}
>>> beta([5.0, 50.0], [[10.0, 100.], [20.0, 200.0]])
array([[ 0.30204576,  0.32154009],
       [ 0.10851908,  0.19207685]])
\end{verbatim}
The \var{shape} argument can still be used to specify the output shape. Any
array argument will be broadcasted to have the given shape:
\begin{verbatim}
>>> beta(5.0, [10.0, 100.0], shape = (3, 2))
array([[ 0.49521708,  0.02218186],
       [ 0.21000148,  0.04366644],
       [ 0.43169656,  0.05285903]])
\end{verbatim}
%% Local Variables:
%% mode: LaTeX
%% mode: auto-fill
%% fill-column: 79
%% indent-tabs-mode: nil
%% ispell-dictionary: "american"
%% reftex-fref-is-default: nil
%% TeX-auto-save: t
%% TeX-command-default: "pdfeLaTeX"
%% TeX-master: "numarray"
%% TeX-parse-self: t
%% End:
