Skip to content

How does python generate random number from normal distribution?

An answer to this question on Stack Overflow.

Question

I know that random.normal() will give me a random number from normal distribution. But how does it actually generate it? I understand that random.random() is either generated by a seed or using system randomness. Is random.normal() also generated similarly? or is it by rejection sampling technique?

Answer

The source code says that random.normalvariate() is generated as follows:

# Uses Kinderman and Monahan method. Reference: Kinderman,
# A.J. and Monahan, J.F., "Computer generation of random
# variables using the ratio of uniform deviates", ACM Trans
# Math Software, 3, (1977), pp257-260.
random = self.random
while 1:
    u1 = random()
    u2 = 1.0 - random()
    z = NV_MAGICCONST*(u1-0.5)/u2
    zz = z*z/4.0
    if zz <= -_log(u2):
        break
return mu + z*sigma

The original paper is available here, though it takes some effort to follow it.

This is, clearly, a form of rejection sampling.

If you set a seed, it specifies the sequence of random numbers generated by random.random() or random.normalvariate(). If you don't set a seed, then randomness is drawn from the machine. Which is to say, you cannot compare the operation of random.normalvariate and seeding: they are two different operations, one of which supports the other.