I am conducting some nonlinear optimization using multivariate probabilities as my objective function. I've spent hours thinking I had issue with the optimization algorithm, but actually I've tracked the bug down to the use of the mvtnorm
package.
Code
library(mvtnorm)
pmvnorm(
lower = c(-1.281552 , 7.089083, 0.5193308),
upper = c(-1.200552, Inf, Inf),
corr = diag(1, nrow =3)
)
If you excecute this code, every 10-20 times it will return NaN
as opposed to 3.047822e-15
.
Why is this the case? Can anyone enlighten me? Also, is there an alternative to mvtnorm::pmvnorm()
that will prevent this type of instability?
Edit:
- according to @LMc in comments you can reproduce the error using seed = 10L as an example
- @PBull gives a great answer below in the comments
- @Gregor Thomas in comments describes that using Miwa() fixes it (though Miwa I believe approximates -Inf/+Inf to -1e4/1e4
Session info
R version 4.3.1 (2023-06-16) Platform: x86_64-pc-linux-gnu (64-bit) Running under: Red Hat Enterprise Linux
Matrix products: default BLAS: /usr/lib64/libblas.so.3.4.2 LAPACK: /usr/lib64/liblapack.so.3.4.2
locale: [1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C LC_TIME=en_US.UTF-8 LC_COLLATE=en_US.UTF-8
[5] LC_MONETARY=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8 LC_PAPER=en_US.UTF-8 LC_NAME=C
[9] LC_ADDRESS=C LC_TELEPHONE=C LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=Ctime zone: America/New_York tzcode source: system (glibc)
attached base packages: [1] stats graphics grDevices utils datasets methods base
other attached packages: [1] mvtnorm_1.2-4
loaded via a namespace (and not attached): [1] compiler_4.3.1 tools_4.3.1 rstudioapi_0.16.0
mvtnorm
version 1.2-3, I consistently get[1] 3.047822e-15 attr(,"error") [1] 0 attr(,"msg") [1] "Normal Completion"
. – Ashleyashlireplicate
withn = 1e4
and I am gettingNaN
a little over 5% of the time. But if I setalgorithm = Miwa()
it works consistently. – Ashleyashlimvtnorm:::probval.GenzBretz()
which then makes a C function calledmvtnorm_C_mvtdst
. This returnsNaN
. Other users can useseed = 10L
as an example. – Grownupqnorm
returnInf
(the offending variable isW(ND)
approaching 1). That isn't handled downstream and the return gets stuck atNaN
after some more additions/multiplications. Note that you start integrating the standard normal at 7.09 which leaves almost no density to the right. FWIW this question shouldn't have been closed. – Rowden