LKJ prior throwing positivity exceptions

Welcome! This is a pretty ambitious place to start.

This shouldn’t be a problem unless the correlations get close to 1 or the variances get close to 0. More information will tend to keep the results away from the boundaries as the posteriors concentrate away from uniform.

No. Yes.

The rejections will cause duplicated states in the sampler, but that’s not the only cause.

We intentionally label these as “Non-fatal error” because it’s recoverable. What’s usually going on is that early in sampling you will get these exceptiosn or you will get them occassionally during sampling. They can indicate there might be bias if they’re all due to the same cause and show up as divergences in the same region of the posterior.

Negative values themselves are necessary in order to get values less than 1. The problem starts when the absolute value of unconstrained variable exceeds 350 or so and starts underflowing 0 (negative) or overflowing to +infinity (positive).

This isn’t necessarily a broken model so much as our sampler not being up to the job. @andrewgelman likes to recommend things like half normal priors on scale parameters in hierarchical models. If the data is consistent with complete pooling, this can run into numerical difficulties compared to a “zero avoiding” prior like lognormal. So while Bayes wants a really small value in these cases, the exp() transform can be a problem.

In another topic here, @aseyboldt posted a more stable altnerative he calls “bisoftplus”. Like we did for sum-to-zero and simplex, we may wind up changing our default built-in transform as a result.

If L[2,2] is bad, you wont see messages for L[2,1] because rejections stop where they’re at.

Right, you take the correlation phi, and the scales sigma[1] and sigma[2] and create

parameters {
  vector<lower=0>[2] sigma;
  real<lower=-1, upper=1> phi;
}
transformed parameters {
  matrix[2, 2] Sigma;
  {
    vector[2] var = sigma^2;
    real cov = sigma[1] * sigma[2] * phi;
    Sigma = [[var[1], cov], [cov, var[2]];
  }
}