R积分返回错误结果;调整细分,rel.tol或abs.tol无效

时间:2018-10-30 12:09:07

标签: r numerical-integration

我目前正在 R 中实现一个模型,该模型涉及数字积分的计算(因为无法导出解析表达式),并且这些积分有时在它们等于零或1.49e-23的情况下真的不应该。

我检查了this answer,但是第二个示例中的函数已经以零为中心。

背景。所讨论的数值积分与随机变量之和的密度表达式相对应,并且它们的联合密度是已知的,因此我们采用以下公式:if < em> Z = X + Y ,然后

在我的模型中, X Y 是系脉连接的,所以。所使用的所有分布函数均按照形状和比例进行表征,除了中心伽玛(但随后知道边界,请参见下文)之外,它们都具有正支撑或负支撑。

1。。考虑一个最简单的FGM copula示例(因此卷积不适用:仅适用于独立RV,而在这种情况下,大多数模型没有独立RV)。集成并不总是按计划进行。由于比例参数太小(因为它的估计值来自每日收益数据),因此数值积分通常表现不佳。但是,当我应用似乎适用于伽马分布的稳定校正时,居中的伽马分布开始返回无意义的结果。考虑以下示例:

shapeX <- 4
shapeY <- 3
scaleX <- 0.1 # Moderate scale
scaleY <- 0.1
f_X <- function(x) dgamma(x, shape=shapeX, scale = scaleX) # Always positive support for X
f_Y <- function(x) dgamma(x, shape=shapeY, scale = scaleY) # Always positive support for Y
# Simplest FGM copula
copula <- function(x, y) 1 + 0.5*(2*pgamma(x, shape=shapeX, scale=scaleX)-1)*(2*pgamma(y, shape=shapeY, scale=scaleY)-1)
f_XY <- function(x, y) f_X(x)*f_Y(y)*copula(x, y)
# By construction, this is a valid density function
f_Z <- Vectorize(function(z) integrate(function(v) f_XY(z-v, v), 0, Inf)$value) # Integrating over support
curve(f_Z, 0, 3, xlab="z", ylab="f_Z(z)")
integrate(f_Z, -Inf, Inf) # 0.9999999 with absolute error < 6.5e-07

PDF of sum of X and Y with moderate scale

现在,从先前的估计中获取一些实际值:

scaleX <- 0.001
scaleY <- 0.001
curve(f_Z, 0, 0.03, xlab="z", ylab="f_Z(z)", lwd=3)
integrate(f_Z, -Inf, Inf) # 0.8307993 with absolute error < 1.1e-05 --- problem!

现在,由于支持量太小,正交无法正确获得域,因此我们通过使用稳定乘数对其进行扩展来在数值上稳定函数:

stab <- (scaleX+scaleY)/2 # In case one of them is close to zero, which can happen
f_Zstab <- Vectorize(function(z) integrate(function(v) f_XY(z-v*stab, v*stab), 0, Inf)$value*stab)
curve(f_Zstab, 0, 0.03, col="red", add = TRUE)
integrate(f_Zstab, -Inf, Inf) # 1 with absolute error < 3.4e-08 --- good!

PDF of sum of X and Y with small scale

Voilà,问题似乎已经解决了,但是在其他规格中,最佳形状和比例不同,因此有时会发生这种情况。

2。。考虑两个具有居中的伽马分布的变量(即,已除臭;伽马分布的RV的平均值为scape⋅scale)。

# Density of centred gamma with domain [shape*scale, +Inf)
dcgamma <- function(x, shape, scale) return(dgamma(x+shape*scale, shape=shape, scale=scale))
shapeX <- 25.6
shapeY <- 25.8
scaleX <- 0.007
scaleY <- 0.028
f_X <- function(x) dcgamma(x,  shape=shapeX, scale = scaleX) # Support [-shapeX*scaleX, Inf)
f_Y <- function(x) dcgamma(-x, shape=shapeY, scale = scaleY) # Support (-Inf, shapeY*scaleY]
copula <- function(x, y) 1
f_XY <- function(x, y) f_X(x)*f_Y(y)*copula(x, y)
stab <- (scaleX+scaleY)/2 # The same stabilisation technique
ulim <- shapeY*scaleY

f_Zstab <- Vectorize(function(z) integrate(function(v) f_XY(z-v*stab, v*stab), -Inf, ulim/stab)$value*stab)
curve(f_Zstab, -0.5, 0.5, xlab="z", ylab="f_Z(z)", lwd=3) # This does not look OK!
integrate(f_Zstab, -Inf, Inf) # 0.2881533 with absolute error < 9.1e-05 --- wrong!

# Now without stabilisation
stab <- 1
curve(f_Zstab, -0.5, 0.5, add=TRUE, col="red") # This looks correct!
integrate(f_Zstab, -Inf, Inf) # 0.9999983 with absolute error < 4.4e-07 --- correct!

PDF of sum of centred-gamma X and Y

我决定研究并固定z=0的值,以便查看f_XY(-v*stab, v*stab)以及为什么从-Infulim/stab的整数为0:

stab <- (scaleX+scaleY)/2
z <- 0
f0 <- function(v) f_XY(z-v*stab, v*stab)
curve(f0, -20, ulim/stab)
integrate(f0, -Inf, 0) # 70.5132 with absolute error < 0.00036
integrate(f0, -Inf, 20) # 155.4917 with absolute error < 0.0031
a <- integrate(f0, -Inf, ulim/stab) # 1.490699e-23 with absolute error < 0 --- WAT
str(a)
# List of 5
#  $ value       : num 1.49e-23
#  $ abs.error   : num 0
#  $ subdivisions: int 2
#  $ message     : chr "OK"
#  $ call        : language integrate(f = f0, lower = -Inf, upper = ulim/stab)
#  - attr(*, "class")= chr "integrate"
integrate(f0, -Inf, ulim/stab, subdivisions = 500) # Same 1.49e-23
integrate(f0, -Inf, ulim/stab, rel.tol=1e-40, abs.tol = 1e-40) # Same 1.49e-23
integrate(f0, -Inf, ulim/stab, abs.tol=0) # Same 1.49e-23

Function the integral of which is 0

看看这个功能!它的行为举止良好,以0为中心,其在支持范围内的数值积分仍为1.49e-23!

这是一个非常奇怪的结果,引发了很多问题。也许添加任意常数会有所帮助,但是我需要一个可靠的解决方案,因为在每个似然函数中,我会评估2000个这些积分,然后使用随机最大化器在2000个点中对该函数进行600次迭代评估。这些积分的数量过高,这些异常值会严重影响最大化,因为在对数似然函数中采用log(f_Z),每2000个5个这样的值导致对数似然性降低了-250!在这种情况下可以做什么?我觉得增加dquagie Fortran路由中的点数将是一个解决方案……但是这种低级别的点很难实现,而高级的点可能会减慢估算速度(数百点)数百万个这样的积分)。

稳定这些古怪的数值积分的最佳解决方案是什么?

0 个答案:

没有答案