该函数默认使用哪种算法rnorm
来生成标准正态分布的随机数?
2 回答
见?RNGkind
。默认是反演算法:
normal.kind
可以是“Kinderman-Ramage”、“Buggy Kinderman-Ramage”(不适用于set.seed
)、“Ahrens-Dieter”、“Box-Muller”、“Inversion”(默认值)或“用户提供”。(关于反转,请参阅参考资料qnorm
。) 1.7.1 之前的版本(现在称为“Buggy”)中使用的 Kinderman-Ramage 生成器有几个近似错误,只能用于重现旧结果。“Box-Muller”生成器是有状态的,因为成对的法线是按顺序生成和返回的。每当它被选中(即使它是当前的普通生成器)和 kind 改变时,状态都会被重置。
您可以通过以下方式更改算法
RNGkind(normal.kind = "Box-Muller")
您可以通过查看找到当前设置的内容RNGkind()[2]
。
另一个答案就足够了,但给我留下了一些问题;特别是,我在文档中没有看到任何地方*该"Inversion"
算法到底是什么,所以我深入研究了源代码,它还提供了对其他可能算法的论文的学术参考,以弄清楚到底在做什么.
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 位,或64 位浮点数的尾数大小),然后将其发送到qnorm5
作为正态分布的 CDF 函数的函数。
至于函数是如何qnorm5
工作的(鉴于 Normal CDF 和逆 CDF 没有封闭形式),我没有太多运气破解这里似乎是源代码的内容,但它们确实提供了进一步的学术参考,即Beasley, JD 和 SG Springer (1977)和Wichura, MJ (1988);前者通常用于 CDF 的小分位数,后者用于大(z>7
左右)。
还可能有趣的是(在撰写本文时)该算法似乎由Julia 语言共享,它也共享.qnorm5
R
*公平地说,回想起来,上面提到了 Wichura ?qnorm
。我认为仍然值得在这个线程中说明一些事情。