问题
The Box-Muller transform, is an elegant and reasonably performant method of sampling random values from a Gaussian distribution.
I'm looking for a faster method clearly written and in C#.
For reference here's an implementation of the Box-Muller Implementation to act as a baseline for performance comparisons...
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);
}
}
回答1:
For the record here's a clearly written implementation, with unit tests:
ZigguratGaussianDistribution.cs
On my Intel Core i7 6700T @ 2.8Ghz (Skylake) I get the following performance results on a single core test (using BenchmarkDotNet):
- Box-Muller: 54.5M samples/sec
- Ziggurat: 79.5M samples/sec
So Ziggurat is about 45% faster in those tests.
Both classes use the Xoshiro256StarStarRandom class from the Redzen library as a source of pseudo-randomness.
回答2:
An implementation of Ziggurat in C:
http://www.seehuhn.de/pages/ziggurat
Also the GSL sources (in C) contain a few implementations of Gaussian random number generators. Includes the Box-Mueller and ratio methods.
http://gsl.sourcearchive.com/documentation/1.14plus-pdfsg-1/randist_2gauss_8c-source.html
回答3:
The use of the ratio-of-uniforms method is very fast. I do not have a C#-implementation but I used it in Excel VBA and it was 3x faster compared to the Box-Muller approach: 70s for 10 million samples using Box-Muller compared to 20s for 10 million samples using the ratio-of-uniform method.

good luck.
回答4:
Ziggurat sampling is very fast and memory efficient. For a C/C++ application, you can use the GSL library
来源:https://stackoverflow.com/questions/7183229/what-is-the-fastest-method-of-sampling-random-values-from-a-gaussian-distributio