(Probably a bit late to the party but I had the same question and found a different solution which I personally prefer.)
You can use the Box-Muller Transform to generate two independent random real numbers z_0
and z_1
that follow a standard normal distribution (zero mean and unit variance) using two uniformly distributed numbers u_1
and u_2
.
Example
If you want to generate N random numbers that follow a normal distribution just like np.random.randn(n)
does you can do something like the following:
import math
import random
rands = []
for i in range(N):
u1 = random.uniform(0, 1)
u2 = random.uniform(0, 1)
z0 = math.sqrt(-2 * math.log(u1)) * math.cos(2 * math.pi * u2)
rands.append(z0)
# z1 can be discarded (or cached for a more efficient approach)
# z1 = math.sqrt(-2 * math.log(u1)) * math.sin(2 * math.pi * u2)
If you plot a histogram of rands
you'll verify the numbers are indeed normally distributed. The following is the distribution of 100000 random numbers with 100 bins: