Calculating values in gen qualtities that don't vary with sample?

Hello,

I have a fairly complex model and it comes with a length generated quantities{} block for computing various predictions. As part of this process, I am creating an array of ID values that help me track which predictions go with which condition.

It would be beneficial to have access to this array in R when working with the model object. I can get it from the generated quantities block, but I end up with 1000 repetitions (i.e., one per draw).

This seems quite inefficient. Is there a way to tell Stan that the values in a given array are simply computed from the data and are constant over posterior samples? I know there is a transformed data {} block for doing this, but my understanding is that it is not currently possible to extract values from this block?

[I could also get around this by simply repeating my calculating in R, but this seems clunky and doubles the chances that I introduce bugs to my code!]

Sorry if this is answered somewhere else… I wasn’t quite sure of the terms when carrying out a search .

Sorry this got missed, @Alasdair_Clarke.

It is inefficient. There’s not only the I/O but also the posterior analysis and compute (though compute is unlikely to be the bottleneck).

One way you could make this more efficient if it really is constant is to use standalone generated quantities. That way, you could write it once. It’s a bit subtle and will depend on which interface you’re using as to how to set it up. But the idea is that you can take the draws from a model that’s been fit, then run a second model where those draws will be set as parameter values. In your case, it doesn’t even seem like you need any input draws. So one way to set it up so that you can do this in one model is this way:

data {
  int<lower=0, upper=1> include_constant_gq;

generated quantities {
  array[include_constant_gq ? N : 0] constant_value;
  if (include_constant_gq) {
    ... do calc to set constant_value ...
  }

Then you can run the program once with include_constant_gq = 1 for a single iteration and save the output, then run again with include_constant_gq = 0 and avoid all the print. It’s verbose and requires an extra input. We use this to write single general models in situations where we don’t want to ship a bunch of compiled models.

Hi

thanks,

so it seems that the solution is a bit clunky whatever I do. I think the easiest solution for me would be to pre-compute the array in the transformed data {} section, and then re-compute it in R when I need to interpret the posterior.

As always, I appreciate your help.

You could also pre-compute the array in R and then pass it as data to Stan. This eliminates duplicated computation, chances for mismatch/bugs, etc, and should simplify your code overall.

Would it make sense to move the relevant calculations inside a Stan function and expose that function in R? That way, you would use the same code in Stan and R.

Yes. that sounds like a good solution, but how would I do that? I have made use of the functions{} block in Stan, but I don’t know how to access those from R. If this is possible, this sounds very useful!

I you are using the R package cmdstanr, once you have compiled the model, use the expose_functions member function of the model object:

2 Likes