簡體   English   中英

均勻分布矩陣Rcpp

[英]matrix of Uniform distribution Rcpp

我正在嘗試使用Rcpp包創建一個函數,該函數創建大小為nxm的矩陣,其中包含均勻分布的條目。 (我沒有使用此軟件包的經驗。)

library(Rcpp)
cppFunction('NumericMatrix rngCpp(const int n,const int m) {
   NumericMatrix X(n, m);
             X(_,0) = runif(n);
             return X;
             }')
set.seed(1)
rngCpp(4,5)
          [,1] [,2] [,3] [,4] [,5]
[1,] 0.2655087    0    0    0    0
[2,] 0.3721239    0    0    0    0
[3,] 0.5728534    0    0    0    0
[4,] 0.9082078    0    0    0    0

預期產量

set.seed(1)
matrix(runif(4*5), nrow=4, ncol = 5)
          [,1]      [,2]       [,3]      [,4]      [,5]
[1,] 0.2655087 0.2016819 0.62911404 0.6870228 0.7176185
[2,] 0.3721239 0.8983897 0.06178627 0.3841037 0.9919061
[3,] 0.5728534 0.9446753 0.20597457 0.7698414 0.3800352
[4,] 0.9082078 0.6607978 0.17655675 0.4976992 0.7774452

很好

 X(_,0) = runif(n);

明確只分配給第一列。 因此,只需循環遍歷所有m列即可。

另一種(內部棒球)方式是請求向量n * m,然后設置(n,m)的dim屬性使其成為矩陣。

相關的是,有一個IIRC構造函數,它將采用該向量並對其進行暗化處理。

編輯:最后一種方法是最簡單的,其工作方式如下:

R> cppFunction('NumericMatrix mu(int n, int m) { 
       NumericVector v = runif(n*m); 
       return NumericMatrix(n, m, v.begin()); }')
R> set.seed(1); mu(4,5)
         [,1]     [,2]      [,3]     [,4]     [,5]
[1,] 0.265509 0.201682 0.6291140 0.687023 0.717619
[2,] 0.372124 0.898390 0.0617863 0.384104 0.991906
[3,] 0.572853 0.944675 0.2059746 0.769841 0.380035
[4,] 0.908208 0.660798 0.1765568 0.497699 0.777445
R> 

編輯2: F.Privé堅持認為的其他變體:

我們可以添加以下兩個:

// [[Rcpp::export]]
NumericMatrix mu3(int n, int m) { 
  return NumericMatrix(n, m, runif(n*m).begin()); 
}

// [[Rcpp::export]]
NumericMatrix mu4(int n, int m) { 
  NumericVector v = runif(n * m);
  v.attr("dim") = Dimension(n, m);
  return as<NumericMatrix>(v); 
}

然后得到

R> N <- 1000; M <- 1000

R> microbenchmark::microbenchmark(
+   mu(N, M),
+   mu2(N, M),
+   mu3(N, M),
+   mu4(N, M),
+   rngCpp(N, M)
+ )
Unit: milliseconds
         expr     min      lq    mean  median      uq     max neval
     mu(N, M) 4.77894 4.98485 7.32315 5.18153 5.36468 33.2427   100
    mu2(N, M) 3.99137 4.05308 5.43207 4.36296 4.57510 30.7335   100
    mu3(N, M) 4.73176 5.01524 6.35186 5.17173 5.39541 31.7425   100
    mu4(N, M) 3.99784 4.10052 4.72563 4.41176 4.60303 30.6166   100
 rngCpp(N, M) 5.18726 5.60165 7.53171 5.83892 6.14315 34.5934   100
R> 

在OP的代碼中,分配僅發生在第一列索引即0 我們可以遍歷列索引並分配均勻分布值

cppFunction('NumericMatrix rngCpp(const int n,const int m) {
   NumericMatrix X(n, m);

             for(int i = 0; i < m; i++){
               X(_,i) = runif(n);
                 }
             return X;
             }')


set.seed(1)
rngCpp(4,5)
#          [,1]      [,2]       [,3]      [,4]      [,5]
#[1,] 0.2655087 0.2016819 0.62911404 0.6870228 0.7176185
#[2,] 0.3721239 0.8983897 0.06178627 0.3841037 0.9919061
#[3,] 0.5728534 0.9446753 0.20597457 0.7698414 0.3800352
#[4,] 0.9082078 0.6607978 0.17655675 0.4976992 0.7774452

通常,我會使用Dirk的第二個想法:更改向量的尺寸,使其成為矩陣。

#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
NumericVector mu2(int n, int m) { 
  NumericVector v = runif(n * m);
  v.attr("dim") = Dimension(n, m);
  return v; 
}

// [[Rcpp::export]]
NumericMatrix mu(int n, int m) { 
  NumericVector v = runif(n*m); 
  return NumericMatrix(n, m, v.begin()); 
}

// [[Rcpp::export]]
NumericMatrix rngCpp(const int n,const int m) {
  NumericMatrix X(n, m);

  for(int i = 0; i < m; i++){
    X(_,i) = runif(n);
  }
  return X;
}

/*** R
set.seed(1); mu(4, 5)
set.seed(1); mu2(4, 5)

N <- 1000; M <- 1000
microbenchmark::microbenchmark(
  mu(N, M),
  mu2(N, M),
  rngCpp(N, M)
)
*/

微基准測試:

Unit: milliseconds
         expr      min        lq     mean    median        uq      max neval cld
     mu(N, M) 7.627591 10.290691 16.05829 10.932174 11.416555 119.2110   100   a
    mu2(N, M) 6.315160  6.590293 12.30125  8.510765  9.368282 117.8750   100   a
 rngCpp(N, M) 8.330158 10.306584 16.14374 10.893767 11.398675 121.4233   100   a

因此, mu2速度更快,因為它不會進行任何復制。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM