celestialgod

rle_Rcpp

Mar 27th, 2015
357
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
R 1.42 KB | None | 0 0
  1. library(Rcpp)
  2. library(RcppArmadillo)
  3. sourceCpp(code = '
  4. // [[Rcpp::depends(RcppArmadillo)]]
  5. #include <RcppArmadillo.h>
  6. using namespace Rcpp;
  7. using namespace arma;
  8.  
  9. template <int RTYPE>
  10. List rle_template(const Vector<RTYPE>& x) {
  11.  IntegerVector tmp = seq_len(x.size()-1);
  12.  LogicalVector loc = head(x, x.size()-1) != tail(x, x.size()-1);
  13.  IntegerVector y = tmp[loc | is_na(loc)];
  14.  y.push_back(x.size());
  15.  Col<int> y2(y.begin(), y.size());
  16.  y2.insert_rows(0, zeros< Col<int> >(1));
  17.  IntegerVector y3 = wrap(y2);
  18.  return List::create(Named("lengths") = diff(y3),
  19.    Named("values") = x[y-1]);
  20. }
  21.  
  22. // [[Rcpp::export]]
  23. List rle_cpp(SEXP x){
  24.  switch( TYPEOF(x) ) {
  25.  case INTSXP: return rle_template<INTSXP>(x);
  26.  case REALSXP: return rle_template<REALSXP>(x);
  27.  case STRSXP: return rle_template<STRSXP>(x);
  28.  }
  29.  return R_NilValue;
  30. }')
  31.  
  32. x <- rev(rep(6:10, 1:5))
  33. all.equal(rle(x), rle_cpp(x), check.attributes = FALSE)
  34. # TRUE
  35.  
  36. N = 100000
  37. testVector = rep(sample(1:150, round(N/10), TRUE),
  38.   sample(1:25, round(N/10), TRUE))
  39. all.equal(rle(testVector), rle_cpp(testVector),
  40.   check.attributes = FALSE)
  41. # TRUE
  42. library(rbenchmark)
  43. benchmark(rle(testVector), rle_cpp(testVector),
  44.   columns = c("test", "replications","elapsed",
  45.   "relative"), replications=100, order="relative")
  46. #         test replications elapsed relative
  47. # 2 rle_cpp(x)          100    0.34    1.000
  48. # 1     rle(x)          100    2.53    7.441
Advertisement
Add Comment
Please, Sign In to add comment