R中的integrate()给出了非常错误的答案



我试图将以下函数从-无穷大集成到无穷大。答案应该是0.2,但R给出的数字小得离谱。怎么了?

 >f=function(x){exp(-10*abs(x-25))}
 >integrate(f,-Inf,Inf)
 5.329164e-15 with absolute error < 1e-14

我需要更长的时间来全面解释这一点,希望其他用户也能添加到这个wiki中。

根据?integrateabs.tol自变量定义为

要求绝对准确。

下面是以下注释:

当在无限间隔上进行积分时,要显式地进行,而不仅仅是使用一个大数字作为端点。这增加了得到正确答案的机会——任何函数在无限区间上的积分是有限的,在该区间的大部分时间里都必须接近零。

因此,如果你想要绝对准确度,而不是相对准确度(定义为.Machine$double.eps^0.25的结果),那么你可以进行

> integrate(f, Inf, -Inf, abs.tol = 0L)
0.2 with absolute error < 8.4e-06

abs.tol的默认参数是从rel.tol传递的,即.Machine$double.eps^0.25

让我们看看"内部"发生了什么。

ifoo<-integrate(f,-Inf,Inf,abs.tol=1e-20)
5.275825e-21 with absolute error < 9.8e-21
str(ifoo)
List of 5
 $ value       : num 5.28e-21
 $ abs.error   : num 9.81e-21
 $ subdivisions: int 3
 $ message     : chr "OK"
 $ call        : language integrate(f = f, lower = -Inf, upper = Inf, abs.tol = 1e-20)
 - attr(*, "class")= chr "integrate"
ifoo<-integrate(f,-Inf,Inf,abs.tol=1e-40)
0.2 with absolute error < 8.4e-06
str(ifoo)
List of 5
 $ value       : num 0.2
 $ abs.error   : num 8.36e-06
 $ subdivisions: int 21
 $ message     : chr "OK"
 $ call        : language integrate(f = f, lower = -Inf, upper = Inf, abs.tol = 1e-40)
 - attr(*, "class")= chr "integrate"

请注意细分数量的突然跳跃。一般来说,更多的细分意味着更好的精度,这毕竟是微积分的要点:将细分宽度减小到零,以获得确切的答案。我的猜测是,对于大的(ish)abs.tol,计算值只需要几次细分就可以与一些"估计公差误差"相一致,但当所需公差变得足够小时,就会"添加更多的细分"

编辑:感谢Hong Ooi,他实际上研究了有问题的被积函数。:-)。由于该函数在x==25处有一个尖点,即导数的不连续性,因此优化算法可能会在收敛方面被"误导"。奇怪的是,利用这个被积函数很快接近零的事实,当而不是积分到+/-Inf时,结果更好。事实上:

Rgames> integrate(f,20,30)
0.2 with absolute error < 1.9e-06
Rgames> integrate(f,22,27)
0.2 with absolute error < 8.3e-07
Rgames> integrate(f,0,50)
0.2 with absolute error < 7.8e-05

虽然?integrate中明确指定+/-Inf作为限制的建议通常是有效的,但在特殊情况下可能是错误的。这是其中之一。

> integrate(f, 20, 30)
0.2 with absolute error < 1.9e-06

基本问题似乎是你的函数不是光滑的,因为它的导数在x=25时是不连续的。这可能是在欺骗算法,尤其是它使用Wynn的epsilon方法来加速收敛。基本上,除了知道你的功能是什么样的,以及它的行为如何会导致问题之外,没有什么真正的替代品。正如这里的答案所指出的,R不是一个符号数学解算器,所以在试图获得数值结果时,你必须更加小心。

最新更新