1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
|
#include <Rcpp.h> #include <RcppEigen.h> #include <RcppParallel.h> using namespace std; using namespace Rcpp; using namespace RcppParallel; using Eigen::Map; using Eigen::MatrixXd; using Eigen::VectorXd; using Eigen::MatrixXi; using Eigen::VectorXi; template<typename Derived> inline MatrixXd matIdx(const Eigen::MatrixBase<Derived>& X, const VectorXi& index) { MatrixXd X2(index.size(), X.cols()); for (unsigned int i = 0; i < index.size(); ++i) X2.row(i) = X.row(index(i)); return X2; } struct CVLM : public Worker { const MatrixXd& X; const VectorXd& y; const MatrixXi& index; MatrixXd& betamat; CVLM(const MatrixXd& X, const VectorXd& y, const MatrixXi& index, MatrixXd& betamat) : X(X), y(y), index(index), betamat(betamat) {} void operator()(std::size_t begin, std::size_t end) { for(unsigned int i = begin; i < end; ++i) { MatrixXd Xi = matIdx(X, index.col(i)); VectorXd yi = matIdx(y, index.col(i)); betamat.col(i) = Xi.colPivHouseholderQr().solve(yi); } } };
Eigen::MatrixXd parallelFit(Rcpp::NumericMatrix xr, Rcpp::NumericVector dvr, Rcpp::IntegerMatrix indexr) { MatrixXd x = MatrixXd::Map(xr.begin(), xr.nrow(), xr.ncol()); VectorXd dv = VectorXd::Map(dvr.begin(), dvr.size()); MatrixXi index = MatrixXi::Map(indexr.begin(), indexr.nrow(), indexr.ncol()); MatrixXd betamat = MatrixXd::Zero(x.cols(), index.cols()); CVLM cvLM(x, dv, index, betamat); parallelFor(0, index.cols(), cvLM); return betamat; }
|