Skip to content

Segmental coordination: many markers on one axis, not each on its own - #3

Merged
alexarje merged 1 commit into
mainfrom
segmental-coordination
Aug 24, 2026
Merged

alexarje merged 1 commit into
mainfrom
segmental-coordination

Conversation

@alexarje

Copy link
Copy Markdown
Contributor

Implements MGT #358. Markers are this package's domain, so the work lands here and MGT closes with a pointer — the same shape as #356 and #357.

One of the three metrics already existed

effective_dimensionality computes the participation ratio the effective-DOF metric wants. Called with rank=False it reproduces the still-standing analysis's pc1 and eff_dof on all 81 sessions to 1e-10. So it is called, not copied — that module's own docstring records the arithmetic drifting between report copies, which is why it exists.

rank=False is load-bearing and now has a test that fails under rank=True. Ranking is right for heavy-tailed descriptors and wrong here: it discards amplitude, and amplitude is the whole content of a projection.

What was actually missing

The projection. principal_axis_projection gives each marker its own axis — and two markers swaying at right angles, each on its own axis, correlate perfectly while sharing no direction of motion at all. Correlating segments only means something once they are on one axis, and that axis must come from a named marker because it is anatomical, not a property of the pooled cloud.

Verified against the study that asked for it

quantity agreement
pc1, eff_dof 1e-10 on all 81 sessions
correlations 4e-16 on every session the study produced a number for
amplitude ratio 4e-16 on 79 of 81

The 2 sessions that differ are exactly the 2 with frames where one hip marker drops out — a caller-side construction choice (the study averages the two projections, so a one-hip frame uses the surviving marker's centred signal). Both are reachable through these functions.

Three things the study code did not do

  1. Correlations are pairwise-complete and each carries its own n. np.corrcoef returns NaN if one sample is missing, dropping 1–2 sessions per pair into a dropna() beneath a heading that reported a single N for every row.
  2. mask chooses between the study's convention (every marker masked by the reference marker's valid frames) and each marker's own, so the coupling is a decision rather than an accident.
  3. reduce names which markers enter the reduction. A derived marker wanted only for a ratio — a hip midpoint — is a linear combination of segments already present, and silently entering it as a ninth changed eff_dof by 0.16. Found by testing against the real data.

Testing

12 tests, all synthetic known-answer. All passed on first run, so each guard was checked by removing it and watching its test fail. Full suite 397 passed, 2 skipped.

No body-part taxonomy is built in — "inverted pendulum" is an interpretation of a ratio above one, not something this computes.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Xg1f739wddu5M4s3UwdNkn

MGT #358 asked for three things: inter-segment correlation along a shared sway
axis, effective degrees of freedom across markers, and a head-to-hip amplitude
ratio. Markers are this package's domain, so they land here.

ONE OF THE THREE ALREADY EXISTED. effective_dimensionality computes the
participation ratio the effective-DOF metric wants, and called with rank=False
it reproduces the still-standing analysis's pc1 and eff_dof on all 81 sessions
to 1e-10. It is called rather than copied --- that module's own docstring says
the arithmetic drifted between report copies, which is why it is there at all.
rank=False is load-bearing and now has a test that fails under rank=True:
ranking discards amplitude, and amplitude is the whole content of a projection.

WHAT WAS ACTUALLY MISSING is the projection. principal_axis_projection gives
each marker its OWN axis, and two markers swaying at right angles, each on its
own axis, correlate perfectly while sharing no direction of motion at all.
Correlating segments only means something once they are on one axis, and that
axis has to come from a named marker, because it is anatomical rather than a
property of the pooled cloud.

Verified against the study that asked for it, not only against synthetic data:
correlations reproduce to 4e-16 on every session it produced a number for, and
the amplitude ratio to 4e-16 on the 79 of 81 sessions where both hip markers
are present throughout. The two that differ are exactly the two with frames
where one hip is missing, which is a caller-side construction choice --- the
study averages the two projections, so a one-hip frame uses the surviving
marker's centred signal --- and both are reachable through these functions.

THREE THINGS THE STUDY CODE DID NOT DO. Correlations are pairwise-complete and
each carries its own n: np.corrcoef returns NaN if one sample is missing, which
dropped one or two sessions per pair into a dropna() beneath a heading that
reported a single N for every row. mask chooses between the study's convention
and each marker's own, so that coupling is a decision rather than an accident.
And reduce names which markers enter the reduction, because a derived marker
wanted only for a ratio is a linear combination of segments already present ---
found by testing against the real data, where it moved eff_dof by 0.16.

Every guard was checked by removing it and watching its test fail. All twelve
passed on first run, and a check that cannot fail is worth nothing.

No body-part taxonomy is built in. "Inverted pendulum" is an interpretation of
a ratio above one, not something this computes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Xg1f739wddu5M4s3UwdNkn
@alexarje
alexarje merged commit b0c976e into main Aug 24, 2026
4 checks passed
@alexarje
alexarje deleted the segmental-coordination branch August 24, 2026 05:57
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