从多元正态分布中有效地随机抽取

时间:2014-03-29 23:39:30

标签: r rcpp

只是想知道是否有人曾经遇到过他/她需要从一个非常高维的多元正态分布(比如维度= 10,000)中随机抽取的问题,作为rmvnorm的{​​{1}}函数包装是不切实际的。

我知道articlemvtnorm包的Rcpp函数有dmvnorm实现,所以我想知道mvtnorm是否存在等价的内容?

1 个答案:

答案 0 :(得分:9)

以下是Ahmadou Dicko给出的mvtnorm::rmvnormRcpp实施的快速比较here。所呈现的时间是来自多元正态分布的100个绘制,维度范围从500到2500.从下图可以推断维度10000所需的时间。时间包括生成随机mu向量的开销和diag矩阵,但这些方法在各种方法中是一致的,对于所讨论的维度来说是微不足道的(例如diag(10000)为0.2秒)。

library(Rcpp)
library(RcppArmadillo)
library(inline)
library(mvtnorm)

code <- '
using namespace Rcpp;
int n = as<int>(n_);
arma::vec mu = as<arma::vec>(mu_);
arma::mat sigma = as<arma::mat>(sigma_);
int ncols = sigma.n_cols;
arma::mat Y = arma::randn(n, ncols);
return wrap(arma::repmat(mu, 1, n).t() + Y * arma::chol(sigma));
'

rmvnorm.rcpp <- 
  cxxfunction(signature(n_="integer", mu_="numeric", sigma_="matrix"), code,
              plugin="RcppArmadillo", verbose=TRUE)

rcpp.time <- sapply(seq(500, 5000, 500), function(x) {
  system.time(rmvnorm.rcpp(100, rnorm(x), diag(x)))[3]  
})

mvtnorm.time <- sapply(seq(500, 2500, 500), function(x) {
  system.time(rmvnorm(100, rnorm(x), diag(x)))[3]  
})


plot(seq(500, 5000, 500), rcpp.time, type='o', xlim=c(0, 5000),
     ylim=c(0, max(mvtnorm.time)), xlab='dimension', ylab='time (s)')

points(seq(500, 2500, 500), mvtnorm.time, type='o', col=2)

legend('topleft', legend=c('rcpp', 'mvtnorm'), lty=1, col=1:2, bty='n')

enter image description here