public void TestUniformity_InUnitCircle()
        {
            var rng = new StatelessRng(kSeed);

            // Parametrization based on polar coords
            Func <Vector2, Vector2?> Parametrize = cartesian => {
                float radius = cartesian.magnitude;
                if (radius == 0)
                {
                    return(null);
                }
                // cdf = cumulative distribution function ~= "area under"
                // area of cirle of radius "mag" relative to area of entire circle
                // to make uniform, compute cdf(var) / cdf (total) = mag^2 / 1^2
                float radiusUniform = radius * radius;

                // area increases linearly with angle01, so just need to rescale to [0,1)
                float angle        = Mathf.Atan2(cartesian.y, cartesian.x);
                float angleUniform = ToAngle01(angle);
                return(new Vector2(angleUniform, radiusUniform));
            };

            S.CheckUniformity(new[] { "theta", "rr" },
                              Gen(i => Parametrize(rng.InUnitCircle(i))));
        }
        public void TestUniformity_InIntRangeSmall()
        {
            var rng = new StatelessRng(kSeed);
            int kMin = -10, kMax = 40;

            S.CheckUniformity("u", Gen(i => (rng.InIntRange(i, kMin, kMax) - kMin + .5f) / (kMax - kMin)));
        }
        public void TestCorrelation_In01()
        {
            // Checks correlation between successive values of the generator.
            // This is kind of a wonky test, but it's what detected our terrible RNG in the first place.
            var rng        = new StatelessRng(kSeed);
            var rStateless = S.GetCorrelation(Gen(i => new Vector2(rng.In01(2 * i), rng.In01(2 * i + 1))));

            Assert.Less(Mathf.Abs(rStateless), .01f);
        }
        public void TestCheckUniformity()
        {
            var rng = new StatelessRng(kSeed);
            Func <Vector2, Vector2?> Parametrize = v => new Vector2((v.x + 1) / 2, (v.y + 1) / 2);

            Assert.Throws <AssertionException>(() =>
                                               S.CheckUniformity(new[] { "x", "y" },
                                                                 Gen(i => Parametrize(rng.InUnitCircle(i)))));
        }
        public void TestUniformity_OnUnitCircle()
        {
            var rng = new StatelessRng(kSeed);

            Func <int, float?> distribution = i => {
                Vector2 v = rng.OnUnitCircle(i);
                return(ToAngle01(Mathf.Atan2(v.y, v.x)));
            };

            S.CheckUniformity("theta", Gen(distribution));
        }
        public void TestUniformity_OnUnitSphere()
        {
            var rng = new StatelessRng(kSeed);

            Vector3[] vals = Gen(i => rng.OnUnitSphere(i)).ToArray();

            S.CheckUniformity(new[] { "theta", "z" }, vals.Select(ParametrizeSphereSurfaceThetaZ));
            // Try along another axis
            S.CheckUniformity(
                new[] { "theta", "y" },
                vals.Select(v => new Vector3(v.x, v.z, v.y))
                .Select(ParametrizeSphereSurfaceThetaZ));
        }
        public void TestUniformity_InUnitSphere()
        {
            var rng = new StatelessRng(kSeed);

            Vector3[] vals = Gen(i => rng.InUnitSphere(i)).ToArray();

            Func <Vector3, Vector3> ThetaRrrZr = v3 => {
                float r = v3.magnitude;
                if (r == 0)
                {
                    return(Vector3.zero);
                }
                float angle01 = ToAngle01(Mathf.Atan2(v3.y, v3.x));
                return(new Vector3(angle01, r * r * r, ((v3.z / r) + 1f) / 2f));
            };

            S.CheckUniformity(new[] { "theta", "rrr", "z/r" }, vals.Select(ThetaRrrZr));
        }
        public void TestUniformity_Rotation()
        {
            var rng = new StatelessRng(kSeed);

            Quaternion[] vals = Gen(i => rng.Rotation(i)).ToArray();

            Func <Quaternion, Vector2> ParametrizeAxisAndAngle = q => {
                Vector3 axis;   // a unit vector
                float   angleRad;
                q.ToAngleAxis(out angleRad, out axis);
                Vector2 param01 = ParametrizeSphereSurfaceThetaZ(axis);
                float   param2  = ToAngle01(angleRad);
                return(new Vector3(param01.x, param01.y, param2));
            };

            S.CheckUniformity(
                new[] { "axis theta", "axis z", "angle" },
                vals.Select(ParametrizeAxisAndAngle));
        }
        public void TestUniformity_InRange()
        {
            var rng = new StatelessRng(kSeed);

            S.CheckUniformity("u", Gen(i => (rng.InRange(i, -10, 20) + 10f) / 30f));
        }
        public void TestUniformity_In01()
        {
            var rng = new StatelessRng(kSeed);

            S.CheckUniformity("u", Gen(i => rng.In01(i)));
        }