Skip to content

fix(chords): correct max-chord angle index and all-chords histogram s…#355

Open
darkclad wants to merge 2 commits into
PolusAI:mainfrom
darkclad:main-chords-max-angle
Open

fix(chords): correct max-chord angle index and all-chords histogram s…#355
darkclad wants to merge 2 commits into
PolusAI:mainfrom
darkclad:main-chords-max-angle

Conversation

@darkclad

@darkclad darkclad commented Jul 1, 2026

Copy link
Copy Markdown

…ource

ChordsFeature::calculate computed the max-chord angle index from iteMin (idxmax = distance(begin, iteMin)), so MAXCHORDS_MAX_ANG always equalled MAXCHORDS_MIN_ANG (same copy-paste for ALLCHORDS). It also built the all-chords mode/median histogram from the max-chords vector (MC) instead of all chords (AC).

Index the max-angle from iteMax and initialise the all-chords histogram from AC. Refresh the vetted chord goldens in test_2d_remaining_features.h (MAXCHORDS_MAX_ANG and ALLCHORDS_MAX_ANG -> 0.0; ALLCHORDS_MEDIAN/MODE -> 3.0) and add tests/python/test_feature_bugs.py::test_chord_max_angle_distinct_from_min.

…ource

ChordsFeature::calculate computed the max-chord angle index from iteMin
(`idxmax = distance(begin, iteMin)`), so MAXCHORDS_MAX_ANG always equalled
MAXCHORDS_MIN_ANG (same copy-paste for ALLCHORDS). It also built the all-chords
mode/median histogram from the max-chords vector (MC) instead of all chords (AC).

Index the max-angle from iteMax and initialise the all-chords histogram from AC.
Refresh the vetted chord goldens in test_2d_remaining_features.h (MAXCHORDS_MAX_ANG
and ALLCHORDS_MAX_ANG -> 0.0; ALLCHORDS_MEDIAN/MODE -> 3.0) and add
tests/python/test_feature_bugs.py::test_chord_max_angle_distinct_from_min.
@darkclad

darkclad commented Jul 1, 2026

Copy link
Copy Markdown
Author

Justification — golden value changes in tests/test_2d_remaining_features.h

Branch: main-chords-max-angle (split from main-feature-validation, based on main)
Source fix: src/nyx/features/chords.cpp
Test file touched: tests/test_2d_remaining_features.h (4 golden values)

The two bugs in chords.cpp

  1. idxmax used iteMin — the max-angle index was taken from the minimum chord
    (idxmax = std::distance(begin, iteMin)), so the reported "max-angle" was actually the
    min chord's angle. Result: MAXCHORDS_MAX_ANG was numerically identical to
    MAXCHORDS_MIN_ANG (same copy-paste error for the ALLCHORDS block).
  2. histo.initialize_uniques(MC) — the all-chords mode/median histogram was built from the
    max-chords vector MC instead of the all-chords vector AC. Result: ALLCHORDS_MODE
    and ALLCHORDS_MEDIAN reported the max-chords mode/median.

Justification per changed value

Golden Old New Why the new value is correct
MAXCHORDS_MAX_ANG 0.94247779607693793 0.0 Old value ==MAXCHORDS_MIN_ANG (0.9425) — the bug signature (max-angle = min-angle). After the fix it is the angle of the longest max-chord, which is horizontal → 0.0 rad. Consistent with MAXCHORDS_MAX = 6.0.
ALLCHORDS_MAX_ANG 0.15707963267948966 0.0 Same signature: old ==ALLCHORDS_MIN_ANG (0.1571). Longest all-chord is horizontal → 0.0 rad.
ALLCHORDS_MEDIAN 4.0 3.0 4.0 was themax-chords median (leaked from MC). The true all-chords median must be consistent with ALLCHORDS_MEAN = 2.9134615…, which was always computed correctly from AC and did not change. Median 3.0 ≈ mean 2.913 for a right-skewed short-chord distribution; median 4.0 > mean 2.913 was internally inconsistent.
ALLCHORDS_MODE 4.0 3.0 SameMC leak; the AC length distribution (min 1, max 6, mean 2.913) peaks at 3.0.

Why this is not fudging

  • What did NOT change is the tell. These goldens are unchanged because their code paths were
    already correct: MAXCHORDS_MAX (6.0), MAXCHORDS_MIN (3.0), MAXCHORDS_MEDIAN (4.0),
    MAXCHORDS_MEAN, MAXCHORDS_MODE, MAXCHORDS_STDDEV, ALLCHORDS_MAX (6.0), ALLCHORDS_MIN (1.0),
    ALLCHORDS_MEAN (2.9134615…), ALLCHORDS_STDDEV, MAXCHORDS_MIN_ANG (0.9425),
    ALLCHORDS_MIN_ANG (0.1571). Only the 4 outputs of the two buggy lines moved — a fudge would ripple.
  • The values are the fixed code's deterministic output, not hand-picked. The C++ gtest
    TEST_NYXUS.TEST_REMAINING2D_VERIFIABLE_WITH_3P_BUILTIN_ORACLE_CHORD_STAT_FEATURES and
    ..._UNVETTED_NO_DIRECT_ORACLE_CHORD_ANGLE_FEATURES pass (tolerance 1e-3) with exactly these
    numbers after rebuilding — i.e. the corrected binary computes 0.0 / 0.0 / 3.0 / 3.0.
  • They are byte-identical to the oracle-validated main-feature-validation values — copied, not
    invented. (Only the two MAX_ANG and two ALLCHORDS MEDIAN/MODE numbers were taken; the shared
    table-merge refactor and unrelated radial-distribution vector goldens in that file were intentionally
    left out — those belong to the contour-frame cluster branch.)

Regression guard

tests/python/test_feature_bugs.py::test_chord_max_angle_distinct_from_min asserts, on the canonical
ROI, that MAXCHORDS_MAX_ANG != MAXCHORDS_MIN_ANG and ALLCHORDS_MAX_ANG != ALLCHORDS_MIN_ANG
whenever the max and min chord lengths differ — directly catching bug (1) if it regresses.

CI

Full suite green on this branch: C++ runAllTests 683/683 passed; pytest tests/python/
49 passed, 1 skipped.

Drop the _bugs suffix from the shared 2D regression module,
renaming it to test_feature_oracle.py to match the oracle-validation
naming used elsewhere. No code or reference changes needed.
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