dtw#

diffsptk.DTW#

alias of DynamicTimeWarping

class diffsptk.DynamicTimeWarping(metric: str | int = 'euclidean', p: int = 4, softness: float = 0.001)[source]#

See this page for details. The current implementation is based on naive nested for loops.

Parameters:
metric[‘manhattan’, ‘euclidean’, ‘squared-euclidean’, ‘symmetric-kl’]

The metric to compute the distance between two vectors.

pint in [0, 6]

The local path constraint type.

softnessfloat > 0

A smoothing parameter. The smaller value makes the output closer to the true dynamic time warping distance, but the gradient vanishes.

References

[1]

M. Cuturi et al., “Soft-DTW: a differentiable loss function for time-series,” Proceedings of ICML 2017, pp. 894-903, 2017.

forward(x: Tensor, y: Tensor, lengths: Tensor | None = None, return_indices: bool = False) Tensor | tuple[Tensor, list[Tensor]][source]#

Compute dynamic time warping distance.

Parameters:
xTensor [shape=(B, T1, D) or (T1, D) or (T1,)]

The query vector sequence.

yTensor [shape=(B, T2, D) or (T2, D) or (T2,)]

The reference vector sequence.

lengthsTensor [shape=(B, 2)] or None

The lengths of the sequences.

return_indicesbool

If True, returns the indices of the viterbi path.

Returns:
distanceTensor [shape=(B,)]

The dynamic time warping distance.

indiceslist[Tensor [shape=(T, 2)]] (optional)

The indices of the viterbi path for each batch.

Examples

>>> import diffsptk
>>> dtw = diffsptk.DynamicTimeWarping(p=1)
>>> x = torch.tensor([1., 3., 6., 9.])
>>> y = torch.tensor([2., 3., 8., 8.])
>>> distance, indices = dtw(x, y, return_indices=True)
>>> distance
tensor([0.8749])
>>> indices[0]
tensor([[0, 0],
        [1, 1],
        [2, 2],
        [3, 2],
        [3, 3]])
static merge(x: Tensor, y: Tensor, indices: Tensor) Tensor[source]#

Merge two sequences according to the given indices.

Parameters:
xTensor [shape=(T1, D) or (T1,)]

The query vector sequence.

yTensor [shape=(T2, D) or (T2,)]

The reference vector sequence.

indicesTensor [shape=(T, 2)]

The indices of the viterbi path.

Returns:
zTensor [shape=(T, 2D) or (T, 2)]

The merged vector sequence.

Examples

>>> import diffsptk
>>> dtw = diffsptk.DynamicTimeWarping(p=1)
>>> x = torch.tensor([1., 3., 6., 9.])
>>> y = torch.tensor([2., 3., 8., 8.])
>>> _, indices = dtw(x, y, return_indices=True)
>>> z = dtw.merge(x, y, indices[0])
>>> z
tensor([[1., 2.],
        [3., 3.],
        [6., 8.],
        [9., 8.],
        [9., 8.]])
diffsptk.functional.dtw(x: Tensor, y: Tensor, lengths: Tensor | None = None, return_indices: bool = False, metric: str | int = 'euclidean', p: int = 4, softness: float = 0.001) Tensor | tuple[Tensor, list[Tensor]][source]#

Compute dynamic time warping distance.

xTensor [shape=(B, T1, D) or (T1, D) or (T1,)]

The query vector sequence.

yTensor [shape=(B, T2, D), (T2, D) or (T2,)]

The reference vector sequence.

lengthsTensor [shape=(B, 2)] or None

The lengths of the sequences.

return_indicesbool

If True, returns the indices of the viterbi path.

metric[‘manhattan’, ‘euclidean’, ‘squared-euclidean’, ‘symmetric-kl’]

The metric to compute the distance between two vectors.

pint in [0, 6]

The local path constraint type.

softnessfloat > 0

A smoothing parameter. The smaller value makes the output closer to the true dynamic time warping distance, but the gradient vanishes.

Returns:
distanceTensor [shape=(B,)]

The dynamic time warping distance.

indiceslist[Tensor [shape=(T, 2)]] (optional)

The indices of the viterbi path for each batch.

diffsptk.functional.dtw_merge(x: Tensor, y: Tensor, indices: Tensor) Tensor[source]#

Merge two sequences according to the given indices.

Parameters:
xTensor [shape=(T1, D) or (T1,)]

The query vector sequence.

yTensor [shape=(T2, D) or (T2,)]

The reference vector sequence.

indicesTensor [shape=(T, 2)]

The indices of the viterbi path.

Returns:
zTensor [shape=(T, 2D) or (T, 2)]

The merged vector sequence.