我需要计算一些积分。我知道R不是这样做的合适软件,但是由于我在R中做了其他所有事情并且积分只是一维的,我认为这可能没问题。
无论如何,当增加积分的上限时,使用stats包中的函数integrate()
会导致跳转。这是情节:
但是,如果我通过构建总和而不是积分,或者使用adaptIntegrate()
包中的函数cubature
,结果如下所示:
为了能够复制这个,这里是代码。我知道可能有一个更简单的例子,但这实际上是我所面对的案例的1:1。使用integrate()
:
v_p = 11269
d_p = seq(0, v_p, 100)
tau = 0.35
interest = 0.05
time_t = 1
mu = 0
sigma_p = 0.1099313
nu_p = 0.0101552
ts = c()
bc = c()
for (i in 1:length(d_p)){
ts = c(ts,integrate(function(x) tau*(x-v_p-interest*d_p[i])*dlnorm(x, log(v_p)+(mu - 0.5 * sigma_p^2) * time_t, sigma_p*sqrt(time_t)), v_p+interest*d_p[i], 10000000)$value)
bc = c(bc,integrate(function(y) nu_p * y * dlnorm(y, log(v_p)+(mu - 0.5 * sigma_p^2) * time_t, sigma_p*sqrt(time_t)), 0, d_p[i])$value)
}
shv = ts + bc
plot(d_p,shv, main = 290801)
abline(v = 9079, col="red")
完全相同的代码,只需使用adaptIntegrate():
v_p = 11269
d_p = seq(0, v_p, 100)
tau = 0.35
interest = 0.05
time_t = 1
mu = 0
sigma_p = 0.1099313
nu_p = 0.0101552
ts = c()
bc = c()
for (i in 1:length(d_p)){
ts = c(ts,adaptIntegrate(function(x) tau*(x-v_p-interest*d_p[i])*dlnorm(x, log(v_p)+(mu - 0.5 * sigma_p^2) * time_t, sigma_p*sqrt(time_t)), v_p+interest*d_p[i], 10000000)$integral)
bc = c(bc,adaptIntegrate(function(y) nu_p * y * dlnorm(y, log(v_p)+(mu - 0.5 * sigma_p^2) * time_t, sigma_p*sqrt(time_t)), 0, d_p[i])$integral)
}
shv = ts + bc
plot(d_p,shv, main = 290801)
abline(v = 9079, col="red")
有人知道为什么会这样吗?
答案 0 :(得分:0)
您应该阅读?integrate
中注意的第二段:
在无限间隔上进行积分时,请明确这样做,而不是仅使用大数字作为端点。这增加了正确答案的机会 - 任何在无限区间内积分有限的函数在该区间的大部分时间内必须接近于零。
( Note 的其余部分也值得一读。)
如果我将10000000的上限更改为Inf,我会得到一个看似合理的结果。 (但请注意,这种问题一般永远不会完全解决...有时你需要调整间隔,开始点数等等,以解决你的特定问题。)
使用Inf替换代码的核心,为了清晰起见略微重写:
f1 <- function(x) tau*(x-v_p-interest*d_p[i])*
dlnorm(x, log(v_p)+(mu - 0.5 * sigma_p^2) * time_t, sigma_p*sqrt(time_t))
f2 <- function(y) nu_p * y *
dlnorm(y, log(v_p)+(mu - 0.5 * sigma_p^2) * time_t, sigma_p*sqrt(time_t))
for (i in 1:length(d_p)){
ts = c(ts,integrate(f1, v_p+interest*d_p[i], Inf)$value)
bc = c(bc,integrate(f2, 0, d_p[i])$value)
}
(顺便说一句,你也应该避免在R中增长对象;首先分配你的整个向量而不是反复追加它们。)