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?
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
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...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With