A popular method to generate normally distributed numbers comes from the ratio of uniform deviates technique derived by Kinderman and Monahan and improved by Leva. The method is compact and requires little memory:
static Random r = new Random();
static double Normal(double mu, double sig)
{
double u, v, x, y, q;
do
{
u = r.NextDouble();
v = 1.7156 * (r.NextDouble() - 0.5);
x = u - 0.449871;
y = Math.Abs(v) + 0.386595;
q = Math.Sqrt(x) + y * (0.19600 * y - 0.25472 * x);
} while (q > 0.27597 && (q > 0.27846 || Math.Sqrt(v) > -4.0 * Math.Log(u) * Math.Sqrt(u)));
return mu + sig * v / u;
}
The Leva paper describes the equations and solutions, but it isn't clear to me how the values were determined:
acceptance region: v^2 < -4*u^2*ln(u)
inner boundary: v = ± u*sqrt(5 - 5.136102*u)
outer boundary: v = ± u*sqrt(1.4 + 1.03696/u)
quadratic form: Q(u,v) = (u-s)^2 - b*(u-s)*(v-t) + a*(v-t)^2
s = 0.449871
t = -0.386595
r1 = 0.27597
a = 0.19600
b = 0.25472
r2 = 0.27846
Where do the magic numbers for v, s, t, r1, a, b, r2
come from?