Skip to content

Add normalized CheapJPDAF with linear-cost soft association - #5475

Draft
FlorianPfaff wants to merge 3 commits into
mainfrom
feature/cheap-jpdaf-20260915
Draft

FlorianPfaff wants to merge 3 commits into
mainfrom
feature/cheap-jpdaf-20260915

Conversation

@FlorianPfaff

Copy link
Copy Markdown
Owner

Summary

Implement CheapJointProbabilisticDataAssociationFilter, exported as CheapJPDAF and CJPDAF, for NumPy linear-Gaussian multitarget tracking.

  • Replace combinatorial joint-event enumeration with Fitzgerald-style row/column competition in O(n_targets * n_meas) association time and memory.
  • Reuse JPDAF's gating, Gaussian likelihoods, per-pair Kalman hypotheses, prediction, and moment-matched state/covariance updates. The existing exact event solver is extracted into an overridable method without changing its mathematics.
  • Compute association odds and exclusive competing-track sums in log space, avoiding cancellation and global rescaling across disconnected components.
  • Add public exports, experimental API registry entries, backend capability metadata, generated documentation tables, and an executable usage guide in docs/cheap-jpdaf.md.

Normalization convention

For gated likelihoods L and clutter intensity kappa, define w_ij = P_D L_ij / ((1-P_D) kappa_j), r_i = sum_j w_ij, and c_j = sum_i w_ij. Detection weights are

beta_ij = w_ij / (1 + r_i + c_j - w_ij)

The missed-detection mass is 1 - sum_j beta_ij, evaluated through an equivalent sum of positive terms to retain tiny miss probabilities. The original separate Fitzgerald miss expression 1/(1+r_i) generally does not normalize under track competition; this deliberate complementary-mass convention is documented rather than silently returning invalid mixture weights.

The approximation has normalized per-track mixtures and measurement-column allocation at most one. It agrees with the current exact JPDAF model for a single track, a single measurement, and disjoint single-track validation components; it is not exact in general ambiguous scenes.

Diagnostic contract

The optional hard diagnostic is a feasible track-order greedy likelihood-ratio assignment, not a joint MAP event. It is returned by find_association and stored as latest_greedy_association; latest_map_association remains None. The diagnostic never drives the soft update. max_enumerated_events is ignored by the cheap subclass and remains enforced by exact JPDAF.

Verified validation

GitHub-hosted Ubuntu / Python 3.12 validation completed successfully:
https://github.com/FlorianPfaff/PyRecEst/actions/runs/34966924288

  • 47 passed: new cheap JPDAF regressions, existing exact JPDAF regressions, and the existing likelihood log-determinant underflow regression.
  • Includes 100 seeded randomized matrix checks, exact reference special cases, extreme likelihood scales, permutation equivariance, event-limit independence, mixture covariance, empty/gated scans, vector clutter, heterogeneous measurement covariances, and backend/input contracts.
  • Pylint: 10.00/10 for the changed tracker modules and new tests.
  • Backend matrix and public API registry checks passed.
  • Minimal-import smoke test passed.
  • Documentation example executed successfully.

The validated integrated source was pushed as cb1abef77903d79c54289ce3ab427c4ccf186f43. Temporary integration workflow/script files were removed from the final branch. The broader repository CI matrix has not yet been confirmed; this PR remains draft pending those checks. No merge or release is performed.

@github-actions

Copy link
Copy Markdown
Contributor

MegaLinter analysis: Success

Descriptor Linter Files Fixed Errors Max errors Warnings Elapsed time
✅ COPYPASTE jscpd yes no no 6.5s
✅ JSON prettier 7 0 0 0 0.56s
✅ JSON v8r 7 0 0 4.29s
✅ MARKDOWN markdownlint 69 0 0 0 2.17s
✅ MARKDOWN markdown-table-formatter 69 0 0 0 0.47s
✅ PYTHON black 2042 1 0 0 53.9s
✅ PYTHON isort 2042 8 0 0 2.42s
✅ REPOSITORY betterleaks yes no no 1.26s
✅ REPOSITORY checkov yes no no 30.99s
✅ REPOSITORY git_diff yes no no 0.1s
✅ REPOSITORY secretlint yes no no 5.87s
✅ REPOSITORY syft yes no no 2.67s
✅ REPOSITORY trivy-sbom yes no no 2.22s
✅ YAML prettier 11 0 0 0 0.56s
✅ YAML v8r 11 0 0 12.15s
✅ YAML yamllint 11 0 0 0.61s

Notices

⚠️ Your configuration references items that have been removed from MegaLinter and are ignored: MAKEFILE_CHECKMAKE. See Removed linters to find their replacements.

See detailed reports in MegaLinter artifacts

Your project could benefit from a custom flavor, which would allow you to run only the linters you need, and thus improve runtime performances. (Skip this info by defining FLAVOR_SUGGESTIONS: false)

  • Documentation: Custom Flavors
  • Command: npx mega-linter-runner@10.1.0 --custom-flavor-setup --custom-flavor-linters PYTHON_BLACK,PYTHON_ISORT,COPYPASTE_JSCPD,JSON_V8R,JSON_PRETTIER,MARKDOWN_MARKDOWNLINT,MARKDOWN_MARKDOWN_TABLE_FORMATTER,REPOSITORY_CHECKOV,REPOSITORY_GIT_DIFF,REPOSITORY_BETTERLEAKS,REPOSITORY_SECRETLINT,REPOSITORY_SYFT,REPOSITORY_TRIVY_SBOM,YAML_PRETTIER,YAML_YAMLLINT,YAML_V8R

MegaLinter is provided by OX Security
Show us your support by starring ⭐ the repository

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.

1 participant