当前位置: 首页>>代码示例 >>用法及示例精选 >>正文


R uniroot 一维求根(零)


R语言 uniroot 位于 stats 包(package)。

说明

函数uniroot在从lowerupper的区间中搜索函数f相对于其第一个参数的根(即零)。

extendInt设置为非"no"字符串,意味着如果sign(f(x))在区间终点不满足要求,则寻找正确的interval = c(lower,upper);请参阅“详细信息”部分。

用法

uniroot(f, interval, ...,
        lower = min(interval), upper = max(interval),
        f.lower = f(lower, ...), f.upper = f(upper, ...),
        extendInt = c("no", "yes", "downX", "upX"), check.conv = FALSE,
        tol = .Machine$double.eps^0.25, maxiter = 1000, trace = 0)

参数

f

求根的函数。

interval

包含要搜索根的区间的 end-points 的向量。

...

要传递给 f 的其他命名或未命名参数

lower , upper

要搜索的区间的下端点和上端点。

f.lower , f.upper

分别与 f(upper)f(lower) 相同。一旦 f() 包含重要的计算,从通常已知的调用者处传递这些值会更经济。

extendInt

字符串,指定当 f() 在端点处没有不同的符号时,是否应扩展间隔 c(lower,upper) 或直接产生错误。默认值 "no" 保留搜索间隔,因此会产生错误。可以缩写。

check.conv

逻辑指示底层 uniroot 的收敛警告是否应被捕获为错误,以及 maxiter 迭代中的不收敛是否应为错误而不是警告。

tol

所需的精度(收敛容差)。

maxiter

最大迭代次数。

trace

整数;如果是肯定的,则产生追踪信息。更高的值提供更多细节。

细节

请注意,... 之后的参数必须完全匹配。

必须指定interval 或同时指定lowerupper:上端点必须严格大于下端点。对于 extendInt="no" 来说,端点处的函数值必须具有相反的符号(或零),这是默认值。否则,如果 extendInt="yes" ,则在两侧扩展间隔,以搜索符号更改,即,直到搜索间隔 满足

如果知道 如何在根 处改变符号,也就是说,如果函数在那里增加或减少,则extendInt可以(通常应该)指定为"upX"(对于“upward crossing”)或"downX" ,分别。同样,定义 ,以在解决方案中要求 。在这种情况下,搜索间隔 可能被扩展为使得

uniroot() 使用基于下面参考文献中给出的算法的 Fortran 子例程 zeroin(来自 Netlib)。它们假设一个连续函数(已知该函数在区间内至少有一个根)。

如果 f(x) == 0 或算法一步的 x 变化小于 tol(加上 x 中的表示错误容限),则声明收敛。

如果算法在 maxiter 步骤中未收敛,则会打印警告并返回当前近似值。

f将被称为f(x, ...)对于数值x.

传递给 f 的参数具有特殊语义,用于在调用之间共享。该函数不应该复制它。

至少包含五个组件的列表:rootf.root 给出根的位置以及在该点计算的函数的值。 iterestim.prec 给出使用的迭代次数以及 root 的近似估计精度。 (如果根出现在端点之一,则估计精度为 NA 。) init.it 包含初始 extendInt 迭代次数(如果有),否则为 NA 。在这种extendInt迭代的情况下,iter包含其中的sumzeroin迭代。

将来可能会添加更多组件。

例子


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 - a
str(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)$root

str(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


##--- 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))

uniroot(sinc, c(0,5), extendInt="yes", maxiter=4) #-> "just" a warning


## now with  check.conv=TRUE, must signal a convergence error :

uniroot(sinc, c(0,5), extendInt="yes", maxiter=4, check.conv=TRUE)


### Weibull cumulative hazard (example origin, Ravi Varadhan):
cumhaz <- function(t, a, b) b * (t/b)^a
froot <- function(x, u, a, b) cumhaz(x, a, b) - u

n <- 1000
u <- -log(runif(n))
a <- 1/2
b <- 1
## Find failure times
ru <- 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":

uniroot(froot, u= 0.99, a=a, b=b, interval= c(0.1, 10), extendInt="down")

来源

基于 'zeroin.c' 在https://netlib.org/c/brent.shar.

参考

Brent, R. (1973) Algorithms for Minimization without Derivatives. Englewood Cliffs, NJ: Prentice-Hall.

也可以看看

polyroot 用于多项式的所有复数根; optimizenlm

相关用法


注:本文由纯净天空筛选整理自R-devel大神的英文原创作品 One Dimensional Root (Zero) Finding。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。