Search code examples
arraysmultidimensional-arrayrcpp

Indexing slice from 3D Rcpp NumericVector


Hi I have what I think must be a really simple Rcpp question regarding treating NumericVector objects as multidimensional arrays. I can't find an answer to what might be obvious. Apologies up front if this is the case -- my inexperience with C++ is to blame...

If I use the answer posted here a (Constructing 3D array in Rcpp) as an example

library("Rcpp")

cppFunction(code='
NumericVector arrayC(NumericVector input, IntegerVector dim) { 
  input.attr("dim") = dim;
  return input;
}
')

How do I extract/access an single slice / row / column out of the "intput" object?

I.e. Do something like

NumericMatrix X = input(_,_,i) 
// FYI -- I know this doesn't work! Simply trying to convey the point... 

And yes I know RcppArmadillo could be used. I have my reasons, for doing things this way but no need to bore folks with them.

Thanks.


Solution

  • Everything I wrote in the previous answer you cite still holds: doable, but possibly painful as you may need to write converters. Contributions would still be welcome.

    For what it is worth, I use the (Rcpp)Armadillo containers for three-dimensional data as they do have the slicing operators. Note that you can't easily convert them to something R likes ,ie I think we still automated converters for cube to lists of matrices.

    Edit: For what it is worth, here is a short loop from a recent GitHub project of mine:

    for (unsigned int j=k-1-1; j>0; j--) {
        arma::mat Ppred = AA.slice(j) * P.slice(j) * AA.slice(j).t() + QQ.slice(j);
        arma::mat lhs = (P.slice(j) * AA.slice(j).t());
        arma::mat rhs = Ppred;
        D.slice(j) = arma::solve(rhs.t(), lhs.t()).t();
        M.col(j) = M.col(j) + D.slice(j) * (M.col(j+1) - AA.slice(j) * M.col(j));
        P.slice(j) = P.slice(j) + D.slice(j) * 
                                 (P.slice(j+1) - Ppred) * D.slice(j).t();
    }
    

    This uses Armadillo slicing on both the left and right-hand sides. And this works rather well from R thanks to RcppArmadillo (modulo the aforementioned issue that because a R has no real native 3-d structure, so we can't pass a 3-d matrix back easily).