Algorithms

Dynamic Time Warping: Aligning Sequences That Drift Out of Phase

Say "hello" twice. The second one is 300 ms longer, your pitch dips on the second syllable, and there's a breath in the middle. Euclidean distance between the two waveforms — pair up sample i with sample i — reports them as wildly different, because every point after the drift is compared against the wrong point. Dynamic Time Warping (DTW) fixes this by letting the time axis stretch and squeeze: it finds the cheapest nonlinear alignment between two sequences, warping one onto the other so peaks meet peaks and valleys meet valleys.

Introduced for spoken-word recognition by Sakoe and Chiba in 1978 (building on Vintsyuk's 1968 speech work), DTW is a textbook dynamic program: fill an n×m cost matrix bottom-up, and the number in the corner is the alignment cost. It powers speech systems, ECG and gesture classifiers, financial time-series matching, and the DTW loss used to train sequence models — anywhere two signals say the same thing at different speeds.

  • TimeΘ(nm)
  • SpaceO(nm), O(n) for distance only
  • InvariantD[i][j] = cost of optimal alignment of prefixes
  • Best forAligning signals warped in time
  • InventedSakoe & Chiba, 1978
  • ConstraintsBoundary, monotonicity, continuity

Interactive visualization

Press play, or step through manually. The visualization is yours to drive — try it before reading on.

Open visualization fullscreen ↗

Watch the 60-second explainer

A condensed visual walkthrough — narrated, captioned, under a minute.

The core idea and the DTW invariant

Given two sequences X = x₁…xₙ and Y = y₁…yₘ over some space with a local cost d(xᵢ, yⱼ) (usually |xᵢ − yⱼ| or squared distance), a warping path is a sequence of index pairs (i, j) that maps X onto Y. DTW seeks the path with the minimum total local cost, subject to three constraints that make the warp physically sensible:

  • Boundary: the path starts at (1, 1) and ends at (n, m) — the first and last elements must correspond, so the whole of X aligns to the whole of Y.
  • Monotonicity: indices never go backwards. If (i, j) precedes (i′, j′) then i ≤ i′ and j ≤ j′ — time only moves forward, so alignment cannot cross itself.
  • Continuity (step size): from (i, j) you may only advance to (i+1, j), (i, j+1), or (i+1, j+1). No index jumps more than one, so no sample is skipped entirely.

The whole algorithm rests on one invariant: D[i][j] holds the cost of the optimal warping path aligning the prefix x₁…xᵢ to the prefix y₁…yⱼ. Because any optimal path to (i, j) must pass through one of its three predecessors, the optimal-substructure property holds and the problem yields to dynamic programming. The final answer, DTW(X, Y), is D[n][m].

The recurrence and the fill order

The Bellman recurrence writes the cost at a cell as the local cost plus the cheapest of its three predecessors:

D[i][j] = d(xᵢ, yⱼ) + min( D[i-1][j],     // insertion in Y (Y stalls)
                          D[i][j-1],     // insertion in X (X stalls)
                          D[i-1][j-1] )  // match / diagonal step

The base cases anchor the corner: D[0][0] = 0, and the entire first row and column are set to (except the origin), which enforces the boundary constraint — no path may start anywhere but (1, 1). Fill the matrix row by row (or column by column); each cell needs only its left, lower, and diagonal-lower neighbors, all computed earlier, so a single sweep suffices.

  • Reading the distance: after the sweep, D[n][m] is the DTW distance. That single number is often all a classifier needs.
  • Recovering the path: to get the alignment itself, backtrack from (n, m), at each step moving to whichever of the three predecessors supplied the min, until you reach (0, 0). Store back-pointers, or recompute the argmin on the way back.

The diagonal step is the crucial difference from plain edit distance: it charges the substitution cost d(xᵢ, yⱼ) as a real number, not a 0/1 flag, so DTW measures how close the aligned values are, not merely whether they match.

Complexity: why it is Θ(nm) and how to shrink space

There are n·m cells; each is computed in O(1) from three neighbors and one distance evaluation. So time is Θ(nm) — quadratic, with no best/worst-case gap. For two 10-second audio clips at 100 frames/second that is 1,000 × 1,000 = 10⁶ cell updates: trivial. For two hour-long signals sampled at 1 kHz it is ~10¹³, which is why constraints and approximations matter (next section).

  • Full matrix: O(nm) space if you need to backtrack the alignment path.
  • Distance only: because each row depends only on the previous row, keep two rows and drop to O(min(n, m)) space — the same rolling-array trick used for edit distance and LCS. You lose the ability to reconstruct the path.
  • Path in linear space: Hirschberg-style divide-and-conquer recovers the alignment in O(n + m) space while keeping O(nm) time, at the cost of ~2× the constant factor.

The multiplicative constant is small — one subtraction, one abs, one 3-way min per cell — so a tight C/NumPy inner loop does tens of millions of cells per second. DTW's practical enemy is the quadratic growth, not the constant.

Global constraints: the Sakoe-Chiba band and Itakura parallelogram

Unconstrained DTW can produce pathological warps: a single point of X mapped onto a long run of Y (a nearly vertical or horizontal path), which is almost always physically meaningless and inflates matching accuracy in bad ways. Two classic constraints tame this and cut cost at the same time:

  • Sakoe-Chiba band: restrict the path to cells where |i − j| ≤ w for a window width w. This is a diagonal band of the matrix. It caps the amount of warp and reduces work from Θ(nm) to Θ(nw) — often a 10-50× speedup with negligible accuracy loss.
  • Itakura parallelogram: a parallelogram-shaped region that allows more warp in the middle than at the ends, matching the intuition that endpoints are pinned but the interior can drift.

The band width w is a hyperparameter: too small and the true alignment is clipped (the path is forced off the optimum and the distance is over-estimated); too large and you pay full quadratic cost. On the UCR time-series benchmark, a learned band of ~5-10% of sequence length typically matches full DTW accuracy. The band also makes DTW's cost independent of length ratio when w is fixed, which is a big deal for streaming and nearest-neighbor search.

Where DTW runs in the real world

DTW earned its keep in isolated-word speech recognition in the 1970s-80s, matching an utterance against stored templates before HMMs and neural nets took over. It never left the field — it remains the workhorse for elastic time-series matching:

  • Time-series classification: 1-nearest-neighbor with DTW is famously hard to beat and is the standard baseline on the UCR archive. Libraries like tslearn, dtaidistance, and fastdtw ship it; librosa.sequence.dtw aligns audio features.
  • Biomedical signals: aligning ECG heartbeats, gait cycles, and EEG epochs that vary in duration between and within patients.
  • Gesture and motion: matching accelerometer/skeleton streams for sign language, controller gestures, and activity recognition — different people perform the same motion at different speeds.
  • Finance and IoT: finding recurring patterns across price series or sensor traces sampled at drifting rates.
  • Deep learning: Soft-DTW (Cuturi & Blondel, 2017) replaces the hard min with a differentiable softmin, giving a smooth, sub-differentiable loss you can backprop through to train sequence-to-sequence and forecasting models directly on alignment cost.

Pitfalls, edge cases, and the FastDTW approximation

DTW is not a metric. It is symmetric and non-negative, but it violates the triangle inequality, and DTW(X, X) can be 0 while distinct sequences also give 0 under some cost choices. This breaks metric-tree indexing (VP-trees, ball-trees) and standard triangle-inequality pruning; use lower bounds instead — LB_Keogh and LB_Kim cheaply skip candidates during nearest-neighbor search without ever computing the full matrix.

  • Amplitude and offset sensitivity: DTW warps time, not value. A constant offset or gain difference still costs. z-normalize each sequence (subtract mean, divide by std) before comparing, or the answer is dominated by scale, not shape.
  • Singularities: without a step-size constraint, one point can absorb many, producing a jagged, unrealistic alignment. Use a band, or a slope constraint / weighted step pattern that penalizes long non-diagonal runs.
  • Endpoint pinning: the boundary constraint forces first-to-first and last-to-last. If your signals have leading/trailing junk, DTW misaligns everything. Open-ended variants (subsequence DTW) relax one or both endpoints to find a query inside a longer stream.
  • The quadratic wall: FastDTW (Salvador & Chan, 2007) approximates DTW in O(n) time and space via a multiresolution scheme — solve on a coarsened sequence, then refine within a radius r around the projected path. It is not exact, and analyses have shown the constant can make it slower than banded exact DTW for the sequence lengths people actually use, so benchmark before adopting it.
DTW versus other sequence-comparison methods
MethodTimeHandles time drift?Metric?Typical use
Euclidean distanceΘ(n)No — rigid index pairingYes (true metric)Aligned, equal-length signals
Dynamic Time WarpingΘ(nm)Yes — nonlinear warpNo (fails triangle ineq.)Speech, gestures, ECG
Edit distance (Levenshtein)Θ(nm)Discrete insert/deleteYesStrings, spell-check
Longest Common SubsequenceΘ(nm)Skips, no substitutionNoDiffs, coarse similarity
Cross-correlationΘ(n log n)Only global shift/lagNoFixed delay estimation

Frequently asked questions

Why not just use Euclidean distance between the two signals?

Euclidean distance pairs sample i with sample i rigidly, so any speed difference or phase shift — a signal that says the same thing 20% slower — makes every subsequent point line up against the wrong point and reports a large, misleading distance. DTW instead searches over all valid nonlinear alignments and pairs peaks with peaks. It is Θ(nm) versus Euclidean's Θ(n), so you pay for that flexibility, but for signals that drift in time DTW is often dramatically more accurate.

What is the exact time and space complexity?

Time is Θ(nm) with no best/worst-case gap: every cell of the n×m matrix is filled once in O(1). Space is O(nm) if you need to backtrack the alignment path, or O(min(n, m)) if you only need the DTW distance, using a two-row rolling array. Restricting to a Sakoe-Chiba band of width w drops both time and space toward Θ(nw).

How is DTW different from edit distance and LCS?

All three are Θ(nm) dynamic programs on a 2-D table with a nearly identical recurrence, and edit distance is essentially DTW's discrete cousin. The difference is the local cost: edit distance and LCS use 0/1 match flags on discrete symbols, while DTW charges a real-valued distance d(xᵢ, yⱼ) between continuous samples on its diagonal step. That makes DTW the right tool for numeric time series and edit distance the right tool for strings.

Is DTW a true distance metric?

No. DTW is symmetric and non-negative, but it violates the triangle inequality, so it cannot be indexed with metric trees or pruned with triangle-inequality tricks. In nearest-neighbor search you instead use cheap lower bounds such as LB_Keogh and LB_Kim to skip candidates before computing the full quadratic matrix, which is what makes DTW-based 1-NN fast enough for large archives.

When does DTW break or give bad answers?

It breaks on amplitude/offset differences because it warps time, not value — always z-normalize first. Without a step or band constraint it produces singularities where one point absorbs a long run of the other. Its boundary constraint forces the endpoints to align, so leading or trailing noise misaligns everything unless you use a subsequence/open-ended variant. And on very long sequences the quadratic cost dominates, pushing you toward a band or FastDTW.

How do you make DTW fast on long sequences?

Three levers. First, a Sakoe-Chiba band of width w restricts the path near the diagonal and cuts cost to Θ(nw), usually with negligible accuracy loss. Second, lower bounds (LB_Keogh) prune most candidates in nearest-neighbor search without a full matrix. Third, FastDTW gives an O(n) multiresolution approximation, though banded exact DTW is often competitive or faster for typical lengths, so benchmark before committing.