Rcpp:使用indexmatrix提取矩阵的子集

时间:2016-01-24 14:02:19

标签: r performance subset default-value rcpp

我有一个关于从矩阵到向量的子集的问题。用户可以明确地给出indexmatrix(这是一个与M大小相同的矩阵,如果不需要该条目则为0,如果必须提取该条目,则为1)。如果提供了indexmatrix,那么我们只是对它进行子集化,如果没有提供indexmatrix(indexmatrix = NULL),那么我们使用type1(采用true或false)来构建它。只有两种类型的索引矩阵是可能的。

我使用了提供的子集技术 Subset of a Rcpp Matrix that matches a logical statement

#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]
using namespace Rcpp;

// [[Rcpp::export]]
arma::colvec extractElementsRcpp(arma::mat M, 
         Rcpp::Nullable<Rcpp::NumericMatrix> indexmatrix = R_NilValue,
         bool type1 = false) {

  unsigned int D = M.n_rows;  // dimension of the data
  arma::mat indmatrix(D, D);  // initialize indexmatrix

  if (indexmatrix.isNotNull()) {
     // copy indexmatrix to numericmatrix
     Rcpp::NumericMatrix indexmatrixt(indexmatrix);
     // make indexmatrix into arma matrix indmatrix  
     indmatrix = Rcpp::as<arma::mat>(indexmatrixt);  
  } //else {
    // get indexmatrix
 //   Rcpp::NumericMatrix indexmatrixt = getindexmatrix(D, type1)["indexmatrix"]; 
 //   // make indexmatrix into arma matrix
 //   indmatrix = Rcpp::as<arma::mat>(indexmatrixt);  
 // }

  arma::colvec unM = M.elem(find(indmatrix == 1)); // extract wanted elements

  return(unM);
}

很有效!然而,速度并不是我所希望的。每当提供索引矩阵时,C ++代码比普通的R代码慢,而我的目标是在速度上有一个很好的改进。我觉得我正在复制太多的矩阵。但我是C ++的新手,并没有找到避免它的方法。

速度比较如下:

                                test replications elapsed relative
2 extractElementsR(M, indexmatrix = ind)      100   0.084     1.00
1 extractElementsRcpp(M, indexmatrix = ind)   100   0.142     1.69

编辑:R函数定义为

extractElementsR <- function (M, indexmatrix, type1 = FALSE) {
  D <- nrow(M)

#  # get indexmatrix, if necessary
#  if(is.null(indexmatrix)) indexmatrix <- getindexmatrix(D, type1 = type1)$indexmatrix

  # extract wanted elements
  return (M[which(indexmatrix > 0)])
}

例如,可以采用矩阵

M <- matrix(rnorm(1000^2), ncol = 1000)
indexmatrix <- matrix(1, 1000, 1000)
indexmatrix[lower.tri(indexmatrix)] <- 0

作为M和indexmatrix。

EDIT2:我在Rcpp函数中注释了else语句,并省略了R函数中的默认NULL值,因为它对我的问题并不重要。我想在提供indexmatrix时提高Rcpp函数的速度。但是,我想保留默认的NULL值(并在必要时创建和索引矩阵)。

1 个答案:

答案 0 :(得分:0)

你能否展示

  1. 函数extractElementR()以及
  2. 示例数据,以便这成为可重现的示例?
  3. 乍一看,你正在混合Rcpp和RcppArmadillo类型,以便与后者合并。这将创建大量的副本。我们现在可以用Rcpp(和Kevin在这里有一些答案)和RcppArmadillo(几个较旧的答案)进行索引,这样你甚至可以尝试两种不同的方式。