Suppose I want to declare a matrix mat with ncol columns, where ncol is a function of some data foo. I could accomplish this with the below data block, which requires I pass Stan a data file with values for ncol.
How can I accomplish this within my Stan program without including ncol in my data file?
data{
vector[2] foo;
int ncol; // assume ncol = sum(foo)
matrix[2, ncol] mat;
}
Below I describe some approaches I've considered, but I'm not sure whether and why they (don't) work.
Approach 1: Operate-and-assign in data block
Operate-and-assign to compute ncol within the data block. However, the Stan Reference Manual states that assignment is not allowed in the data block. Therefore, this shouldn't work:
data{
vector[2] foo;
int ncol = sum(foo); // illegal: assignment isn't allowed in data!
matrix[2, ncol] mat;
}
Approach 2: move operate-and-assignment to the transformed_data block
Assign in the transformed_data block. My understanding is that I can't pass data directly to objects in the transformed_data block, which means I wouldn't be able to pass data to mat if I moved it there (see below). Similarly, I couldn't fix this by keeping mat in data because its dimensions would then depend on transformed_data, which is illegal.
data{
vector[2] foo;
}
transformed_data{
int ncol = sum(foo);
matrix[2, ncol] mat; // can't read and assign to `mat` because it's not in `data`?
}
Approach 3: Operate-but-don't-assign in data block
Compute but do not assign the value of ncol in the declaration of mat. I don't think this would work unless foo is always read in first and am not sure if it's legal anyway.
data{
vector[2] foo;
matrix[2, sum(foo)] mat; // possible illegal in data block?
}
Approach 3 succeeds at this while all of the other approaches do not. It is legal because:
datablock can be used in subsequent declarations within thedatablock;datablock. This is a bit subtle, since it does compute values used to declare an object.In the following, I show that Approach 3 succeeds at doing what I sought to do in the question while the others do not.
Baseline Example: passing
rstanextra dataApproach 3: compute without assignment in
datablockDemonstrating other approaches don't succeed
Approach 1: operate-and-assign in
data(error)Approach 2: operate and assign in
transformed data(no error but empty matrix)