I have already make the following stan model which is compiling and I obtain good results (I use cmdstanr).
In this model, the prior distributions for the logit of the components of \lambda are Normal(0,10).
// The input data:
// 'n0' an array of integers giving the numbers of seronegative persons of the different ages in the sample,
// 'n' an array if integers giving the numbers of persons of the different ages in the sample,
// 'n0' and 'n' of length 'N' the number of ages observed in the sample.
data {
int<lower=0> N;
array[N] int<lower=0> n0; //int<lower=0> n0[N];
array[N] int<lower=0> n;//int<lower=0> n[N];
}
parameters {
// specify logitlambda as a parameter
vector[N] logitlambda;
}
transformed parameters {
// treat lambda as a transformed parameter
vector[N] lambda;
lambda[1:N] = inv_logit(logitlambda[1:N]);
vector[N] theta;
vector[N] delta;
theta = cumulative_sum(lambda);
delta = exp(-theta);
}
model {
for (i in 1:N){
logitlambda[i] ~ normal(0, 10);
}
n0 ~ binomial(n,delta);
}
But now I want to change the prior distributions for the components of my vector \lambda. Indeed, I want a priori a kind of Bernoulli-Logit distribution:
with two parameters s
and max
, lambda[i]
should be equal to zero with probability s
, and should follow a uniform(0,max)
with probability 1-s
.
Then I modified my model in the following way, but it is not compiling anymore:
data {
int<lower=0> N;
array[N] int<lower=0> n0; //int<lower=0> n0[N];
array[N] int<lower=0> n;//int<lower=0> n[N];
real<lower=0> max1;
real<lower=0> s1;
}
parameters {
// 'u' of length 'N', to compute the prior for lambda.
vector[N] lambda;
}
transformed parameters {
vector[N] theta;
vector[N] delta;
theta = cumulative_sum(lambda);
delta = exp(-theta);
vector[N] u;
}
model {
for (i in 1:N){
u[i] ~ uniform(0,1);
if (u[i] < s1)
lambda[i] = 0;
else
lambda[i] ~ uniform(0,max1);
}
n0 ~ binomial(n,delta);
}
The error is in the model block, and is the following:
Cannot assign to global variable ‘lambda’ declared in previous blocks.
Any help would be welcome. I understand that I can not assign lambda[i]=0
in the model block, but I do not know where to assign it. I tried different things without success. Maybe I should create a new function to define a custom distribution but I do not know how to do. I read this part of the manual concerning a zero-inflated Poisson (5.6 Zero-Inflated and Hurdle Models | Stan User’s Guide), but it does not concern a prior distribution, in this example it is the data which follows the new zero inflated poisson distribution, not a parameter (hence it concerns the likelihood, not the prior).
You can use the following data if you want to make some tests:
n <- rep(100,10)
n0 <- c(97,91,85,77,68,58,49,40,30,24)
data_list <- list(N = 10, n0 = n0 ,n=n, max1=0.5,s1=0.05)
# Ajusting model
fit <- mod$sample(
data = data_list,
seed = 123,
chains = 4,
parallel_chains = 4,
refresh = 0,
iter_warmup=200,
iter_sampling=2000,
save_warmup = TRUE
)