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
Post a Comment