给定 y 值获取 x 值:线性/非线性插值函数的一般求根

2024-01-08

我对插值函数的一般求根问题感兴趣。

假设我有以下内容(x, y) data:

set.seed(0)
x <- 1:10 + runif(10, -0.1, 0.1)
y <- rnorm(10, 3, 1)

以及线性插值和三次样条插值:

f1 <- approxfun(x, y)
f3 <- splinefun(x, y, method = "fmm")

我怎样才能找到x-这些插值函数与水平线交叉的值y = y0?下面是一个图形说明y0 = 2.85.

par(mfrow = c(1, 2))
curve(f1, from = x[1], to = x[10]); abline(h = 2.85, lty = 2)
curve(f3, from = x[1], to = x[10]); abline(h = 2.85, lty = 2)

我知道之前有一些关于这个主题的帖子,比如

  • 通过简单拟合预测 x 值并在图中进行注释 https://stackoverflow.com/q/37455512/4891738
  • 使用拟合模型根据 Y 值预测 X 值 https://stackoverflow.com/q/43322568/4891738

建议我们简单地反转x and y,进行插值(y, x)并计算插值y = y0.

然而,这是一个错误的想法。让y = f(x)是一个插值函数(x, y),这个想法只有在以下情况下才有效f(x)是一个单调函数x以便f是可逆的。否则x不是一个函数y并插值(y, x)没有意义。

用我的示例数据进行线性插值,这个假想法给出了

fake_root <- approx(y, x, 2.85)[[2]]
# [1] 6.565559

首先,根数不正确。我们从图中(左侧)看到两个根,但代码只返回一个。其次,它不是一个正确的根,因为

f1(fake_root)
#[1] 2.906103

不是2.85。

我第一次尝试解决这个普遍问题如何在R中approxfun()之后根据y值输入估计x值 https://stackoverflow.com/q/52650467/4891738。该解对于线性插值来说是稳定的,但对于非线性插值来说不一定是稳定的。我现在正在寻找一个稳定的解决方案,特别是对于三次插值样条线。


解决方案如何在实践中发挥作用?

有时,经过一段单变量线性回归y ~ x or a 单变量非线性回归y ~ f(x)我们想要反求解x对于一个目标y。这个问答就是一个例子,吸引了很多答案:求解最佳拟合多项式并绘制下拉线 https://stackoverflow.com/q/41687406/4891738,但没有一个是真正具有适应性或易于在实践中使用的。

  • 接受的答案使用polyroot仅适用于简单的多项式回归;
  • 使用二次公式求解析解的答案仅适用于二次多项式;
  • 我的回答使用predict and uniroot一般情况下可以工作,但不方便,因为在实践中使用uniroot需要与用户交互(参见R 中的 Uniroot 解决方案 https://stackoverflow.com/q/38961221/4891738了解更多uniroot).

如果有一个自适应且易于使用的解决方案,那就太好了。


首先,让我复制中提出的线性插值的稳定解决方案我之前的回答 https://stackoverflow.com/a/52650890/4891738.

## given (x, y) data, find x where the linear interpolation crosses y = y0
## the default value y0 = 0 implies root finding
## since linear interpolation is just a linear spline interpolation
## the function is named RootSpline1
RootSpline1 <- function (x, y, y0 = 0, verbose = TRUE) {
  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)
  ## analytical root finding
  xr <- x[k] - z[k] * (x[k + 1] - x[k]) / (z[k + 1] - z[k])
  ## make a plot?
  if (verbose) {
    plot(x, y, "l"); abline(h = y0, lty = 2)
    points(xr, rep.int(y0, length(xr)))
    }
  ## return roots
  xr
  }

对于由返回的三次插值样条stats::splinefun有方法"fmm", "natrual", "periodic" and "hyman",以下函数提供稳定的数值解。

RootSpline3 <- function (f, y0 = 0, verbose = TRUE) {
  ## extract piecewise construction info
  info <- environment(f)$z
  n_pieces <- info$n - 1L
  x <- info$x; y <- info$y
  b <- info$b; c <- info$c; d <- info$d
  ## list of roots on each piece
  xr <- vector("list", n_pieces)
  ## loop through pieces
  i <- 1L
  while (i <= n_pieces) {
    ## complex roots
    croots <- polyroot(c(y[i] - y0, b[i], c[i], d[i]))
    ## real roots (be careful when testing 0 for floating point numbers)
    rroots <- Re(croots)[round(Im(croots), 10) == 0]
    ## the parametrization is for (x - x[i]), so need to shift the roots
    rroots <- rroots + x[i]
    ## real roots in (x[i], x[i + 1])
    xr[[i]] <- rroots[(rroots >= x[i]) & (rroots <= x[i + 1])]
    ## next piece
    i <- i + 1L
    }
  ## collapse list to atomic vector
  xr <- unlist(xr)
  ## make a plot?
  if (verbose) {
    curve(f, from = x[1], to = x[n_pieces + 1], xlab = "x", ylab = "f(x)")
    abline(h = y0, lty = 2)
    points(xr, rep.int(y0, length(xr)))
    }
  ## return roots
  xr
  }

It uses polyroot分段,首先找到所有根complex字段,然后只保留real分段区间上的那些。这是可行的,因为三次插值样条只是许多分段三次多项式。我的回答在如何在R中保存和加载样条插值函数? https://stackoverflow.com/q/51540182/4891738已经展示了如何获得分段多项式系数,因此使用polyroot很简单。

使用问题中的示例数据,两者RootSpline1 and RootSpline3正确识别所有根。

par(mfrow = c(1, 2))
RootSpline1(x, y, 2.85)
#[1] 3.495375 6.606465
RootSpline3(f3, 2.85)
#[1] 3.924512 6.435812 9.207171 9.886640
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

给定 y 值获取 x 值:线性/非线性插值函数的一般求根 的相关文章

  • 在 R 中编写多重积分函数

    为了将以下内容转换为函数 我想知道如何用 R 代码编写以下二重积分 bar x mu 假设pi0 and pi1以向量化方式实现函数 pi 0 和 pi 1 可能的解决方案是 integral lt function n mu s pi0
  • 有什么方法可以访问 makeActiveBinding 安装的函数吗?

    标题基本上说明了一切 如果我这样做 makeActiveBinding x function runif 2 GlobalEnv x 1 0 7332872 0 4707796 x 1 0 5500310 0 5013099 那我有什么办法
  • 如何计算满足条件的行数

    假设我有以下数据框 Data1 X1 X2 1 15 1 2 3 1 3 7 0 4 11 1 5 1 0 6 9 0 7 18 0 8 6 1 9 3 1 我想知道如何找到观察的总数X1大于 9 并且X2等于1 我想我需要使用sum 但我
  • 挖泥机子集 (MuMIn) - 如果存在主效应,则必须包括交互作用

    我正在使用 dredge MuMIn 进行一些探索性工作 在此过程中 我想将两个变量设置为仅当它们之间存在相互作用时才允许一起出现 即它们不能仅作为主要效果一起出现 使用样本数据 我想挖掘模型 fm1 尽管它可能没有意义 如果变量 GNP
  • RQuantLib 包不适用于 R 3.5.0

    有没有其他人尝试加载 R 3 5 0 的 RQuantLib 包 我尝试过 以前有效 install packages drat dependencies TRUE drat addRepo ghrr install packages RQ
  • 如何为 nls 函数找到良好的起始值?

    我不明白为什么我不能对这些数据使用 nls 函数 我尝试过很多不同的起始值 但总是出现相同的错误 这是我一直在做的事情 expFct2 function x a b c a 1 exp x b c vec x lt c 77 87 87 7
  • 如何在 R 中更新和重新编译 nlme 源代码

    我正在尝试更新 nlme 包 以便我可以在 gls 命令中使用大圆距离进行相关性 我正在尝试使用指定的更改来编辑源代码here http r 789695 n4 nabble com nlme spatial autocorrelation
  • 将儒略日期转换为 PosixCt 日期

    我发现自己在解决这个问题 我需要将 R 中的儒略日期转换为正常日期 YYYY MM DD 我知道我可以指定as Date julian date origin 但我不知道应该提供哪个来源 我的朱利安日期类似于 2458010 2458011
  • 为什么我收到保存错误、软盘错误的消息?

    我最近更新了 R 和 R studio 当我尝试保存文件时 收到一条错误消息 保存 文件名 时出错 驱动器中的软盘错误 将 2 卷序列号 3 插入驱动器 1 这是第一次看到这个错误信息 不知道该怎么办 我也无法 另存为 感谢您的帮助 尝试使
  • 计算带状矩阵的 colCumsums 的更快替代方案

    我是 R 和 stats 的新手 在我当前工作的领域中 我需要以独特的方式计算累积列总和 最初提供宽度为 b 行数为 n 的方带矩阵 例如 n 8 且 b 3 0 1 2 7 0 0 0 0 0 0 3 6 7 0 0 0 0 0 0 3
  • R 中带有变音符号的字符列表

    我试图将字符串中的电话 字符 出现次数制成表格 但变音符号单独作为字符制成表格 理想情况下 我有一个国际音标的单词列表 其中包含大量变音符号以及它们与基本字符的几种组合 我在这里给出了仅包含一个单词的 MWE 但对于单词列表和更多类型的组合
  • Sweave + RweaveHTML:cat 输出未出现在输出中

    我对 Sweave RweaveHTML 有疑问 我希望 cat 的输出最终出现在正在生成的 html 文件中 我有一个案例 它没有 我不明白为什么 test function bla bla cat Result is 然后在 Rnw 文
  • 如何合并具有相同列名的数据框

    我有一个数据框 如下所示 structure list Variables structure list ADA ADA LEAD LEAD BIG4 BIG4 LOGMKT LOGMKT LEV LEV ROA ROA ROAL ROAL
  • 在函数中调用其他列的控制流程

    我正在尝试在给定条件的情况下连接到函数中的其他列 本质上 我想让数据框在给定条件的情况下从长到宽 其中一列中的这些值是NA相对于同一行中具有值的另一列 转动NAs转化为特定的数字 尽管分配的值必须是特定于列的 因此 如果2010 has N
  • R data.table:在当前测量之前对出现次数进行计数

    我有一组在几天内进行的测量结果 测量次数通常为 4 任何测量中可以捕获的数字范围为 1 5 在现实生活中 给定测试集 范围可能高达 100 或低至 20 我想每天计算每个值在当天之前发生的次数 让我用一些示例数据来解释 test data
  • R 如何按行值进行分组、拆分或子集

    这是上一个问题的延续R 如何按行值分组 分裂 https stackoverflow com questions 64602607 r how to group by row value split 输入数据帧的变化是 id str c x
  • 在 R 中,如何让 PRNG 在平台之间给出相同的浮点数?

    在 R 4 1 1 中运行以下代码会在平台之间产生不同的结果 set seed 1 x lt rnorm 3 3 print x 22 0 83562861241004716 intel windows 0 8356286124100471
  • 在 Microsoft Windows 上安装 RQuantLib

    我需要安装R包RQuantLib在 Microsoft Windows 计算机上 这个包没有二进制文件 所以我下载了 tar 源 我打开它 它包含 QuantLib C 库 所以我需要编译这个包 我不想安装 Visual Studio 我使
  • 三角形内的热图

    考虑以下示例 triangle lines lt data frame X c 0 0 1 1 0 5 0 5 Y c 0 0 0 0 1 1 grp c 1 2 1 3 2 3 df lt matrix c c 0 2 0 5 0 8 c
  • 在r中的数据框中循环线性回归输出

    我有一个下面的数据集 我想在其中对每个国家和州进行线性回归 然后绑定数据集中的预测值 添加另外三列后的最终数据框 我已经对一个国家和一个地区进行了此操作 但想对每个国家和地区进行此操作 并将预测值 上限值和下限值放回到cbind的数据集中

随机推荐

  • 是否可以在 Android/dalvik 中重写 Java 类中的本机方法?

    我正在对一个类进行单元测试TestMe使用 EasyMock 及其方法之一 例如method N n 需要一个类型的参数N它有一个本机方法 比如nativeMethod class TestMe void method N n Do stu
  • 移动/触摸屏幕 - 滑动时水平滚动

    这个问题是在详细讨论后提出的这个问题 https stackoverflow com q 11649405 226906 Problem 我需要一个水平滚动 可以使用桌面上的鼠标拖动和启用触摸的屏幕上的滑动事件来滚动 可能的解决方案 我尝试
  • 时间:2019-03-07 标签:c#PinvokeforGetWindowDpiAwarenessContext

    我试图在 C 应用程序中实现 GetWindowDpiAwarenessContext 但没有成功 相关头文件是 windef h DECLARE HANDLE DPI AWARENESS CONTEXT typedef enum DPI
  • 替换全球变音符号[重复]

    这个问题在这里已经有答案了 可能的重复 PHP 将变音符号替换为 UTF 8 字符串中最接近的 7 位 ASCII 等效项 https stackoverflow com questions 158241 php replace umlau
  • Kivy 多显示器

    我正在考虑使用 Kivy 创建一个需要在每个监视器上显示一个窗口的程序 有没有办法实现这一点 我也不希望有一个跨越的窗口 如果没有 是否有另一个 好看的 windows linux GUI 工具包可以完成这个任务 您可以有两个单独的窗口运行
  • 添加常见图例

    我试图做一个多图ggplot2 这是我最初的代码 nucmer s1 lt ggarrange eight uniform ten uniform twelve uniform fourteen uniform sixteen unifor
  • 一次撤销多个用户的 Oracle 权限

    我们正在合理化我们的数据库用户权限 为此 我们希望撤销授予所有用户 但不是特定角色 的架构中所有表的所有选择权限 通过一些正则表达式 我尝试创建一个通用的revoke对于每个表 给出如下内容 撤销 USER1 USER2 USER3 对 T
  • SQL*Plus 脚本执行两次

    我正在尝试使用 sqlplus 运行脚本 我的脚本是一个简单的删除语句 我通过将以下内容放入 ksh 终端来执行它 sqlplus username password sql delete societes sql sql delete s
  • AttributeError:“模块”对象没有属性“请求”

    当我在 Python 3 3 中运行以下代码时 import urllib tempfile urllib request urlopen http yahoo com 我收到以下错误 我也这样做来验证 我究竟做错了什么 The urlli
  • 如何在 Unity 协程中通过引用局部变量?

    我有一些函数可以接受 Enemy 实例并更改其字段之一 敌人类别有一些基本字段 如速度 伤害 攻击范围 每个函数只存储敌人的一个正常值 然后将当前字段更改为某个值一段时间 然后将其更改回正常状态 我在 Unity 中编写代码并使用 Coro
  • 无法在anaconda上安装tensorflow

    我正在尝试在 anaconda 上安装tensorflow i tried conda install c conda forge tensorflow 但安装卡住了Solving environment 寻找解决方案 因此有人建议使用调试
  • 使用回车键提交输入字段

    我正在构建天气应用程序 并希望使用 Enter 键将城市名称提交到服务器 我收到错误 提交不是一个函数 我想解决这个问题 并且想知道如何将值发送到 Express 服务器 以便在 API 调用中使用它 这是我的代码
  • 如何将 Beyond Compare 与 ClearCase 集成?

    我想将 Beyond Compare 与 ClearCase 集成 这样我就可以用它来比较和合并文件 而不是 ClearCase 提供的那些糟糕的工具 有人有执行此集成的说明吗 正如我的文章中提到的之前的回答 https stackover
  • 用于访问数组中第一个/最后一个元素的 Ruby 约定[关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 这是一个关于约定的问题 下面的两组命令返回相同的结果 a 1 2 3 a first gt 1 a 0 gt 1 a last gt 3 a 1
  • 我可以在 Android 上获得英语以外语言的语音识别吗?

    我正在尝试构建一个应用程序 将使用印地语和其他区域语言 来获取语音命令 我的应用程序中还需要文本转语音功能 我想知道是否有什么方法可以在 Android 上获得语音识别库 我在 Google 上进行了快速搜索 并在互联网上找到了几个印地语库
  • 无法 ssh 到 AWS EC2:身份文件无法访问[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 Locked 这个问题及其答案是locked help locked posts因为这个问题是题外话 但却具有历史意义 目前不接受新的答案
  • HTML 输入字段禁用输入但仍然 POST

    基本上我想要一个禁用文本字段来显示存储在数据库中的值 但我不希望用户可以编辑它 我尝试过使用disabled disabled 但随后它不再发布到我的表单处理程序 有什么建议么 thanks docu http www w3 org TR
  • 构建一台 LISP 机器需要多少原语?十个、七个还是五个?

    在这个网站上 他们说有 10 个 LISP 原语 原语是 atom quote eq car cdr cons cond lambda label apply http hyperpolyglot wikidot com lisp ten
  • 用于运行检测显示器的 Applescript

    当我将外接显示器插入 Macbook 并唤醒它时 显示器的分辨率通常是错误的 在使用 Mountain Lion 之前 我能够运行以下 applescript 来检测显示器 tell application System Preferenc
  • 给定 y 值获取 x 值:线性/非线性插值函数的一般求根

    我对插值函数的一般求根问题感兴趣 假设我有以下内容 x y data set seed 0 x lt 1 10 runif 10 0 1 0 1 y lt rnorm 10 3 1 以及线性插值和三次样条插值 f1 lt approxfun