Search code examples
rrcpp

Index element from list in Rcpp


Suppose I have a List in Rcpp, here called x containing matrices. I can extract one of the elements using x[0] or something. However, how do I extract a specific element of that matrix? My first thought was x[0](0,0) but that does not seem to work. I tried using * signs but also doesn't work.

Here is some example code that prints the matrix (shows matrix can easily be extracted):

library("Rcpp")

cppFunction(
includes = ' 
NumericMatrix RandMat(int nrow, int ncol)
 {
  int N = nrow * ncol;
  NumericMatrix Res(nrow,ncol);
  NumericVector Rands  = runif(N);
   for (int i = 0; i < N; i++) 
  {
    Res[i] = Rands[i];
  }
  return(Res);
 }',

code = '
void foo()
{
  List x;
  x[0] = RandMat(3,3);
  Rf_PrintValue(wrap( x[0] )); // Prints first matrix in list.
}
')


foo()

How could I change the line Rf_PrintValue(wrap( x[0] )); here to print the the element in the first row and column? In the code I want to use it for I need to extract this element to do computations.


Solution

  • Quick ones:

    1. Compound expression in C++ can bite at times; the template magic gets in the way. So just assign from the List object to a whatever the element is, eg a NumericMatrix.

    2. Then pick from the NumericMatrix as you see fit. We have row, col, element, ... access.

    3. Printing can be easier using Rcpp::Rcout << anElement but note that we currently cannot print entire matrices or vectors -- but the int or double types are fine.

    Edit:

    Here is a sample implementation.

    #include <Rcpp.h>
    
    // [[Rcpp::export]]
    double sacha(Rcpp::List L) {
        double sum = 0;
        for (int i=0; i<L.size(); i++) {
            Rcpp::NumericMatrix M = L[i];
            double topleft = M(0,0);
            sum += topleft;
            Rcpp::Rcout << "Element is " << topleft << std::endl;
        }
        return sum;    
    }
    
    /*** R
    set.seed(42)
    L <- list(matrix(rnorm(9),3), matrix(1:9,3), matrix(sqrt(1:4),2))
    sacha(L) # fix typo   
    */
    

    And its result:

    R> Rcpp::sourceCpp('/tmp/sacha.cpp')
    
    R> set.seed(42)
    
    R> L <- list(matrix(rnorm(9),3), matrix(1:9,3), matrix(sqrt(1:4),2))
    
    R> sacha(L)
    Element is 1.37096
    Element is 1
    Element is 1
    [1] 3.37096
    R>