Rcpp的有效矩阵子集

问题描述 投票:2回答:1

我正在尝试找到一种有效的方法来为行和列的[[非连续集使用Rcpp子集矩阵:

m <- matrix(1:20000000, nrow=5000) rows <- sample(1:5000, 100) cols <- sample(1:4000, 100)
在R中,矩阵可以使用rowscols向量直接子集:

matrix_subsetting <- function(m, rows, cols){ return(m[rows, cols]) } m[rows, cols] # or matrix_subsetting(m, rows, cols)

到目前为止,我能找到的最快的

Rcpp

方法是:Rcpp::cppFunction(" NumericMatrix cpp_matrix_subsetting(NumericMatrix m, NumericVector rows, NumericVector cols){ int rl = rows.length(); int cl = cols.length(); NumericMatrix out(rl, cl); for (int i=0; i<cl; i++){ NumericMatrix::Column org_c = m(_, cols[i]-1); NumericMatrix::Column new_c = out(_, i); for (int j=0; j<rl; j++){ new_c[j] = org_c[rows[j]-1]; } } return(out); }")
但是相比之下,Rcpp版本要慢得多:

> microbenchmark::microbenchmark(matrix_subsetting(m, rows, cols), cpp_matrix_subsetting(m, rows, cols), times=500) Unit: microseconds expr min lq mean median uq max neval matrix_subsetting(m, rows, cols) 23.269 90.127 107.8273 130.347 135.3285 605.235 500 cpp_matrix_subsetting(m, rows, cols) 69191.784 75254.277 88484.9328 90477.448 95611.9090 178903.973 500

任何想法,至少要达到与Rcpp相当的速度?

我已经尝试过RcppArmadillo arma::mat::submat函数,但是它比我的版本慢。


解决方案:

cpp_matrix_subsetting代替IntegerMatrix实现NumericMatrix功能。

新基准:

> microbenchmark::microbenchmark(matrix_subsetting(m, rows, cols), cpp_matrix_subsetting(m, rows, cols), times=1e4) Unit: microseconds expr min lq mean median uq max neval matrix_subsetting(m, rows, cols) 41.110 60.261 66.88845 61.730 63.8900 14723.52 10000 cpp_matrix_subsetting(m, rows, cols) 43.703 61.936 71.56733 63.362 65.8445 27314.11 10000

c++ r rcpp
1个回答
2
投票
这是因为您有一个类型为m的矩阵integer(不是double所期望的NumericMatrix,所以这会复制整个矩阵(这会花费很多时间)。

例如,尝试使用m <- matrix(1:20000000 + 0, nrow=5000)

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.