0
votes

I'm writing a package with some functions calling RcppArmadillo::sample from RcppArmadillo. However I met the following error when compiling.

In file included from Citrus.cpp:2: ./R/x86_64-unknown-linux-gnu-library/3.0/RcppArmadillo/include/RcppArmadilloExtensions/sample.h: In function ‘T Rcpp::RcppArmadillo::sample(const T&, int, bool, Rcpp::NumericVector) [with T = arma::subview_col]’: Citrus.cpp:241: instantiated from here ./R/x86_64-unknown-linux-gnu-library/3.0/RcppArmadillo/include/RcppArmadilloExtensions/sample.h:45: error: ‘const struct arma::subview_col’ has no member named ‘size’ ./R/x86_64-unknown-linux-gnu-library/3.0/RcppArmadillo/include/RcppArmadilloExtensions/sample.h:48: error: no matching function for call to ‘arma::subview_col::subview_col(const int&)’ ./R/x86_64-unknown-linux-gnu-library/3.0/RcppArmadillo/include/armadillo_bits/subview_bones.hpp:236: note: candidates are: arma::subview_col::subview_col() [with eT = double] ./R/x86_64-unknown-linux-gnu-library/3.0/RcppArmadillo/include/armadillo_bits/subview_meat.hpp:2608: note: arma::subview_col::subview_col(const arma::Mat&, arma::uword, arma::uword, arma::uword) [with eT = double] ./R/x86_64-unknown-linux-gnu-library/3.0/RcppArmadillo/include/armadillo_bits/subview_meat.hpp:2597: note: arma::subview_col::subview_col(const arma::Mat&, arma::uword) [with eT = double] ./R/x86_64-unknown-linux-gnu library/3.0/RcppArmadillo/include/armadillo_bits/forward_bones.hpp:29: note: arma::subview_col::subview_col(const arma::subview_col&) make: *** [Citrus.o] Error 1

The RcppArmadillo I'm using is 0.7.700.0.0.

The same error appeared on both linux and OSX. When compiling using Rstudio, the error message as follows: no member named 'size' in 'arma::subview_col<double>'. no matching constructor for initialization of 'arma::subview_col<double>'

I used RcppArmadillo::sample in my previous work a lot. It suddenly doesn't work. I appreciate any help.

1
This isn't really helpful without context as to what you were trying to accomplish. RcppArmadilloExtensions/sample.h has lots of tests so I'm a bit skeptical here.coatless
Your compiler may be too old. That you are installing via a R 3.0.0 (about three years old / out-of-date) is a bit of a tell.Dirk Eddelbuettel

1 Answers

1
votes

This feature works on pre-subset data in either arma::vec or NumericVector Always has and always will. Do not use this with an intermediary vector obtained from a subset operation (e.g. .col(), .cols(), or .submat()).


The issue you are running into is you've decided to subset the data within the call to sample. (You've omitted code to diagnose this part, so I'm speculating here.) Since sample() needs to work with both Rcpp and Armadillo data types there never was a call to Armadillo specific size member functions. Instead, the library opted to call the .size() member function of an STL container, which armadillo supported, since that was shared between both objects. However, armadillo limits where the member function was implemented to the "active" data structures and not temporaries. As a result, the .size() member function was not implemented for subview_col. So, we end up with the error of:

error: ‘const struct arma::subview_col’ has no member named ‘size’


To get around this limitation and save memory, use an advanced vec ctor that will reuse memory and, thus, avoiding the need for an intermediary arma::subview_col to be created.

// [[Rcpp::depends(RcppArmadillo)]]
#include <RcppArmadillo.h>

#include <RcppArmadilloExtensions/sample.h>

// [[Rcpp::export]]
void adv_rnd(int nrow, int ncol, bool replace = true){
    // Create a matrix of given dimensions
    arma::mat X(nrow, ncol);
    X.randn();

    // Show state before randomization
    Rcpp::Rcout << "Before Randomization:" << std::endl << X << std::endl;

    // Randomize each column
    for(int i = 0; i < ncol; ++i){
        arma::vec Y(X.colptr(i), nrow, false, true);
        X.col(i) = Rcpp::RcppArmadillo::sample(Y, nrow, replace);
    }

    // Show state after randomization
    Rcpp::Rcout << "After Randomization:" << std::endl << X << std::endl;

}

Sample output:

> adv_rnd(3,3)
Before Randomization:
  -0.7197   1.2590  -0.5898
   0.0253   0.1493  -0.0685
  -0.6074   1.3843   0.0400

After Randomization:
  -0.7197   1.2590   0.0400
  -0.6074   1.2590  -0.5898
  -0.6074   0.1493  -0.0685