Skip to content

Add EnRTS Smoother - #268

Merged
SamDuffield merged 4 commits into
state-space-models:mainfrom
DanWaxman:dw-enrts-smoother
Aug 6, 2026
Merged

Add EnRTS Smoother#268
SamDuffield merged 4 commits into
state-space-models:mainfrom
DanWaxman:dw-enrts-smoother

Conversation

@DanWaxman

@DanWaxman DanWaxman commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator

Addresses #242. This PR adds an EnRTS smoother to complement the EnKF. This is based on the presentation of Raanes (2016), which also demonstrates an equivalence with the forward pass-only "ensemble Kalman smoother."

Some implementation choices:

  • The EnRTS smoother requires the "predicted states," i.e., the ensemble $x_{t+1 \mid t}$. Under the current EnKf implementation, this would require re-computing $E_{t+1 \mid t}$, which felt wasteful. Moreover, since the EnKF implementation is of the stochastic EnKF, one would have to be rather careful with PRNG keys as well to make this happen. The compromise I took is thus to add a store_predicted_states option to the filter, and store the corresponding info in the EnKFState. To run the EnRTS filter, this information must be present. This comes at a modest memory cost (at least, for the typical EnKF application of N_particles << d_X).
  • I left this new argument to be False by default, documented its need in the EnRTS, and give errors if it is not in the EnKF state.

The EnRTS tests in cuthbertlib includes a basic atomic test of the update, whilst the tests in cuthbert do a more end-to-end comparison to the RTS smoother with a large particle count.

DanWaxman and others added 3 commits August 4, 2026 15:57
This commit adds an EnRTS smoother to complement the EnKF. This is based on the presentation of [Raanes (2016)](https://rmets.onlinelibrary.wiley.com/doi/10.1002/qj.2728), which also demonstrates an equivalence with the forward pass-only "ensemble Kalman smoother."

Some implementation choices:
- The EnRTS smoother requires the "predicted states," i.e., the ensemble $x_{t+1 \mid t}$. Under the current EnKf implementation, this would require re-computing $E_{t+1 \mid t}$, which felt wasteful. Moreover, since the EnKF implementation is of the stochastic EnKF, one would have to be rather careful with PRNG keys as well to make this happen. The compromise I took is thus to add a `store_predicted_states` option to the filter, and store the corresponding info in the `EnKFState`. To run the EnRTS filter, this information must be present. This comes at a modest memory cost (at least, for the typical EnKF application of N_particles << d_X).
- I left this new argument to be `False` by default, documented its need in the EnRTS, and give errors if it is not in the EnKF state.

The EnRTS tests in `cuthbertlib` includes a basic atomic test of the update, whilst the tests in cuthbert do a more end-to-end comparison to the RTS smoother with a large particle count.
Co-authored-by: Matt Levine <mattlevine22@gmail.com>
These passed exactly on my machine, but apparently need a small epsilon on the GitHub CI machines.
@DanWaxman DanWaxman linked an issue Aug 5, 2026 that may be closed by this pull request

@SamDuffield SamDuffield left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Love this @DanWaxman thanks! Couple of minors and then good to merge!

I did also wonder if it made sense to rename e.g. cuthbert.enkf to cuthbert.ensemble_kalman with the addition of smoothing but it's a fair bit longer. What do you think?

Comment thread cuthbertlib/enkf/__init__.py Outdated
Comment thread zensical.toml Outdated
@DanWaxman

Copy link
Copy Markdown
Collaborator Author

I did also wonder if it made sense to rename e.g. cuthbert.enkf to cuthbert.ensemble_kalman with the addition of smoothing but it's a fair bit longer. What do you think?

I think that makes sense! I made this change in 63a1bcb, and addressed the other comments as well.

@SamDuffield
SamDuffield merged commit f57c9e7 into state-space-models:main Aug 6, 2026
2 checks passed
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.

Implement an Ensemble Kalman Smoother

3 participants