red*_*alx 3 c# math performance gaussian sampling
所述盒-缪勒变换,是从高斯分布随机采样值的优雅和合理高性能方法.
我正在寻找一种更清晰的C#编写方法.
作为参考,这里是Box-Muller实现的一个实现,作为性能比较的基准......
public class GaussianGenerator
{
FastRandom _rng = new FastRandom();
double? _spareValue = null;
/// <summary>
/// Get the next sample point from the gaussian distribution.
/// </summary>
public double NextDouble()
{
if(null != _spareValue)
{
double tmp = _spareValue.Value;
_spareValue = null;
return tmp;
}
// Generate two new gaussian values.
double x, y, sqr;
// We need a non-zero random point inside the unit circle.
do
{
x = 2.0 * _rng.NextDouble() - 1.0;
y = 2.0 * _rng.NextDouble() - 1.0;
sqr = x * x + y * y;
}
while(sqr > 1.0 || sqr == 0);
// Make the Box-Muller transformation.
double fac = Math.Sqrt(-2.0 * Math.Log(sqr) / sqr);
_spareValue = x * fac;
return y * fac;
}
/// <summary>
/// Get the next sample point from the gaussian distribution.
/// </summary>
public double NextDouble(double mu, double sigma)
{
return mu + (NextDouble() * sigma);
}
}
Run Code Online (Sandbox Code Playgroud)
这里的记录是一个清晰的书面实现,单元测试:
ZigguratGaussianDistribution.cs
在我的英特尔酷睿i7 6700T @ 2.8Ghz(Skylake)上,我在单核测试(使用BenchmarkDotNet)上获得以下性能结果:
所以Ziggurat在这些测试中的速度提高了约45%.
两个类都使用Redzen库中的Xoshiro256StarStarRandom类作为伪随机源.