在 R 中查找函数的最大根

问题描述 投票:0回答:1

我有一个由数据生成的函数,而不是多项式。对于大多数数据来说,它只有一个根,但也可以有两个根,如下图所示:

enter image description here

uniroot()
往往会失败,因为该函数在 h 的小值和 h 的大值(我在区间端点处使用)处具有相同的符号。

有没有办法找到 R 中函数的最大根,对于已知其参数值较大时会趋于负无穷大的函数?

作为解决方法,我将搜索间隔放置在 h 的较大值周围,即放入右侧我知道函数没有根的区域,然后使用参数

extendInt="downX"
。不过我想知道是否有更强大的东西。

根据评论的要求,这是一个可重现的示例:

# function whose largets root h is to be found
h.root <- function(x, h) {
  n <- length(x)
  f2 <- function(y) {
    h2 <- h*h
    (sum(((x-y)^2/h2 - 1) * dnorm((x-y)/h)) / (n*h*h2))^2
  }
  f2.int <- integrate(Vectorize(f2), -Inf, Inf)$value
  (0.5 / sqrt(pi) / f2.int / n)^0.2 - h
}

# examples for problematic seeds: 45, 36
set.seed(36)
x <- rnorm(50)
h <- seq(0.05, 0.6, 0.01)
res <- h
for (i in 1:length(h)) res[i] <- h.root(x,h[i])
plot(h, res, type="l")
abline(h=0, lty=2)

print(uniroot(h.root, c(0.05, 10), x=x)$root)
r numeric
1个回答
0
投票

也许你可以用数值方法来求解最大根

idx <- which(rowSums(sign(embed(res, 2))) == 0)
sols <- rowMeans(cbind(h[idx], h[idx + 1]))

你就得到了根(从左到右)

> sols
[1] 0.1065 0.2545 0.5525

您可以验证解决方案

> h.root(x, sols)
[1] -7.801779e-05 -1.402256e-04 -6.189450e-05

数据

实际上,您可以对

h.root
进行矢量化并提供更高分辨率的
h
,例如,

# function whose largets root h is to be found
h.root <- Vectorize(function(x, h) {
    n <- length(x)
    f2 <- function(y) {
        h2 <- h * h
        (sum(((x - y)^2 / h2 - 1) * dnorm((x - y) / h)) / (n * h * h2))^2
    }
    f2.int <- integrate(Vectorize(f2), -Inf, Inf)$value
    (0.5 / sqrt(pi) / f2.int / n)^0.2 - h
}, vectorize.args = "h")

# examples for problematic seeds: 45, 36
set.seed(36)
x <- rnorm(50)
h <- seq(0.05, 0.6, 1e-3)
res <- h.root(x, h)

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.