使用 Rcpp 的高效矩阵子集
Efficient Matrix subsetting with Rcpp
我正在尝试找到一种有效的方法来使用 Rcpp 对一组非连续的行和列进行矩阵子集:
m <- matrix(1:20000000, nrow=5000)
rows <- sample(1:5000, 100)
cols <- sample(1:4000, 100)
在 R 中,矩阵可以使用rows
和cols
向量直接子集:
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
功能,但它比我的版本慢。
使用IntegerMatrix
而不是NumericMatrix
实现cpp_matrix_subsetting
函数。
新基准:
> 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
这是因为您有一个类型为integer
的矩阵m
(不像NumericMatrix
期望的那样double
(,因此这会复制整个矩阵(这需要花费大量时间(。
例如,请尝试改用m <- matrix(1:20000000 + 0, nrow=5000)
。
相关文章:
- C++中高效的大型稀疏块压缩线性方程
- C++中的高效循环缓冲区,它将被传递给C样式数组函数参数
- 给定一个向量,如何找到该向量的所有子集和的原始索引
- 如何在C++中高效地构造随机骰子
- 如何实现高效的算法来计算大型数据集的多个不同值?
- 在子集化后将包含索引号的列表列表映射到标准索引序列
- 显示字符串的集合和子集
- 更高效地在微控制器上对C++进行基准测试
- 从C++无序集合中高效提取元素
- 高效的字符串截断算法,按顺序删除相等的前缀和后缀
- 用于子集字符串的 Rcpp 函数
- C++中特征对角矩阵类型的高效存储
- 为什么我的子集和方法不正确?
- 计算总和为 x 的所有整数子集(包括负数)
- 高效简单的结构比较运算符
- 在尝试使用递归查找集合子集的总数时,我遇到了分割错误
- 从小于或等于某个 N 的数字列表中最小化或找到 n 个理想的子集和
- 使用 Rcpp 的高效矩阵子集
- 对定义顺序的向量的子集进行高效排序
- C++:从只能通过迭代器访问的数据类型中高效地提取元素子集