How to implement arbitrary constraints on functions of parameters in a stan model

Dear stan community. I want to apply in my stan models below the following inequality constraints:

#inequality constraints for model 1

(1) alpha_0 ≤0;
(2) exp(- alpha_0) ≥ 1 + alpha_1 ≥0;
(3) exp(- alpha_0) ≥ 1 + alpha_2 ≥ 0; and
(4) exp(- alpha_0) ≥ 1 + alpha_1 + alpha_2 + alpha_3 ≥0

#inequality constraints for model 2

(1) 1 + beta_1 > 0;
(2) 1 + beta_2 > 0; and
(3) 1 + beta_1 + beta_2 + beta_3 > 0

#model 1

data{
int N;  
int ncases[N];
int A[N]; 
int B[N];  
int nn[N]; 
}

parameters {
real alpha_0; 
real alpha_1;
real alpha_2; 
real alpha_3; 
}

transformed parameters {
vector[N] pp_hat;   
for (i in 1:N) {    
pp_hat[i] = exp(alpha_0) * (1 + alpha_1*A[i] + alpha_2*B[i] + alpha_3*A[i]*B[i]);
}
}

model {
alpha_0 ~ normal(0, 5);
alpha_1 ~ normal(0, 5);
alpha_2 ~ normal(0, 5);
alpha_3 ~ normal(0, 5);
ncases ~ binomial(nn, pp_hat);
}

#model 2

data{
int N;                            
int ncases[N];                       
int A[N];                               
int B[N];                                 
int nn[N];                                          
}

parameters {
real beta_0;
real beta_1; 
real beta_2; 
real beta_3; 
}

transformed parameters {
vector[N] pp_hat; 
vector[N] odds;   
for (i in 1:N) {   
odds[i] = exp(beta_0) * (1 + beta_1*A[i] + beta_2*B[i] + beta_3*A[i]*B[i]);
pp_hat[i] = odds[i]/(1 + odds[i]);
}
}

model {
beta_0 ~ normal(0, 5);
beta_1 ~ normal(0, 5);
beta_2 ~ normal(0, 5);
beta_3 ~ normal(0, 5);
for (i in 1:N)
  ncases ~ binomial(nn, pp_hat);;
  
}

EDIT: right-hand side of the third constraint for model 1 corrected by replacing alpha_1 with alpha_2

Thank you in advance for any help.

The third constraint is the same as the second, so I assume it should refer to alpha_2.

parameters {
  real<upper = 0> alpha_0;
  real<lower = -1, upper = exp(-alpha_0)> alpha_1;
  real<lower = -1, upper = exp(-alpha_0)> alpha_2;
  real<lower = -1 - alpha_1 - alpha_2, upper = exp(-alpha_0)> alpha_3;
}
parameters {
  real<lower = -1> beta_1;
  real<lower = -1> beta_2;
  real<lower = -1 - beta_1 - beta_2> beta_3;
}
1 Like

This is perfect and brilliant. Thank you very much @bgoodri. Just edited the right-hand side of the third constraint for model 1.