6.2 Non-Uniform Random Numbers

Uniform random numbers are useful, but usually we want to generate random numbers from some non-uniform distribution. There are a few ways to do this depending on the distribution.

6.2.1 Inverse CDF Transformation

The most generic method (but not necessarily the simplest) uses the inverse of the cumulative distribution function of the distribution.

Suppose we wnat to draw samples from a distribution with density f and cumulative distribution function F(x)=xf(t)dt. Then we can do the following:

  1. Draw UUnif(0,1) using any suitable PRNG.

  2. Let X=F1(U). Then X is distributed according to f.

Of course this method requires the inversion of the CDF, which is usually not possible. However, it works well for the Exponential(λ) distribution. Here, we have that f(x)=1λex/lambda and F(x)=1ex/λ. Therefore, the inverse of the CDF is F1(u)=λlog(1u).

First we can draw our uniform random variables.

set.seed(2017-12-4)
u <- runif(100)
hist(u)
rug(u)

Then we can apply the inverse CDF.

lambda <- 2  ## Exponential with mean 2
x <- -lambda * log(1 - u)
hist(x)
rug(x)

The problem with this method is that inverting the CDF is usually a difficult process and so other methods will be needed to generate other random variables.

6.2.2 Other Transformations

The inverse of the CDF is not the only function that we can use to transform uniform random variables into random variables with other distributions. Here are some common transformations.

To generate Normal random variables, we can

  1. Generate U1,U2Unif(0,1) using a standard PRNG.

  2. Let Z1=2logU1cos(2πU2)Z2=2logU1sin(2πU2) Then Z1 and Z2 are distributed independent N(0,1).

What about multivariate Normal random variables with arbitrary covariance structure? This can be done by applying an affine transformation to independent Normals.

If we want to generate XN(μ,Σ), we can

  1. Generate ZN(0,I) where I is the identity matrix;

  2. Let Σ=LL be the Cholesky decomposition of Σ.

  3. Let X=μ+Lz. Then XN(μ,Σ).

In reality, you will not need to apply any of the transformations described above because almost any worthwhile analytical software system will have these generators built in, if not carved in stone. However, once in a while, it’s still nice to know how things work.