Question

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.

Was it helpful?

Solution 2

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).

OTHER TIPS

Rcpp11 has Array for this, templated with both the dimension depth and the R type.

For example, you could do:

#include <Rcpp.h>
using namespace Rcpp ;

typedef Array<3,REALSXP> Numeric3D ; 

// [[Rcpp::export]]
Numeric3D test(){
  Numeric3D res(2,3,4) ;
  for( int i=0; i<2; i++)
    for( int j=0; j<3; j++)
      for( int k=0; k<4; k++)
        res(i,j,k) = i+j+k ;
  return res ;
}

/*** R
  test()
*/

All the relevant indexing logic is in the Index class template. The implementation uses C++11 variadic templates.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top