Multiplication between real, vector and array in Stan

Recently I am writing a Stan code with the following simplification of the original code:

Here time is known data with length N, and b is a vector of regression coefficient with length 4, when I definied them as:

data {
real time[N];
}

paramters{
vector[4] b;
}

model{
product = b[4]*time;
}

There is error message as:

SYNTAX ERROR, MESSAGE(S) FROM PARSER:
No matches for: 

  real * real[ ]

Available argument signatures for operator*:

  real * real
  vector * real
  row_vector * real
  matrix * real
  row_vector * vector
  vector * row_vector
  matrix * vector
  row_vector * matrix
  matrix * matrix
  real * vector
  real * row_vector
  real * matrix

No matches for: 

  vector + ill-formed

In my understanding that now time is a vector of length 4 and time is an array of length N, but why we cannot multiply them together in this case? Since if it’s in R, it is very natural to write something like :real * real[ ] but now it rertuns an error and makes me so confused.

After trying I found the following code works:

data {
vector[N] time;
}

paramters{
vector[4] b;
}

model{
product = b[4]*time;
}

Could anyone explain the difference between these two Stan codes and why the first one returns some error?

edit by @Max_Mantei: added stan tags for code formatting

Hey!

Loosely speaking, Stan doesn’t know how to treat an array of real numbers when it comes to mathematical operations. However, Stan does know how to multiply a scalar and a vector! Therefore, the second solution works. When you are coming from R this is probably a bit weird. After all there is this saying “Everything in R is a vector.” (which is not quite true, but there is ‘some’ truth to it). Unlike in a lot of R code types matter in Stan.

That being said, you could use an array of reals, but you’d have to loop over the array. This is fine in Stan, because unlike R, loops in Stan are fast. So in your first code you could do something like this:

for (n in 1:N)
   product[n] = b[4] * time[n];

Cheers!
Max

2 Likes

Maybe I am missing something, but dot-* should work also, no? Like:

product = b[4] .* time;

Does this work for you? I get an error:

SYNTAX ERROR, MESSAGE(S) FROM PARSER:
No matches for: 

  real .* real[ ]

Yes, it would only work with the second code:

data {
  vector[N] time;
}

parameters { 
  vector[4] b; 
}

generated quantities { 
  product = b[4] .* time; 
}

@Max_Mantei: as you explained earlier and I was just proposing to write your code in one line :-)