What is the fastest method of sampling random values from a Gaussian distribution?

扶醉桌前 提交于 2019-12-10 21:42:24

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!