Найти root с помощью uniroot
Я пытаюсь найти корень следующей функции (на основе гаммы (
gamma()
) function) с помощью функции:
cv = 0.056924/1.024987^2
fx2 = function(theta, eta){
p1 = 1 - 2/(theta*(1-eta))
p2 = 1 - 1/(theta*(1-eta))
return(( gamma(p1)/(gamma(p2))^2 ) - (cv+1) )
}
Эта функция дает мне следующий график:
v = seq(0, 1, 0.01)
plot(v, fx2(3.0, v), type='l' )
Мне кажется, что корень этой функции близок к 0,33, но
uniroot()
функция не находит корень, возвращая следующий результат:
uniroot(fx2, interval = c(0,0.3), theta=3 )
Ошибка в uniroot (fx2, interval = c (0, 0,3), theta = 3): значения f () в конечных точках не противоположного знака
Как мне найти корень этой функции? Есть ли другие пакеты с более точным алгоритмом?
1 ответ
Сначала я переписал вашу функцию, чтобы (необязательно) выразить
cv = 0.056924/1.024987^2
fx3 <- function(theta, eta, lgamma = FALSE) {
p1 <- 1 - 2/(theta*(1-eta))
p2 <- 1 - 1/(theta*(1-eta))
if (lgamma) {
val <- exp(lgamma(p1) - 2*lgamma(p2)) - (cv+1)
} else {
val <- ( gamma(p1)/(gamma(p2))^2 ) - (cv+1)
}
}
Вычислите функцию с масштабированием журнала и без него:
x <- seq(0, 1, length.out = 20001)
v <- sapply(x, fx3, theta = 3.0, lgamma = TRUE)
v2 <- sapply(x, fx3, theta = 3.0, lgamma = FALSE)
Найдите корень (более подробное объяснение ниже):
uu <- uniroot(function(eta) fx3(3.0, eta, lgamma = TRUE),
c(0.4, 0.5))
Постройте это:
par(las=1, bty="l")
plot(x, abs(v), col = as.numeric(v<0) + 1, type="p", log="y",
pch=".", cex=3)
abline(v = uu$root, lty=2)
cvec <- sapply(c("blue","magenta"), adjustcolor, alpha.f = 0.2)
points(x, abs(v2), col=cvec[as.numeric(v2<0) + 1], pch=".", cex=3)
Здесь я изображаю абсолютное значение в логарифмической шкале со знаком, обозначенным цветом (черный / синий>0, красный> пурпурный <0). Черный / красный - расчет в логарифмической шкале, синий / пурпурный - исходный расчет. Я также построил график функции в очень высоком разрешении, чтобы попытаться избежать пропуска или искажения характеристик.
Здесь происходит много странных вещей.
- обе версии функции делают что-то интересное около x=1/3; исходная версия выглядит как полюс (значение расходится до +∞, «возвращается» из -∞), в то время как вычисление в логарифмической шкале увеличивается до +∞ и возвращается без изменения знака.
- вычисление в логарифмическом масштабе имеет корень около x = 0,45 (абсолютное значение становится маленьким, когда знак переворачивается), но исходное вычисление нет - предположительно из-за какой-то катастрофической потери точности? Если мы дадим
границы, не включающие полюс, он может найти этот корень. - есть другие полюса и / или корни при больших значениях x, которые я не исследовал.
Все это в основном говорит о том, что довольно опасно возиться с этой функцией, не зная, каковы ее математические свойства. Я обнаружил кое-что путем численного исследования, но было бы лучше проанализировать функцию, чтобы вы действительно знали, что происходит; любое числовое исследование можно обмануть, если функция ведет себя достаточно странно.