数学理论之------生成高斯随机数
本说明是关于在给定均匀伪随机数源的情况下生成高斯伪随机数的主题。 这个话题出现的频率比我预想的要高,所以我决定把它写成最好的方法之一。 在本说明的末尾,有与该主题相关的文献中的参考文献列表。 您可以看到一些实现该技术的代码示例,以及生成 Weibull 分布随机数的分步示例。
有很多方法可以解决这个问题(例如,参见 Rubinstein,1981,对该主题进行了广泛的讨论),但我们在这里只讨论一种重要的方法。 如果我们有一个描述我们想要的分布函数的方程,那么就有可能使用一些基于概率基本变换定律的数学技巧来获得分布的变换函数。 这种转换将来自一个分布的随机变量作为输入,并在一个新的分布函数中输出随机变量。 这些变换函数中最重要的可能被称为 Box-Muller (1958) 变换。 它允许我们将均匀分布的随机变量转换为一组具有高斯(或正态)分布的新随机变量。
最基本的转换形式如下:
y1 = sqrt( - 2 ln(x1) ) cos( 2 pi x2 )
y2 = sqrt( - 2 ln(x1) ) sin( 2 pi x2 )
我们从两个独立的随机数 x1 和 x2 开始,它们来自均匀分布(范围从 0 到 1)。 然后应用上述变换得到两个新的独立随机数,它们具有零均值和标准差为 1 的高斯分布。
这种特殊形式的转换有两个问题,
1.由于对数学库的多次调用,它很慢。
2.当 x1 非常接近于零时,它可能会出现数值稳定性问题。
如果您正在进行随机建模并生成数百万个数字,这些都是严重的问题。
Box-Muller 变换的极坐标形式在数值上更快更稳健。 它的算法描述是:
float x1, x2, w, y1, y2;
do {
x1 = 2.0 * ranf() - 1.0;
x2 = 2.0 * ranf() - 1.0;
w = x1 * x1 + x2 * x2;
} while ( w >= 1.0 );
w = sqrt( (-2.0 * ln( w ) ) / w );
y1 = x1 * w;
y2 = x2 * w;
其中 ranf() 是获取均匀分布在 [0,1] 中的随机数的例程。 极坐标形式更快,因为它在几何上等效于正弦和余弦,而无需调用三角函数库。 但是由于对 ranf() 的调用可能很多,所以统一随机数生成器应该很快(对于大多数应用程序,我通常推荐 R250)。
注意:我在 20 多年前写了前一段,我最关心的是嵌入式系统的性能。 使用现代硬件,您可能会发现直接形式更快。 您应该在目标环境中对直接形式和极性形式进行基准测试。
非高斯分布的概率变换
寻找像 Box-Muller 这样的变换是一个乏味的过程,在经验分布的情况下这是不可能的。 发生这种情况时,必须求助于其他(通常是近似的)方法。 有关更多信息,请参阅下面的参考列表(特别是 Rubinstein,1981)。
还有其他非常有用的分布,这些概率变换已经被计算出来。 诸如 Erlang、指数、超指数和 Weibull 分布等分布的变换可以在文献中找到(例如,参见 MacDougall,1987)。
gammping代码:
double pf_ran_gaussian(double sigma)
{
double x1, x2, w;
double r;
do
{
do { r = drand48(); } while (r == 0.0);
x1 = 2.0 * r - 1.0;
do { r = drand48(); } while (r == 0.0);
x2 = 2.0 * drand48() - 1.0;
w = x1*x1 + x2*x2;
} while(w > 1.0 || w==0.0);
return(sigma * x2 * sqrt(-2.0*log(w)/w));
}
Useful References
Box, G.E.P, M.E. Muller 1958; A note on the generation of random normal deviates, Annals Math. Stat, V. 29, pp. 610-611
Carter, E.F, 1994; The Generation and Application of Random Numbers , Forth Dimensions Vol XVI Nos 1 & 2, Forth Interest Group, Oakland California
Knuth, D.E., 1981; The Art of Computer Programming, Volume 2 Seminumerical Algorithms, Addison-Wesley, Reading Mass., 688 pages, ISBN 0-201-03822-6
MacDougall,M.H., 1987; Simulating Computer Systems, M.I.T. Press, Cambridge, Ma., 292 pages, ISBN 0-262-13229-X
Press, W.H., B.P. Flannery, S.A. Teukolsky, W.T. Vetterling, 1986; Numerical Recipes, The Art of Scientific Computing, Cambridge University Press, Cambridge, 818 pages, ISBN 0-512-30811-9
Rubinstein, R.Y., 1981; Simulation and the Monte Carlo method, John Wiley & Sons, ISBN 0-471-08917-6