I am developing some functions in Rcpp that work with big.matrix objects from the bigmemory package. These objects are passed to Rcpp as SEXP objects, which then need to be passed to XPtr<BigMatrix> , and then to the MatrixAccessor object to access the matrix elements.
For example, if I want to implement a function that receives a diagonal:
#include <Rcpp.h> using namespace Rcpp; // [[Rcpp::depends(BH, bigmemory) #include <bigmemory/MatrixAccessor.hpp> #include <numeric> // [[Rcpp::export]] NumericVector GetDiag(SEXP pmat) { XPtr<BigMatrix> xpMat(pMat); // allows you to access attributes MatrixAccessor<double> mat(*xpMat); // allows you to access matrix elements NumericVector diag(xpMat->nrow()); // Assume matrix is square for (int i = 0; i < xpMat->nrow(); i++) { diag[i] = mat[i][i]; } return diag; }
This function works beautifully if the big.matrix object in R is filled with doubles.
However, if you call this function on an integer matrix (for example, diag(as.big.matrix(matrix(1:9, 3))@address) ), you get garbage as a result because MatrixAccessor was initialized as <double> .
Internally, big.matrix objects can have four types:
void typeof(SEXP pMat) { XPtr<BigMatrix> xpMat(pMat); int type = xpMat->matrix_type(); type == 1
Since all we do is access the matrix elements, the diag function should be able to handle each of these types. But for now, since our signature NumericVector , I will ignore the character matrices.
To handle this, I decided that I could just specify the switch statement by initializing the corresponding mat with the appropriate type at runtime:
However, this leads to compiler errors, because I override mat after it was declared already in the first case .
The only way I can do this is to write three different diag functions, one for each type, whose code is the same, except for the initialization mat . Is there a better way?