Skip to content

Add Smoothers#192

Merged
DanWaxman merged 26 commits into
mainfrom
dw-smoothing
May 14, 2026
Merged

Add Smoothers#192
DanWaxman merged 26 commits into
mainfrom
dw-smoothing

Conversation

@DanWaxman
Copy link
Copy Markdown
Collaborator

@DanWaxman DanWaxman commented Apr 9, 2026

This PR adds smoothers under a new Smoother(...) handler, mirroring the current Filter(...) interface. It introduces a number of different smoothing algorithms from CD-Dynamax/cuthbert, some new documentation, and also introduces a bit of a refactor to integration code that was getting quite long (now split into filtering, smoothing, and util files).

Currently, prediction is not handled the way I would like it to be: I would like prediction to use the smoother within the smoothing window, and only pass forward the final predict_times as a filtered_times/filtered_dists pair. This is not currently done because missing data is not properly implemented in cd_dynamax for continuous time, and our indexing is not really correct for discrete time. For now, we decided to properly handle predict_times >= max(obs_times), and defer a more complete treatment to a later time.

  • Include Smoother Handler
  • Integration
    • Cuthbert
      • Particle Smoother
      • Kalman (RTS) Smoother
      • Extended Kalman (RTS) Smoother
    • CD-Dynamax
      • Kalman (RTS) Smoother
      • Extended Kalman (RTS) Smoother
    • Dynamax
      • Kalman (RTS) Smoother
      • Extended Kalman (RTS) Smoother
      • Unscented Kalman Smoother
  • New tests
    • Smoke tests
    • Science tests
  • Documentation
    • API Reference Pages
    • Full docstring & references for configs
    • Tutorial notebooks
  • Proper prediction behavior

@DanWaxman DanWaxman mentioned this pull request Apr 9, 2026
@DanWaxman DanWaxman mentioned this pull request May 8, 2026
@DanWaxman DanWaxman linked an issue May 8, 2026 that may be closed by this pull request
@DanWaxman DanWaxman requested a review from mattlevine22 May 8, 2026 22:12
@DanWaxman DanWaxman added deploy-docs PRs with this label will allow you to have doc previews on every push labels May 8, 2026
@DanWaxman DanWaxman marked this pull request as ready for review May 8, 2026 22:13
@DanWaxman
Copy link
Copy Markdown
Collaborator Author

@mattlevine22 I think this is ready for a look now!

"outputs": [
{
"data": {
"image/png": "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
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I'd add:

"Recall that Filter does, however, already support prediction times within the observation window."

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Done!

Comment thread dynestyx/inference/smoothers.py Outdated
Comment thread docs/tutorials/gentle_intro/09_discrete_smoothing.ipynb Outdated
Comment thread dynestyx/simulators.py
Comment thread dynestyx/inference/smoothers.py Outdated
Comment thread dynestyx/inference/smoothers.py Outdated
Comment thread dynestyx/inference/smoothers.py Outdated
Comment thread dynestyx/inference/smoothers.py Outdated
Comment thread dynestyx/inference/smoothers.py Outdated
Comment thread dynestyx/inference/smoother_configs.py Outdated
Comment thread dynestyx/inference/filter_configs.py Outdated
Copy link
Copy Markdown
Collaborator

@mattlevine22 mattlevine22 left a comment

Choose a reason for hiding this comment

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

Looks great!

  1. Why expand Filter API to include record_smoothed_*?

  2. Sharing functions between filters + smoothers:

  • Seems like _cuthbert_states_to_dists, _posterior_to_dists, _particle_to_batched_dists can all be shared by filters + smoothers via very slight expansion (e.g. add a filter vs smooth mode to their arguments and very few additional lines)

@DanWaxman DanWaxman requested a review from mattlevine22 May 12, 2026 03:43
Comment thread dynestyx/inference/filters.py Outdated
Comment thread dynestyx/inference/filters.py Outdated
Comment thread dynestyx/inference/filters.py Outdated
Comment thread dynestyx/inference/smoothers.py Outdated
Copy link
Copy Markdown
Collaborator

@mattlevine22 mattlevine22 left a comment

Choose a reason for hiding this comment

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

Approving, with recommendation to remove the unnecessarily thin wrappers in smoothers.py and filters.py , e.g. _smoothed_posterior_to_dists can just be removed by using _posterior_sequence_to_dists directly. This happens a few times in the filter/smoother files.

@DanWaxman DanWaxman merged commit c5c3812 into main May 14, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

deploy-docs PRs with this label will allow you to have doc previews on every push

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add Smoothers

2 participants