using System;

namespace EvoBoat.EvoAlg
{
    /// <summary>
    /// Gaussion random number generator
    /// </summary>
    public class GaussRandom : Random
    {
        int phase = 0;
        double x;

        public GaussRandom()
        { }

        public GaussRandom(int seed)
            : base(seed)
        { }

        /// <summary>
        /// generate a normal Gaussion random number
        /// </summary>
        public override double NextDouble()
        {
            double v1, v2, s;
            if (phase == 0)
            {
                do
                {
                    double u1 = base.NextDouble(), u2 = base.NextDouble();
                    v1 = 2.0 * u1 - 1.0;
                    v2 = 2.0 * u2 - 1.0;
                    s = v1 * v1 + v2 * v2;
                }
                while (s >= 1.0 || s == 0.0);
                double tmp = Math.Sqrt(-2.0 * Math.Log(s) / s);
                phase = 1;
                x = v1 * tmp;
                return v2 * tmp;
            }
            else
            {
                phase = 0;
                return x;
            }
        }
    }
}
