celestialgod

randn matrix in Rcpp

Jan 15th, 2017
411
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
R 3.01 KB | None | 0 0
  1. Rcpp::sourceCpp(code = "
  2. // [[Rcpp::depends(RcppBlaze)]]
  3. // [[Rcpp::plugins(cpp11)]]
  4. #include <RcppBlaze.h>
  5. #include <random>
  6. #include <functional>
  7.  
  8. // [[Rcpp::export]]
  9. blaze::DynamicMatrix<double> rcppblaze_randn(size_t m, size_t n, double mean = 0.0, double stddev = 1.0) {
  10.  static std::random_device rd;
  11.  static std::normal_distribution<double> dist( mean, stddev );
  12.  
  13.  blaze::DynamicMatrix<double> A(m, n);
  14.  for( size_t i=0UL; i<A.columns(); ++i)
  15.    std::generate(A.begin(i), A.end(i), std::bind(dist, std::default_random_engine( rd() ) ) );
  16.  return A;
  17. }")
  18.  
  19. Rcpp::sourceCpp(code = "
  20. // [[Rcpp::depends(RcppBlaze)]]
  21. // [[Rcpp::plugins(cpp11,openmp)]]
  22. #include <RcppBlaze.h>
  23. #include <random>
  24. #include <functional>
  25.  
  26. // [[Rcpp::export]]
  27. blaze::DynamicMatrix<double> rcppblaze_randn_omp(size_t m, size_t n, double mean = 0.0, double stddev = 1.0) {
  28.  blaze::setNumThreads( blaze::getNumThreads() );
  29.  static std::random_device rd;
  30.  static std::normal_distribution<double> dist( mean, stddev );
  31.  
  32.  blaze::DynamicMatrix<double> A(m, n);
  33.  #pragma omp parallel for
  34.  for( size_t i=0UL; i<A.columns(); ++i)
  35.    std::generate(A.begin(i), A.end(i), std::bind(dist, std::default_random_engine( rd() ) ) );
  36.  return A;
  37. }")
  38.  
  39. Rcpp::sourceCpp(code = "
  40. // [[Rcpp::depends(RcppArmadillo)]]
  41. #include <RcppArmadillo.h>
  42.  
  43. // [[Rcpp::export]]
  44. arma::mat rcpparma_randn(arma::uword m, arma::uword n, double mean = 0.0, double stddev = 1.0) {
  45.  return arma::randn<arma::mat>(m, n) * stddev + mean;
  46. }")
  47.  
  48. Rcpp::sourceCpp(code = "
  49. // [[Rcpp::depends(RcppEigen)]]
  50. // [[Rcpp::plugins(cpp11)]]
  51. #include <RcppEigen.h>
  52. #include <random>
  53.  
  54. inline double randn(double dummy, double mean, double stddev) {
  55.  static std::random_device rd;
  56.  static std::default_random_engine randEng(rd());
  57.  static std::normal_distribution<double> dist(mean, stddev);
  58.  return dist(randEng);
  59. }
  60.  
  61. // [[Rcpp::export]]
  62. SEXP rcppeigen_randn(std::size_t m, std::size_t n, double mean = 0.0, double stddev = 1.0) {
  63.  auto randn_f = [&mean, &stddev](double x){ return randn(x, mean, stddev); };
  64.  Eigen::MatrixXd A = Eigen::MatrixXd::Zero(m, n).unaryExpr(randn_f);
  65.  return Rcpp::wrap(A);
  66. }")
  67.  
  68. library(microbenchmark)
  69. nn <- 3e3L
  70. microbenchmark(rcppblaze = rcppblaze_randn(nn, nn, 30, 20),
  71.                rcppblaze_omp = rcppblaze_randn_omp(nn, nn, 30, 20),
  72.                rcpparma = rcpparma_randn(nn, nn, 30, 20),
  73.                rcppeigen = rcppeigen_randn(nn, nn, 30, 20),
  74.                r = matrix(rnorm(nn*nn), nn)*20 + 30,
  75.                times = 20L)
  76. # Unit: milliseconds
  77. #           expr       min        lq     mean   median       uq      max neval
  78. #      rcppblaze 354.75299 361.32248 371.5106 373.1244 378.2249 393.6559    20
  79. #  rcppblaze_omp  84.60684  97.30579 106.6932 104.9424 117.8100 144.1054    20
  80. #       rcpparma 697.18385 702.32619 714.4662 712.7235 722.5486 750.9504    20
  81. #      rcppeigen 368.96569 373.56575 386.1028 381.8487 395.9508 432.4745    20
  82. #              r 587.96085 595.83358 619.2839 609.2916 624.7770 700.9972    20
Advertisement
Add Comment
Please, Sign In to add comment