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

Pat*_*ick 4 r

我试图将以下函数从-infinity集成到无穷大.答案应该是0.2,但R给出了一个非常小的数字.怎么了?

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

Ric*_*ven 7

我需要更长时间才能完全解释这一点,并希望其他用户将添加到此维基.

?integrate,abs.tol论证定义为

要求绝对准确.

下面是以下说明:

当无限区间的积分明确地这样做时,而不是仅使用大数作为端点.这增加了正确答案的机会 - 任何在无限区间内积分有限的函数必须在该区间的大部分时间内接近零.

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

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

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"
Run Code Online (Sandbox Code Playgroud)

注意细分数突然跳跃.一般来说,更多的细分意味着更高的准确性,毕竟这是微积分的要点:将细分宽度减少到零以获得确切的答案.我的猜测是,对于一个较大的(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
Run Code Online (Sandbox Code Playgroud)