Minute syntax question. Let’ say I want to create a sequence of integers. The following doesn’t work:
int sequence[n] = 1:n;
and the error message is the following
SYNTAX ERROR, MESSAGE(S) FROM PARSER:
Variable definition base type mismatch, variable declared as base type int[ ] variable definition has base type intVariable definition dimensions mismatch, definition specifies 1, declaration specifies 0 error in 'model873b2e593919_monster_reparm_par' at line 215, column 34
-------------------------------------------------
213: real C_inh[N_exh];
214:
215: int exp_index[N_experiments] = 1:N_experiments; // for reduce_sum
^
216:
-------------------------------------------------
Error in stanc(filename, allow_undefined = TRUE) :
failed to parse Stan model 'monster_reparm_par' due to the above error.
It’s easy to do this in a for loop, but I was wondering if the above syntax is expected to work.
I don’t think it is. Unless something has changed in the latest stan versions, Stan doesn’t use range-expressions like R does. E.g., R takes 1:10 and expands it to c(1,2,3,4,...,10). Stan does not do this. It’s really just some syntactic sugar. E.g., the for(n in 1:N) does not expand out to 1,2,…,10; but rather something like for(int n = 1; n <= N; ++n); so A:B is really just another way of setting a starting value and a condition.
That’s something I’ve wanted to do before, and would make for a nice convenience function.
I can add this to the Math library pretty easily, @rok_cesnovar would this be difficult for the parser? In other words, would it be difficult to deduce the different meanings of 1:N between:
linspaced_array(K, low, high) produces an array from low to high (included) with elements spaced as (high - low) / (K - 1). For K=1, the array will contain the high value, for K=0 it returns an empty array.
We might be able to parse 1:N to linspaced_*(N,1,N). I am however not an expert on parsing to say that with much authority. Please open a stanc3 issue if you would prefer 1:N to linspaced_array.
Yeah that’s what I was thinking. It just needs to be tweaked because the current implementation will only return an array of doubles (i.e., std::vector<double> / real[]) which can’t be used for indexing or assigned to an integer array.
But that just needs some simple templating added to make that work
Ohh yeah, skimmed this to fast. If int is important then yes, we would need to make int[] linspaced_int_array(int, int, int), or int[] linspaced_array(int, int, int)
The colon is allowed in both for-loops and index expressions. In both cases an integer array is also a valid expressions but the ambiguity does not change behaviour; either interpretation does the same thing.
vector[N] svec = vec[1:N];
for (i in 1:N) {
int seq[N] = (1:N);
vector[N] svec = vec[seq];
for (i in seq) {
linspaced does not quite work with integers. For example, linspaced_array(3,1,2) should be {1.0,1.5,2.0} but those aren’t integers.
Instead you want something like int[] unitspaced_array(int low, int high).