単純な繰り返しループの集計計算がかなり時間がかかるので、Rcppでどれくらい改善されるか挑戦
まずは通常のコード
非常に単純で以下のxとBeta,Alphaの線形結合のquantileを求めるというもの。
x <- rnorm(100) Beta <- Alpha <- rnorm(1000000) res1 <- sapply(1:length(x), function(i) quantile(exp(Beta*x[i]+Alpha)/(1+exp(Beta*x[i]+Alpha)),probs=0.025))次にRcpp+inline
library(Rcpp) library(inline) src <- "NumericVector xx(x); NumericVector beta(b); NumericVector alpha(a); Function quantile(\"quantile\"); int xsize=xx.size(), bsize=beta.size(); NumericVector mu(bsize); NumericVector res(xsize); for(unsigned long int i=0; i < xsize; i++){ for(unsigned long int j=0; j < bsize; j++){ double dummy=exp(beta[j]*xx[i]+alpha[j]); mu[j]=0.0; mu[j]=dummy/(1.0+dummy); } res[i]=0.0; res[i]=as結果(quantile(mu, _[\"probs\"]=0.025)); } return res;" fun.R <- cxxfunction(signature(x="numeric",a="numeric",b="numeric"), src,plugin="Rcpp")
x <- rnorm(100) Beta <- Alpha <- rnorm(1000000) system.time(res1 <- sapply(1:length(x), function(i) quantile(exp(Beta*x[i]+Alpha)/(1+exp(Beta*x[i]+Alpha)),probs=0.025))) ユーザ システム 経過 19.162 1.008 20.169 system.time(res2 <- fun.R(x,Beta,Alpha)) ユーザ システム 経過 8.936 0.932 9.870計算結果も同じだった
summary(res1-res2) Min. 1st Qu. Median Mean 3rd Qu. Max. 0 0 0 0 0 0RcppでRの関数を使うのではなく、GNU Scientific Library (GSL)のquantile(gsl_stats_quantile_from_sorted_data)も試してみたけどこちらは通常のRの1.5倍ぐらいの時間がかかった.... 何がボトルネックなんだろう...
0 件のコメント:
コメントを投稿