Reputation: 660
Generally when we write a function in c++ to parse a 2D array, it passes through the first row then move to the second row.
for(int i = 0; i < ROW_SIZE; i++){
for(int j = 0; j < COL_SIZE; j++){
*((Mat+i*COL_SIZE) + j) = value;
}
}
However, when I use Rcpp::NumericMatrix it parses through columns first.
// [[Rcpp::export]]
NumericMatrix TestMatrixParsing(){
NumericMatrix xx(4, 5);
int xsize = xx.nrow() * xx.ncol();
for (int i = 0; i < xsize; i++) {
xx[i] = i+100;
}
return xx;
}
/*** R
TestMatrixParsing()
# [,1] [,2] [,3] [,4] [,5]
# [1,] 100 104 108 112 116
# [2,] 101 105 109 113 117
# [3,] 102 106 110 114 118
# [4,] 103 107 111 115 119
*/
Is there any way to force it to parse through rows as my previous code was written to have matrix stored as consecutive rows so pointer doesn't have to jump equal to the COL_SIZE.
Upvotes: 0
Views: 275
Reputation: 26823
Rcpp::NumericMatrix
just follows the way R lays out its memory, which is in column major mode. A simple solution would be to transpose the matrix:
#include <Rcpp.h>
// [[Rcpp::export]]
Rcpp::NumericMatrix TestMatrixParsing(){
Rcpp::NumericMatrix xx(4, 5);
int xsize = xx.nrow() * xx.ncol();
xx = Rcpp::transpose(xx);
for (int i = 0; i < xsize; ++i) {
xx[i] = i + 100;
}
xx = Rcpp::transpose(xx);
return xx;
}
/*** R
TestMatrixParsing()
# [,1] [,2] [,3] [,4] [,5]
# [1,] 100 101 102 103 104
# [2,] 105 106 107 108 109
# [3,] 110 111 112 113 114
# [4,] 115 116 117 118 119
*/
That might be to expensive for large matrices though. In that case it is probably best to adapt your algorithm.
Upvotes: 2