如何从R中的roximun()之后输入的y值估算x值

时间:2018-10-04 15:30:27

标签: r

我想使用approxfun或类似的方法来估算曲线的函数,然后估算给定已知点x的值给点的y值。

这是一个简化的示例。

y <- seq(from=1, to =10, by = 1)

x <-seq(from=0.1, to =1, by = 0.1)

fun <- approxfun(x,y)

我可以使用以下命令在已知y值的情况下近似x值:

fun(0.65)
#[1] 6.5

但是我该如何做相反的事情,即从x解决6.5 = approxfun(x)

感谢您对我最可能是愚蠢的问题的帮助。

1 个答案:

答案 0 :(得分:0)

线性插值的解析解(稳定)

假设我们有一些(x, y)数据。线性插值后,找到所有x,以使插值的值等于y0

## with default value y0 = 0, it finds all roots of the interpolant
RootLinearInterpolant <- function (x, y, y0 = 0) {
  if (is.unsorted(x)) {
     ind <- order(x)
     x <- x[ind]; y <- y[ind]
     }
  z <- y - y0
  ## which piecewise linear segment crosses zero?
  k <- which(z[-1] * z[-length(z)] < 0)
  ## analytically root finding
  xk <- x[k] - z[k] * (x[k + 1] - x[k]) / (z[k + 1] - z[k])
  xk
  }

更复杂的示例和测试。

set.seed(0)
x <- sort(runif(10, 0, 10))
y <- rnorm(10, 3, 1)
y0 <- 2.5
xk <- RootLinearInterpolant(x, y, y0)
#[1] 3.375952 8.515571 9.057991

plot(x, y, "l"); abline(h = y0, lty = 2)
points(xk, rep.int(y0, length(xk)), pch = 19)


用于非线性插值的数值求根(不一定稳定)

## suppose that f is an interpolation function of (x, y)
## this function finds all x, such that f(x) = y0
## with default value y0 = 0, it finds all roots of the interpolant
RootNonlinearInterpolant <- function (x, y, f, y0 = 0) {
  if (is.unsorted(x)) {
     ind <- order(x)
     x <- x[ind]; y <- y[ind]
     }
  z <- y - y0
  k <- which(z[-1] * z[-length(z)] < 0)
  nk <- length(k)
  xk <- numeric(nk)
  F <- function (x) f(x) - y0
  for (i in 1:nk) xk[i] <- uniroot(F, c(x[k[i]], x[k[i] + 1]))$root
  xk
  }

尝试自然三次样条插值。

## cubic spline interpolation
f <- splinefun(x, y)
xk <- RootNonlinearInterpolant(x, y, f, y0)
#[1] 3.036643 8.953352 9.074306

curve(f, from = min(x), to = max(x))
abline(v = x, lty = 3)  ## signal pieces
abline(h = y0)
points(xk, rep.int(y0, length(xk)), pch = 20)

我们看到RootNonlinearInterpolant在第3个棋子上错过了两个交叉点。

RootNonlinearInterpolant依赖于uniroot,因此搜索受到更多限制。仅当y - y0的符号在相邻结上改变时,才会调用uniroot。显然,这并不适用于第三部分。 (在Uniroot solution in R上了解有关uniroot的更多信息。)

还要注意,uniroot仅返回单个根。因此,最稳定的情况是插值在棋子上是单调的,因此存在唯一根。如果实际上有多个根,uniroot只会找到其中一个。