Skip to content
Prev 46237 / 63458 Next

Problem following an R bug fix to integrate()

On 2013-07-16 07:55, Hans W Borchers wrote:
Short answer: use a larger value of 'rel.tol' for the outer integral
than for the inner integral.

Using R 2.11.1 on Windows:

 > fn <- function(x, y) ifelse(x^2 + y^2 <= 1, 1 - x^2 - y^2, 0)
 > tol <- 1.5e-8
 > fy <- function(x) integrate(function(y) fn(x, y), 0, 1,
           subdivisions = 300, rel.tol = tol)$value
 > Fy <- Vectorize(fy)
 > xa <- -1; xb <- 1
 > Q  <- integrate(Fy, xa, xb,
           subdivisions = 300, rel.tol = tol)$value
Error in integrate(Fy, xa, xb, subdivisions = 300, rel.tol = tol) :
   roundoff error was detected

Now increase 'rel.tol' in the outer integral:

 > Q  <- integrate(Fy, xa, xb,
           subdivisions = 300, rel.tol = tol*10)$value
 > Q - pi/4
[1] -1.233257e-07

Longer answer: Fy, the integrand of the outer integral, is in effect
computed with noise added to it that is of the order of magnitude of
the 'rel.tol' of the inner integral; this noise prevents the outer
integral from attaining relative accuracy of this magnitude or smaller.
The version of integrate() in use since R 2.12.0 did not accurately
reproduce the computations in the Fortran routines (in the QUADPACK
package) on which it was based, and in consequence failed to detect this
situation.  Reversion to the R 2.11.1 version of integrate() restores
concordance with the Fortran routines and correctly diagnoses the
inability of the outer integral to achieve the requested accuracy.
(And, btw, the Q computed above is actually closer to pi/4 than you
will have been getting with the code that "worked well".)


J. R. M. Hosking