Offset multiplier syntax sampling behavior

I’m working a model with hierarchical intercepts and slopes.
When specifying the non-centered parameterization using offset and multiplier syntax like this I get poor sampling behavior:

parameters {
    real mu_a;
    real mu_b;
    real<lower=0> sigma_a;
    real<lower=0> sigma_b;
    vector<offset=mu_a, multiplier=sigma_a>[N] a;
    vector<offset=mu_b, multiplier=sigma_b>[N] b;
    ...
}

model {
    a ~ normal(mu_a, sigma_b);
    b ~ normal(mu_b, sigma_b);

    mu_a ~ normal(3, 0.04);
    sigma_a ~ std_normal();

    mu_b ~ normal(1, 0.01);
    sigma_b ~ std_normal();
    ...
}

However, when expressing a and b as transformed parameters like this, everything works fine:

parameters {
    real mu_a;
    real mu_b;
    real<lower=0> sigma_a;
    real<lower=0> sigma_b;
    vector[N] a_raw;
    vector[N] b_raw;
    ...
}

transformed parameters {
    vector[N] a = (a_raw + mu_a) * sigma_a;
    vector[N] b = (b_raw + mu_b) * sigma_b;
}

model {
    a_raw ~ std_normal();
    b_raw ~ std_normal();

    mu_a ~ normal(3, 0.04);
    sigma_a ~ std_normal();

    mu_b ~ normal(1, 0.01);
    sigma_b ~ std_normal();
    ...
}

I realize this is not much to work with, but does someone have any pointers of what may be going on here? Is there something going on “under the hood” that may explain these differences in sampling behavior?

In your manual noncentering, you multiply the means (as well as the unscaled offsets) by the sd. The sd should just multiply the unscaled offsets.

1 Like

Oops! That was way more obvious than expected. Thank you very much!!