celestialgod

RcppParallel calculation of lm coef

Oct 7th, 2016
143
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
R 2.48 KB | None | 0 0
  1. library(Rcpp)
  2. library(RcppArmadillo)
  3. library(RcppParallel)
  4.  
  5. sourceCpp(code = "
  6. // [[Rcpp::depends(RcppArmadillo)]]
  7. #include <RcppArmadillo.h>
  8. using namespace Rcpp;
  9. using namespace arma;
  10. // [[Rcpp::depends(RcppParallel)]]
  11. #include <RcppParallel.h>
  12. using namespace RcppParallel;
  13.  
  14. struct coef_compute: public Worker {
  15.  const mat X;
  16.  const vec& y;
  17.  const umat& combnMat;
  18.  mat& coefMat;
  19.  coef_compute(const mat& X, const vec& y, const umat& combnMat,mat& coefMat):
  20.    X(X), y(y), combnMat(combnMat), coefMat(coefMat) {}
  21.  void operator()(std::size_t begin, std::size_t end)
  22.  {
  23.    for (uword i = begin; i < end; i++)          
  24.    coefMat.row(i) = solve(join_rows(ones<vec>(y.n_elem),
  25.                           X.cols(combnMat.col(i))), y).t();
  26.  }
  27. };
  28.  
  29.  
  30. // [[Rcpp::export]]
  31. List fastCoef_allCombns(arma::vec y, arma::mat x, int k)
  32. {
  33.  Rcpp::Function combn_rcpp(\"combn\");
  34.  umat combnMat = conv_to<umat>::from(as<mat>(combn_rcpp(x.n_cols, k))) - 1;
  35.  mat coefMat = zeros<mat>(combnMat.n_cols, k + 1);
  36.  coef_compute coefResults(x, y, combnMat, coefMat);
  37.  parallelFor(0, combnMat.n_cols, coefResults);
  38.  return List::create(combnMat.t() + 1, coefMat);
  39. }")
  40.  
  41. n <- 30
  42. X <- matrix(rnorm(120), n)
  43. coefs <- c(2, 5, -7, 8, 0.5)
  44. y <- as.vector(cbind(1, X) %*% coefs) + rnorm(n, 0, 5)
  45.  
  46. outRes <- lapply(1:ncol(X), function(i){                
  47.   fastCoef_allCombns(y, X, i)
  48. })
  49.  
  50. outRes[[2]]
  51. # # 哪些X的組合
  52. # [[1]]
  53. #      [,1] [,2]
  54. # [1,]    1    2   # X1 跟 X2的組合
  55. # [2,]    1    3
  56. # [3,]    1    4
  57. # [4,]    2    3
  58. # [5,]    2    4
  59. # [6,]    3    4
  60. #
  61. # # 每一個組合的X,其係數,BY列去看
  62. # [[2]]
  63. #           [,1]      [,2]       [,3]
  64. # [1,] 0.4210033  6.445250 -7.5248928
  65. # [2,] 0.7895878  7.378273  8.7397441
  66. # [3,] 0.6180885  6.864235  0.9617974
  67. # [4,] 2.6213473 -6.677914  6.3579295
  68. # [5,] 2.3471788 -7.834296  1.4096750
  69. # [6,] 2.9802756  8.212602  0.9764216      
  70.  
  71. # benchmark
  72. n <- 3000; p <- 10
  73. X <- matrix(rnorm(n*p), n)
  74. coefs <- sample(-10:10, p+1, TRUE)
  75. y <- as.vector(cbind(1, X) %*% coefs) + rnorm(n, 0, 5)
  76.  
  77. st <- proc.time()
  78. outRes <- lapply(1:ncol(X), function(i){
  79.   fastCoef_allCombns(y, X, i)
  80. })
  81. proc.time() - st
  82. # user  system elapsed
  83. # 0.14    0.08    0.07
  84.  
  85. st <- proc.time()
  86. outRes2 <- lapply(1:ncol(X), function(i){
  87.   combnMat <- combn(1:ncol(X), i)
  88.   return(list(t(combnMat), t(apply(combnMat, 2, function(v){
  89.     coef(lm(y ~ X[,v]))
  90.   }))))
  91. })
  92. proc.time() - st
  93. # user  system elapsed  
  94. # 3.57    0.19    3.56
Advertisement
Add Comment
Please, Sign In to add comment