Find or Which command in Stan?

Hi,

I have a matrix programming question.

In Matlab, there is a “find” command (https://www.mathworks.com/help/matlab/ref/find.html).

In R, the equivalent command is “which”.

In Stan, I need to find the indices of a matrix when the elements meet my condition. And then I am going to assign new values to these elements based on the indices.

Is there a command like “find” or “which” that I can use?

Thanks.

1 Like

The short answer is no. You can, of course, accomplish that by looping. (btw, loops are fast in Stan.)

Hopefully you’re just considering this for the transformed data block or the generated quantities block. If not, this sounds like it could be a lot of trouble for Stan.

If this is not too much trouble, are you able to provide a simple example or two?

I use the Find or Which command often in my Matlab and R programs. I never even thought about how looping could have accomplished the same task, although I am sure it would be feasible.

Thank you in advance.

That find function in MATLAB is like a Swiss Army knife. It’s a hard function to write in Stan because of the size declarations. But let’s look at what it does for a vector (the matrix returns of positions is odd and I don’t think it’ll be any use in Stan).

functions {
  int num_lt(real x, vector y) {
    int n = 0;
    for (i in 1:rows(y))
      if (y[i] < x)
         n = n + 1;
    return n;
  }

  int[] find_lt(real x, vector y) {
    vector[num_lt(x, y)] result;
    int n = 1;
    for (i in 1:rows(y)) {
      if (y[i] < x) {
        result[n] = i;
        n = n + 1;
      }
    }
    return result;
  }
}

Then you can use num_lt(x, y) to find the number of items in y that are less than x and then use find_lt(x, y) to return the integer array of indexes of elements less than y.

For any of this to be at all useful, we really need to build in some of the selection logic from R. We’d also need something like lambdas if we want to bind arbitrary conditions.

1 Like

Hi

Thank you for those. I have a simpler question that maybe easier to answer.

In R, if I have a simple binary matrix, W, and a vector, a, I can do the following:

W<-matrix(c(0,1,0,1,1,0), nrow=2)

a<-c(2,3,4)

W[W>0] <- a

In a way, this is doing what “find” or “which” does, even more succinctly. Is this operation legit within Stan, without resorting to theose user-defined functions, num_lt(x, y) and find_lt(x, y), or their variations for matrices?

Thanks again.

Nope, nothing like that in Stan yet. Some of it we could build in with special functions, but this one would need to vectorize comparisons then use them as indexes.

I see. Thanks for the suggestion. It makes sense!

Is it true that at the current moment, I need to reply on for-loops to vectorize a matrix and reshape a vector back into a matrix?

There are functions like to_matrix and to_vector to unflatten and flatten.

Also, I should’ve added that loops to reshape may be clunky, but they’re fast in Stan. There’s no autodiff overhead, so it’s just executing C++ loops.