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
Declared unbound ragged plate observation loses its public predictive output #61
Declared unbound ragged plate observation loses its public predictive output
StanBlocks 1e0af724be4f rejects a missing censored observation inside a ragged plate even when its hygienic cell name is declared as an observation. The same check is present on devibeec50705dc48e673ad356b15afc6c58cd44e03213.
using StanBlocks
data = (; t=[[0.2, 0.8], [0.3]], lo=[[0.05, 0.05], [0.05]], nsub=2)
base =@slic data begin
p ~plate(t, lo; outer=(nsub,)) do tt, ll
y ~censored(normal, tt, 1.0; lower=ll)
tt
endend
model = StanBlocks.SlicModel(base.model, base.data, base.mod, (:p_y,))
StanBlocks.stan_code(model)
This errors with censored: observations must be data-qualified; censored priors are not supported. The plate's discovery probe validates p_y, but emitted sampling uses private ragged storage p_y__pl_mem_1, which does not inherit that observation status. Adding the private name to the declaration permits code generation, but stan_descriptor(model).outputs contains only p_y__pl_mem_1; there is no public p_y_gen with flat coordinates and ragged segments.
Expected: one public predictive carrier for the declared observation, with a flat draw and inclusive per-group ends, and no sampled censored prior. Bound ragged cell observations should retain their flat predictive and aggregate pointwise likelihood carriers.
A declared observation sampled inside a ragged plate cell now keeps its public name. With SlicModel(..., (:p_y,)) the reproducer above compiles and:
generated quantities assign the public carrier, p_y_gen = p_y__pl_mem_…;
stan_descriptor(model).outputs contains p_y_gen (generative == :draw, source == :p_y) with inclusive per-group segments, and :predict lists it;
no censored prior is sampled;
a bound ragged sibling keeps its _gen and _likelihood carriers.
Declaring the private p_y__pl_mem_1 name is no longer needed; adding it as well still compiles. An undeclared censored cell, and a declared name that is actually a fitted latent, are still refused with censored priors are not supported.
Regression test: the slic: declared missing plate cells keep public predictive names testitem in test/unbound_observations.jl covers normal and censored laws, descriptor segments, data rebinding and stanc acceptance.
Activity
nsiccha commentedon Oct 20, 2026
Fixed on
devibeby c417234 (merged in f442bee).A declared observation sampled inside a ragged
platecell now keeps its public name. WithSlicModel(..., (:p_y,))the reproducer above compiles and:p_y_gen = p_y__pl_mem_…;stan_descriptor(model).outputscontainsp_y_gen(generative == :draw,source == :p_y) with inclusive per-groupsegments, and:predictlists it;_genand_likelihoodcarriers.Declaring the private
p_y__pl_mem_1name is no longer needed; adding it as well still compiles. An undeclared censored cell, and a declared name that is actually a fitted latent, are still refused withcensored priors are not supported.Regression test: the
slic: declared missing plate cells keep public predictive namestestitem intest/unbound_observations.jlcovers normal and censored laws, descriptor segments, data rebinding and stanc acceptance.