I've noticed that sourceCpp()
respects C++ #define
while devtools::document()
and R CMD build
seems to disregard them, at least in the case of Eigen matrix initialization.
Consider this .cpp file:
#define EIGEN_INITIALIZE_MATRICES_BY_ZERO
//[[Rcpp::depends(RcppEigen)]]
#include <RcppEigen.h>
//[[Rcpp::export]]
Eigen::MatrixXd initialize_matrix(int nrow, int ncol) {
return Eigen::MatrixXd(nrow, ncol);
}
One may source this file using sourceCpp
, and then run the following in R:
> initialize_matrix(5, 3)
[,1] [,2] [,3]
[1,] 0 0 0
[2,] 0 0 0
[3,] 0 0 0
[4,] 0 0 0
[5,] 0 0 0
Great, the matrix is initialized with zeros!
Now put the same .cpp file in an RcppEigen package and compile using devtools::document()
or R CMD build
.
> initialize_matrix(5, 3)
[,1] [,2] [,3]
[1,] 1.845608e-317 9.881313e-324 9.881313e-324
[2,] 1.107517e-311 0.000000e+00 0.000000e+00
[3,] 9.881313e-324 0.000000e+00 0.000000e+00
[4,] 0.000000e+00 2.121963e-314 9.881313e-324
[5,] 0.000000e+00 1.107517e-311 0.000000e+00
The matrix is not initialized with zeros, rather what looks like a memset.
Why does sourceCpp()
respect the pragma declaration while devtools::document()
ignores it during compilation?
I think, to be used in a package, you need to add -DEIGEN_INITIALIZE_MATRICES_BY_ZERO
to src/Makevars
,
e.g. as in https://github.com/privefl/bigstatsr/blob/master/src/Makevars#L2 (there are 2 flags for armadillo there).
Or maybe just a problem of ordering? Try putting the #define
after #include <RcppEigen.h>
.