微不足道——但很神奇:
BBP <- function(n = 13) {
sum(sapply(seq_len(n), function(k) {
((sample.int(8*k+1, 1) <= 4) -
(sample.int(8*k+4, 1) <= 2) -
(sample.int(8*k+5, 1) <= 1) -
(sample.int(8*k+6, 1) <= 1)) / 16^k
})) + (4 - 2/4 - 1/5 - 1/6)
}
正如您在此代码中看到的,R
仅对使用. 默认情况下,仅次绘制(值从不大于)——但结果的预期值是到完全双精度!sample.int
13∗4=52110π
这是次迭代的示例运行(需要一秒钟的时间):10,000
x <- replicate(1e4, BBP())
mu <- mean(x)
se <- sd(x) / sqrt(length(x))
signif(c(Estimate=mu, SE=se, Z=(mu-pi)/se), 4)
它的输出是
Estimate SE Z
3.1430000 0.0004514 2.0870000
换句话说,的这个(随机)估计值为的小 Z 值的真实值没有显着偏差。π3.143±0.000452.08π.
这是微不足道的,因为我希望代码很明显,像sample.int(b,1) <= a
(当整数a
不超过时b
)这样的计算只是估计有理分数的愚蠢方法a/b
。因此,此代码估计Bailey Borwein Plouffe 公式
π=∑k=0∞116k(48k+1−28k+4−18k+5−18k+6)
通过明确表达项并通过 由于公式中的每一项在额外的位,因此在该点终止采样会在二进制点之后给出位,这略高于最大位的总精度在 . 使用的 IEEE 双精度浮点数中可用。k=0k=13.4π,4∗(13)=5252 R
尽管我们可以通过分析计算出方差,但前面的示例已经为我们提供了一个很好的估计,因为标准误差仅为每次迭代的方差为0.0045,0.002
var(x)
[1] 0.002037781
因此,如果您想将BBP
估计在 sigma 的标准误差内您将需要大约次迭代。例如,以这种方式估计到小数点后六位将需要大约 20 亿次迭代(大约需要三天的计算)。πσ,0.002/σ2π
减少方差(极大)的一种方法是一劳永逸地计算 BBP 和中的一些初始项,仅使用蒙特卡罗模拟来估计结果的最低有效位:-)。