I want to reparameterize the model as below. The key thing I think that need to be reparameterized is itc_k_pr and itc_beta_pr. But they will depend on X which will be updated in the loop in model block. So my question is how I could reparameterize them. I think if I follow the general instructions to put them in transformed_parameters block, itc_k_pr and itc_beta_pr will be sampled with fixed X. So I think maybe I need to put them in model block but I wonder whether it will work.
Here is the original code and I delete something unnecessary for others to understand the structure.
parameters {
real itc_k_pr[N,W]; // itc
real itc_beta_pr[N,W]; // itc
real<lower=-1, upper=1> C[2,Xdim];
matrix[N, Xdim] X1;
real<lower=0, upper=1> eta[N]; //eta
matrix[Xdim, exo_q_num] B;
vector[2] mu;
vector<lower=0.00000001>[2] sigma_r;
}
transformed parameters {
real<lower=0> itc_k[N,W]; // change for the sake of consistency - k_itc
real<lower=0> itc_beta[N,W];
itc_k = exp(itc_k_pr); // itc
itc_beta = exp(itc_beta_pr); // itc
}
model {
to_vector(to_matrix(C)) ~ normal(0, 0.05);
to_vector(X1) ~ normal(0, 0.1);
eta ~ normal(0.01, 0.1);// prior for eta
to_vector(B) ~ normal(0, 0.05);
mu ~ normal(0, 0.1);
sigma_r ~ normal(0, 0.1);
real X[N,W,Xdim];
real itc_grad_sum[N, W, 2];
for (s in 1:N) {
real reward_sum = 0;
for (w in 1:W) {
reward_sum += reward[s, w];
matrix[2, Tr_itc[s,w]] itc_grad ;
if (w == 1) {
X[s,w,] = to_array_1d(inv_logit(X1[s,]));
} else {
vector[Xdim] a = eta[s].*(reward[s, w] - reward_sum/w)* to_matrix(C)' * to_vector(itc_grad_sum[s, w-1]);
vector[Xdim] b = to_vector(X[s,w-1,]);
X[s,w,] = to_array_1d( b + a); //
}
itc_k_pr[s,w] ~ normal(mu[1] + B * to_vector(U[s,w,]) + to_matrix(C)[1,] * to_vector(X[s,w,]),sigma_r[1] );
itc_beta_pr[s,w] ~ normal(mu[2] + B * to_vector(U[s,w,]) + to_matrix(C)[2,] * to_vector(X[s,w,]),sigma_r[2] );
vector[Tr_itc[s,w]] ev_later = xxxxxx
vector[Tr_itc[s,w]] ev_sooner = xxxxxx
choice_itc[s,w,:Tr_itc[s,w]] ~ bernoulli_logit(itc_beta[s,w] * (ev_later - ev_sooner));
vector[Tr_itc[s,w]] itc_p = xxxx
vector[Tr_itc[s,w]] log_likelihood_p_grad = xxxxx
itc_grad = xxxx
itc_grad_sum[s, w, ] = xxxx
}
}
}
Below is the reparameterized code I think may work. But I am not sure about it and wonder how it can be revised so that the reparameterization can be done.
parameters {
real itc_k_pr[N,W]; // itc
real itc_beta_pr[N,W]; // itc
real itc_k_pr_standard[N,W]; // itc
real itc_beta_pr_standard[N,W]; // itc
real<lower=-1, upper=1> C[2,Xdim];
matrix[N, Xdim] X1;
real<lower=0, upper=1> eta[N]; //eta
matrix[Xdim, exo_q_num] B;
vector[2] mu;
vector<lower=0.00000001>[2] sigma_r;
}
transformed parameters {
//real itc_k_pr[N,W]; // itc
//real itc_beta_pr[N,W]; // itc
real<lower=0> itc_k[N,W]; // change for the sake of consistency - k_itc
real<lower=0> itc_beta[N,W];
itc_k = exp(itc_k_pr); // itc
itc_beta = exp(itc_beta_pr); // itc
}
model {
to_vector(to_matrix(C)) ~ normal(0, 0.05);
to_vector(X1) ~ normal(0, 0.1);
eta ~ normal(0.01, 0.1);// prior for eta
to_vector(B) ~ normal(0, 0.05);
mu ~ normal(0, 0.1);
sigma_r ~ normal(0, 0.1);
real X[N,W,Xdim];
real itc_grad_sum[N, W, 2];
for (s in 1:N) {
real reward_sum = 0;
for (w in 1:W) {
reward_sum += reward[s, w];
matrix[2, Tr_itc[s,w]] itc_grad ;
if (w == 1) {
X[s,w,] = to_array_1d(inv_logit(X1[s,]));
} else {
vector[Xdim] a = eta[s].*(reward[s, w] - reward_sum/w)* to_matrix(C)' * to_vector(itc_grad_sum[s, w-1]);
vector[Xdim] b = to_vector(X[s,w-1,]);
X[s,w,] = to_array_1d( b + a); //
}
itc_k_pr_standard[s,w] ~ std_normal();
itc_k_pr_standard[s,w] ~ std_normal();
itc_k_pr[s,w] = mu[1] + B * to_vector(U[s,w,]) + to_matrix(C)[1,] * to_vector(X[s,w,]) + sigma_r[1]*itc_k_pr_standard[s,w];
itc_beta_pr[s,w] = mu[2] + B * to_vector(U[s,w,]) + to_matrix(C)[1,] * to_vector(X[s,w,]) + sigma_r[2]*itc_beta_pr_standard[s,w];
vector[Tr_itc[s,w]] ev_later = xxxxxx
vector[Tr_itc[s,w]] ev_sooner = xxxxxx
choice_itc[s,w,:Tr_itc[s,w]] ~ bernoulli_logit(itc_beta[s,w] * (ev_later - ev_sooner));
vector[Tr_itc[s,w]] itc_p = xxxx
vector[Tr_itc[s,w]] log_likelihood_p_grad = xxxxx
itc_grad = xxxx
itc_grad_sum[s, w, ] = xxxx