我正在努力使用此函数生成一个有效的代码来计算来自输入向量r
的向量结果v
结果。
r(i) = \sum_{j=i}^{i-N} [o(i)-o(j)] * exp(o(i)-o(j))
其中i
在向量v
上循环(从N到M)。 v
的尺寸为M>>N
。
当然这对于2个嵌套的for循环来说是可行的,但它对于计算目的来说太慢了,可能不合时宜和不赞成式......
MWE:
for (i in c(N+1):length(v)){
csum <- 0
for (j in i:c(i-N)) {
csum <- csum + (v[i]-v[j])*exp(v[i]-v[j])
}
r[i] <- csum
}
在我的真实应用M > 10^5
中,v
向量确实是几个向量。
我一直在尝试使用lapply和rollapply的嵌套应用程序而没有成功。 欢迎提出任何建议。
谢谢!
答案 0 :(得分:3)
我不知道它是否更有效,但您可以尝试:
r[N:M] <- sapply(N:M, function(i) tail(cumsum((v[i]-v[1:N])*exp(v[i]-v[1:N])), 1))
检查两个计算是否给出相同的结果,我用r
和我的r2
,将r2
初始化为rep(NA, M)
并评估相似度:
all((r-r2)<1e-12, na.rm=TRUE)
# [1] TRUE
注意:,如@lmo回答,只需使用tail(cumsum(...), 1)
即可有效替换sum(...)
:
r[N:M] <- sapply(N:M, function(i) sum((v[i]-v[1:N])*exp(v[i]-v[1:N])))
答案 1 :(得分:3)
这是一个带有for
循环的方法。
# create new blank vector
rr <- rep(NA,M)
for(i in N:length(v)) {
rr[i] <- sum((v[i] - v[seq_len(N)]) * exp(v[i] - v[seq_len(N)]))
}
检查是否相等
all.equal(r, rr)
[1] TRUE
如果存储差异,则可以将操作数减少1。这应该加快一点。
for(i in N:length(v)) {
x <- v[i] - v[seq_len(N)]
rr[i] <- sum(x * exp(x))
}