Skip to content

Conversation

THargreaves
Copy link
Collaborator

@THargreaves THargreaves commented Sep 27, 2025

This PR implements the changes discussed in the attached proposal, which aims to offer first-class support for Rao-Blackwellisation. This involves abstracting elements of our codebase so that the RBPF is "nothing special" — if a feature (e.g. CSMC, AS, auxiliary weights, guided proposal) works for the regular PF, it should also work for the RBPF. This is motivated by the fact that they really are the same thing, with just some small changes to how we predict the particles and compute weights — p(y_t | x_t) becomes p(y_t | z_t, x_t).

This provides a concrete value proposition for our package that no other package provides, which will make it much easier to write our journal paper. I will get these changes finished within the next few days, and we can then look at package performance through use of StaticArrays as well as implementing some more advanced examples.

A few core changes to the interface were made to make this redesign feasible. These are:

  • Auxiliary particle filter is no longer its own thing but rather a modification to the resampler to incorporate pre-weights a wrapper for an existing filter (e.g. APF(RBPF(BF)))). This was needed because the APF needs access to the model/inner filter to compute the lookahead weights, and the resample step doesn't have access to these.
  • Initialise, predict, update now take the prior/dyn/obs respectively rather than the whole model. This is because we need to call them from within the RBPF but there is no model that corresponds to the predict step of the outer dynamics
  • There are a lot more layers to the initialise/predict/update functions now. Taking predict for example. Calling predict will map the function predict_particle over all particles. predict_particle dispatches on RB vs regular particle. This then calls propogate which is a function that updates a state (particle with weight and ancestry). This doesn't change anything about the implementation, just gives us more opportunities to use dispatch to change behaviour.

For ease of getting this PR implemented, I've made a few regressions. I've only done these if I could see a way of simply reimplementing them once it's clear this PR provides the full feature set it claims. These are:

  • Because predict now only accepts the dynamics (rather than whole model), it's a bit more faffy to have a proposal that depends on the ObservationProcess. This isn't too big of a problem since you add a field in you Proposal struct to store the ObservationProcess (e.g. in the example script, I implement an optimal Gaussian proposal), but I appreciate this is more work for the user since they have to create a new proposal for each ObservationProcess they use.
  • I haven't implemented the Weighted vs Unweighted particles to allow type consistency. This is a fairly simple reversion.
  • I'm not mutating any particles because I'm scared of introducing strange bugs. This makes the resampler quite messy and allocation heavy. This is easy to fix once we know the code works correctly without mutation.
  • The APF requires resampling at every step. The incremental ll will be incorrect if resampling doesn't occur. If using the APF you probably want to always resample so this is not a big deal, but should be fixed.

Likewise, there are a few things we can do in the future to tidy the code-base up a touch:

  • Introduce HierarchicalState and RBState types. Will make some of the dispatch more elegant
  • Normalise weights to unity sum rather than N (will align the APF and BF/GF)

A temporarily testing script is located at test/combination_test_script.jl which tests all combinations of filter components New unit tests are now merged with the main runtests.jl.

Progress:

  • Unified RBPF and PF code
  • Support for a RBPF wrapping a guided filter
  • Support for RB resampling
  • Implemented RB-CSMC
  • Implemented auxiliary resampling
  • [ ] Implemented RB-AS
  • Clean-up and documentation

GeneralisedFilters Distinguishing Features.pdf

Copy link
Contributor

SSMProblems.jl/SSMProblems documentation for PR #116 is available at:
https://TuringLang.github.io/SSMProblems.jl/SSMProblems/previews/PR116/

@THargreaves THargreaves marked this pull request as ready for review September 30, 2025 11:01
@THargreaves
Copy link
Collaborator Author

All existing unit tests now pass.

Copy link
Contributor

SSMProblems.jl/GeneralisedFilters documentation for PR #116 is available at:
https://TuringLang.github.io/SSMProblems.jl/GeneralisedFilters/previews/PR116/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant