uniroot()
及其使用注意事项
uniroot https://svn.r-project.org/R/trunk/src/library/stats/src/zeroin.c正在实施粗二分法 https://en.wikipedia.org/wiki/Bisection_method。这种方法要简单得多(拟)牛顿法 https://en.wikipedia.org/wiki/Newton%27s_method,但需要更强的假设来确保根的存在:f(lower) * f(upper) < 0
.
这可能会很痛苦,因为这样的假设是充分条件,但不是必要条件。在实践中,如果f(lower) * f(upper) > 0
,仍然有可能存在根,但由于这不是 100% 确定,二分法不能冒这个风险。
考虑这个例子:
# a quadratic polynomial with root: -2 and 2
f <- function (x) x ^ 2 - 4
显然,有根[-5, 5]
. But
uniroot(f, lower = -5, upper = 5)
#Error in uniroot(f, lower = -5, upper = 5) :
# f() values at end points not of opposite sign
实际上,使用二分法需要观察/检查f
,这样就可以提出根所在的合理区间。在R中,我们可以使用curve()
:
curve(f, from = -5, to = 5); abline(h = 0, lty = 3)
从图中,我们观察到根存在于[-5, 0]
or [0, 5]
。所以这些工作正常:
uniroot(f, lower = -5, upper = 0)
uniroot(f, lower = 0, upper = 5)
你的问题
现在让我们尝试一下你的函数(为了便于阅读,我将其分成几行;这样也很容易检查正确性):
f <- function(y) {
g <- function (u) 1 - exp(-0.002926543 * u^1.082618 * exp(0.04097536 * u))
a <- 1 - pbeta(g(107.2592+y), 0.2640229, 0.1595841)
b <- 1 - pbeta(g(x), 0.2640229, 0.1595841)
a - b^2
}
x <- 0.5
curve(f, from = 0, to = 1000)
这个函数怎么会是一条水平线呢?它不可能有根!
- 检查
f
以上,它真的是在做你想做的正确的事情吗?我怀疑有什么问题g
;你可能把括号放错了地方?
- 一旦你得到
f
正确,使用curve
检查存在根的适当间隔。然后使用uniroot
.