Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implementation of Non-Gaussian transition models #1043

Open
wants to merge 70 commits into
base: main
Choose a base branch
from

Conversation

zhenyuen
Copy link

@zhenyuen zhenyuen commented Jun 16, 2024

@hpritchett-dstl

Features:

  1. Introduce a new family of transition models that generalise transition models driven by white noise to the Levy process.
  2. Provides support for normal sigma-mean and normal variance-mean mixture processes.
  3. Users can inject the desired driving processes into the selected transition model
  4. Introduce marginalised particle filtering for inferencing the newly-introduced class of models.
  5. Added a tutorial notebook for the new class of models and marginalised particle filter

Refactored:

  1. Improve inference speed for Levy models with known state transition matrices, e.g. LevyLangevin model
  2. Wrote minimal tests to lock down the behaviour of the introduced models. Some of Simon's students will still actively contribute to his work here, and I would require their help to improve the test coverage.
  3. Better separation of concerns/class design than before.

Todo:

  1. Implementation of PDF and log PDF functions, certain Levy distributions have non-trivial PDFs/CDFs, currently looking into inverse FFT methods involving characteristic functions.
  2. Provide support for more models, e.g. Singer
  3. Improve tests.

Additional comments:

I believe the current design is a good compromise between speed and compatibility with the existing stone soup framework to avoid introducing any breaking changes. The newly introduced models decouple the deterministic (transition model) and non-deterministic (noise driver) components. That being said, suggestions are welcome and highly appreciated.

zhenyuen and others added 30 commits May 11, 2024 01:13
Initial commit to introduce Levy (non-Gaussian) transition models
stonesoup/models/base_driver.py Outdated Show resolved Hide resolved
stonesoup/models/tests/test_driver.py Outdated Show resolved Hide resolved
stonesoup/types/state.py Outdated Show resolved Hide resolved
stonesoup/types/state.py Outdated Show resolved Hide resolved
stonesoup/updater/particle.py Show resolved Hide resolved
stonesoup/updater/particle.py Outdated Show resolved Hide resolved
stonesoup/predictor/particle.py Outdated Show resolved Hide resolved
stonesoup/models/transition/tests/test_ca.py Outdated Show resolved Hide resolved
@zhenyuen
Copy link
Author

@hpritchett-dstl
I believe I’ve addressed all your comments and refactored the code accordingly. However, my tests on CircleCI for Python 3.8 seem to be failing due to the KS test from SciPy. I’m not entirely sure what’s causing this, so I’d appreciate it if you could take a look and help troubleshoot.

Additionally, I noticed that some of my formatting changes might have affected other parts of the repository that aren’t mine. I’ll need more time to undo those, but it might be helpful if we had standardized code styles throughout the repository. For example:

  1. Using absolute imports instead of relative imports
  2. Configuring flake8 and black consistently, ideally with a pre-commit hook

Lastly, it would be really helpful to have a local development setup that mirrors the CircleCI test environment. This way, I could run the tests locally and address any issues before pushing changes. A docker image would be great!

@zhenyuen zhenyuen force-pushed the levy-models-slow branch 2 times, most recently from f788491 to 19d9940 Compare November 16, 2024 10:57
Copy link
Contributor

@nperree-dstl nperree-dstl left a comment

Choose a reason for hiding this comment

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

I've made some comments on the tutorial that could do with being applied throughout to make the documentation render properly.

There is some guidance here which might be useful: https://sphinx-gallery.github.io/stable/syntax.html - you can also render the docs locally by running python -m sphinx -W docs/source docs/build.

Comment on lines +24 to +26
# The state of the target can be represented as 2D Cartesian coordinates, $\left[x, \dot x, y, \dot y\right]^{\top}$, modelling both its position and velocity. A simple truth path is created with a sampling rate of 1 Hz.

# In[2]:
Copy link
Contributor

@nperree-dstl nperree-dstl Jan 3, 2025

Choose a reason for hiding this comment

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

See previous comment (check my editing of the maths here though)

Suggested change
# The state of the target can be represented as 2D Cartesian coordinates, $\left[x, \dot x, y, \dot y\right]^{\top}$, modelling both its position and velocity. A simple truth path is created with a sampling rate of 1 Hz.
# In[2]:
# %%
# The state of the target can be represented as 2D Cartesian coordinates, :math`[x, \dot{x}, y, \dot{y}]^{\top}`, modelling both its position and velocity. A simple truth path is created with a sampling rate of 1 Hz.

Comment on lines +15 to +17
# Consider the scenario where the target evolves according to the Langevin model, driven by a normal sigma-mean mixture with the mixing distribution being the $\alpha$-stable distribution.

# In[1]:
Copy link
Contributor

@nperree-dstl nperree-dstl Jan 3, 2025

Choose a reason for hiding this comment

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

Each section of text in the tutorial (i.e. not code) needs to begin with # %%. To format mathematical symbols you need to wrap in ":math:maths_goes_here". You can also remove all the # In[] lines from the tutorial file.

Suggested change
# Consider the scenario where the target evolves according to the Langevin model, driven by a normal sigma-mean mixture with the mixing distribution being the $\alpha$-stable distribution.
# In[1]:
# %%
# Consider the scenario where the target evolves according to the Langevin model, driven by a normal sigma-mean mixture with the mixing distribution being the :math:`\alpha`-stable distribution.

Comment on lines +29 to +35
from stonesoup.types.groundtruth import GroundTruthPath, GroundTruthState
from stonesoup.models.base_driver import NoiseCase
from stonesoup.models.driver import AlphaStableNSMDriver
from stonesoup.models.transition.levy_linear import LevyLangevin, CombinedLinearLevyTransitionModel

# And the clock starts
start_time = datetime.now().replace(microsecond=0)
Copy link
Contributor

Choose a reason for hiding this comment

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

Could these initial imports sit in the first block of code rather than in the middle of the text?

start_time = datetime.now().replace(microsecond=0)


# The `LevyLangevin` class creates a one-dimensional Langevin model, driven by the $\alpha$-stable NSM mixture process defined in the `AlphaStableNSMDriver` class.
Copy link
Contributor

Choose a reason for hiding this comment

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

If you add ":class:~.class_name" around your class names they create links within the tutorial to the documentation pages for the class.

Suggested change
# The `LevyLangevin` class creates a one-dimensional Langevin model, driven by the $\alpha$-stable NSM mixture process defined in the `AlphaStableNSMDriver` class.
# The :class:`~.LevyLangevin` class creates a one-dimensional Langevin model, driven by the :math:`\alpha`-stable NSM mixture process defined in the `AlphaStableNSMDriver` class.

Comment on lines +72 to +77
# <!-- and in the $\alpha$-stable law is a function of the conditional Gaussian mean $\mu_W$
#
# where $\beta=\begin{cases} 1, \quad \mu_W \neq 0 \\ 0, \quad \text{otherwise} \end{cases}$ with $\beta=0$ being the a symmetric stable distribution.
#
# $\sigma=\frac{\mathbb{E}|w|^\alpha \Gamma(2-\alpha) \cos(\pi \alpha / 2))}{1- \alpha}$ represent the scale parameter and $\beta=$ controlling the skewness of the stable distribution. -->
#
Copy link
Contributor

Choose a reason for hiding this comment

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

Does this part need to be removed?

@@ -0,0 +1,426 @@
from abc import abstractmethod
Copy link
Contributor

Choose a reason for hiding this comment

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

This file (stonesoup.models.base_driver) needs to be added to the docs/source/stonesoup.models.rst file for it to appear in the documentation. It may be worth creating a subfolder for driver models similar to clutter models or transition models.

Copy link
Author

@zhenyuen zhenyuen Feb 9, 2025

Choose a reason for hiding this comment

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

As the Gaussian model lives within models.base, I created a separate LevyModel class as it should be as general as the Gaussian model, with a similar interface. Would it help if I created a separate stonesoup/models/driver/ folder to store the implementation of the drivers there? But I leave the base_driver.py under stonesoup/models/.

@@ -0,0 +1,251 @@
from typing import Callable, Generator, Optional, Union
Copy link
Contributor

Choose a reason for hiding this comment

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

This file (stonesoup.models.driver) needs to be added to the docs/source/stonesoup.models.rst file for it to appear in the documentation.

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.

7 participants