Skip to content

Declared unbound ragged plate observation loses its public predictive output #61

Open

Description

@nsiccha

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 devibe ec50705dc48e673ad356b15afc6c58cd44e03213.

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
    end
end
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.

Activity

  1. nsiccha commented on Oct 20, 2026

    @nsiccha
    OwnerAuthor

    Fixed on devibe by c417234 (merged in f442bee).

    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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions