The cumulative distribution function of an exponential is $$ 1-e^{-\lambda x} $$ We can easily compute the inverse distribution function by solving the following equation with respect to $x$ $$ u = 1-e^{-\lambda x} $$ giving $$ x = -\frac{1}{\lambda} \ln (1-u) $$ We can therefore generate an Exponential draw with the function
generate_exponential(u::Float64, θ::Float64) = -θ*log(1-u)
using Distributions
Compare this function with the quantile function in the package Distributions.
u = 0.2
θ = 2.0
d = Exponential(θ)
x = generate_exponential(u,θ)
y = quantile(d,u)
println("x =",x)
println("y =",y)
u = 0.99
x = generate_exponential(u,θ)
y = quantile(d,u)
println("x =",x)
println("y =",y)
The numbers are very close, but not exaclty the same. To obtain the same numbers, we redefine the generatin function as
?log1p
generate_exponential(u::Float64, θ::Float64) = -θ*log1p(-u)
u = 0.99
x = generate_exponential(u,θ)
y = quantile(d,u)
println("x =",x)
println("y =",y)
On http://www.johndcook.com/julia_rng.html we find the code
function rand_exponential(mean)
if mean <= 0.0
error("mean must be positive")
end
-mean*log(rand())
end
This does not correspond to the quantile function! It can raises issues when used in combination with variance reduction techniques.
The standard library in Julia uses another approach.
?randexp
From https://en.wikipedia.org/wiki/Ziggurat_algorithm, we learn that the "ziggurat algorithm is an algorithm for pseudo-random number sampling. Belonging to the class of rejection sampling algorithms, it relies on an underlying source of uniformly-distributed random numbers, typically from a pseudo-random number generator, as well as precomputed tables."
The algorithm can have performance issues with variance reduction techniques (especially quasi-Monte Carlo methods), and we will avoid it.
The ziggurat method is also used for the normal distribution. In addition to the previous remark, we note from https://en.wikipedia.org/wiki/Inverse_transform_sampling that "on the other hand, it is possible to approximate the quantile function of the normal distribution extremely accurately using moderate-degree polynomials, and in fact the method of doing this is fast enough that inversion sampling is now the default method for sampling from a normal distribution in the statistical package R."
Julia used an interpolation of the error function as basis for the normal distribution.
?randn
?erf
d = Normal(1,2)
quantile(d,0.95)