I would like to generate some pseudorandom numbers and up until now I've been very content with the .Net library's Random.Next(int min, int max)
function. PRNGs of this variety are supposed to be using a Uniform distribution, but I would very much like to generate some numbers using an Exponential Distribution.
I'm programming in C#, although I'll accept pseudocode or C++, Java or the like.
Any suggestions / code snippets / algorithms / thoughts?
One interesting property of the exponential distribution: Consider an arrival process with exponential interarrival times. Take any period of time (t1, t2) and the arrivals in that period. Those arrivals are UNIFORMLY distributed between t1 and t2. (Sheldon Ross, Stochastic Processes).
If I have a pseudo-random number generator and, for some reason (e.g. my software can't calculate logs) you don't want to do the above transformation, but want an exponential r.v. with mean of 1.0.
You can :
1) Create 1001 U(0,1) random variables.
2) Sort in order
3) Subtract the second from the first, third from the second,... to get 1000 differences.
4) Those differences are exponential RVs with from a distribution with mean = 1.0.
Less efficient, I think, but a means to the same end.
This was what I used when faced with similar requirements:
Of course this is the formula of squaring the random number so you're generating a random number along a quadratic curve.
Since you have access to a uniform random number generator, generating a random number distributed with other distribution whose CDF you know is easy using the inversion method.
So, generate a uniform random number,
u
, in[0,1)
, then calculatex
by:x = log(1-u)/(
−λ)
,where λ is the rate parameter of the exponential distribution. Now,
x
is a random number with an exponential distribution. Note thatlog
above isln
, the natural logarithm.The Fundamental Theorem of Sampling holds that if you can normalize, integrate and invert the desired distribution you are home free.
If you have a desired distribution
F(x)
normalized on[a,b]
. You computeinvert that to get
C^{-1}
, throwz
uniformly on [0,1) and findwhich will have the desired distribution.
In your case:
F(x) = ke^{-kx}
and I will assume that you want[0,infinity]
. We get :which is invertable to give
for z thrown uniformly on
[0,1)
.But, frankly, using a well debugged library is smarter unless you're doing this for your own edification.
If you want good random numbers, consider linking to the gsl routines: http://www.gnu.org/software/gsl/. They have the routine
gsl_ran_exponential
. If you want to generate random numbers using a built-in generator with a uniform distribution on [0, 1) (e.g. u=Random.Next(0, N-1)/N, for some large N), then just use:See randist/exponential.c in the gsl source.
EDIT: just for comparison with some later answers - this is equivalent with mu = 1/lambda. mu here is the mean of the distribution, also called the scale parameter on the wikipedia page the OP linked to, and lambda is the rate parameter.
The open-source Uncommons Maths library by Dan Dyer provides random number generators, probability distributions, combinatorics and statistics for Java.
Among other valuable classes,
ExponentialGenerator
has essentially implemented the idea explained by @Alok Singhal. In its tutorial blog, a code snippet is given to simulate some random event that happened on average 10 times a minute:Of course, if you prefer to the time unit
per second
(instead ofa minute
here), you just need to setfinal long oneMinute = 1000
.Going deeper into the source code of the method
nextValue()
ofExponentialGenerator
, you will find the so-called inverse transform sampling described in Generating_exponential_variates [wiki]:P.S.: Recently I am using the Uncommons Maths library. Thanks Dan Dyer.