rnorm
函数默认使用哪种算法生成标准正态分布的随机数?
见?RNGkind
。默认是反演算法:
normal.kind
可以是“Kinderman-Ramage”,“Buggy Kinderman-Ramage”(不适用于set.seed
),“Ahrens-Dieter”,“Box-Muller”,“Inversion”(默认)或“用户提供”。 (有关反演,请参阅qnorm
中的参考。)1.7.1之前版本中使用的Kinderman-Ramage生成器(现在称为“Buggy”)有几个近似误差,只能用于复制旧结果。 “Box-Muller”生成器是有状态的,因为生成了一对法线并且顺序返回。无论何时选择状态(即使它是当前的正常发生器)和更改种类,状态都会复位。
您可以通过更改算法
RNGkind(normal.kind = "Box-Muller")
您可以通过查看RNGkind()[2]
找到当前设置的内容。
另一个答案是充分的,但还有一些问题;特别是,我没有看到文档中的任何地方* "Inversion"
算法到底是什么,所以我潜入了source code,它也提供了对其他可能的算法的论文的学术参考,以弄清楚到底是做什么的。
case INVERSION:
#define BIG 134217728 /* 2^27 */
/* unif_rand() alone is not of high enough precision */
u1 = unif_rand();
u1 = (int)(BIG*u1) + unif_rand();
return qnorm5(u1/BIG, 0.0, 1.0, 1, 0);
所以在基数上似乎默认的"Inversion"
算法生成高精度浮点数(看起来像53位,或mantissa size for 64-bit floating numbers),然后将其发送到qnorm5
函数,这是正态分布的CDF函数。
关于qnorm5
功能如何工作(鉴于普通CDF没有封闭形式也没有反向CDF),我没有太多运气破解似乎是源代码here,但他们确实提供了进一步的学术参考,即Beasley, J. D. and S. G. Springer (1977)和Wichura, M.J. (1988);前者通常用于CDF的小分位数,后者用于大型(z>7
左右)。
值得注意的是(截至本文撰写时)这个算法似乎是shared by the Julia language,它也分享了qnorm5
使用的R
代码。
*公平地说,回想起来,在上面引用的?qnorm
中提到了Wichura。我认为,仍然值得在这个帖子中拼出一些东西。