/// <summary>
        /// Get normal (Gaussian) random sample with mean 0 and standard deviation 1
        /// </summary>
        /// <returns></returns>
        public static double GetNormal()
        {
            // Use Box-Muller algorithm
            double u1    = GenerateUniform.GetUniform();
            double u2    = GenerateUniform.GetUniform();
            double r     = Math.Sqrt(-2.0 * Math.Log(u1));
            double theta = 2.0 * Math.PI * u2;

            return(r * Math.Sin(theta));
        }
 public override double ComputeValue()
 {
     if (!double.IsNaN(this.Min))
     {
         if (!double.IsNaN(this.Max))
         {
             return(GenerateUniform.GetUniform(this.Min, this.Max));
         }
         return(this.Min + GenerateUniform.GetUniform());
     }
     return(GenerateUniform.GetUniform());
 }
        /// <summary>
        /// Get gamma random sample with parameters
        /// </summary>
        /// <param name="shape"></param>
        /// <param name="scale"></param>
        /// <returns></returns>
        public static double GetGamma(double shape, double scale)
        {
            // Implementation based on "A Simple Method for Generating Gamma Variables"
            // by George Marsaglia and Wai Wan Tsang.  ACM Transactions on Mathematical Software
            // Vol 26, No 3, September 2000, pages 363-372.

            double d, c, x, xsquared, v, u;

            if (shape >= 1.0)
            {
                d = shape - 1.0 / 3.0;
                c = 1.0 / Math.Sqrt(9.0 * d);
                for (; ;)
                {
                    do
                    {
                        x = GenerateNormal.GetNormal();
                        v = 1.0 + c * x;
                    }while (v <= 0.0);
                    v        = v * v * v;
                    u        = GenerateUniform.GetUniform();
                    xsquared = x * x;
                    if (u < 1.0 - .0331 * xsquared * xsquared || Math.Log(u) < 0.5 * xsquared + d * (1.0 - v + Math.Log(v)))
                    {
                        return(scale * d * v);
                    }
                }
            }
            else if (shape <= 0.0)
            {
                string msg = string.Format("Shape must be positive. Received {0}.", shape);
                throw new ArgumentOutOfRangeException(msg);
            }
            else
            {
                double g = GetGamma(shape + 1.0, 1.0);
                double w = GenerateUniform.GetUniform();
                return(scale * g * Math.Pow(w, 1.0 / shape));
            }
        }