Skip to content

[ENH] Gradient-based soft barycentre averaging#3526

Open
chrisholder wants to merge 2 commits into
soft-msm-distancefrom
soft-barycentre-averaging
Open

[ENH] Gradient-based soft barycentre averaging#3526
chrisholder wants to merge 2 commits into
soft-msm-distancefrom
soft-barycentre-averaging

Conversation

@chrisholder

Copy link
Copy Markdown
Contributor

Reference Issues/PRs

Third of the soft-distance stack. Stacked on #3508 (soft-MSM distance), which is stacked on #3483. Please review/merge those first; this branch targets #3508 and the diff shrinks as they merge.

What does this implement/fix?

Adds gradient-based soft barycentre averaging. soft_barycenter_average (new _ba_soft.py) minimises a differentiable soft elastic objective with scipy.optimize.minimize (L-BFGS-B), using the private soft-DTW / soft-MSM gradients from the earlier PRs. It is wired into elastic_barycenter_average as method="soft", added to the averaging callable registry, and exported alongside VALID_SOFT_BA_METHODS.

Clean separation — soft distances only via method="soft". Soft distances are not used by the discrete BA methods (a soft distance has an alignment distribution, not a single hard path, so DBA-style discrete realignment is ill-defined and was a no-op). soft_dtw is removed from VALID_BA_DISTANCE_METHODS and from _get_alignment_path; early validation rejects method="soft" with a hard distance and the discrete methods with a soft distance. The discrete-BA test list drops soft_dtw and the temporary test_kasba skip added in #3483 is reverted.

Fixes over the prototype:

  • return_distances_to_center now recomputes the distances at the optimised barycentre instead of returning the initial (inf) values from setup.
  • Multivariate soft-MSM averaging accumulates the gradient per channel (independent), matching the soft-MSM distance. The prototype assigned a 1D gradient into a 2D slot, so soft-MSM averaging never actually worked (it also had no tests).
  • Threading uses numba_thread_handler (the prototype imported a module that does not exist on main); the docstring covers both soft distances.
  • _ba_setup gains a compute_previous_cost flag so the soft path skips the upfront pairwise-cost computation.

Does your contribution introduce a new dependency?

No. (tslearn, already optional, is used only as a guarded test oracle.)

Test plan

  • New test_soft_ba.py parametrised over soft-DTW and soft-MSM: shape/finiteness (uni + multivariate), return_cost/return_distances_to_center, weights change the result, single-series passthrough, the method="soft" validation matrix, and dispatch-equals-direct.
  • soft-DTW barycentre validated against tslearn's softdtw_barycenter (guarded with importorskip).
  • Verified locally: full aeon/clustering/averaging suite + test_k_means (402 passed) with the discrete-BA changes, and the soft BA tests. Pre-commit passes.

@aeon-actions-bot aeon-actions-bot Bot added clustering Clustering package enhancement New feature, improvement request or other non-bug code enhancement testing Testing related issue or pull request labels Jun 21, 2026
@aeon-actions-bot

Copy link
Copy Markdown
Contributor

Thank you for contributing to aeon

I have added the following labels to this PR based on the title: [ enhancement ].
I have added the following labels to this PR based on the changes made: [ clustering, testing ]. Feel free to change these if they do not properly represent the PR.

The Checks tab will show the status of our automated tests. You can click on individual test runs in the tab or "Details" in the panel below to see more information if there is a failure.

If our pre-commit code quality check fails, please run pre-commit locally and push the fixes to your PR branch.

Don't hesitate to ask questions on the aeon Discord channel if you have any.

PR CI actions

These checkboxes will add labels to enable or disable CI functionality for this PR. This may not take effect immediately, and a new commit may be required to run the new configuration.

  • Run pre-commit checks for all files
  • Run mypy typecheck tests
  • Run all pytest tests and configurations
  • Run all notebook example tests
  • Run numba-disabled codecov tests
  • Disable numba cache loading
  • Regenerate expected results for testing
  • Push an empty commit to re-run CI checks

Add `soft_barycenter_average` (in `_ba_soft.py`): a gradient-based barycentre
that minimises a soft elastic objective with `scipy.optimize.minimize`
(L-BFGS-B) using the private soft-DTW / soft-MSM gradients. Wired into
`elastic_barycenter_average` as `method="soft"` and into the averaging callable
registry, exported alongside `VALID_SOFT_BA_METHODS`.

Clean separation (no soft distances in discrete BA): soft distances are only
averaged via `method="soft"`. `soft_dtw` is removed from
`VALID_BA_DISTANCE_METHODS` and from `_get_alignment_path`, and early validation
rejects `method="soft"` with a hard distance and discrete methods with a soft
distance. The discrete-BA test list drops `soft_dtw` and the temporary
`test_kasba` skip is reverted.

Fixes over the prototype:
- `return_distances_to_center` now recomputes distances at the optimised
  barycentre instead of returning the initial values.
- Multivariate soft-MSM averaging accumulates the gradient per channel
  (independent), matching the soft-MSM distance; the prototype assigned a 1D
  gradient into a 2D slot and never worked for soft-MSM.
- Threading uses `numba_thread_handler`; docstring covers both soft distances.
- `_ba_setup` gains `compute_previous_cost` so the soft path skips the upfront
  pairwise-cost computation.

Tests parametrise over soft-DTW and soft-MSM, and validate the soft-DTW
barycentre against tslearn's `softdtw_barycenter`.
…dd tests

- `_soft_barycenter_one_iter` now threads `window` and `itakura_max_slope` through
  to both gradient branches. Previously `window` was silently ignored for
  `distance="soft_msm"` (and `itakura_max_slope` for both), despite being listed in
  the docstring kwargs.
- document `method="soft"` and the `minimise_method` parameter in
  `elastic_barycenter_average` (both were undocumented).
- replace the unused `_ba_setup` unpack targets with `_`.
- add tests: the optimiser moves the barycentre away from its init, and a
  MULTITHREAD_TESTING-gated determinism test (n_jobs must not change the result),
  mirroring the discrete-BA threaded tests.
@chrisholder chrisholder force-pushed the soft-barycentre-averaging branch from 13fcd3c to 4a175f4 Compare June 23, 2026 18:24
@chrisholder chrisholder marked this pull request as ready for review June 23, 2026 19:37
@chrisholder chrisholder requested a review from TonyBagnall as a code owner June 23, 2026 19:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clustering Clustering package enhancement New feature, improvement request or other non-bug code enhancement testing Testing related issue or pull request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant