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

时间:2014-09-24 18:27:11

标签: r

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

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

2 个答案:

答案 0 :(得分:7)

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

?integrate开始,abs.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

让我们看看发生了什么&#34;内部&#34;一点点。

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,只需要对计算值进行一些细分即可得出一些估计的容差误差&#39; ,但是当要求的公差变得足够小时,就会增加更多的细分。&#34;

编辑,感谢Hong Ooi,他实际上看了有问题的被积函数。 :-)。因为此函数在x==25处具有尖点,即导数中的不连续性,所以优化算法可能会被误导&#34;关于收敛。奇怪的是,通过利用这个被积函数很快接近零的事实,当积分到+/-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

答案 1 :(得分:2)

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

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

基本问题似乎是你的函数不平滑,因为它的导数在x = 25处是不连续的。这可能会欺骗算法,尤其是使用Wynn的epsilon方法来加速收敛。基本上没有真正的替代品来了解你的功能是什么样的,以及它的行为如何导致问题。正如答案here中所指出的,R不是一个象征性的数学解算器,因此在尝试获得数值结果时你必须更加谨慎。