我想找到以下函数的根:
x=0.5
f <- function(y) ((1-pbeta(1-exp(-0.002926543
*( 107.2592+y)^1.082618 *exp(0.04097536*(107.2592+y))),shape1=0.2640229,shape2=0.1595841)) -
(1-pbeta(1-exp(-0.002926543*(x)^1.082618 *exp(0.04097536*(x))),shape1=0.2640229,shape2=0.1595841))^2)
sroot=uniroot(f, lower=0, upper=1000)$root
我该如何解决错误?
最佳答案
uniroot()
及其使用注意事项
uniroot
正在实现粗略的bisection method。这种方法比(quasi) Newton's 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]
有根。但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]
或[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
。