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

GOSPAMetric: Avoid unnecessary copies and inefficient masking #1059

Merged
merged 10 commits into from
Jul 18, 2024

Conversation

marvonlar
Copy link
Contributor

@marvonlar marvonlar commented Jul 15, 2024

GOSPAMetric.compute_over_time() was taking a complete copy of all measurements and ground truth states for every timestep in the sequence. Additionally, it used multiple full linear masks for every iteration on the sorted timestamps. These steps cause the metric to have $\mathcal{O}(n^2)$ running time in the number of timesteps, resulting in slow compute on long datasets.

This PR performs the copying once and uses itertools.groupby() to avoid the linear masking in each iteration. As a result, GOSPAMetric now uses slightly less memory (we perform the same copy, but save the masking) and, in practice, runs linearly in the number of timesteps. The PR also includes a test which demonstrates 30-40x speedup on a 1k timestep long sequence. Offline I'm seeing 150x speedup (going from 20 min to 8 sec) on a real-world dataset with 50k timesteps.

This patch is also likely to help in the case of #1032.

Copy link

codecov bot commented Jul 15, 2024

Codecov Report

Attention: Patch coverage is 97.05882% with 1 line in your changes missing coverage. Please review.

Project coverage is 94.23%. Comparing base (92dae99) to head (59bd95b).

Files Patch % Lines
stonesoup/metricgenerator/ospametric.py 97.05% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1059      +/-   ##
==========================================
+ Coverage   94.19%   94.23%   +0.04%     
==========================================
  Files         207      207              
  Lines       13465    13487      +22     
  Branches     2740     2743       +3     
==========================================
+ Hits        12683    12710      +27     
+ Misses        530      524       -6     
- Partials      252      253       +1     
Flag Coverage Δ
integration 67.62% <2.94%> (-0.09%) ⬇️
unittests 90.30% <97.05%> (+0.05%) ⬆️

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.

@@ -319,6 +350,8 @@ def compute_gospa_metric(self, measured_states, truth_states):
if num_truth_states == 0:
# When truth states are empty all measured states are false
opt_cost = -1.0 * num_measured_states * dummy_cost
if self.alpha == 2:
gospa_metric['false'] = opt_cost
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This change was not part of my first patch, but came up as I added some tests to provide coverage of my original changes.

It seems reasonable that GOSPA should report tracks as false also in the case where there are 0 ground truth states, right?

I don't fully understand why we test for self.alpha == 2, but this is what is done everywhere else (see for instance line 369).

@marvonlar marvonlar marked this pull request as ready for review July 16, 2024 10:06
@marvonlar marvonlar requested a review from a team as a code owner July 16, 2024 10:06
@marvonlar marvonlar requested review from orosoman-dstl and mharris-dstl and removed request for a team July 16, 2024 10:06
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.

Thanks for the contribution: a significant speed up!

@sdhiscocks sdhiscocks merged commit cb9b3ca into dstl:main Jul 18, 2024
10 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.

3 participants