Hi
I have a multivariate normal distribution in five variables. The
distribution is specified by a vector of means ('means') and a
variance-covariance matrix ('varcov'), both set up as global variables.
I'm trying to figure out the probabilities of each random variable
being the smallest.
So I've made a function:
integrand<-function(x){
#create new mv normal dist, conditional on fixing the value of
element i to x
sig11 <- varcov[-i,-i]
sig12 <- varcov[,i]
sig12 <- sig12[-i]
sig21 <- varcov[i,]
sig21 <- sig21[-i]
sig22 <- varcov[i,i]
mu1 <- means[-i]
mu2 <- means[i]
muBar <- mu1 + sig12*(x-mu2)/sig22
sigBar <- sig11 - (sig12) %*% t(sig21)/sig22
#now calculate the probability that variable i takes the value x,
#and that all other variables are bigger than x...
arg <- dnorm(x,means[i],sigma[i])
arg <- arg*pmvnorm(lower=c(x,x,x,x), upper=c(10,10,10,10),
mean=muBar,sigma=sigBar)
return(as.numeric(arg))
}
Then I need to perform a 1-d integration of this function over all
possible values of x, which gives the total probability of variable i
being the smallest.
If I use a numerical integration function with explicit looping then
this works fine. But if I try and use a vectorised integrator (such as
the 'integrate' function), to improve performance, then I run into the
following error message:
Error in checkmvArgs(lower = lower, upper = upper, mean = mean, corr
= corr, :
?diag(sigma)? and ?lower? are of different length
checkmvArgs is a function required by pmvnorm, so I'm fairly sure
that's where the problem lies. diag(sigma) and lower certainly are of
the same length, so not sure at all what's happening here. Has anyone
else encountered this issue? And, if so, do you know the solution?
Many thanks
Paul
Trouble with pmvnorm?
5 messages · Peter Dalgaard, Paul Parsons
1 day later
You almost said it yourself: Your integrand doesn't vectorize. The direct culprit is the following: If x is a vector, what is lower=c(x,x,x,x)? A vector of length 4*length(x). And pmvnorm doesn't vectorize so it wouldn't help to have lower= as a matrix (e.g., cbind(x,x,x,x)) instead. A straightforward workaround is to Vectorize() your function. Possibly more efficient to put an mapply() of sorts around the pmvnorm call. However, wouldn't it be more obvious to work out the mean and variance matrix of (x1-x5, x2-x5, x3-x5, x4-x5) and then just pmvnorm(... lower=c(0,0,0,0), upper=c(Inf, Inf, Inf, Inf))??
On 06 Feb 2014, at 21:53 , Paul Parsons <pparsons298 at gmail.com> wrote:
Hi
I have a multivariate normal distribution in five variables. The distribution is specified by a vector of means ('means') and a variance-covariance matrix ('varcov'), both set up as global variables.
I'm trying to figure out the probabilities of each random variable being the smallest.
So I've made a function:
integrand<-function(x){
#create new mv normal dist, conditional on fixing the value of element i to x
sig11 <- varcov[-i,-i]
sig12 <- varcov[,i]
sig12 <- sig12[-i]
sig21 <- varcov[i,]
sig21 <- sig21[-i]
sig22 <- varcov[i,i]
mu1 <- means[-i]
mu2 <- means[i]
muBar <- mu1 + sig12*(x-mu2)/sig22
sigBar <- sig11 - (sig12) %*% t(sig21)/sig22
#now calculate the probability that variable i takes the value x,
#and that all other variables are bigger than x...
arg <- dnorm(x,means[i],sigma[i])
arg <- arg*pmvnorm(lower=c(x,x,x,x), upper=c(10,10,10,10), mean=muBar,sigma=sigBar)
return(as.numeric(arg))
}
Then I need to perform a 1-d integration of this function over all possible values of x, which gives the total probability of variable i being the smallest.
If I use a numerical integration function with explicit looping then this works fine. But if I try and use a vectorised integrator (such as the 'integrate' function), to improve performance, then I run into the following error message:
Error in checkmvArgs(lower = lower, upper = upper, mean = mean, corr = corr, :
?diag(sigma)? and ?lower? are of different length
checkmvArgs is a function required by pmvnorm, so I'm fairly sure that's where the problem lies. diag(sigma) and lower certainly are of the same length, so not sure at all what's happening here. Has anyone else encountered this issue? And, if so, do you know the solution?
Many thanks
Paul
______________________________________________ R-help at r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.
Peter Dalgaard, Professor, Center for Statistics, Copenhagen Business School Solbjerg Plads 3, 2000 Frederiksberg, Denmark Phone: (+45)38153501 Email: pd.mes at cbs.dk Priv: PDalgd at gmail.com
An embedded and charset-unspecified text was scrubbed... Name: not available URL: <https://stat.ethz.ch/pipermail/r-help/attachments/20140209/7d92d7ab/attachment.pl>
1 day later
On 09 Feb 2014, at 10:56 , Paul Parsons <pparsons298 at gmail.com> wrote:
Many thanks, Peter. Creating a wrapper function for integrand using Vectorize, and then integrating the wrapper, does indeed solve the problem. I tried your final suggestion, but the variable x still gets passed into pmvnorm inside the new mean and variance matrix, leading to the same problem when the integrate function vectorizes x.
You missed the point: There's nothing to integrate if you do it that way. All you need is the marginal distribution of the differences. -pd
All the best Paul On 8 Feb 2014, at 18:04, peter dalgaard wrote:
ou almost said it yourself: Your integrand doesn't vectorize. The direct culprit is the following: If x is a vector, what is lower=c(x,x,x,x)? A vector of length 4*length(x). And pmvnorm doesn't vectorize so it wouldn't help to have lower= as a matrix (e.g., cbind(x,x,x,x)) instead. A straightforward workaround is to Vectorize() your function. Possibly more efficient to put an mapply() of sorts around the pmvnorm call. However, wouldn't it be more obvious to work out the mean and variance matrix of (x1-x5, x2-x5, x3-x5, x4-x5) and then just pmvnorm(... lower=c(0,0,0,0), upper=c(Inf, Inf, Inf, Inf))??
Peter Dalgaard, Professor, Center for Statistics, Copenhagen Business School Solbjerg Plads 3, 2000 Frederiksberg, Denmark Phone: (+45)38153501 Email: pd.mes at cbs.dk Priv: PDalgd at gmail.com
An embedded and charset-unspecified text was scrubbed... Name: not available URL: <https://stat.ethz.ch/pipermail/r-help/attachments/20140211/4bdab590/attachment.pl>