|
using System; |
|
|
|
namespace Unity.MLAgents.Inference.Utils |
|
{ |
|
|
|
|
|
|
|
|
|
|
|
|
|
internal class RandomNormal |
|
{ |
|
readonly double m_Mean; |
|
readonly double m_Stddev; |
|
readonly Random m_Random; |
|
|
|
public RandomNormal(int seed, float mean = 0.0f, float stddev = 1.0f) |
|
{ |
|
m_Mean = mean; |
|
m_Stddev = stddev; |
|
m_Random = new Random(seed); |
|
} |
|
|
|
|
|
bool m_HasSpare; |
|
double m_SpareUnscaled; |
|
|
|
|
|
|
|
|
|
|
|
public double NextDouble() |
|
{ |
|
if (m_HasSpare) |
|
{ |
|
m_HasSpare = false; |
|
return m_SpareUnscaled * m_Stddev + m_Mean; |
|
} |
|
|
|
double u, v, s; |
|
do |
|
{ |
|
u = m_Random.NextDouble() * 2.0 - 1.0; |
|
v = m_Random.NextDouble() * 2.0 - 1.0; |
|
s = u * u + v * v; |
|
} |
|
while (s >= 1.0 || Math.Abs(s) < double.Epsilon); |
|
|
|
s = Math.Sqrt(-2.0 * Math.Log(s) / s); |
|
m_SpareUnscaled = u * s; |
|
m_HasSpare = true; |
|
|
|
return v * s * m_Stddev + m_Mean; |
|
} |
|
} |
|
} |
|
|