You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Lift the "(Transformed) parameters cannot be integers" restriction #3363
When working with ragged arrays, it's sometimes useful to me to have transformed parameters of the type
tuple(
array[n_groups] int,
vector[n_total]
)
However, this is not allowed, due to the restriction in the title.
It would be nice if ths restriction could be lifted, though there are of course ways to work around it.
Can you say a bit more? The fragment you provided doesn't look like valid Stan code to me, and I'm not clear why something like this wouldn't just be transformed data
Edit: ah I see, you want a tuple that contains two pieces, one of which is an integer. Presumably the integer items do not change per iteration? If so, I think you'd be better off making this a local in the model block
you want a tuple that contains two pieces, one of which is an integer. Presumably the integer items do not change per iteration?
Yes, exactly! And yes, usually the integer values don't change.
If so, I think you'd be better off making this a local in the model block.
Wait that would work? And you can also write out integers in the generated quantities block, but you can't do so in the transformed parameters block? That seems a bit arbitrary, don't you think?
In any case, the reason why I'd prefer to be able to have transformed parameters of the above type is that then I don't have to worry about repeatedly packing and unpacking the tuples that I have represent ragged vectors - instead, a ragged vector is simply a tuple of the above type, but the ragged vector as a whole can of course logically live in any of the blocks, depending on whether the vector component is data / transformed data / parameter / generated quantity.
With the current restriction in place, even though I may have functions which logically act on ragged vectors and return ragged vectors, I'll always have to attach extra unpacking logic whenever the result gets stored in the transformed parameters bloc. But not at any other time, e.g. within UDFs, in the transformed data block or in the generated quantites block.
I don't think there's really any drawback in lifting the restriction - or can anything be made to break by this? It's already not allowed that size information depends on parameter variables, even if that size information is constant. It's backwards compatible, because it simply makes the language more permissive. The only potential drawback is that more data would get written out (e.g. via cmdstanpy to CSV) - but (IMO) that should be a trade off that the user can make if they want to.
I'd be curious to hear @bob-carpenter's thoughts as well.
Yes, we could potentially allow integers as transformed parameters. There's a reason I didn't allow them in the original design. I think of transformed parameters as transforms of parameters. Our parameters are continuous and while you can in various ways launder them into integer values, it's strongly discouraged because it almost always breaks continuous differentiability. If the integer values don't change based on the parameters, then they should be defined in the transformed data block.
Do you have a use case where the integer value changes based on the parameters but it doesn't break autodiff? I didn't understand the ragged vectors example.
If they're constant, is there a reason you can't define them in the transformed data block? Then they only need to get computed once. If a constant value goes into the transformed parameter block, it gets stored in the output and run through posterior diagnostics, which will all be NaN other than mean and zero variance.
Activity
WardBrian commentedon Oct 10, 2025
Can you say a bit more? The fragment you provided doesn't look like valid Stan code to me, and I'm not clear why something like this wouldn't just be transformed data
Edit: ah I see, you want a tuple that contains two pieces, one of which is an integer. Presumably the integer items do not change per iteration? If so, I think you'd be better off making this a local in the model block
nsiccha commentedon Oct 13, 2025
Yes, exactly! And yes, usually the integer values don't change.
Wait that would work? And you can also write out integers in the generated quantities block, but you can't do so in the transformed parameters block? That seems a bit arbitrary, don't you think?
In any case, the reason why I'd prefer to be able to have transformed parameters of the above type is that then I don't have to worry about repeatedly packing and unpacking the tuples that I have represent ragged vectors - instead, a ragged vector is simply a tuple of the above type, but the ragged vector as a whole can of course logically live in any of the blocks, depending on whether the vector component is data / transformed data / parameter / generated quantity.
With the current restriction in place, even though I may have functions which logically act on ragged vectors and return ragged vectors, I'll always have to attach extra unpacking logic whenever the result gets stored in the transformed parameters bloc. But not at any other time, e.g. within UDFs, in the transformed data block or in the generated quantites block.
I don't think there's really any drawback in lifting the restriction - or can anything be made to break by this? It's already not allowed that size information depends on parameter variables, even if that size information is constant. It's backwards compatible, because it simply makes the language more permissive. The only potential drawback is that more data would get written out (e.g. via cmdstanpy to CSV) - but (IMO) that should be a trade off that the user can make if they want to.
I'd be curious to hear @bob-carpenter's thoughts as well.
bob-carpenter commentedon Oct 13, 2025
Yes, we could potentially allow integers as transformed parameters. There's a reason I didn't allow them in the original design. I think of transformed parameters as transforms of parameters. Our parameters are continuous and while you can in various ways launder them into integer values, it's strongly discouraged because it almost always breaks continuous differentiability. If the integer values don't change based on the parameters, then they should be defined in the transformed data block.
Do you have a use case where the integer value changes based on the parameters but it doesn't break autodiff? I didn't understand the ragged vectors example.
nsiccha commentedon Oct 14, 2025
No - the integer values are generally constant for my use cases.
I'll share a minimal motivating example when I have the time - hopefully soon!
bob-carpenter commentedon Oct 14, 2025
If they're constant, is there a reason you can't define them in the transformed data block? Then they only need to get computed once. If a constant value goes into the transformed parameter block, it gets stored in the output and run through posterior diagnostics, which will all be NaN other than mean and zero variance.