[英]Divergent Integral in R is solvable in Wolfram
我知道我之前也问过同样的问题,但是由于我很陌生,所以这个问题被问得很差并且不能重复。 因此,我尝试在这里做得更好。 (如果我只编辑旧的,可能没人会读)
我有一个要积分的双重积分: 这是一张照片
ff<-function(g,t) exp((16)*g)*exp(-8*t-(-t-0.01458757)^2/(0.0001126501))
integrate(Vectorize(function(t) integrate(function(g)
ff(g,t), -2.5,0)$value), -2, 2)
在R中运行此错误给我:
the integral is probably divergent
当我尝试在Wolfram中运行sam函数时,它给了我一个适当的值:(我必须切换g = x和t = y)
链接:
如您所见,它得到了有限的结果,有人可以在这里帮助我吗?
我在定义的区域上绘制了函数,但是找不到奇异性问题。 看到:
library('Plot3D')
x <- seq(-2.5,0, by = 0.01) #to see the peak change to: seq(-0.2,0, by = 0.001)
y <- seq(-2,2, by = 0.01) #"": seq(-0.1,0.1, by = 0.001)
grid <- mesh(x,y)
z <- with(grid,exp((16)*x)*
exp(-8*y-(-0.013615734-y-0.001+0.5*0.007505^2*1)^2/(2*0.007505^2)))
persp3D(z = z, x = x, y = y)
感谢您的帮助,我希望这个问题比以前的问题有更好的结构。
还值得注意的是,在integrated.c源文件中,错误消息的描述为
error messages
...
ier = 5 the integral is probably divergent, or
slowly convergent. it must be noted that
divergence can occur with any other value of ier.
因此,尽管该消息显示“可能存在分歧”,但看起来与您的代码很可能会逐渐收敛。
此外,如果设置了stop.on.error=FALSE
则在收到此消息时可以继续运行并提取错误。
r <- integrate(Vectorize(function(t)
integrate(function(g) ff(g,t), -2.5,0)$value
), -2, 2, stop.on.error=FALSE);
r$value
R并不像Mathematica之类的Wolfram产品那样声称自己是花哨的数学求解器。 它没有对积分进行任何符号简化,这就是Wolfram多年来不断完善的东西。 如果您只是想数值地求解一堆双积分,那么Mathematica或Maple之类的程序可能是更好的选择。 这似乎不是R花费大量开发资源的地方。
您的被积数仅在y = 0附近的很小范围内明显为非零。 从?integrate
在无限间隔内进行积分时,应明确地进行积分,而不仅仅是使用大量端点。 这增加了正确答案的机会-在无限间隔内积分为有限的任何函数在该间隔的大部分时间内必须接近零。
虽然您不是严格地在无限的时间间隔内进行积分,但是存在相同的数值问题。 确实:
ff <- function(x, y)
exp(16*x - 8*y - (-y - 0.01458757)^2/0.0001126501)
f <- function(y)
integrate(ff, lower=-2.5, upper=0, y=y)$value
integrate(Vectorize(f), lower=-Inf, upper=Inf)
0.001323689 with absolute error < 4.4e-08
有趣的是,答案与从Wolfram Alpha获得的答案不同。 我不确定谁可以信任这里; 一方面,我已经多次使用R的integrate
,并且没有遇到任何问题(我可以说)。 但是,正如@MrFlick所说,R不是Wolfram Alpha这样的专用数学求解器。
您还可以将rel.tol
收敛参数设置为更严格的值,例如1e-7或1e-8。 在内部积分中,这比外部积分更重要,因为前者的误差会传播到后者。 在这种情况下,它对最终结果没有影响。
对于双积分,最好使用cubature
包装。
library(cubature)
f <- function(x){
exp(16*x[1] - 8*x[2] - (x[2] + 0.01458757)^2/0.0001126501)
}
当降低容差时, hcubature
功能会产生不稳定的结果:
> hcubature(f, c(-2.5, -2), c(0,2))$integral
[1] 0.001285129
> hcubature(f, c(-2.5, -2), c(0,2), tol=1e-10)$integral
[1] 0.001293842
与pcubature
的结果相反,它是稳定的:
> pcubature(f, c(-2.5, -2), c(0,2))$integral
[1] 0.001323689
> pcubature(f, c(-2.5, -2), c(0,2), tol=1e-10)$integral
[1] 0.001323689
具有p适应性的版本pcubature基于Clenshaw-Curtis正交规则的张量积,反复将正交规则的程度加倍直到实现收敛。 对于在几维(<= 3)上的光滑被积物,此算法通常优于h自适应积分,但是对于较大尺寸或非光滑的被积物,该算法是较差的选择。
接下来, RcppNumerical
提供了强大的多重集成。
// [[Rcpp::depends(RcppEigen)]]
// [[Rcpp::depends(RcppNumerical)]]
#include <RcppNumerical.h>
#include <cmath>
using namespace Numer;
class ValegardIntegrand: public MFunc
{
public:
double operator()(Constvec& x)
{
return exp(16*x[0] - 8*x[1] - pow(-x[1] - 0.01458757,2)/0.0001126501);
}
};
// [[Rcpp::export]]
Rcpp::List Valegard()
{
ValegardIntegrand f;
Eigen::VectorXd lower(2);
lower << -2.5, -2;
Eigen::VectorXd upper(2);
upper << 0.0, 2.0;
double err_est;
int err_code;
double res = integrate(f, lower, upper, err_est, err_code,
10000000, 1e-14, 1e-14);
return Rcpp::List::create(
Rcpp::Named("approximate") = res,
Rcpp::Named("error_estimate") = err_est,
Rcpp::Named("error_code") = err_code
);
}
它产生与pcubature
相同的结果:
> Valegard()
$approximate
[1] 0.001323689
$error_estimate
[1] 9.893371e-14
$error_code
[1] 0
顺便说一下,与Mathematica 11的精确集成也提供了以下结果:
Integrate[E^(16 x - 8877.04 (0.0145876 + y)^2 - 8 y), {y, -2, 2}, {x, -2.5, 0}]
0.00132369
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.