Search code examples
rrcpparmadillo

Rcpp sugar commands in armadillo


I'm trying to use ifelse() command of Rcpp sugar with arma::vec. The code fails with error

'ifelse' was not declared in this scope

I could not find a solution. A simple example code (resulted with error) is below.

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

// [[Rcpp::export]]
arma::vec f(arma::vec x, arma::vec y) {
  arma::vec res1 = Rcpp::ifelse(x < y, x, y);
  arma::vec res = trans(res1)*y;
  return res;
}

/*** R
f(c(1,2,3),c(3,2,1))
*/

Solution

  • Using Armadillo's advanced constructors you can have Rcpp::NumericVector and arma::vec that refer to the same memory location. Then you can use both Rcpp functions and arma functions by using the correct front-end object for that piece of memory:

    #include <RcppArmadillo.h>
    // [[Rcpp::depends(RcppArmadillo)]]
    
    // [[Rcpp::export]]
    arma::vec f(Rcpp::NumericVector xr, Rcpp::NumericVector yr) {
      arma::vec x(xr.begin(), xr.size(), false, true); 
      arma::vec y(yr.begin(), yr.size(), false, true);
      Rcpp::NumericVector res1r(xr.size());
      arma::vec res1(res1r.begin(), res1r.size(), false, true);  
      res1r = Rcpp::ifelse(xr < yr, xr, yr);
      arma::vec res = trans(res1)*y;
      return res;
    }
    
    /*** R
    f(c(1,2,3),c(3,2,1))
    */
    

    I am not 100% sure that this does not have any unwanted side-effects.