How to Generate a Poisson Random Variable from a Uniform One
At a glance
- 1. Find the probabilities
For the chosen rate lambda, start with the Poisson probability at zero and use the recurrence to get later probabilities.
- 2. Build cumulative totals
Add the probabilities in order until the cumulative total reaches the uniform value.
- 3. Return the count
The first count whose cumulative probability is at least the uniform draw is the Poisson sample.
- 4. Check the rate
A rate of zero always returns zero; use a numerically robust method for very large rates.
A single standard uniform random variable can be transformed into a Poisson random variable by dividing the interval from 0 to 1 into pieces whose lengths match the Poisson probabilities. This is the inverse-transform method. It gives a direct algorithm for one sample; to generate independent Poisson samples, use independent uniform draws.
The inverse-transform idea
Let be uniform on , and let have a Poisson distribution with rate parameter . Its probability mass function is
Define the cumulative distribution function by . The inverse-transform rule is to return the smallest nonnegative integer for which .
Equivalently, assign the interval from to to the outcome , with . The interval’s length is . A uniform draw lands in that interval with probability , exactly the probability required for a Poisson outcome. The precise assignment of interval endpoints does not affect the distribution because any individual endpoint has probability zero.
A step-by-step algorithm
You do not need factorials or a table of probabilities. Start with , then use the recurrence
Maintain a running cumulative total. Stop as soon as that total is at least .
- Set , , and .
- While , increase by 1, update , and add to .
- Return .
For , return 0 directly. In an ideal mathematical calculation, the cumulative probabilities tend to 1 as increases. A computer-generated uniform is normally in , so a finite count is returned.
Worked example
Take and suppose the uniform draw is . The probability at zero is . The recurrence gives the following probabilities and cumulative totals:
| (approximately) | (approximately) | |
|---|---|---|
| 0 | 0.049787 | 0.049787 |
| 1 | 0.149361 | 0.199148 |
| 2 | 0.224042 | 0.423190 |
| 3 | 0.224042 | 0.647232 |
| 4 | 0.168031 | 0.815263 |
The cumulative total is below 0.8 at and above it at . Therefore the transformed value is . In general, values of between about 0.647232 and 0.815263 produce 4 for this rate.
Python implementation
The function below transforms a supplied uniform value. It uses only the Python standard library’s math module and is suitable for ordinary, moderate values of .
import math
def poisson_from_uniform(u, lam):
if not 0.0 <= u < 1.0:
raise ValueError('u must be in [0, 1)')
if lam < 0.0:
raise ValueError('lam must be nonnegative')
if lam == 0.0:
return 0
k = 0
p = math.exp(-lam)
cumulative = p
while u > cumulative:
k += 1
p *= lam / k
cumulative += p
return k
For example, poisson_from_uniform(0.8, 3.0) returns 4. To generate a sample in a program, pass in a uniform value from a random-number generator; repeated samples intended to be independent should use independent draws.
Why the algorithm is correct
For a given , the procedure returns when the uniform draw falls in the portion of the unit interval allocated to that count. That portion has length . Since is uniform, the probability of landing there is its length, so . This verifies the full distribution, not just its mean or variance.
Common mistakes and numerical limits
- Stopping at the first probability above instead of the cumulative total. Compare with , the sum through , not with the individual probability .
- Using the wrong recurrence index. When advancing from to , multiply by .
- Treating as an integer. The rate can be any nonnegative real number; only the generated outcome must be an integer.
- Passing . For , the inverse CDF does not reach 1 at any finite count in exact arithmetic; for , it reaches 1 at . Standard pseudorandom generators ordinarily return values below 1; if your source can return 1, handle that endpoint separately.
- Using this direct recurrence for very large . It can require many iterations, and computing may underflow to zero in floating-point arithmetic. For large rates, use a tested Poisson random-variate routine based on a method designed for that range rather than relying on this simple inverse-CDF implementation.
The inverse-transform construction itself applies to any discrete distribution: use its cumulative probabilities and return the first outcome whose cumulative total reaches the uniform draw.
References
- Non-Uniform Random Variate Generation — Luc Devroye
- Simulation — Sheldon M. Ross
Spotted an error? Send a correction. Read how we write and check articles in our editorial policy.