有没有比 R 中的 stats:uniroot 函数更快的替代方法?

互联网 行业动态 更新时间:2024-06-13 00:19:32

Ben*_*ker 5

160 秒 (1e6/5e4 * 8) 对我来说一百万行听起来还不错(尽管您的实际功能可能比froot您在这里使用的要慢得多?)。这可以简单地并行化,在不同的核心上运行单独的块(参见例如对这个问题的回答)。

你有多需要extendInt?如果我制作一个uniroot()只有核心功能、没有参数测试逻辑等的功能的破解版本,我可以将速度提高三倍。但是,如果您的目标功能比你在这里给出的例子;如果是这种情况,您应该专注于加速您的目标函数(我尝试froot在 C++ 中通过重新编码您的代码Rcpp,但在这种情况下它并没有真正帮助 - 该函数非常简单,函数调用开销需要大部分时间...)

为了便于基准测试,我只用了 5000 行来执行此操作:

n <- 5000
u <- -log(runif(n))
a <- 1/2
b <- 1
dt = data.table(u = u, a = a, b = b)

最小功能:

uu <- function(f, lower, upper, tol = 1e-8, maxiter =1000L, ...) {
  f.lower <- f(lower, ...)
  f.upper <- f(upper, ...)
  val <- .External2(stats:::C_zeroin2, function(arg) f(arg, ...),
                    lower, upper, f.lower, f.upper, tol, as.integer(maxiter))
  return(val[1])
}

检查我们是否得到相同的结果:

identical(uniroot(froot, u = 3.242, a=0.5, b=1, interval = c(0.01,100))$root,
          uu(froot, u = 3.242, a=0.5, b=1, lower = 0.01, upper = 100))
## TRUE

基准测试包;将评估包装在函数中以实现紧凑性

library(rbenchmark)
f1 <- function() {
  dt[, c := uniroot(froot_cpp, u=u, a=a, b=b, interval= c(0.01, 10), extendInt="yes")$root, by = u]
}
f2 <- function() {
  dt[, c := uu(froot, u=u, a=a, b=b, lower = 0.01, upper = 100), by = u]
}
bb <- benchmark(f1(), f2(), 
    columns =c("test", "replications", "elapsed", "relative"))

结果:

  test replications elapsed relative
1 f1()          100  34.616    3.074
2 f2()          100  11.261    1.000

更多推荐

更快,函数,方法,stats,uniroot

本文发布于:2023-04-21 10:00:06,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/hyzx/255d6c7c40d189384d8686833507e41d.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:更快   函数   方法   stats   uniroot

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!