## ## b r e n t d e k k e r . R Brent-Dekker Algorithm ## brentDekker <- function(fun, a, b, maxiter = 500, tol = 1e-12, ...) # Brent and Dekker's root finding method, # based on bisection, secant method and quadratic interpolation { fun <- match.fun(fun) f <- function(x) fun(x, ...) stopifnot(is.numeric(a), is.numeric(b), length(a) == 1, length(b) == 1) if (!is.function(f) || is.null(f)) stop("Argument 'f' must be a valid R function.") x1 <- a; f1 <- f(x1) if (f1 == 0) return(list(root = a, f.root = 0, f.calls = 1, estim.prec = 0)) x2 <- b; f2 <- f(x2) if (f2 == 0) return(list(root = b, f.root = 0, f.calls = 1, estim.prec = 0)) if (f1*f2 > 0.0) stop("Brent-Dekker: Root is not bracketed in [a, b].") x3 <- 0.5*(a+b) # Beginning of iterative loop niter <- 1 while (niter <= maxiter) { f3 <- f(x3) if (abs(f3) < tol) { x0 <- x3 break } # Tighten brackets [a, b] on the root if (f1*f3 < 0.0) b <- x3 else a <- x3 if ( (b-a) < tol*max(abs(b), 1.0) ) { x0 <- 0.5*(a + b) break } # Try quadratic interpolation denom <- (f2 - f1)*(f3 - f1)*(f2 - f3) numer <- x3*(f1 - f2)*(f2 - f3 + f1) + f2*x1*(f2 - f3) + f1*x2*(f3 - f1) # if denom==0, push x out of bracket to force bisection if (denom == 0) { dx <- b - a } else { dx <- f3*numer/denom } x <- x3 + dx # If interpolation goes out of bracket, use bisection. if ((b - x)*(x - a) < 0.0) { dx <- 0.5*(b - a) x <- a + dx; } # Let x3 <-- x & choose new x1, x2 so that x1 < x3 < x2. if (x1 < x3) { x2 <- x3; f2 <- f3 } else { x1 <- x3; f1 <- f3 } niter <- niter + 1 if (abs(x - x3) < tol) { x0 <- x break } x3 <- x; } if (niter > maxiter) warning("Maximum numer of iterations, 'maxiter', has been reached.") prec <- min(abs(x1-x3), abs(x2-x3)) return(list(root = x0, f.root = f(x0), f.calls = niter+2, estim.prec = prec)) } # alias brent <- brentDekker