Create temporary stan object for indexing (needs to be integer) that is not a data object

Dear stan community,

I have a question that is rather a “nice thing to have” than an error/ necessity.

If I see correctly, in stan, to extract values from vectors or matrices, I need to provide indices of the rows/columns from which to extract those values.
These indices need to be integers (obviously given that non-integer rows/ columns are note defined).
However, afaics, the only objects that stan allows to be integers are those defined under data or transformed data.

Sometimes, it can however be nice to create a temporary object that is an scalar integer (e.g. the stimulus ID or the response on a particular trial in a cognitive task) and that is then used repeatedly as an index to extract certain bits of data from other vectors/ matrices. Just for convenience (to avoid multiple nesting of several objects with brackets into each other).

Question:
Afaics stan does not allow objects in the parameters or transformed parameters to be integers… is there another way to define such temporary objects?

Here a short example:

data {
  int<lower=0> nStim;           // number of stimuli
  int<lower=0> nResp;           // number of responses
  int<lower=0> nTrial;          // number of trials per subject
  int<lower=0> nSub;            // number of subject

  int<lower=1> stimuli[nSub,nTrial];            // stimulus identifier 1-12
  int<lower=0, upper=1> resp[nSub,nTrial];      // responses (1/0)
  int<lower=-1, upper=1> outcome[nSub,nTrial];  // outcomes (-1 or 1)

  matrix[nStim,nResp] Qi;                       // initial action values: for each stimulus (rows), response (columns), used to initialize Q
}
// ... dropping some code here...
transformed parameters {
  matrix[nStim,nResp] Q;                        // Current action values for all cues: for each cue, for each response (12x2)
  // Learning model:
  for (iSub in 1:nSub){                         // Loop over subjects
  
      // Initialize variables:
      Q  = Qi;                                  // Initialize action values for all cues
      for(iTrial in 1:nTrial){                  // Loop over trials
        
        // Retrieve settings for this trial
        for(iResp in 1:nResp){                  // For each possible response:
          q[iResp] = Q[nStim,iResp];            // Retrieve action value given cue s seen in this trial iTrial of this subject iSub
        }
        
        // Update Q-values:
        PE = outcome[iSub,iTrial] - Q[stimuli[iSub,iTrial],2-resp[iSub,iTrial]];                                        // Compute prediction error
        Q[stimuli[iSub,iTrial],2-resp[iSub,iTrial]] = Q[stimuli[iSub,iTrial],2-resp[iSub,iTrial]] + epsilon[iSub]*PE;   // Update Q-values
    }
}

You see that in the last row,

  1. I need indices for the stimuli and the resp matrices, and the outputs of these matrices are again indices for the Q matrix… and there can be cases with even more nesting.
  2. I have to hard-code the transformation of the 0/1 values in the resp matrix into 1/2 in order to use them as indices for Q—every time I use the resp[iSub,iTrial] in my code.

Could I somehow define temorary objects s and r like

s = stimuli[iSub,iTrial];
r = 2 - resp[iSub,iTrial]];

that are integers and can be used for further indexing?

Thanks already for any pointers!

You can create temporary integer objects by wrapping them in curly braces ({}), with the caveat that they can’t be accessed outside of the braces. This also means that you can declare integer objects within loops like so:

    for (iSub in 1:nSub){                         // Loop over subjects
      ...
      for(iTrial in 1:nTrial){                  // Loop over trials
        int stim_ind = stimuli[iSub,iTrial];
        ...
        }
    }

Thanks @andrjohns! I never tried to initialize new objects with in the for-loops/ curly braces, but always straight at the beginning of the transformed parameters section…
But it works now!

This thread can be closed now.