Given a parameter that I expect to follow a lognormal distribution (e.g., because I know the value must be greater than 0), I find it more intuitive to use a transformation. So, instead of doing the following where I need to use a complicated formula to convert the values of mu and sigma so that I can obtain the mean value of the distribution:
parameters {
real mu;
real sigma;
real gain;
}
model {
gain ~ lognormal(mu, sigma);
}
Can I just do the following?
parameters {
real mu;
real sigma;
real t_gain;
}
transformed parameters {
real gain;
gain = exp(t_gain);
}
model {
t_gain ~ normal(mu, sigma);
}
This is just a snippet of a much larger model, but I’m wondering if my approach is reasonable or if there’s a reason to favor the added conceptual complexity of the lognormal approach? Is the lognormal more likely to converge or sample better?
Which is what I’ve proposed in my original post (except that the transformation is performed in the transformed parameters block).
Are they mathematically equivalent? Do I need to perform a Jacobian correction regardless of whether I do log(y) ~ normal(..., ...) or y ~ exp(normal(..., ...))?
Those two models are equivalent. Though in the first model, you would want to write real <lower=0> gain; rather than real gain;
The second model will likely be more numerically stable, since under the hood when you do the greater than zero constraint, it does the exponential transformation, and then takes the log of x in the lognormal distribution statement.
@stemangiola: Are you fine with the approach proposed by @aaronjg? He seems to think it’s a bit more computationally stable. I’m running it now, but my model is very slow so I won’t know for some time whether it works.
I have a lognormal model that requires addition of two components. Is there any adjustment needed for the following?
data {
int N;
vector<lower=0>[N] x;
vector<lower=0>[N] y;
}
parameters {
real log_beta;
real<lower=0> sigma_log_e;
}
model {
vector[N] mu = x + exp(log_beta);
y ~ lognormal(log(mu), sigma_log_e);
}
No adjustment needed. Though it may be more numerically stable to transform x to log_x in the transformed data block and use log_mix(prop,log_x[i],log_beta[i]). On the other hand, it won’t be vectorized so may be slower. If I were you, I’d keep it as is for now, but if you start running into divergent transitions, you should consider using log_mix. You might even want to roll your own version of it, and handle the translation of prop_raw on the unconstrained space to prop on the constrained space and then calculate the appropriate values for log(prop) and log(-prop) using prop_raw.
Anyway, probably not worth worrying about unless you see stability issues, as indicated by divergences.