When trying to integrate the following smooth function with integrate()
in R, I always obtain an error, either the "integral is probably divergent" or "maximum number of subdivisions reached":
The problem seems to be that the function approaches zero at around +/-1, but it is difficult to set the limits appropriately, and increasing subdivisions
or reducing rel.tol
does not help.
Are there other integration routines in R (or in R packages) that I could try? Is there e.g. a routine for simple Simpson integration available for equidistantly sampled functions?
Edit: As someone asked, here is the implementation of the function:
a <- -1
b <- 1
sigma <- 0.1
# P(Y >= t)
PY <- function(t) {
za <- (t-a)/sigma
zb <- (t-b)/sigma
1 + sigma/(b-a) * (zb*pnorm(zb) + dnorm(zb) - za*pnorm(za) - dnorm(za))
}
# P(Y >= t | X=x)
PY.x <- function(t, x) {
1 - pnorm((t-x)/sigma)
}
# density of Y: p(y)
p.y <- function(y) {
zb <- (b-y)/sigma
za <- (a-y)/sigma
1/(b-a) * (pnorm(zb) - pnorm(za))
}
# Var in numerator
Var.Yt <- function(t) {
integrand <- function(x) {
(PY.x(t,x) - PY(t))^2
}
integrate(integrand, a, b)$value
}
# THIS IS THE FUNCTION TO BE INTEGRATED
f <- function(t) {
Var.Yt(t)*p.y(t)
}
The computation of Var.Yt(t)
succeeds for any value of t
, but the integration of f
fails with the aforementioned error.
I think you forgot to vectorize your function f
before pushing it to integrate
or pramca::integral
.
Here you can see they would work if we apply Vectorize()
> pracma::integral(Vectorize(f), -2, 2)
[1] 0.2799594
> integrate(Vectorize(f), -2, 2)
0.2799594 with absolute error < 5.4e-06