I would like to implement a zero-based constraints of a Q dimensional parameter vector such that a subset (i.e. D parameters) is set to zero while the remaining elements (P= Q-D parameters) are assigned random samples. Currently, I create the index vectors in R and pass them on to rstan as data
G <- 5
Q <- G*G
gamma_zeros <- c(1:G, (1:(G-1))* G +1)
gamma_nonzeros <- setdiff(1:Q, gamma_zeros)
D <- length(gamma_zeros)
P <- length(gamma_nonzeros)
These would be used in the transformed parameter block as such
data {
int<lower=1> Q; // dimension of parameter vector
int<lower=1> D; // total number of zeros constrains
int<lower=1> P; // total number of non zeros constraints
int<lower=1> gamma_zeros[D]; // zero constraint index
int<lower=1> gamma_nonzeros[P]; // non zero index
}
parameters {
vector[P] gamma_tilde;
}
transformed parameters {
vector[Q] gamma;
for(d in 1:D) {
gamma[gamma_zeros[d]] = 0;
}
for(p in 1:P) {
gamma[gamma_nonzeros[p]] = gamma_tilde[p];
}
}
model {
gamma_tilde ~ student_t(4, 0, 4);
// ..
}
I tired to create the index vectors in stan’s model, but I was not able to do so. I was expecting that stan would be able to append arrays together and convert real to integer types but that does not seem to be the case. Is there an easy way to create integer index arrays in stan?
The for loop can help me create the sequence of integers
for(q in 1:Q) {
s[q] = q;
}
but I am not sure the R-like syntax start:end would work since I would need to append integer arrays (i.e. c(1:G, (1:(G-1))* G +1)at one point and such an operation is not implemented in stan. For example, say
There is an append_array function in 2.18 but it only takes two arguments. You are probably best to just create your array via a loop in the transformed data block.
int<lower=1> D= 2*G-1; // total number of zeros constrains
int<lower=1> P= G*G-D; // total number of non zeros
int<lower=1> gamma_zeros[D]; // zero constraint index array
int<lower=1> gamma_nonzeros[P]; // nonzero index array
int<lower=1> dd;
int<lower=1> pp;
dd=1;
pp=1;
for(i in 1:G) {
for(j in 1:G) {
if (i==1 || j==1) {
gamma_zeros[dd] = (i-1)*(G)+j;
dd += 1;}
else {
gamma_nonzeros[pp]= (i-1)*(G)+j;
pp += 1;}
}
}