Even if LCG itself would be considered expensive, for quick prototyping needs this should be sufficient.
https://en.wikipedia.org/wiki/Cumulative_distribution_functi...
Log is an integral. Exp is an infinite series.
Normal cdf (erf) and its inverse (erfinv) are implemented almost everywhere exp and log are implemented. E.g. MKL and CUDA. Both can be computed via series or integral (like exp and log).
[1] https://en.wikipedia.org/wiki/Error_function
[2] https://people.maths.ox.ac.uk/gilesm/files/gems_erfinv.pdf
> The normal distribution provides uniform sampling on the > unit n-sphere.
What does that mean? Assume one wants to sample a point uniformly from the unit circle. So we want to uniformly sample from the set { (x, y) : xx + yy = 1 }.
The naive method of uniformly sampling x over [0, 1] and then uniformly sampling y in [0, 1 - xx] doesn't work. It doesn't work because for a given change in dx, the change in dy is not uniform.
For example, if we are the point (x=0, y=1), in an infinitesimal region around this point, it looks like "flat land", so moving in dx does not change dy. That is, the tangent to the point (x=0, y=1) is horizontal.
On the other hand, if we are at the point (x=1, y=0), in an infinitesimal region around this point, it looks like a cliff face: all we have is vertical. So the dy change is "infinity". That is, the tangent to the point (x=1, y=0) is vertical.
Let's sample both x and y from the normal distribution. So the probability of getting x=r is e^{-rr}. The probability of getting y=s is e^{-ss}. The probability of getting some random point (x, y) = (r, s) is e^{-(rr+s*s)} = e^{-1} = constant.
So if we sample two points using the normal distribution, the points are uniformly distributed on the unit circle.
### Box–Muller transform
On the flip side, assume we have a uniformly distributed point on the circle. This means that the angle theta is uniformly distributed in [0, 2pi].
Given such a uniformly distributed point, we can generate two gaussian distributed numbers by taking their x and y component.
The intuition for why this works comes from the above:
- We saw that (x ~ normal, y ~ normal) => (theta ~ uniform) [as explained before].
- We can also show that (theta ~ uniform) => (x ~ normal, y ~ normal)
which is what the box-muller transform does.
Something else that might be useful to know are methods to transform the uniform output of LCG into various other types of distribution shapes:
When U is uniform between 0 and 1 exclusive,
One can get an Exp(lambda) distributed variable with -log(U)/lambda
One can get a heavy-tailed Pareto(m,a) distributed variable with m/(1-u)^(1/a)
I'm still missing something easily memorable for bell-shaped distributions. The normal distribution would be nice because it's so easy to transform N(0,1) into a distribution with arbitrary parameters, but there's no simple way to compute the standard normal.