我正在R中编写一个函数,它必须在继续之前计算两个向量的值并做一些其他花哨的东西。两个向量R和B由以下总结给出:
和
其中$ \ beta $是一个常量, ts 被传递给函数,并且是事件的发生时间。所以,基本上,当第i个事件发生时(在时间t_i
),我计算B(i)
和R(i)
,它们是使用之前所有出现时间t_k
完成的总结。直到那一刻我的事件。
我想提出一些比这更有效的方法
r <- rep(0,length(t))
for(i in 2:length(t)) {
r[i] <- sum((t[i]-t[which(t<t[i])])*exp(beta*(t[i]-t[which(t<t[i])])))
}
b <- rep(0,length(t))
for(i in 2:length(t)) {
b[i] <- sum(((t[i]-t[which(t<t[i])])^2)*exp(beta*(t[i]-t[which(t<t[i])])))
}
基本上计算两次,即使两者之间的唯一区别是指数之前的平方。有任何想法吗?谢谢!
答案 0 :(得分:1)
由于输入矢量的大小,你不能比使用显式循环更好(否则你需要太多的内存)。但很明显,你只需要一个循环就可以解决这个问题。
这是我对你的问题的理解:
library(doParallel)
cl <- makeCluster(4)
registerDoParallel(cl)
fun_r <- function(t, beta) {
res <- foreach(i = seq_along(t)[-1], .combine = cbind) %dopar% {
d <- t[i] - t[seq_len(i - 1)]
c(sum(d^2 * exp(-beta * d)),
sum(d * exp(-beta * d)))
}
cbind(0, unname(res))
}
set.seed(42)
t <- sort(rnorm(1e4))
ttt <- fun_r(t, 0.5)
ttt[,1:10]
# [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
#[1,] 0 0.3223427 0.3571912 0.5101723 0.5369059 0.6072245 0.6420904 0.6625009 0.7287196 0.8478711
#[2,] 0 0.4800071 0.5391521 0.8341596 0.8901340 1.0569168 1.1455994 1.2034259 1.3972700 1.7177646
library(microbenchmark)
microbenchmark(fun_r(t, 0.5), times=5)
#Unit: seconds
# expr min lq median uq max neval
#fun_r(t, 0.5) 5.538867 5.558164 5.562138 5.567474 5.642002 5
stopCluster(cl)
如果这仍然太慢,您可以尝试使用Rcpp实现它。
答案 1 :(得分:0)
如果我正确理解您的方程式,您只需先单独计算t[i] - t[1:i-1]
,然后在所有后续计算中使用这些值。
t <- rnorm(10)
i <- 10
beta <- 1
tdiffs <- t[i]-t[1:i-1]
betaexp <- exp(-beta*tdiffs)
B <- sum(tdiffs^2*betaexp)
R <- sum(tdiffs*betaexp)