【发布时间】:2015-06-20 07:36:57
【问题描述】:
我继承了 R 的一些代码,它的运行速度非常慢。大部分时间都花在评估表单的函数上(大约有 15 个这样的函数具有不同的被积函数 G):
TMin <- 0.5
F <- function (t, d) {
result <- ifelse(((d > 0) & (t > TMin)),
mapply(function(t, d) integrate(G, lower=0, upper=t, t, d)$value, t, d),
0)
return(result)
}
为了测试,我使用了下面的虚拟函数,但在实际代码中,Gs 要复杂得多,涉及 exp()、log()、dlnorm()、plnorm() 等。
G <- function(x, t, d) {
mean(rnorm(1e5))
x + t - d
}
在最坏的情况下,F 将被计算大约 200 万次。
该函数以 3 种不同的方式调用:
t 是单个数字,d 是数字向量,或者,
t 是数值向量,d 是单个数字,或者,
t是数值向量,是数值向量
有没有(简单的)方法可以加速这个功能?
到目前为止,我已经尝试了以下方面的变化(以摆脱 ifelse 循环):
F2 <- function (t,d) {
TempRes <- mapply(function(t, d) integrate(G, lower=0, upper=t, t, d)$value, t, d)
TempRes[(d <= 0) | (t <= TMin)] <- 0
result <- TempRes
return(result)
}
和
F3 <- function (t,d) {
result <- rep(0, max(length(t),length(d)))
test <- ((d > 0) & (t > TMin))
result[test] <- mapply(function(t, d) integrate(G, lower=0, upper=t, t, d)$value, t, d)[test]
return(result)
}
但它们几乎花费了完全相同的时间。
【问题讨论】:
-
你确定积分没有闭式解吗?因为到目前为止,您拥有提高性能的最佳潜力。如果你的数学技能生疏了,你可以问问 CAS。
-
和往常一样,如果您对性能不满意,请分析您的代码。
-
如果有一个封闭的,我会感到非常惊讶,但是,你是对的,这值得一看。
-
这可能是个坏主意,但您可以尝试将 15 个函数合并为一个向量值函数,并使用 cubature 包中的
adaptIntegrate。它比 R 的一维积分要慢,但具有处理向量值函数的优势。如果您以后想用更快的语言编写被积函数,它can be easily interfaced in C++ code。 -
result = …; return(result)在 R 中真的没有意义:函数的最后一个表达式自动是函数的结果。无需将其分配给变量,无需return。
标签: r optimization integrate mapply