I have a program in which I need to calculate repeatedly the column means of each slice of a cube X(nRow, nCol, nSlice)
in Rcpp, with the resulting means forming a matrix M(nCol, nSlice)
. The following code produced an error:
#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]
using namespace Rcpp;
using namespace arma;
// [[Rcpp::export]]
mat cubeMeans(arma::cube X){
int nSlice = X.n_slices;
int nCol = X.n_cols;
int nRow = X.n_rows;
arma::vec Vtmp(nCol);
arma::mat Mtmp(nRow, nCol);
arma::mat Means(nCol, nSlice);
for (int i = 0; i < nSlice; i++){
Mtmp = X.slice(i);
for(int j = 0; j < nCol; j++){
Vtmp(j) = sum(Mtmp.col(j))/nRow;
}
Means.col(i) = Vtmp;
}
return(wrap(Means));
}
'/Rcpp/internal/Exporter.h:31:31: error: no matching function for call to 'arma::Cube::Cube(SEXPREC*&)'
I couldn't quite figure it out. I didn't get the error when the input of the function was a matrix (and returned a vector). However, I included the above function as part of my main program i.e.
#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]
using namespace Rcpp;
using namespace arma;
mat cubeMeans(arma::cube X){
int nSlice = X.n_slices;
...
return(Means);
}
// [[Rcpp::export]]
main part of program
The program compiled successfully, but it is painfully slow (almost as slow as the R version of the program using colMeans
). Is there a better way to calculate column means on a cube, and why am I getting that compilation error?
I'd appreciate any help.
Regards,
I also received this error when attempting to use an
arma::cube
as an Rcpp function parameter.Based on the compiler error, I believe this is because there is no† After reading a couple of related examples online, it looks like the typical workaround is to read in your RRcpp::wrap<arma::cube>
currently defined (which is needed to handle the R object you would pass to the function).array
as aNumericVector
, and since it retains itsdims
attribute, use these to set yourarma::cube
dimensions. Despite the fact that there is an extra step or two required to account for themissing†, the Armadillo version I put together seems to be quite a bit faster than my R solution:wrap
specializationwhere I am taking advantage of the fact that the
arma::mean
function overload forarma::mat
s will calculate column means by default (arma::mean(x.slice(i), 1)
would give you the row means of that slice).Edit: † On second thought, I'm not really sure if this has to do with
Rcpp::wrap
or not - but the issue seems to be related to a missingExporter<>
specialization forarma::cube
- line 31 of Rcpp's Exporter.h:Regardless,
NumericVector
/ setting dimensions approach I used seems to be functional solution for now.Based on the output dimensions you described in your question, I assumed you wanted each column of the resulting matrix to be a vector of column means of the corresponding array slice (column 1 = column means of slice 1, etc...), i.e.
but it would be trivial for you to alter this if needed.