Yun*_*Nie -4 c r random-sample rcpp
我想生成一些大的随机多变量(超过6维)正常样本.在R中,许多软件包可以做到这一点,例如rmnorm,rmvn ......但问题是速度!所以我试着通过Rcpp编写一些C代码.我在线浏览了一些教程,但似乎在多变量分布中没有"糖",在STL库中也没有.
任何帮助表示赞赏!
谢谢!
我不确定Rcpp是否有帮助,除非你找到一个好的算法来近似你的多变量(cholesky,svd等)并使用Eigen(RccpEigen)或Armadillo(使用RcppArmadillo)编程.
这是使用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);
}
Run Code Online (Sandbox Code Playgroud)
现在是纯粹的R的天真实现
mvrnormR <- function(n, sigma) {
ncols <- ncol(sigma)
matrix(rnorm(n * ncols), ncol = ncols) %*% chol(sigma)
}
Run Code Online (Sandbox Code Playgroud)
您还可以检查每件事是否有效
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))
Run Code Online (Sandbox Code Playgroud)
现在让我们对它进行基准测试
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
Run Code Online (Sandbox Code Playgroud)
在这个例子中,我使用了具有单位方差和零均值的正态分布,但您可以使用自定义均值和方差轻松推广到高斯分布.
希望这可以帮助