Dear all,
I would like to fit a model with a truncated normal distribution to my data. The data is from 50 subjects who on each trial do two ratings which go from 0 to 100 (including those values). I would like to truncate the normal distribution for these ratings with a lower boundary of 0 and an upper boundary of 100. However, when I include the truncation, some chains finish, but others give the error: “Initialization between (-2, 2) failed after 100 attempts.”
data {
int ntr; // number of trials
int ntr_phase; // maximum trial number per phase
int nrow; // number of rows of whole data set (equal to ntr * nsub)
int nsub; // total number of subjects
int subID[nrow]; // subject ID
real U; // = 100, upper bound for ratings
real L; // = 0, lower bound for ratings
// ratings
real<lower=L,upper=U> RateSelf[nrow]; // go from 0 to 100
real<lower=L,upper=U> RateOther[nrow]; // go from 0 to 100
int active_trial[nrow]; // trial type, 0 or 1
real control_level[nrow]; // goes from 0.2 to 0.8
real feedback[nrow]; // goes from 0 to 100
int phase_trial[nrow];
}
parameters {
real<lower=0> rating_noise[nsub];
real<lower=0,upper=1>learning_rate[nsub];
}
model {
real belief_self[nrow];
real belief_other[nrow];
real belief_total[nrow];
real PE_total[nrow];
real PE_self[nrow];
real PE_other[nrow];
// Priors for parameters
rating_noise ~ normal(20,5);
learning_rate ~ normal(0.5,0.1);
// Learning model: how we update beliefs based on outcomes
for (itr in 1:nrow){
if (phase_trial[itr]==1){
belief_self[itr] = RateSelf[itr];
belief_other[itr] = RateOther[itr];
}
// Based on feedback, update the belief for the next trial
if (active_trial[itr]!=1){
belief_total[itr] = control_level[itr] * belief_self[itr] + (1-control_level[itr])*belief_other[itr];
} else{
belief_total[itr] = control_level[itr] * 0 + (1-control_level[itr])*belief_other[itr];
}
PE_total[itr] = feedback[itr] - belief_total[itr];
// split up total PE
PE_self[itr] = PE_total[itr] * control_level[itr];
PE_other[itr] = PE_total[itr] - PE_self[itr];
// Update beliefs for next trial
if (phase_trial[itr] < ntr_phase){
belief_self[itr+1] = belief_self[itr] + learning_rate[subID[itr]]*PE_self[itr];
belief_other[itr+1] = belief_other[itr] + learning_rate[subID[itr]]*PE_other[itr];
}
}
// Decision model: mapping beliefs to ratings
for (itr in 1:nrow){
RateSelf[itr] ~ normal(belief_self[itr],rating_noise[subID[itr]]) T[L,U];
RateOther[itr] ~ normal(belief_other[itr],rating_noise[subID[itr]]) T[L,U];
}
}
I tried the following things:
- Works for only one subject at a time (for e.g. subjects 1-5)
- Does not work for subjects 1-5 together
- works with only upper boundary and works with only lower boundary
What has not helped:
- force data to be >0 and <100
- avoid fitting the first trial where rating = belief
- in the model, force beliefs (i.e. mean of truncated distribution) to remain within boundaries
I called stan with this command:
fit_data = rstan::stan(file='model_truncated.stan',data=data_real,chains=3,iter=1000, cores=1)
Could anyone point out what went wrong in the model?
Help is much appreciated!
Best, Lisa