random - R: can 'mu' or 'Sigma' be vectorized in MASS::mvrnorm() when generating bivariate normal samples? -


consider data below,

n <- 3 phi0 <- 1 phi1 <- 0.1 phi2 <- 0.2 w2 <- runif(n,0,1) w3 <- runif(n,0,1) w <- cbind(w2,w3) phi <- rbind(phi0,phi1,phi2) rho <- 0.4 sigma1 <- exp(as.numeric(model.matrix(~w) %*% phi)) sigma2<- 1  library(mass) #sigma <- ??? mu <- rep(0,2) v <- mvrnorm(n, mu, sigma) 

sigma1 vector of variance.

i want generate bivariate vector v=(v1,v2) of length n normal bivariate distribution. in such way i-th line of v has bivariate normal distribution of mean mu=(0,0), correlation rho=0.4 , marginal variance sigma=(sigma1, 1) sigma1 receives value of i-th line sigma1. how can proceed?


editor's clarification

in 1d case, rnorm accepts vectorized mu , sigma, that

rnorm(3, 0, sqrt(sigma1)) 

gives samples n(0, sqrt(sigma1[i])). op asking same capability mvrnorm.

basic solution

no, can't vectorized. write for loop.

v <- matrix(0, n, 2) (i in 1:n) {   sig11 <- sigma1[i]   sig21 <- rho * sqrt(sig11)   sigma <- matrix(c(sig11, sig21, sig21, 1), 2)   v[i, ] <- mvrnorm(1, c(0,0), sigma)   } 

advanced solution

given covariance sigma

sig11 ^ 2                rho * sig11 * sig22 rho * sig11 * sig22      sig22 ^ 2 

its lower triangular cholesky factor l is

sig11          0 rho * sig22    sqrt(1 - rho ^ 2) * sig22 

if x <- rnorm(2), mu + l %*% x sample n(mu, sigma).

this gives vectorized solution

# mu1, mu2, sig11, sig22, rho can ## length-n vectors ## scalars ## vectors can recycled length-n birnorm <- function (n, mu1, mu2, sig11, sig22, rho) {   x1 <- rnorm(n)   x2 <- rnorm(n)   z1 <- sig11 * x1 + mu1   z2 <- rho * sig22 * x1 + sqrt(1 - rho ^ 2) * sig22 * x2 + mu2   cbind(z1, z2)   } 

for data, can use

v <- birnorm(3, 0, 0, sqrt(sigma1), 1, 0.4) 

rebuild mvrnorm bivariate case

note function can used rebuild mvrnorm bivariate case.

mvrnorm2 <- function (n, mu, sigma) {   sig11 <- sqrt(sigma[1])   sig22 <- sqrt(sigma[4])   rho <- sigma[2] / (sig11 * sig22)   birnorm(n, mu[1], mu[2], sig11, sig22, rho)   } 

and faster

mu <- c(0,0) sigma <- matrix(c(1,0.5,0.5,1),2) library(microbenchmark) microbenchmark(mvrnorm(1000, mu, sigma), mvrnorm2(1000, mu, sigma)) 

Comments

Popular posts from this blog

Command prompt result in label. Python 2.7 -

javascript - How do I use URL parameters to change link href on page? -

amazon web services - AWS Route53 Trying To Get Site To Resolve To www -