celestialgod

parallel_boot_lm.cpp

Dec 31st, 2016
227
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 1.85 KB | None | 0 0
  1. // [[Rcpp::depends(RcppParallel)]]
  2. // [[Rcpp::depends(RcppEigen)]]
  3. #include <Rcpp.h>
  4. #include <RcppEigen.h>
  5. #include <RcppParallel.h>
  6.  
  7. using namespace std;
  8. using namespace Rcpp;
  9. using namespace RcppParallel;
  10.  
  11. using Eigen::Map;
  12. using Eigen::MatrixXd;
  13. using Eigen::VectorXd;
  14. using Eigen::MatrixXi;
  15. using Eigen::VectorXi;
  16.  
  17. template<typename Derived>
  18. inline MatrixXd matIdx(const Eigen::MatrixBase<Derived>& X, const VectorXi& index)
  19. {
  20.   MatrixXd X2(index.size(), X.cols());
  21.   for (unsigned int i = 0; i < index.size(); ++i)
  22.     X2.row(i) = X.row(index(i));
  23.   return X2;
  24. }
  25.  
  26. struct CVLM : public Worker
  27. {
  28.   // design matrix and outcome
  29.   const MatrixXd& X;
  30.   const VectorXd& y;
  31.   const MatrixXi& index;
  32.  
  33.   // output
  34.   MatrixXd& betamat;
  35.  
  36.   // initialize with input and output
  37.   CVLM(const MatrixXd& X, const VectorXd& y, const MatrixXi& index, MatrixXd& betamat)
  38.     : X(X), y(y), index(index), betamat(betamat) {}
  39.  
  40.   void operator()(std::size_t begin, std::size_t end) {
  41.     for(unsigned int i = begin; i < end; ++i)
  42.     {
  43.       MatrixXd Xi = matIdx(X, index.col(i));
  44.       VectorXd yi = matIdx(y, index.col(i));
  45.       betamat.col(i) = Xi.colPivHouseholderQr().solve(yi);
  46.     }
  47.   }
  48. };
  49.  
  50. // [[Rcpp::export]]
  51. Eigen::MatrixXd parallelFit(Rcpp::NumericMatrix xr,
  52.                             Rcpp::NumericVector dvr,
  53.                             Rcpp::IntegerMatrix indexr) {
  54.   MatrixXd x = MatrixXd::Map(xr.begin(), xr.nrow(), xr.ncol());
  55.   VectorXd dv = VectorXd::Map(dvr.begin(), dvr.size());
  56.   MatrixXi index = MatrixXi::Map(indexr.begin(), indexr.nrow(), indexr.ncol());
  57.  
  58.   // allocate the output matrix
  59.   MatrixXd betamat = MatrixXd::Zero(x.cols(), index.cols());
  60.  
  61.   // pass input and output
  62.   CVLM cvLM(x, dv, index, betamat);
  63.  
  64.   // parallelFor to do it
  65.   parallelFor(0, index.cols(), cvLM);
  66.  
  67.   return betamat;
  68. }
Advertisement
Add Comment
Please, Sign In to add comment