Cannot determine source of error causing scale param to be < 0 for prior predictive check

I’m trying to code a very basic intercept only model with both prior and predictive checks following the code provided in Chapter 26 of the Stan User guide (https://mc-stan.org/docs/2_23/stan-users-guide/ppcs-chapter.html). I’m getting two errors and have spent the last hour and a half trouble shooting to no success.

Error 1 " Exception: normal_rng: Scale parameter is -9.4569, but must be > 0! (in ‘model3abc45661853_002_intercept_only’ at line 47)"

Error 1 I think is referring to the line y_prior[N] = normal_rng(prior_nation_coef, prior_tau); I think this is telling me that prior_tau must be > 0. Earlier in that generated quantities block I declare prior_tau as having a lower limit of 0, so I’m not sure how I’m getting prior_tau values < 0.

Error 2: “Exception: model3abc2ba239f6_002_intercept_only_namespace::write_array: sd_y_rep is nan, but must be greater than or equal to 0 (in ‘model3abc2ba239f6_002_intercept_only’ at line 38)”

I think Error 2 is referring to the line sd_y_rep = sd(to_vector(y_rep)); where I’m trying to calculate the sd of my y_reps. I imagine I’m getting this error because earlier I declared sd_y_rep with a lower limit of 0, but I’m confused as to how the sd() function could be returning a value < 0.

data {
  int<lower = 1> N; // number of obs
  vector[N] Y; // 
}

transformed data{
  real<lower = 0> mean_y = mean(to_vector(Y));
  real<lower = 0> sd_y = sd(to_vector(Y));
}


parameters {
real nation_coef; // national level regression coefs
real<lower=0> tau; // standardeviation of regression coefs
}


model {
 //priors
 nation_coef ~ normal(0, 5); 
 tau ~ cauchy(0, 2.5); 
 

// likelihood 
Y ~ normal(nation_coef, tau);
}

generated quantities{
  // prior predictive check declarations
  real prior_nation_coef;
  real<lower = 0> prior_tau;
  real y_prior[N];

  // posterior predictive checks declarations
  real y_rep[N];
  real mean_y_rep;
  real<lower = 0> sd_y_rep;
  int<lower = 0, upper = 1> mean_gte;
  
  // Log Likelihoods for WAIC/LOO declare
  vector[N] log_lik;
  
  //prior predictive check 
  prior_nation_coef = normal_rng(0, 5);
  prior_tau = cauchy_rng(0, 2.5);
  y_prior[N] = normal_rng(prior_nation_coef, prior_tau);
  
  // poster pred check
  y_rep[N] = normal_rng(nation_coef, tau);
  mean_y_rep = mean(to_vector(y_rep));
  sd_y_rep = sd(to_vector(y_rep));
  mean_gte = (mean_y_rep >= mean_y);
  
  //log likelihood
  for (n in 1:N) {
    log_lik[n] = normal_lpdf(Y[n] | nation_coef, tau);
  }

}

If you want to try this yourself, any random vector of Ys will work, I think to test.

Thank you for your help!

You need prior_tau = fabs(cauchy_rng(0, 2.5)); here in order to draw from a half-Cauchy distribution.

2 Likes

Thanks - that helped solve Error 1. Can you explain why I need the fabs() function though? I thought by specifying that real<lower = 0> prior_tau; was enough to keep the values positive.

That is only for tau in the parameters block. For things in the generated quantities block like prior_tau, you have to ensure things are positive yourself.

1 Like