I am trying to use an LKJ prior. I have simplified my model down to the following. It’s so simple that I feel like I must be doing something wrong, yet it does not work for me:
parameters {
cholesky_factor_corr[2] L;
}
model {
L ~ lkj_corr_cholesky(1.0);
}
I’m calling this lkj_test.stan. I run this through CmdStanPy. Again, after simplifying things as much as possible, here is exactly what I run:
import cmdstanpy
model = cmdstanpy.CmdStanModel(stan_file="lkj_test.stan")
fit = model.sample({}, chains=1)
print(fit.summary())
The result is:
16:09:46 - cmdstanpy - INFO - CmdStan start processing
chain 1: 100%|█████████████████████████████████████████████████████████████████████| 2000/2000 [00:00<00:00, 134301.53it/s, (Sampling completed)]
16:09:46 - cmdstanpy - INFO - CmdStan done processing.
16:09:46 - cmdstanpy - WARNING - Non-fatal error during sampling:
Exception: lkj_corr_cholesky_lpdf: Random variable[2] is 0, but must be positive! (in 'lkj_test.stan', line 5, column 2 to column 29)
Exception: lkj_corr_cholesky_lpdf: Random variable[2] is 0, but must be positive! (in 'lkj_test.stan', line 5, column 2 to column 29)
Exception: lkj_corr_cholesky_lpdf: Random variable[2] is 0, but must be positive! (in 'lkj_test.stan', line 5, column 2 to column 29)
Exception: lkj_corr_cholesky_lpdf: Random variable[2] is 0, but must be positive! (in 'lkj_test.stan', line 5, column 2 to column 29)
Consider re-running with show_console=True if the above output is unclear!
Mean MCSE StdDev MAD 5% 50% 95% ESS_bulk ESS_tail ESS_bulk/s R_hat
lp__ -0.609607 0.047758 0.855861 0.365846 -2.327080 -0.260325 -0.001084 394.434 410.966 98608.5 1.00091
L[1,1] 1.000000 NaN 0.000000 0.000000 1.000000 1.000000 1.000000 NaN NaN NaN NaN
L[1,2] 0.000000 NaN 0.000000 0.000000 0.000000 0.000000 0.000000 NaN NaN NaN NaN
L[2,1] -0.022324 0.031549 0.572107 0.707185 -0.912745 -0.009924 0.890539 301.995 331.944 75498.8 1.00651
L[2,2] 0.788447 0.011914 0.225666 0.169100 0.312378 0.877953 0.999458 394.434 410.966 98608.5 1.00091
While I don’t see anything wrong with the final L, the exceptions are worrying. I looked at the samples, and they looked like valid Cholesky factorizations of correlation matrices; but anything invalid should have been rejected, so I don’t think that’s any evidence of anything. When I run my actual model, I get the same exception many dozens of times.
As an experiment, I also tried
parameters {
corr_matrix[2] M;
}
model {
M ~ lkj_corr(1.0);
}
Calling this lkj_test2.stan and running it precisely as before results in:
16:21:25 - cmdstanpy - INFO - CmdStan start processing
16:24:32 - cmdstanpy - INFO - CmdStan start processing
chain 1: 100%|██████████████████████████████████████████████████████████████████████| 2000/2000 [00:00<00:00, 78904.82it/s, (Sampling completed)]
16:24:32 - cmdstanpy - INFO - CmdStan done processing.
16:24:32 - cmdstanpy - WARNING - Non-fatal error during sampling:
Exception: lkj_corr_lpdf: Correlation matrix is not positive definite. (in 'lkj_test2.stan', line 5, column 2 to column 20)
Exception: lkj_corr_lpdf: Correlation matrix is not positive definite. (in 'lkj_test2.stan', line 5, column 2 to column 20)
Exception: lkj_corr_lpdf: Correlation matrix is not positive definite. (in 'lkj_test2.stan', line 5, column 2 to column 20)
Exception: lkj_corr_lpdf: Correlation matrix is not positive definite. (in 'lkj_test2.stan', line 5, column 2 to column 20)
Consider re-running with show_console=True if the above output is unclear!
Mean MCSE StdDev MAD 5% 50% 95% ESS_bulk ESS_tail ESS_bulk/s R_hat
lp__ -0.663346 0.082399 1.006740 0.414771 -2.299060 -0.307206 -0.003113 425.331 212.841 53166.3 1.00199
M[1,1] 1.000000 NaN 0.000000 0.000000 1.000000 1.000000 1.000000 NaN NaN NaN NaN
M[1,2] -0.005443 0.031301 0.587459 0.766037 -0.930505 -0.008561 0.880960 265.173 212.546 33146.6 1.00977
M[2,1] -0.005443 0.031301 0.587459 0.766037 -0.930505 -0.008561 0.880960 265.173 212.546 33146.6 1.00977
M[2,2] 1.000000 NaN 0.000000 0.000000 1.000000 1.000000 1.000000 NaN NaN NaN NaN
Again, the final M and the individual samples look okay to me, but the exceptions are worrying. Also again, my actual model produces the same error, but many more times.
My question is: Am I doing something wrong? Or is this just the expected behavior when sampling from the LKJ distribution? If it is the expected behavior, is there some way I can suppress these exceptions (but not others)?
I am using Python 3.14.4 and CmdStanPy 1.3.0.