/// <summary> /// Returns a Gaussian distributed double. /// </summary> public double GetDouble() { double value; if (!Double.IsNaN(m_cachedValue)) { value = m_cachedValue; m_cachedValue = Double.NaN; } else { // using the polar form of the Box-Muller transformation to // transform two random uniform values to two Gaussian // distributed values double x1, x2, w; do { x1 = 2.0 * m_rndUniform.UniformDouble() - 1.0; x2 = 2.0 * m_rndUniform.UniformDouble() - 1.0; w = x1 * x1 + x2 * x2; } while (w >= 1.0); w = Fun.Sqrt((-2.0 * Fun.Log(w)) / w); value = x1 * w; m_cachedValue = x2 * w; } return(value); }
/// <summary> /// Generates normal distributed random variable with given mean and standard deviation. /// Uses the Box-Muller Transformation to transform two uniform distributed random variables to one normal distributed value. /// NOTE: If multiple normal distributed random values are required, consider using <see cref="RandomGaussian"/>. /// </summary> public static double Gaussian(this IRandomUniform rnd, double mean = 0.0, double stdDev = 1.0) { // Box-Muller Transformation var u1 = 1.0 - rnd.UniformDouble(); // uniform (0,1] -> log requires > 0 var u2 = rnd.UniformDouble(); // uniform [0,1) var randStdNormal = Fun.Sqrt(-2.0 * Fun.Log(u1)) * Fun.Sin(Constant.PiTimesTwo * u2); return(mean + stdDev * randStdNormal); }