Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
91c9a10
Reimplement particle MCMC (SMC and PG) natively, removing AdvancedPS
yebai Aug 26, 2026
d9e4704
particle_mcmc: Report the model's own varinfo updates, and slim the r…
yebai Aug 26, 2026
519b9a2
particle_mcmc: Tidy two comments in the particle tests
yebai Aug 26, 2026
bf9f9b2
particle_mcmc: Mark the `@addlogprob!` helper as maybe-producing
yebai Aug 26, 2026
c2f2399
particle_mcmc: Resample between observations, not before the first
yebai Aug 26, 2026
08f0e8c
particle_mcmc: Give PG a plain-data state so chains serialise
yebai Aug 26, 2026
ee405cd
particle_mcmc: Report an ignored `initial_params` under PG
yebai Aug 26, 2026
b305718
particle_mcmc: Name the observation that kills the population
yebai Aug 26, 2026
9005380
particle_mcmc: Skip SMC's closing resample at equal weights
yebai Aug 26, 2026
b1b019b
particle_mcmc: Weight explicit prior terms
yebai Aug 26, 2026
39c1aec
particle_mcmc: Preserve SMC ESS in MCMCChains
yebai Aug 26, 2026
d6d2faf
particle_mcmc: Reject empty particle populations
yebai Aug 26, 2026
ecbf4ea
particle_mcmc: Produce explicit prior terms from `acclogprior!!`
yebai Aug 26, 2026
6594ecc
particle_mcmc: Give `SMC` the usual `verbose` default
yebai Aug 26, 2026
cb9b352
particle_mcmc: Trim the implementation and its comments
yebai Aug 26, 2026
e6b40e1
HISTORY: Record the particle chain statistic renames
yebai Aug 26, 2026
5c89d84
particle_mcmc: Cover both fields of a named `@addlogprob!`
yebai Aug 26, 2026
655bda0
particle_mcmc: Drop the per-step seed refresh
yebai Aug 27, 2026
acf2441
particle_mcmc: Trim a helper, comments and the changelog
yebai Aug 27, 2026
095effe
particle_mcmc: Validate the sampler constructor arguments
yebai Aug 27, 2026
e1ec12c
particle_mcmc: Guard the produced prior weight with its accumulation
yebai Aug 27, 2026
ad1967a
particle_mcmc: Report SMC's ignored state keywords
yebai Aug 27, 2026
4c750c1
particle_mcmc: Pin the offspring counts and the quadrature grids
yebai Aug 27, 2026
7e3f1ff
particle_mcmc: Cut redundant tests and halve the SSM particle counts
yebai Aug 27, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ CI matrix: Julia stable + min, Ubuntu/Windows/macOS, 1 and 2 threads.

Most complexity is in DynamicPPL. Turing.jl contains:

- **Sampler implementations** (`src/mcmc/`): HMC/NUTS/HMCDA (wrapping AdvancedHMC), MH (wrapping AdvancedMH), particle samplers SMC/PG/CSMC (wrapping AdvancedPS), ESS (wrapping EllipticalSliceSampling), SGLD/SGHMC, Emcee, and Gibbs.
- **Sampler implementations** (`src/mcmc/`): HMC/NUTS/HMCDA (wrapping AdvancedHMC), MH (wrapping AdvancedMH), particle samplers SMC/PG/CSMC (implemented natively in `particle_mcmc.jl` on top of Libtask coroutines), ESS (wrapping EllipticalSliceSampling), SGLD/SGHMC, Emcee, and Gibbs.
- **External sampler interface** (`src/mcmc/external_sampler.jl`): The `externalsampler()` wrapper lets any `AbstractMCMC.AbstractSampler` that implements `step` for `LogDensityModel` work with Turing models. This is the easier path for new samplers — it only requires a dependency on AbstractMCMC and the LogDensityProblems.jl interface, with no Turing internals. The tradeoff is less power: you can only interact with the model as a black-box log-density function, just like using `LogDensityFunction` directly.
- **Variational inference** (`src/variational/`): Wraps AdvancedVI algorithms.
- **Mode estimation** (`src/optimisation/`): MAP and MLE via Optimization.jl.
Expand Down
21 changes: 21 additions & 0 deletions HISTORY.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,24 @@
# 0.47.0

## Breaking changes

### Particle MCMC (SMC and PG)

`SMC` and `PG` / `CSMC` have been reimplemented natively and no longer depend on AdvancedPS.

Resampling schemes are now types rather than functions — `StratifiedResampler()`, `SystematicResampler()`, and `MultinomialResampler()` (in `Turing.Inference`), optionally wrapped in `ESSThresholdResampler(threshold, scheme)` to resample only when the effective sample size falls below `threshold * nparticles`; for example `SMC(Turing.Inference.SystematicResampler())`, `SMC(0.5)`, or `PG(10, Turing.Inference.MultinomialResampler(), 0.5)`.
The old function-based API (`resample_systematic`, `AdvancedPS.ResampleWithESSThreshold`, …) is gone.

The default scheme is now **stratified** rather than systematic: it stays consistent as the number of particles grows, which systematic does not.
The selected scheme applies to unconditional sweeps; `PG` / `CSMC` draw the ancestors of a conditional sweep from the categorical over the weights, since a correct conditional version of stratified or systematic resampling is scheme-specific rather than "pin one draw and keep the rest".
Exact draws may therefore differ from previous releases, but remain statistically consistent (the same target distribution).

The rewrite also brings:

- **Reproducibility.** Internal seeds are derived through a counter-based (Philox) generator, so a fixed user seed gives the same draws on every Julia version and platform, and splitting one stream into many is better decorrelated. Previously, results could drift between Julia versions even under a `StableRNG` (https://github.com/TuringLang/Turing.jl/issues/2781).
- **Parallelism** at two independent levels. *Across chains*, SMC/PG work with AbstractMCMC's `MCMCThreads()` / `MCMCDistributed()` like any other sampler — each chain is an independent run. *Within a single sweep*, `SMC(; multithreaded=true)` / `PG(n; multithreaded=true)` spread that sweep's particles across threads. These are separate knobs: the ensemble does not parallelise a sweep, `multithreaded` does not parallelise chains, and they compose. Neither changes the results; start Julia with multiple threads (e.g. `julia -t auto`) for the thread-based paths to take effect.
- **Equal-weight draws & diagnostics.** `SMC` resamples once at the end of the sweep so the returned particles are an equal-weight sample — `mean(chain[...])` and other summaries need no weighting. `SMC`, `PG`, and `CSMC` chains all carry `log_normalizing_constant`; `SMC` chains additionally carry `ess_per_step`, the per-observation effective sample size across the sweep (a degeneracy diagnostic). For `SMC`, `exp(log_normalizing_constant)` is an unbiased estimator of the marginal likelihood `p(y)` under the usual particle-filter assumptions. For `PG` / `CSMC`, the exponentiated estimate is biased and must not be used for model comparison; see the `PG` docstring.

# 0.46.1

Fixed a bug, present since v0.41.0, that biased `PG` / `CSMC` posteriors, whether sampled on their own or as a Gibbs component.
Expand Down
6 changes: 3 additions & 3 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name = "Turing"
uuid = "fce5fe82-541a-59a6-adf8-730c64b5f9a0"
version = "0.46.1"
version = "0.47.0"

[deps]
ADTypes = "47edcb42-4c32-4615-8424-f2b9edc5f35b"
Expand All @@ -9,7 +9,6 @@ AbstractPPL = "7a57a42e-76ec-4ea3-a279-07e840d6d9cf"
Accessors = "7d9f7c33-5ae7-4f3b-8dc6-eff91059b697"
AdvancedHMC = "0bf59076-c3b1-5ca4-86bd-e02cd72cde3d"
AdvancedMH = "5b7e9947-ddc0-4b3f-9b55-0d8042f74170"
AdvancedPS = "576499cb-2369-40b2-a588-c64705576edc"
AdvancedVI = "b5ca4192-6429-45e5-a2d9-87aec30a685c"
BangBang = "198e06fe-97b7-11e9-32a5-e1d131e6ad66"
Bijectors = "76274a88-744f-5084-9051-94815aaf08c4"
Expand All @@ -29,6 +28,7 @@ OptimizationOptimJL = "36348300-93cb-4f02-beb5-3c3902f8871e"
OrderedCollections = "bac558e1-5e72-5ebc-8fee-abe8a469f55d"
Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
Random123 = "74087812-796a-5b5d-8853-05524746bad3"
Reexport = "189a3867-3050-52da-a836-e630ba90ab69"
SciMLBase = "0bca4576-84f4-4d90-8ffe-ffa030f20462"
SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b"
Expand All @@ -52,7 +52,6 @@ AbstractPPL = "0.15"
Accessors = "0.1"
AdvancedHMC = "0.8.3"
AdvancedMH = "0.8.9"
AdvancedPS = "0.7.2"
AdvancedVI = "0.7"
BangBang = "0.4.2"
Bijectors = "0.15.17, 0.16"
Expand All @@ -74,6 +73,7 @@ OptimizationOptimJL = "0.1 - 0.4"
OrderedCollections = "1, 2"
Printf = "1"
Random = "1"
Random123 = "1.7.1"
Reexport = "0.2, 1"
SciMLBase = "2, 3"
SpecialFunctions = "0.7.2, 0.8, 0.9, 0.10, 1, 2"
Expand Down
1 change: 0 additions & 1 deletion src/mcmc/Inference.jl
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ import AdvancedHMC
const AHMC = AdvancedHMC
import AdvancedMH
const AMH = AdvancedMH
import AdvancedPS
import EllipticalSliceSampling
import LogDensityProblems
import Random
Expand Down
Loading
Loading