feat: add DynamicTimeWarping, alignment distance with a Sakoe-Chiba band - #7619
Merged
DenizAltunkapan merged 2 commits intoSep 27, 2026
Merged
Conversation
The Euclidean distance compares sample i with sample i and nothing else, so two recordings of the same gesture, one performed slightly faster, come out as far apart as two unrelated ones. Dynamic time warping looks for the cheapest way to line the two series up instead: every point of each series is matched to at least one point of the other, the matching never goes backwards, and the cost is the sum over the matched pairs. That alignment is a shortest path through a grid, and the dynamic program has one line. Left alone the alignment may match one point against an arbitrarily long stretch of the other, so the Sakoe-Chiba band is offered as well: it forbids matches further apart in time than a given width, which rules out those degenerate alignments and narrows the grid that has to be filled. The band has to be at least the difference in length or no alignment exists, and that is rejected rather than returned as infinity. The distance runs in O(min(n, m)) memory over two rows; the warping path itself needs the whole grid and is returned as index pairs. The Javadoc notes that the result is not a metric, so it ranks candidates but cannot be indexed without further care. Signed-off-by: alxkm <19151554+alxkm@users.noreply.github.com>
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #7619 +/- ##
============================================
+ Coverage 81.40% 81.45% +0.04%
- Complexity 8030 8051 +21
============================================
Files 834 835 +1
Lines 25321 25387 +66
Branches 4938 4950 +12
============================================
+ Hits 20613 20679 +66
Misses 3921 3921
Partials 787 787 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
DenizAltunkapan
approved these changes
Sep 27, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds dynamic time warping: how far apart two series are once one of them is allowed to be stretched and squeezed in time.
The Euclidean distance compares sample
iwith sampleiand nothing else, so two recordings of the same gesture, one performed slightly faster, come out as far apart as two unrelated ones. Dynamic time warping instead looks for the cheapest way to line the two series up: every point of the first has to be matched to at least one point of the second and the other way round, the matching may never go backwards, and the cost is the sum over the matched pairs. That alignment is a shortest path through a grid, and the dynamic program is the obvious one:The three predecessors are exactly the three legal moves: consume a point of the first series, of the second, or of both.
Left alone, the alignment may match one point of a series against an arbitrarily long stretch of the other, which is rarely meaningful. The Sakoe-Chiba band is offered alongside: it forbids matches further apart in time than a given width, which both rules out those degenerate alignments and narrows the grid that has to be filled. A band narrower than the difference in length admits no alignment at all, and that is rejected with a clear message rather than returned as an infinity for the caller to puzzle over.
The distance runs in
O(min(n, m))memory over two rows. The warping path itself needs the whole grid, so it is a separate method and returns the matched pairs of indices. The Javadoc also notes what the result is not: it does not satisfy the triangle inequality, so it ranks candidates but cannot be used to index them without further care.DynamicTimeWarpingTestcovers 18 cases. The ones worth naming:(0, 0), ends at the two last indices, never steps back and never stands still;Two of those tests started out asserting the wrong thing, which is worth mentioning because the intuition is easy to get backwards: warping is cheaper than a sample by sample comparison even for a constant offset, because a point may be reused, so
{1,2,3,4}against{3,4,5,6}costs 6 and not 8. There is now a test pinning exactly that.Checklist
clang-format -i --style=file path/to/your/file.java