r - Rcpp swap function with NumericVector -


as exploring rcpp came realization following swap function

// swap.cpp #include <rcpp.h> using namespace rcpp;  // [[rcpp::export]] void swap(numericvector x) {   double tmp = x[0];   x[0] = x[1];   x[1] = tmp; } 

does not perform swap when passed integer vector. example,

x <- 1:2 str(x) # int [1:2] 1 2 swap(x) x # [1] 1 2 

however,

y <- c(1,2) str(y) # num [1:2] 1 2 swap(y) y # [1] 2 1 

works fine. suspicion when swap passed integer vector x forced make copy of x converted numericvector. performed on copy of x not effect original variable passed. reasoning correct? if so, why conversion have result in copy? there way write more robust swap function in wouldn't have worry accidentally passing integer vector when should passing numeric vector?

i apologize if question has been asked before, not find suitable answer.

edit:

the code below indeed show copy of object made when integer vector passed swap instead of numeric vector.

// [[rcpp::export]] void where(sexp x) {   rcout << x << std::endl; }  // [[rcpp::export]] void swap(numericvector x) {   double tmp = x[0];   x[0] = x[1];   x[1] = tmp;   rcout << "during swap function: " << x << std::endl; }  /*** r test_swap <- function(x) {   cat("before swap function: ")    cat(where(x))   swap(x)   cat("after swap function: ")    cat(where(x)) }  y <- c(1, 2) // type num x <- 1:2 // type int  test_swap(y) // swap works because type matches function #> before swap function: 0x116017bf8 #> during swap function: 0x116017bf8 #> after swap function: 0x116017bf8  test_swap(x) // swap not work because type not match function #> before swap function: 0x10d88e468 #> during swap function: 0x116015708 #> after swap function: 0x10d88e468 */ 

building on @r2evans' comments, here's minimal implementation:

#include <rcpp.h>  template <int t> void swap_templ(rcpp::vector<t> x) {   double tmp = x[0];   x[0] = x[1];   x[1] = tmp; } // [[rcpp::export]] void swap(sexp x) {   switch (typeof(x)) {   case intsxp:      swap_templ<intsxp>(x);     break;   case realsxp:     swap_templ<realsxp>(x);     break;   default:     rcpp::rcout <<       "\ninput vector must numeric or integer type" <<       std::endl;     break;   } }  /*** r iv <- 1l:3l dv <- 1:3 + 0.5  r> class(iv) [1] "integer"  r> class(dv) [1] "numeric"  r> swap(iv); iv [1] 2 1 3  r> swap(dv); dv [1] 2.5 1.5 3.5  r> class(iv) [1] "integer"  r> class(dv) [1] "numeric" */ 

Comments

Popular posts from this blog

javascript - oscilloscope of speaker input stops rendering after a few seconds -

javascript - gulp-nodemon - nodejs restart after file change - Error: listen EADDRINUSE events.js:85 -

Fatal Python error: Py_Initialize: unable to load the file system codec. ImportError: No module named 'encodings' -