Rev 68055 | Rev 82618 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed
% File src/library/stats/man/uniroot.Rd% Part of the R package, https://www.R-project.org% Copyright 1995-2014 R Core Team% Distributed under GPL 2 or later\name{uniroot}\title{One Dimensional Root (Zero) Finding}\alias{uniroot}\usage{uniroot(f, interval, \dots,lower = min(interval), upper = max(interval),f.lower = f(lower, \dots), f.upper = f(upper, \dots),extendInt = c("no", "yes", "downX", "upX"), check.conv = FALSE,tol = .Machine$double.eps^0.25, maxiter = 1000, trace = 0)}\arguments{\item{f}{the function for which the root is sought.}\item{interval}{a vector containing the end-points of the intervalto be searched for the root.}\item{\dots}{additional named or unnamed arguments to be passedto \code{f}}\item{lower, upper}{the lower and upper end points of the interval tobe searched.}\item{f.lower, f.upper}{the same as \code{f(upper)} and\code{f(lower)}, respectively. Passing these values from the callerwhere they are often known is more economical as soon as \code{f()}contains non-trivial computations.}\item{extendInt}{character string specifying if the interval\code{c(lower,upper)} should be extended or directly produce an errorwhen \code{f()} does not have differing signs at the endpoints. Thedefault, \code{"no"}, keeps the search interval and hence producesan error. Can be abbreviated.}\item{check.conv}{logical indicating whether a convergence warning of theunderlying \code{\link{uniroot}} should be caught as an error and ifnon-convergence in \code{maxiter} iterations should be an errorinstead of a warning.}\item{tol}{the desired accuracy (convergence tolerance).}\item{maxiter}{the maximum number of iterations.}\item{trace}{integer number; if positive, tracing information isproduced. Higher values giving more details.}}\description{The function \code{uniroot} searches the interval from \code{lower}to \code{upper} for a root (i.e., zero) of the function \code{f} withrespect to its first argument.Setting \code{extendInt} to a non-\code{"no"} string, means searchingfor the correct \code{interval = c(lower,upper)} if \code{sign(f(x))}does not satisfy the requirements at the interval end points; see the\sQuote{Details} section.}\details{Note that arguments after \code{\dots} must be matched exactly.Either \code{interval} or both \code{lower} and \code{upper} must bespecified: the upper endpoint must be strictly larger than the lowerendpoint.The function values at the endpoints must be of opposite signs (orzero), for \code{extendInt="no"}, the default. Otherwise, if\code{extendInt="yes"}, the interval is extended on both sides, insearch of a sign change, i.e., until the search interval \eqn{[l,u]}satisfies \eqn{f(l) \cdot f(u) \le 0}{f(l) * f(u) <= 0}.If it is \emph{known how} \eqn{f} changes sign at the root\eqn{x_0}{x0}, that is, if the function is increasing or decreasing there,\code{extendInt} can (and typically should) be specified as\code{"upX"} (for \dQuote{upward crossing}) or \code{"downX"},respectively. Equivalently, define \eqn{S := \pm 1}{S:= +/- 1}, torequire \eqn{S = \mathrm{sign}(f(x_0 + \epsilon))}{S = sign(f(x0 +eps))} at the solution. In that case, the search interval \eqn{[l,u]}possibly is extended to be such that \eqn{S\cdot f(l)\le 0}{%S * f(l) <= 0} and \eqn{S \cdot f(u) \ge 0}{S * f(u) >= 0}.\code{uniroot()} uses Fortran subroutine \file{"zeroin"} (from Netlib)based on algorithms given in the reference below. They assume acontinuous function (which then is known to have at least one root inthe interval).Convergence is declared either if \code{f(x) == 0} or the change in\code{x} for one step of the algorithm is less than \code{tol} (plus anallowance for representation error in \code{x}).If the algorithm does not converge in \code{maxiter} steps, a warningis printed and the current approximation is returned.\code{f} will be called as \code{f(\var{x}, ...)} for a numeric valueof \var{x}.The argument passed to \code{f} has special semantics and used to beshared between calls. The function should not copy it.}\value{A list with at least four components: \code{root} and \code{f.root}give the location of the root and the value of the function evaluatedat that point. \code{iter} and \code{estim.prec} give the number ofiterations used and an approximate estimated precision for\code{root}. (If the root occurs at one of the endpoints, theestimated precision is \code{NA}.)Further components may be added in future: component \code{init.it}was added in \R 3.1.0.}%\author{of \code{extendInt} and \code{check.conv}: Martin Maechler.}% originally as% safeUroot() in CRAN packages nor1mix and copula\source{Based on \file{zeroin.c} in \url{http://www.netlib.org/c/brent.shar}.}\references{Brent, R. (1973)\emph{Algorithms for Minimization without Derivatives.}Englewood Cliffs, NJ: Prentice-Hall.}\seealso{\code{\link{polyroot}} for all complex roots of a polynomial;\code{\link{optimize}}, \code{\link{nlm}}.}\examples{\donttest{require(utils) # for str## some platforms hit zero exactly on the first step:## if so the estimated precision is 2/3.f <- function (x, a) x - astr(xmin <- uniroot(f, c(0, 1), tol = 0.0001, a = 1/3))## handheld calculator example: fixed point of cos(.):uniroot(function(x) cos(x) - x, lower = -pi, upper = pi, tol = 1e-9)$rootstr(uniroot(function(x) x*(x^2-1) + .5, lower = -2, upper = 2,tol = 0.0001))str(uniroot(function(x) x*(x^2-1) + .5, lower = -2, upper = 2,tol = 1e-10))## Find the smallest value x for which exp(x) > 0 (numerically):r <- uniroot(function(x) 1e80*exp(x) - 1e-300, c(-1000, 0), tol = 1e-15)str(r, digits.d = 15) # around -745, depending on the platform.exp(r$root) # = 0, but not for r$root * 0.999...minexp <- r$root * (1 - 10*.Machine$double.eps)exp(minexp) # typically denormalized}% donttest because printed output is so much platform dependent##--- uniroot() with new interval extension + checking features: --------------f1 <- function(x) (121 - x^2)/(x^2+1)f2 <- function(x) exp(-x)*(x - 12)try(uniroot(f1, c(0,10)))try(uniroot(f2, c(0, 2)))##--> error: f() .. end points not of opposite sign## where as 'extendInt="yes"' simply first enlarges the search interval:u1 <- uniroot(f1, c(0,10),extendInt="yes", trace=1)u2 <- uniroot(f2, c(0,2), extendInt="yes", trace=2)stopifnot(all.equal(u1$root, 11, tolerance = 1e-5),all.equal(u2$root, 12, tolerance = 6e-6))## The *danger* of interval extension:## No way to find a zero of a positive function, but## numerically, f(-|M|) becomes zero :u3 <- uniroot(exp, c(0,2), extendInt="yes", trace=TRUE)## Nonsense example (must give an error):tools::assertCondition( uniroot(function(x) 1, 0:1, extendInt="yes"),"error", verbose=TRUE)## Convergence checking :sinc <- function(x) ifelse(x == 0, 1, sin(x)/x)curve(sinc, -6,18); abline(h=0,v=0, lty=3, col=adjustcolor("gray", 0.8))\dontshow{tools::assertWarning(}uniroot(sinc, c(0,5), extendInt="yes", maxiter=4) #-> "just" a warning\dontshow{ , verbose=TRUE)}## now with check.conv=TRUE, must signal a convergence error :\dontshow{tools::assertError(}uniroot(sinc, c(0,5), extendInt="yes", maxiter=4, check.conv=TRUE)\dontshow{ , verbose=TRUE)}### Weibull cumulative hazard (example origin, Ravi Varadhan):cumhaz <- function(t, a, b) b * (t/b)^afroot <- function(x, u, a, b) cumhaz(x, a, b) - un <- 1000u <- -log(runif(n))a <- 1/2b <- 1## Find failure timesru <- sapply(u, function(x)uniroot(froot, u=x, a=a, b=b, interval= c(1.e-14, 1e04),extendInt="yes")$root)ru2 <- sapply(u, function(x)uniroot(froot, u=x, a=a, b=b, interval= c(0.01, 10),extendInt="yes")$root)stopifnot(all.equal(ru, ru2, tolerance = 6e-6))r1 <- uniroot(froot, u= 0.99, a=a, b=b, interval= c(0.01, 10),extendInt="up")stopifnot(all.equal(0.99, cumhaz(r1$root, a=a, b=b)))## An error if 'extendInt' assumes "wrong zero-crossing direction":\dontshow{tools::assertError(}uniroot(froot, u= 0.99, a=a, b=b, interval= c(0.1, 10), extendInt="down")\dontshow{ , verbose=TRUE)}}\keyword{optimize}