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

Addition of Efficient/Lagrangian Point-Mass Filter #1052

Closed
wants to merge 20 commits into from

Conversation

pesslovany
Copy link
Contributor

@pesslovany pesslovany commented Jun 26, 2024

J. Matoušek, J. Duník and M. Brandner, "Design of Efficient Point-Mass Filter with Terrain Aided Navigation Illustration," 2023 26th International Conference on Information Fusion (FUSION), Charleston, SC, USA, 2023, pp. 1-8, doi: 10.23919/FUSION52260.2023.10224172.

J. Matoušek, J. Duník, M. Brandner, Chan Gook Park, Yeongkwon Choe,
Efficient Point Mass Predictor for Continuous and Discrete Models with Linear Dynamics,IFAC-PapersOnLine,Volume 56, Issue 2,2023,Pages 5937-5942,ISSN 2405-8963,https://doi.org/10.1016/j.ifacol.2023.10.621.

J. Matoušek, J. Duník, O. Straka,
Lagrangian Grid-Based Filters with Application to Terrain-Aided Navigation
IEEE Signal Processing Magazine - Accepted, to be published

Added points mass updater, point mass predictor, and point mass state.

Copy link

codecov bot commented Jun 26, 2024

Codecov Report

Attention: Patch coverage is 97.18876% with 7 lines in your changes missing coverage. Please review.

Project coverage is 93.72%. Comparing base (956f1d1) to head (a7f3bc6).
Report is 10 commits behind head on main.

Files with missing lines Patch % Lines
stonesoup/updater/pointmass.py 85.71% 4 Missing ⚠️
stonesoup/functions/__init__.py 94.33% 3 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1052      +/-   ##
==========================================
+ Coverage   93.69%   93.72%   +0.02%     
==========================================
  Files         212      214       +2     
  Lines       13881    13993     +112     
  Branches     1922     1923       +1     
==========================================
+ Hits        13006    13115     +109     
- Misses        623      627       +4     
+ Partials      252      251       -1     
Flag Coverage Δ
integration 65.75% <42.16%> (-0.42%) ⬇️
unittests 90.91% <97.18%> (+0.03%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.


🚨 Try these New Features:

@pesslovany pesslovany marked this pull request as ready for review July 2, 2024 07:47
@pesslovany pesslovany requested a review from a team as a code owner July 2, 2024 07:47
@pesslovany pesslovany requested review from sdhiscocks and akenyon and removed request for a team July 2, 2024 07:47
functions.py Outdated
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this file required? Looks like added functionality from the file e.g. gridCreation has been added to functions/init.py

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I have deleted the file.

Comment on lines 48 to 49
gridDim = np.zeros((nx, Npa[0]))
gridStep = np.zeros(nx)
Copy link
Contributor

Choose a reason for hiding this comment

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

These are unused and so can be removed as they redefined below.

Suggested change
gridDim = np.zeros((nx, Npa[0]))
gridStep = np.zeros(nx)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

combvec_predGrid = np.array(list(itertools.product(*gridDim)))
predGrid_pom = np.dot(eigVect, combvec_predGrid.T)
size_pom = np.size(predGrid_pom, 1)
# Grid rotation by eigenvectors and traslation to the counted unscented mean
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
# Grid rotation by eigenvectors and traslation to the counted unscented mean
# Grid rotation by eigenvectors and translation to the counted unscented mean

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed

sFactor: float = Property(default=4, doc="How many sigma to cover by the grid")

# @profile
def predict(self, prior, timestamp=1, **kwargs):
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
def predict(self, prior, timestamp=1, **kwargs):
def predict(self, prior, timestamp=None, **kwargs):

Default timestamp is an int, which contradicts documentation

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed

An implementation of a Particle Filter predictor.
"""

sFactor: float = Property(default=4, doc="How many sigma to cover by the grid")
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
sFactor: float = Property(default=4, doc="How many sigma to cover by the grid")
sFactor: float = Property(default=4., doc="How many sigma to cover by the grid")

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed

Comment on lines 18 to 20
"""ParticlePredictor class

An implementation of a Particle Filter predictor.
Copy link
Contributor

Choose a reason for hiding this comment

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

docstring is that for the ParticlePredictor, could you change it, even if it's just ParticlePredictor -> PointMassPredictor :)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed. Sorry. As said below. :)

"""Sample mean for particles"""
return np.hstack(self.state_vector @ self.weight * np.prod(self.grid_delta))

# @profile
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
# @profile

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Deleted

Perform an update by multiplying grid points weights by PDF of measurement
model
"""
sFactor: float = Property(default=4, doc="How many sigma to cover by the grid")
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
sFactor: float = Property(default=4, doc="How many sigma to cover by the grid")
sFactor: float = Property(default=4., doc="How many sigma to cover by the grid")

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)

# @profile
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
# @profile

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Deleted

Comment on lines 146 to 149
"""ParticleStatePrediction type

This is a simple Particle state prediction object.
"""
Copy link
Contributor

Choose a reason for hiding this comment

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

This docstring is for ParticleStatePrediction, could you make a minor change to make it relevant for PointMassStatePrediction ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sorry, I am a bit new to both python and GitHub and getting lost sometimes, so I don't see obvious mistakes. Fixed

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I am also lost what at what is the purpose of the prediction object, but everything seems to be working....

@pesslovany
Copy link
Contributor Author

Thank you for your comments. I think I have fixed the codes based on them. I have also merged my branch with the latest changes. And it seems I have fixed all the issues so the code should run all of the testes successfully.

Hopefully we can finish the pull request. :)

Copy link
Contributor

@hpritchett-dstl hpritchett-dstl left a comment

Choose a reason for hiding this comment

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

Some final comments - just need to change the name of the predictor and updater files to maintain python naming conventions.

Once that's done I'm happy to approve this. This is some great work!

A prior state object
timestamp: :class:`datetime.datetime`, optional
A timestamp signifying when the prediction is performed
(the default is `1`)
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
(the default is `1`)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

Copy link
Contributor

Choose a reason for hiding this comment

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

to maintain python file naming convention, could you change the name of this file to pointmass.py? Note that the import for this in test_pointmass.py will then need to be changed to reflect this :)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done. Thank you for mentioning the test.

Copy link
Contributor

Choose a reason for hiding this comment

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

to maintain python file naming convention, could you change the name of this file to pointmass.py? Note that the import for this in test_pointmass.py.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

@pesslovany
Copy link
Contributor Author

Comments should be addressed. :)

Copy link
Member

@sdhiscocks sdhiscocks left a comment

Choose a reason for hiding this comment

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

A few minor changes needed for matlib which is deprecated and using meshgrid rather than itertools. But other wise looks good.

diff --git a/stonesoup/functions/__init__.py b/stonesoup/functions/__init__.py
index de1ac82a..aac10c57 100644
--- a/stonesoup/functions/__init__.py
+++ b/stonesoup/functions/__init__.py
@@ -1,20 +1,18 @@
 """Mathematical functions used within Stone Soup"""
 
 import copy
-import itertools
 import warnings
 from functools import lru_cache
 
 import numpy as np
 from numpy import linalg as LA
-from numpy import matlib as matlib
 
 from ..types.array import CovarianceMatrix, StateVector, StateVectors
 from ..types.numeric import Probability
 from ..types.state import State
 
 
-def gridCreation(xp_aux, Pp_aux, sFactor, nx, Npa):
+def grid_creation(xp_aux, Pp_aux, sFactor, nx, Npa):
     """Grid for point mass filter
 
     Create a PMF grid based on center, covariance matrix, and sigma probability
@@ -69,11 +67,10 @@ def gridCreation(xp_aux, Pp_aux, sFactor, nx, Npa):
         gridDim.append(np.linspace(-gridBound[ind3], gridBound[ind3], Npa[ind3]))
         gridStep.append(np.absolute(gridDim[ind3][0] - gridDim[ind3][1]))  # Grid step
 
-    combvec_predGrid = np.array(list(itertools.product(*gridDim)))
-    predGrid_pom = np.dot(eigVect, combvec_predGrid.T)
-    size_pom = np.size(predGrid_pom, 1)
+    combvec_predGrid = np.array(np.meshgrid(*gridDim, indexing='ij')).reshape(nx, -1).T
+    predGrid = np.dot(eigVect, combvec_predGrid.T)
     # Grid rotation by eigenvectors and translation to the counted unscented mean
-    predGrid = predGrid_pom + matlib.repmat(xp_aux, 1, size_pom)
+    predGrid += xp_aux
     predGridDelta = gridStep  # Grid step size
     return predGrid, predGridDelta, gridDim, xp_aux, eigVect
 

There is some issues with some other changes unrealted to this PR scope, I think caused by a merge from main branch. I'll add the change above and resolve this issue with a squash merge.

Thanks for the great contribution @pesslovany and apologies it's taken so long for us to get around to reviewing this.

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.

3 participants