feat(state-space): exact discrete NB-branching latent with particle Gibbs (issue #48)#116
Draft
seabbs-bot wants to merge 3 commits into
Draft
feat(state-space): exact discrete NB-branching latent with particle Gibbs (issue #48)#116seabbs-bot wants to merge 3 commits into
seabbs-bot wants to merge 3 commits into
Conversation
Tests for the candidate state-space architecture for issue #48: the exact discrete-time NB-branching infection process with particle Gibbs inference. They cover the delay discretisation, onset-staging convolution, the NB renewal step mean, the weekly knot helpers, and both a prior-predictive draw and a gradient check on the continuous nuisance block (latent path conditioned). All red until the implementation lands. Also adds the proposal: docs/proposals/state-space-particle.md.
…ibbs Implements the state-space candidate architecture for issue #48: the exact discrete-time NB-overdispersed branching renewal as the latent infection process, with particle Gibbs as the inference route for the latent integer path and Mooncake-differentiable continuous nuisances for NUTS inside Gibbs. Sibling to the LNA route in PR #101 and the deterministic renewal route in PR #103. - src/state_space.jl: building-block submodels (Rt weekly walk, generation interval, incubation, onset-to-death, onset-to-report, onset-to-detection, CFR, surveillance dispersion, pooled ascertainment, traveller volume, seed size, offspring dispersion), NB-branching renewal kernel, onset staging via shared convolution, the `state_space_joint` composer wiring four streams plus the genetic TMRCA soft bound. Submodels injected as keyword arguments so every prior including the generation interval carries uncertainty into the fit; no inline `using` / `import`. The Rt walk uses a typed cumulative-sum non-centred parameterisation so Libtask's IR transformation handles it under PG (the abstract `Vector{Real}` allocation pattern is rejected). - test/test_state_space.jl: unit tests on the delay discretisation, onset-staging convolution, NB renewal mean, weekly knot helpers, prior-predictive draw, and a continuous-only Mooncake gradient check (latent path conditioned). - scripts/state_space.jl: end-to-end demo. Prior-predictive draw, continuous-nuisance gradient check, and a particle-Gibbs smoke test (50 particles, 10 iterations, ~80s on the n = 60 day grid). - docs/src/proposals/state-space-particle.md: full design, inference plan, runtime calculation, comparison vs the LNA route (PR #101), identifiability and honest verdict. - docs/make.jl: adds a "Redesign proposals" group with the page wired in so it renders in the docs build. PF-vs-LNA verdict: the architecture is mechanically operational (compiles, draws from the prior, PG completes). On the available data — four aggregate cumulative streams plus the genetic TMRCA bound — the exact discrete latent buys little over the LNA at roughly an order of magnitude higher cost, because cumulatives are nearly Gaussian regardless of latent discreteness. The state-space route becomes worthwhile when time-resolved early-phase data lands.
A one-knot grid would have indexed `knot_days[b + 1]` out of bounds. The single-knot path returns the constant value early; the multi-knot loop is unchanged. Regression test added (coderabbit review).
|
📖 Documentation preview is ready! View the docs for this PR at: http://epiforecasts.io/BVDOutbreakSize/previews/PR116/ This preview will be updated automatically when you push new commits. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Note
Draft — agent-generated. Not for merge without human review.
Candidate redesign for issue #48: a state-space architecture in which the latent daily infection counts follow the exact discrete-time NB-overdispersed branching renewal step, with particle Gibbs as the inference route for the integer latent path and Mooncake-differentiable continuous nuisances for NUTS inside Gibbs.
Sibling to the LNA route in #101 and the deterministic renewal route in #103.
Architecture
t = 1, …, n. Day 1 seeded from a small-cluster prior. Each subsequent dayI_t | I_{<t}, R_t ~ NegativeBinomial(mean = R_t · Σ_s I_{t-s} g_s, dispersion = φ), the exact NB-overdispersed branching renewal step.φ → ∞recovers the Poisson branching limit.R_twith non-centred Gaussian-walk knots; Gamma generation interval (mean and SD priors); Gamma incubation, onset-to-death, onset-to-report and onset-to-detection delays (each with priors on parameters); CFR; surveillance dispersion (NB1/√kprior); pooled DRC/Uganda ascertainment (non-centred, same as baseline); traveller volume; seed size; offspring dispersionφ.O_t. The four observation streams (deaths, reports, exports, deaths-among-exports) are built by convolvingO_twith onset-to-X delays once and shared across streams.missingso the composer doubles as a prior-predictive generator. Genetic TMRCA enters as the same censored upper-tail soft lower bound the baseline uses.Design rules
rt,gi,incubation,onset_to_death,onset_to_report,onset_to_detect,cfr,dispersion,ascertainment,traveller,seed,offspring, all overridable.using/importinsrc/state_space.jl; all imports stay on the module page.Vector{Real}allocation pattern that the renewal track uses is rejected by the PG transform.Inference and runtime
The natural sampler is
Gibbs(:I => PG(N), :nuisances => NUTS())— particle Gibbs over the integer latent path, NUTS over the continuous nuisances with Mooncake gradients.Demonstrated:
PG(50)smoke test runs to completion in ~80s on the n = 60 day grid.Honest runtime estimate for a full fit: roughly an order of magnitude or more above the LNA route, because per-Gibbs-sweep cost scales as
O(N · n)likelihood evaluations against a single evaluation per NUTS leapfrog on the LNA. Forn ≈ 130 d, N ≈ 200particles, expect ~5–25 h per chain for 1000 post-warmup samples versus ~15–25 min for the LNA route.PF-vs-LNA verdict
What the exact discrete latent buys in principle: heavier-than-Gaussian early-phase tails, integer realism at small counts, and one extra mass term in the posterior for minimum outbreak age consistent with an early-cluster fluctuation.
What it does not buy on the available data: the four primary observation streams are all cumulative aggregates, which by CLT are nearly Gaussian regardless of the latent's discreteness. The earliest-onset bound and the TMRCA bound only depend on
T, not on path discreteness, so the LNA captures both faithfully. The PG path-mixing rate is also weakest at the start of the path — exactly where the architecture is meant to be most informative — because the observational anchor is weakest there.Recommendation: do not pursue this as the default architecture for the current data. Keep #101 (LNA) as the production route while streams remain aggregate. The state-space route becomes worthwhile when a future data drop adds time-resolved early-phase records (e.g. dated first-onset trail, or sequenced cases with sampling dates that anchor the early branching) — at which point the path's discreteness starts to matter.
Identifiability risks
φ, process noise, and surveillance dispersionkall add to observed-total spread and are weakly separated under cumulative-only data; priors carry the inference.I_1andR_1near-degenerate, same asT/rin the baseline.Files
src/state_space.jl,test/test_state_space.jl,scripts/state_space.jl,docs/src/proposals/state-space-particle.md.docs/make.jlwires the proposal under a new "Redesign proposals" page group.This was opened by a bot. Please ping @seabbs for any questions.