File size: 2,929 Bytes
05c9ac2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
using System;
using NUnit.Framework;
using Unity.MLAgents.Inference.Utils;

namespace Unity.MLAgents.Tests
{
    public class RandomNormalTest
    {
        const float k_FirstValue = -1.19580f;
        const float k_SecondValue = -0.97345f;
        const double k_Epsilon = 0.0001;

        [Test]
        public void RandomNormalTestTwoDouble()
        {
            var rn = new RandomNormal(2018);

            Assert.AreEqual(k_FirstValue, rn.NextDouble(), k_Epsilon);
            Assert.AreEqual(k_SecondValue, rn.NextDouble(), k_Epsilon);
        }

        [Test]
        public void RandomNormalTestWithMean()
        {
            var rn = new RandomNormal(2018, 5.0f);

            Assert.AreEqual(k_FirstValue + 5.0, rn.NextDouble(), k_Epsilon);
            Assert.AreEqual(k_SecondValue + 5.0, rn.NextDouble(), k_Epsilon);
        }

        [Test]
        public void RandomNormalTestWithStddev()
        {
            var rn = new RandomNormal(2018, 0.0f, 4.2f);

            Assert.AreEqual(k_FirstValue * 4.2, rn.NextDouble(), k_Epsilon);
            Assert.AreEqual(k_SecondValue * 4.2, rn.NextDouble(), k_Epsilon);
        }

        [Test]
        public void RandomNormalTestWithMeanStddev()
        {
            const float mean = -3.2f;
            const float stddev = 2.2f;
            var rn = new RandomNormal(2018, mean, stddev);

            Assert.AreEqual(k_FirstValue * stddev + mean, rn.NextDouble(), k_Epsilon);
            Assert.AreEqual(k_SecondValue * stddev + mean, rn.NextDouble(), k_Epsilon);
        }

        [Test]
        public void RandomNormalTestDistribution()
        {
            const float mean = -3.2f;
            const float stddev = 2.2f;
            var rn = new RandomNormal(2018, mean, stddev);

            const int numSamples = 100000;
            // Adapted from https://www.johndcook.com/blog/standard_deviation/
            // Computes stddev and mean without losing precision
            double oldM = 0.0, newM = 0.0, oldS = 0.0, newS = 0.0;

            for (var i = 0; i < numSamples; i++)
            {
                var x = rn.NextDouble();
                if (i == 0)
                {
                    oldM = newM = x;
                    oldS = 0.0;
                }
                else
                {
                    newM = oldM + (x - oldM) / i;
                    newS = oldS + (x - oldM) * (x - newM);

                    // set up for next iteration
                    oldM = newM;
                    oldS = newS;
                }
            }

            var sampleMean = newM;
            var sampleVariance = newS / (numSamples - 1);
            var sampleStddev = Math.Sqrt(sampleVariance);

            // Note a larger epsilon here. We could get closer to the true values with more samples.
            Assert.AreEqual(mean, sampleMean, 0.01);
            Assert.AreEqual(stddev, sampleStddev, 0.01);
        }
    }
}