예제 #1
0
        // Thanks to John D. Cook (johndcook.com) for this public domain random variate code

        // Get normal (Gaussian) random sample with specified mean and standard deviation
        static double GetNormal(double mean = 0.0, double standardDeviation = 1.0)
        {
            if (standardDeviation <= 0.0)
            {
                StnSciScenario.LogWarning("Invalid standard deviation: " + standardDeviation);
                return(0);
            }
            // Use Box-Muller algorithm
            double u1    = GetUniform();
            double u2    = GetUniform();
            double r     = Math.Sqrt(-2.0 * Math.Log(u1));
            double theta = 2.0 * Math.PI * u2;

            return(mean + standardDeviation * r * Math.Sin(theta));
        }
예제 #2
0
        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 = GetNormal();
                        v = 1.0 + c * x;
                    }while (v <= 0.0);
                    v        = v * v * v;
                    u        = 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)
            {
                StnSciScenario.LogWarning("Invalid Gamma shape: " + shape);
                return(0);
            }
            else
            {
                double g = GetGamma(shape + 1.0, 1.0);
                double w = GetUniform();
                return(scale * g * Math.Pow(w, 1.0 / shape));
            }
        }