Advertisement
celestialgod

dist_test (c++ part)

Oct 27th, 2016
152
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.05 KB | None | 0 0
  1. // [[Rcpp::depends(RcppArmadillo)]]
  2. #include <RcppArmadillo.h>
  3. // [[Rcpp::depends(RcppParallel)]]
  4. #include <RcppParallel.h>
  5. #include <string>
  6. using namespace arma;
  7.  
  8. void chk_mat(const mat& x, const std::string& varName, const std::string& type){
  9.   if (!is_finite(x))
  10.     Rcpp::stop(varName + " must be numerical.\n");
  11. }
  12.  
  13. arma::vec quantileCpp(const arma::vec& x, const arma::vec& probs){
  14.   chk_mat(x, "x", "double");
  15.   chk_mat(probs, "probs", "double");
  16.   if (any(probs < 0) || any(probs > 1))
  17.     Rcpp::stop("There is values in probs outside [0, 1].");
  18.  
  19.   vec x_sort = sort(x);
  20.   vec index = (x.n_elem - 1) * probs;
  21.   uvec lo = conv_to<uvec>::from(floor(index)), hi = conv_to<uvec>::from(ceil(index));
  22.   vec h = (index - conv_to<vec>::from(lo));
  23.   vec qs = (1 - h) % x_sort.elem(lo) + h % x_sort.elem(hi);
  24.   return qs;
  25. }
  26.  
  27. struct Worker_bs_stat: public RcppParallel::Worker {
  28.   const vec& X;
  29.   const vec& Y;
  30.   const vec& probs;
  31.   mat& bsStat;
  32.  
  33.   Worker_bs_stat(const vec& X, const vec& Y, const vec& probs, mat& bsStat):
  34.     X(X), Y(Y), probs(probs), bsStat(bsStat) {}
  35.  
  36.   void operator()(std::size_t begin, std::size_t end)
  37.   {
  38.     for (uword i = begin; i < end; ++i)
  39.     {
  40.       uvec indx_x = randi<uvec>(X.n_elem, distr_param(0, X.n_elem-1));
  41.       uvec indx_y = randi<uvec>(Y.n_elem, distr_param(0, Y.n_elem-1));
  42.       bsStat.col(i) = quantileCpp(X.elem(indx_x), probs) - quantileCpp(Y.elem(indx_y), probs);
  43.     }
  44.   }
  45. };
  46.  
  47. // [[Rcpp::export]]
  48. arma::vec dist_test(const arma::vec& X, const arma::vec& Y, const arma::vec& probs, const double& bsSize){
  49.   // check data
  50.   chk_mat(X, "X", "double");
  51.   chk_mat(Y, "Y", "double");
  52.   chk_mat(probs, "probs", "double");
  53.  
  54.   if (bsSize <= 0 || std::abs(bsSize - floor(bsSize)) > 1e-6)
  55.     Rcpp::stop("bsSize must be a positive number.\n");
  56.  
  57.   mat bsDiff = zeros<mat>(probs.n_elem, bsSize);
  58.   Worker_bs_stat bs_stat(X, Y, probs, bsDiff);
  59.   RcppParallel::parallelFor(0, bsSize, bs_stat);
  60.   vec stat = (quantileCpp(X, probs) - quantileCpp(Y, probs)) / stddev(bsDiff, 0, 1);
  61.   return stat;
  62. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement