I am trying to create truncated multivariate normal r.vector with sigma that depends on some random vector z. Since initially sigma (in my code called nn) is not positive definite, i used function make.positive.definite()
and then i got nn to be positive definite (and symmetric).
But in calling rtmvnorm
i get the following error:
"Error in checkSymmetricPositiveDefinite(sigma) -sigma must be positive definite".
Any idea what might be wrong?
library(tmvtnorm)
library(matrixcalc)
library(corpcor)
zmean <- rep(0, 100)
zSigma <- diag(100)
z <- rmvnorm(n=1, mean=zmean, sigma=zSigma)
umean <- rep(0, 100)
usigma <- exp(-0.5 * rep(1, 100) + z)
nn <- t(usigma) %*% usigma
is.positive.definite(nn)
nn <- make.positive.definite(nn)
is.positive.definite(nn)
isSymmetric(nn)
a <- rep(0,100)
b <- rep(+Inf, 100)
U <- rtmvnorm(n=1, mean=umean, sigma=nn, lower=a, upper=b, algorithm="gibbs")
Your problem is related to machine precision. Your matrix is positive definite after transformation, however you used different precision tolerance level in make.positive.definite
than the one used in internal rtmvnorm
checks.
With your example:
is.positive.definite(nn)
[1] TRUE
However:
det(nn)
[1] 0
So any function using det()
to get determinant of your matrix will see it as non positive definite. You can overcome this by making sure your det(nn)
returns a positive value.
One way is to add some variance in all directions:
nn <- nn + diag(ncol(nn))*0.01
det(nn)
[1] 9.98501e-253
Now rtmvnorm
works.
If you want to use make.positive.definite()
you have to change the tolerance:
nn <- make.positive.definite(nn, tol=1e-3)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.