I managed to find the source code in sexp.c
, and the algorithm (Ahrens & Dieter). I mostly understand the first half of the code - it seems like it finds the coarse location of the returned value, using the fact that $\int_{k\cdot\ln2}^{(k+1)\cdot\ln2}e^{-x}dx=2^{-k-1}$. So if we stopped there, more or less, we would get a distribution which is a step function of the exp:
I don't understand the 2nd half.
I guess I agree that $u$ (in this point) is again uniform distributed in $U(0, \ln 2)$ (the $\ln2$ comes from multiplying the result). I more or less understand that: "With probabilities ... $(\ln 2)^i/i!$ consider the minimum of $i$ uniform samples from $(0, \ln2)$". I just don't know how you show this is indeed an exponential distribution ... I know how to find the pdf of $\min u_i$ but here it has different probabilities for each $i$.
Can anyone show this?
Here is the code:
double exp_rand(void)
{
/* q[k-1] = sum(log(2)^k / k!) k=1,..,n, */
/* The highest n (here 16) is determined by q[n-1] = 1.0 */
/* within standard precision */
const static double q[] =
{
0.6931471805599453,
0.9333736875190459,
0.9888777961838675,
0.9984959252914960,
0.9998292811061389,
0.9999833164100727,
0.9999985691438767,
0.9999998906925558,
0.9999999924734159,
0.9999999995283275,
0.9999999999728814,
0.9999999999985598,
0.9999999999999289,
0.9999999999999968,
0.9999999999999999,
1.0000000000000000
};
double a = 0.;
double u = unif_rand(); /* precaution if u = 0 is ever returned */
while(u <= 0. || u >= 1.) u = unif_rand(); for (;;) {
u += u;
if (u > 1.)
break;
a += q[0];
}
u -= 1.;
if (u <= q[0])
return a + u; # Up to here I understand
int i = 0;
double ustar = unif_rand(), umin = ustar;
do {
ustar = unif_rand();
if (umin > ustar)
umin = ustar;
i++;
} while (u > q[i]);
return a + umin * q[0];
}