简体   繁体   English

Rcpp 如何在 Rcpp 中生成随机多元法向量?

[英]Rcpp How to generate random multivariate normal vector in Rcpp?

I would like to generate some large random multivariate (more than 6 dimensions) normal samples.我想生成一些大型随机多元(超过 6 维)正态样本。 In R, many packages can do this such as rmnorm, rmvn... But the problem is the speed!在 R 中,很多包都可以做到这一点,比如 rmnorm、rmvn……但问题是速度! So I tried to write some C code through Rcpp.所以我尝试通过 Rcpp 编写一些 C 代码。 I went through some tutorial online but it seems there is no "sugar" for multivariate distribution, neither in STL library.我在网上浏览了一些教程,但似乎多元分布没有“糖”,STL库中也没有。

Any help is appreciated!任何帮助表示赞赏!

Thanks!谢谢!

I'm not sure that Rcpp will help unless you find a good algorithm to approximate your multivariate (cholesky, svd, etc.) and program it using Eigen (RccpEigen) or Armadillo (using RcppArmadillo).我不确定 Rcpp 会有所帮助,除非您找到一个很好的算法来近似您的多元变量(cholesky、svd 等)并使用 Eigen (RccpEigen) 或 Armadillo(使用 RcppArmadillo)对其进行编程。

Here is one approach using the Cholesky decomposition and (Rcpp)Armadillo这是使用 Cholesky 分解和 (Rcpp)Armadillo 的一种方法

#include <RcppArmadillo.h>

// [[Rcpp::depends(RcppArmadillo)]]

// [[Rcpp::export]]

using namespace arma; 
using namespace Rcpp;

mat mvrnormArma(int n, mat sigma) {
   int ncols = sigma.n_cols;
   mat Y = randn(n, ncols);
   return Y * chol(sigma);
}

Now a naive implementation in pure R现在是纯 R 中的幼稚实现

mvrnormR <- function(n, sigma) {
    ncols <- ncol(sigma)
    matrix(rnorm(n * ncols), ncol = ncols) %*% chol(sigma)
}

You can also check if everythings work您还可以检查一切是否正常

sigma <- matrix(c(1, 0.9, -0.3, 0.9, 1, -0.4, -0.3, -0.4, 1), ncol = 3)
cor(mvrnormR(100, sigma))
cor(MASS::mvrnorm(100, mu = rep(0, 3), sigma))
cor(mvrnormArma(100, sigma))

Now let's benchmark it现在让我们对它进行基准测试

require(bencharmk)
benchmark(mvrnormR(1e4, sigma),
          MASS::mvrnorm(1e4, mu = rep(0, 3), sigma),
          mvrnormArma(1e4, sigma),
          columns=c('test', 'replications', 'relative', 'elapsed'))


## 2 MASS::mvrnorm(10000, mu = rep(0, 3), sigma)          100
## 3                   mvrnormArma(10000, sigma)          100
## 1                      mvrnormR(10000, sigma)          100
##   relative elapsed
## 2    3.135   2.295
## 3    1.000   0.732
## 1    1.807   1.323

In this example I used a normal distribution with unit variance and null mean but you could easily generalize to gaussian distribution with custom mean and variance.在这个例子中,我使用了具有单位方差和空均值的正态分布,但您可以轻松地推广到具有自定义均值和方差的高斯分布。

Hope this helps希望这可以帮助

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM