Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Selecting a non-contiguous submatrix in Rcpp

Tags:

c++

r

rcpp

I am trying to select a submatrix in Rcpp with non-contiguous slices. The equivalent R code is

> xx = matrix(0,nrow=10,ncol=8)
> xx[,c(1,3,4)]
      [,1] [,2] [,3]
 [1,]    0    0    0
 [2,]    0    0    0
 [3,]    0    0    0
 [4,]    0    0    0
 [5,]    0    0    0
 [6,]    0    0    0
 [7,]    0    0    0
 [8,]    0    0    0
 [9,]    0    0    0
[10,]    0    0    0

In Rcpp, I am tried to do

Rcpp::NumericMatrix xx(10,8);
Rcpp::NumericMatrix aa = xx(Rcpp::Range(0,9), Rcpp::NumericVector::create(1,3,4));

However, this gives

error: no match for call to '(Rcpp::NumericMatrix) (Rcpp::Range, Rcpp::Vector<14>)'
/opt/local/lib/R/library/Rcpp/include/Rcpp/vector/Matrix.h:126: note: candidates are: typename Rcpp::Vector<RTYPE>::Proxy Rcpp::Matrix<RTYPE>::operator()(const size_t&, const size_t&) [with int RTYPE = 14]
/opt/local/lib/R/library/Rcpp/include/Rcpp/vector/Matrix.h:132: note:                 typename Rcpp::Vector<RTYPE>::Proxy Rcpp::Matrix<RTYPE>::operator()(const size_t&, const size_t&) const [with int RTYPE = 14]
/opt/local/lib/R/library/Rcpp/include/Rcpp/vector/Matrix.h:142: note:                 Rcpp::MatrixRow<RTYPE> Rcpp::Matrix<RTYPE>::operator()(int, Rcpp::internal::NamedPlaceHolder) [with int RTYPE = 14]
/opt/local/lib/R/library/Rcpp/include/Rcpp/vector/Matrix.h:146: note:                 Rcpp::MatrixColumn<RTYPE> Rcpp::Matrix<RTYPE>::operator()(Rcpp::internal::NamedPlaceHolder, int) [with int RTYPE = 14]
/opt/local/lib/R/library/Rcpp/include/Rcpp/vector/Matrix.h:150: note:                 Rcpp::SubMatrix<RTYPE> Rcpp::Matrix<RTYPE>::operator()(const Rcpp::Range&, const Rcpp::Range&) [with int RTYPE = 14]
/opt/local/lib/R/library/Rcpp/include/Rcpp/vector/Matrix.h:154: note:                 Rcpp::SubMatrix<RTYPE> Rcpp::Matrix<RTYPE>::operator()(Rcpp::internal::NamedPlaceHolder, const Rcpp::Range&) [with int RTYPE = 14]
/opt/local/lib/R/library/Rcpp/include/Rcpp/vector/Matrix.h:158: note:                 Rcpp::SubMatrix<RTYPE> Rcpp::Matrix<RTYPE>::operator()(const Rcpp::Range&, Rcpp::internal::NamedPlaceHolder) [with int RTYPE = 14]

Is this possible in Rcpp?

like image 643
highBandWidth Avatar asked Dec 08 '11 17:12

highBandWidth


2 Answers

Here's how I've done it:

library(inline)

testSlice = cxxfunction(signature(r_mat='int', r_cols='int'), body = 
'
NumericMatrix mat (r_mat);
NumericVector cols (r_cols);

NumericMatrix matslice (mat.nrow(), cols.size());

for (int i=0; i<cols.size(); i++) {
  matslice(_,i) = mat(_, cols(i)-1);
}

return(matslice);
'
, plugin='Rcpp')
> xx = matrix(sample(10, 10*10, replace=T), nrow=10)
> xx
      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
 [1,]    6    7    9    8    2    6    1    8   10     8
 [2,]    5    6    9    5    1    5    2    7   10     3
 [3,]    9    5    1   10    8   10   10    1    2     7
 [4,]    2    7    1    4    5    1    8    2   10     9
 [5,]    6    6    9    8    3    1    2   10    2     1
 [6,]    4    6    7    9    7    5    4    7   10    10
 [7,]   10   10    8    8   10    7   10    4    6     3
 [8,]    6    3   10    6    3    2    5    4    1    10
 [9,]    8    7    2    7    9    7    7    8    3    10
[10,]    5    4    5    4    4    8   10    1    5     4

> testSlice(xx, c(2,5,6))
      [,1] [,2] [,3]
 [1,]    7    2    6
 [2,]    6    1    5
 [3,]    5    8   10
 [4,]    7    5    1
 [5,]    6    3    1
 [6,]    6    7    5
 [7,]   10   10    7
 [8,]    3    3    2
 [9,]    7    9    7
[10,]    4    4    8
like image 168
John Colby Avatar answered Sep 28 '22 19:09

John Colby


The help file for NumericMatrix: http://dirk.eddelbuettel.com/code/rcpp/html/classMatrix.html

It shows that there are no methods that take a Range and a NumericVector, only two Ranges or an "_" and a range... So there is no direct way of selecting non-contiguous slices...

like image 22
Tommy Avatar answered Sep 28 '22 18:09

Tommy