Search code examples
rmontecarlomultivariate-testing

How to generate samples from MVN model?


I am trying to run some code on R based on this paper here through example 5.1. I want to simulate the following:

enter image description here

My background on R isn't great so I have the following code below, how can I generate a histogram and samples from this?

xseq<-seq(0, 100, 1)  
n<-100
Z<- pnorm(xseq,0,1)
U<- pbern(xseq, 0.4, lower.tail = TRUE, log.p = FALSE)
Beta <- (-1)^U*(4*log(n)/(sqrt(n)) + abs(Z))

Solution

  • Some demonstrations of tools that will be of use:

    rnorm(1)                 # generates one standard normal variable
    rnorm(10)                # generates 10 standard normal variables
    rnorm(1, 5, 6)           # generates 1 normal variable with mu = 5, sigma = 6
                             # not needed for this problem, but perhaps worth saying anyway
    
    rbinom(5, 1, 0.4)        # generates 5 Bernoulli variables that are 1 w/ prob. 0.4
    

    So, to generate one instance of a beta:

    n <- 100                 # using the value you gave; I have no idea what n means here
    u <- rbinom(1, 1, 0.4)   # make one Bernoulli variable
    z <- rnorm(1)            # make one standard normal variable
    beta <- (-1)^u * (4 * log(n) / sqrt(n) + abs(z))
    

    But now, you'd like to do this many times for a Monte Carlo simulation. One way you might do this is by building a function, having beta be its output, and using the replicate() function, like this:

    n <- 100                    # putting this here because I assume it doesn't change
    genbeta <- function(){      # output of this function will be one copy of beta
      u <- rbinom(1, 1, 0.4)
      z <- rnorm(1)
      return((-1)^u * (4 * log(n) / sqrt(n) + abs(z)))
    }
    
    # note that we don't need to store beta anywhere directly; 
    # rather, it is just the return()ed value of the function we defined
    
    betadraws <- replicate(5000, genbeta())
    hist(betadraws)
    

    This will have the effect of making 5000 copies of your beta variable and putting them in a histogram.

    There are other ways to do this -- for instance, one might just make a big matrix of the random variables and work directly with it -- but I thought this would be the clearest approach for starting out.


    EDIT: I realized that I ignored the second equation entirely, which you probably didn't want.

    We've now made a vector of beta values, and you can control the length of the vector in the first parameter of the replicate() function above. I'll leave it as 5000 in my continued example below.

    To get random samples of the Y vector, you could use something like:

    x <- replicate(5000, rnorm(17))     
      # makes a 17 x 5000 matrix of independent standard normal variables
    epsilon <- rnorm(17)
      # vector of 17 standard normals
    y <- x %*% betadraws + epsilon
      # y is now a 17 x 1 matrix (morally equivalent to a vector of length 17)
    

    and if you wanted to get many of these, you could wrap that inside another function and replicate() it.

    Alternatively, if you didn't want the Y vector, but just a single Y_i component:

    x <- rnorm(5000)    
      # x is a vector of 5000 iid standard normal variables 
    epsilon <- rnorm(1)
      # epsilon_i is a single standard normal variable
    y <- t(x) %*% betadraws + epsilon
      # t() is the transpose function; y is now a 1 x 1 matrix