The Box-Muller 变换 http://en.wikipedia.org/wiki/Box%E2%80%93Muller_transform,是一种从高斯分布中采样随机值的优雅且性能合理的方法。
我正在寻找一种用 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);
}
}
作为记录,这里有一个清晰编写的实现,带有单元测试:
ZigguratGaussianDistribution.cs https://github.com/colgreen/Redzen/blob/master/Redzen/Numerics/Distributions/Double/ZigguratGaussian.cs
在我的 Intel Core i7 6700T @ 2.8Ghz (Skylake) 上,我在单核测试中得到以下性能结果(使用 BenchmarkDotNet):
- 博克斯-穆勒:54.5M 样本/秒
- 金字形神塔:79.5M 样本/秒
因此,Ziggurat 在这些测试中的速度大约快了 45%。
两个类都使用Xoshiro256Star星星随机 https://github.com/colgreen/Redzen/blob/master/Redzen/Random/Xoshiro256StarStarRandom.cs类来自Redzen https://github.com/colgreen/Redzen库作为伪随机性的来源。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)