我正在尝试使用R
来加速Rcpp
代码,该代码采用长度为L(psi)的向量和一个维度矩阵(L,L),并执行一些元素操作。有没有更有效的方法来使用Rcpp进行这些元素操作?
r:
UpdateLambda <- function(psi,phi){
# updated full-day infection probabilites
psi.times.phi <- apply(phi,1,function(x) x*psi)
## return Lambda_{i,j} = 1 - \prod_{j} (1 - \psi_{i,j,t} \phi_{i,j})
apply(psi.times.phi,2,function(x) 1-prod(1-x))
}
CPP:
#include <Rcpp.h>
#include <algorithm>
using namespace Rcpp;
// [[Rcpp::export]]
NumericVector UpdateLambdaC(NumericVector psi,
NumericMatrix phi
){
int n = psi.size();
NumericMatrix psi_times_phi(n,n);
NumericVector tmp(n,1.0);
NumericVector lambda(n);
for(int i=0; i<n;i++){
psi_times_phi(i,_) = psi*phi(i,_);
}
for(int i=0; i<n;i++){
// \pi_{j} (1- \lambda_{i,j,t})
for(int j=0; j<n;j++){
tmp[i] *= 1-psi_times_phi(i,j);
}
lambda[i] = 1-tmp[i];
}
return lambda;
}
答案 0 :(得分:1)
您可以使用矢量化替代方案替换apply
循环。
第一个相当于:
t(phi)*psi
第二个:
1-exp(colSums(log(1-psi.times.phi)))
#test data
phi <- matrix(runif(1e6),1e3)
psi <- runif(1e3)
#new function
UpdateLambda2 <- function(psi,phi) 1-exp(colSums(log(1-t(phi)*psi)))
#sanity check
identical(UpdateLambda(psi,phi),UpdateLambda2(psi,phi))
[1] TRUE
#timings
library(rbenchmark)
benchmark(UpdateLambda(psi,phi),UpdateLambda2(psi,phi))
test replications elapsed relative user.self sys.self
1 UpdateLambda(psi, phi) 100 16.05 1.041 15.06 0.93
2 UpdateLambda2(psi, phi) 100 15.42 1.000 14.19 1.19
好吧,它似乎没有太大的区别,这是非常令人惊讶的,因为colSums
通常比apply
快得多。我不确定我使用的测试数据是否相关,因为输出是全部1
的第二部分中由于数量小于1的乘法数。如果你想记下这些小数字的细节,你最好还是以对数比例工作。