2011-08-24 108 views
3

Box-Muller transform是從高斯分佈中採樣隨機值的優雅且合理的高性能方法。從高斯分佈中抽取隨機值的最快方法是什麼?

我正在尋找一種清晰寫入並以C#編寫的更快速的方法。

僅供參考這裏的箱穆勒執行充當性能比較基準的實現......

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); 
    } 
} 
+0

您有問題嗎? –

+0

您是否在C#中使用了Ziggurat算法? – redcalx

+1

你想要速度和優雅?實行制服比例! Ziggurat在我看來是醜陋而難以調整的。 –

回答

6

對於有通過此鏈接到源文件的SVN倉庫內的可用寫得很好,測試,優化和解釋版本記錄:

ZigguratGaussianSampler.cs

在我的酷睿i7 920 @ 2.66Ghz在一個核心上運行約45k/samples/millisec。 Box-Muller在相同的環境/設置下可達到約24k/ms。兩者都使用RedzenXorShiftRandom類作爲均勻隨機數的來源。

+1

鏈接到.cs被破壞... – JFS

+1

我已更正所有鏈接。編輯位於審閱隊列中。 – Xharlie

+1

@Xharlie我編輯了你的編輯。那些sourceforge鏈接是我應該刪除的舊版本的軟件。現在一切都在https://github.com/colgreen/Redzen/tree/master/Redzen/Numerics – redcalx

1

使用ratio-of-uniforms方法非常快。我沒有C#實現,但是我在Excel VBA中使用它,與Box-Muller方法相比,它速度提高了3倍:使用Box-Muller的1000萬個樣本的70秒,而使用比率 - 統一的方法。

enter image description here

祝你好運。

0

Ziggurat採樣速度非常快,並且內存效率很高。對於C/C++應用程序,您可以使用GSL庫

相關問題