/// <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);
        }
예제 #2
0
        /// <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);
        }