[Rcpp-devel] speed fix
Richard Chandler
richard.chandlers at gmail.com
Mon Dec 27 13:57:41 CET 2010
Hi,
I am trying to speed up a vectorized R function without much luck. Perhaps
it is not possible, but if it is could someone suggest how to improve the
C++/Rcpp code below? The speed is approximately equal on a 64-bit version of
R, but the R code is much faster when using 32-bit R (on windows). Here's an
example.
# R function
nllR <- function(y, psi, p, nd) {
cp <- (p^y) * ((1 - p)^(1 - y))
cp <- exp(rowSums(log(cp))) # faster than: apply(cp, 1, prod)
loglik <- log(cp * psi + nd * (1 - psi))
-sum(loglik)
}
# Rcpp function
nllRcpp <- cxxfunction(signature(yR="matrix", psiR="numeric", pR="matrix",
ndR="integer"),
'
NumericMatrix y(yR);
NumericVector psi(psiR);
NumericMatrix p(pR);
IntegerVector nd(ndR);
NumericVector yV(y);
int R = y.nrow();
int J = y.ncol();
NumericMatrix cp(R, J);
NumericVector ll(R);
NumericVector cpsum(R);
for(int i=0; i<R; i++) {
for(int j=0; j<J; j++) {
cp(i,j) = pow(p(i,j), y(i,j)) * pow(1-p(i,j), 1-y(i,j));
}
NumericVector cpi = cp(i, _);
cpsum[i] = exp(sum(log(cpi)));
ll[i] = log(cpsum[i] * psi[i] + nd[i] * (1-psi[i]));
}
double nll = -1*sum(ll);
return wrap(nll);
', plugin="Rcpp")
# Test
M <- 10000
J <- 100
psi <- runif(M)
Z <- rbinom(M, 1, psi)
p <- matrix(runif(M*J), M, J)
y <- matrix(rbinom(M*J, 1, p*Z), M, J)
nd <- ifelse(rowSums(y, na.rm=TRUE) == 0, 1, 0)
all.equal(nllR(y, psi, p, nd), nllRcpp(y, psi, p, nd))
# 64-bit
> benchmark(nllR(y, psi, p, nd), nllRcpp(y, psi, p, nd))
test replications elapsed relative user.self
1 nllR(y, psi, p, nd) 100 10.58 1.046489 9.35
2 nllRcpp(y, psi, p, nd) 100 10.11 1.000000 9.81
sys.self user.child sys.child
1 1.14 NA NA
2 0.26 NA NA
# 32-bit
> benchmark(nllR(y, psi, p, nd), nllRcpp(y, psi, p, nd))
test replications elapsed relative user.self
1 nllR(y, psi, p, nd) 100 16.75 1.000000 15.54
2 nllRcpp(y, psi, p, nd) 100 29.97 1.789254 29.81
sys.self user.child sys.child
1 1.08 NA NA
2 0.01 NA NA
> sessionInfo()
R version 2.12.0 (2010-10-15)
Platform: x86_64-pc-mingw32/x64 (64-bit)
...
attached base packages:
[1] stats graphics grDevices utils datasets methods
[7] base
other attached packages:
[1] rbenchmark_0.3 inline_0.3.8 RcppArmadillo_0.2.10
[4] Rcpp_0.9.0
loaded via a namespace (and not attached):
[1] tools_2.12.0
>
Thanks,
Richard
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.r-forge.r-project.org/pipermail/rcpp-devel/attachments/20101227/70057632/attachment.htm>
More information about the Rcpp-devel
mailing list