Skip to content

Preserve sigma-point pair symmetry under rounding - #5379

Merged
FlorianPfaff merged 3 commits into
mainfrom
fix/sigma-point-pair-symmetry
Aug 21, 2026
Merged

Preserve sigma-point pair symmetry under rounding#5379
FlorianPfaff merged 3 commits into
mainfrom
fix/sigma-point-pair-symmetry

Conversation

@FlorianPfaff

@FlorianPfaff FlorianPfaff commented Aug 20, 2026

Copy link
Copy Markdown
Owner

Summary

Fix a floating-point symmetry bug in the Merwe and Julier sigma-point generators.

Both generators originally formed each pair independently as x + U[:, i] and x - U[:, i]. For small spreads, the represented offsets can differ by one ULP. With the standard CircularUKF Merwe parameters (alpha=1e-3), the large off-center weights amplify that tiny asymmetry enough to break the existing identity-prediction regression.

Fix

Construct each pair through the representable displacement and re-realize that displacement once after forming the negative point:

positive_point = x + U[:, i]
realized_offset = positive_point - x
negative_point = x - realized_offset
realized_offset = x - negative_point
positive_point = x + realized_offset

The second realization matters: a one-pass reflection can itself re-round on x - realized_offset, leaving the final stored pair one ULP asymmetric. Rebuilding the positive point from the negative point's final representable displacement removes that residual asymmetry without using the overflow-prone expression 2*x - point.

The implementation is shared by MerweScaledSigmaPoints and JulierSigmaPoints through _symmetric_sigma_points.

Regression coverage

tests/test_sigma_points_pair_symmetry.py checks exact pair-offset equality for small-spread Merwe and Julier cases. The existing CircularUKF.test_predict_nonlinear_identity_function independently checks the downstream numerical effect.

Numerical reproduction for the affected Merwe coordinate:

  • original construction: pair offsets differ (0.0008366600265340973 vs 0.0008366600265341528 in the negative-mean coordinate)
  • one-pass reflection: can still differ by one ULP in the same coordinate
  • two-stage realization: final stored offsets are exactly equal for the regression case

The branch changes only the sigma-point implementation and the targeted regression test.

@github-actions

github-actions Bot commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

MegaLinter analysis: Success

Descriptor Linter Files Fixed Errors Max errors Warnings Elapsed time
✅ COPYPASTE jscpd yes no no 8.58s
✅ JSON prettier 7 0 0 0 0.55s
✅ JSON v8r 7 0 0 4.31s
✅ MARKDOWN markdownlint 68 0 0 0 1.95s
✅ MARKDOWN markdown-table-formatter 68 0 0 0 0.42s
✅ PYTHON black 1990 15 0 0 59.18s
✅ PYTHON isort 1990 28 0 0 2.87s
✅ REPOSITORY betterleaks yes no no 1.18s
✅ REPOSITORY checkov yes no no 35.34s
✅ REPOSITORY git_diff yes no no 0.12s
✅ REPOSITORY secretlint yes no no 100.59s
✅ REPOSITORY syft yes no no 3.45s
✅ REPOSITORY trivy-sbom yes no no 2.58s
✅ YAML prettier 11 0 0 0 0.71s
✅ YAML v8r 11 0 0 16.34s
✅ YAML yamllint 11 0 0 1.0s

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.0.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

@FlorianPfaff
FlorianPfaff merged commit 99aaab5 into main Aug 21, 2026
14 of 24 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.

1 participant