从尾部的qnorm获取高精度值

时间:2017-04-12 07:07:20

标签: r normal-distribution

问题

我正在寻找尾部(1e-10 and 1 - 1e-10)中正态分布的高精度值,因为我正在使用的R包将任何超出此范围的数字设置为这些值,然后调用{{1 }和qnorm函数。

我注意到,在查看尾部时,R中的qt实现不是对称的。这对我来说是非常令人惊讶的,因为众所周知这个分布是对称的,我已经看到其他语言中的实现是对称的。我检查了qnorm函数,它在尾部也不对称。

以下是qnorm函数的结果:

qt

很明显,当x qnorm(x) qnorm(1-x) qnorm(1-x) + qnorm(x) 1e-2 -2.3263478740408408 2.3263478740408408 0.0 (i.e < machine epsilon) 1e-3 -3.0902323061678132 3.0902323061678132 0.0 (i.e < machine epsilon) 1e-4 -3.71901648545568 3.7190164854557084 2.8421709430404007e-14 1e-5 -4.2648907939228256 4.2648907939238399 1.014299755297543e-12 1e-10 -6.3613409024040557 6.3613408896974208 -1.2706634855419452e-08 的值接近0或1时,此函数会崩溃。是的,在&#34;正常&#34;使用这不是一个问题,但我正在研究边缘情况并将小概率乘以非常大的值,在这种情况下,错误x变为一个大值。

注意:我已尝试使用(1e-08)并输入实际数字1-x0.00001,但准确性问题仍然存在。

问题

首先,这是0.99999qnorm实施的已知问题吗?我在文档中找不到任何内容,对于来自qt的p值,算法应该是准确的16位数,如Algorithm AS 241论文所述。

引自R doc:

  

Wichura,M。J.(1988)Algorithm AS 241:正态分布的百分点。应用统计学,37,477-484。

     

可提供高达约16位的精确结果。

如果R代码实现7位数版本,为什么它会声明16位数?或者它是否准确&#34;但原始算法不对称而且错误?

如果R确实实现了Algorithm AS 241的两个版本,我可以打开16位数版本吗?

或者,R中是否有更准确的10^-314版本? 或者,我的问题的另一个解决方案,我需要在分位数函数的尾部高精度。

R版

qnorm

1 个答案:

答案 0 :(得分:3)

事实证明(正如Spencer Graves在his response中对R-devel列表服务中的同一问题所指出的那样)qnorm() 确实实际上如宣传所表现的那样。只是,为了在分布的上尾获得高度准确的结果,您需要利用函数的lower.tail参数。

这是怎么做到的:

options(digits=22)

## For values of p in [0, 0.5], specify lower tail probabilities 
qnorm(p = 1e-10)                      ## x: P(X <= x) == 1e-10
# [1] -6.3613409024040557

## For values of p in (0.5, 1], specify upper tail probabilities
qnorm(p = 1e-10, lower.tail=FALSE)    ## x: P(X > x)  == 1e-10     (correct approach)
# [1] 6.3613409024040557
qnorm(p = 1 - 1e-10)                  ## x: P(X <= x) == 1-(1e-1)  (incorrect approach)
# [1] 6.3613408896974208

问题是1-1e-10(例如)受到浮点舍入误差的影响,因此距离1(区间的上端)的距离实际上并不相同因为1e-10来自0(间隔的下端)。当置于更熟悉的形式时,潜在的问题(它的R-FAQ 7.31!)变得明显:

1 - (1 - 1e-10) == 1e-10
## [1] FALSE

最后,我们快速确认qnorm()为其帮助文件中声明的值提供了准确(或至少对称)的结果:

qnorm(1e-314)
## [1] -37.906647423565666
qnorm(1e-314, lower.tail=FALSE)
## [1] 37.906647423565666

## With this failing in just the way (and for just the reason) you'd now expect
qnorm(1-1e-314)
# [1] Inf
1 == (1-1e-314)
# [1] TRUE