Skip to content
mikerabat edited this page Mar 20, 2018 · 1 revision

Dynamic Time Warp

From Wikipedia:

In time series analysis, dynamic time warping (DTW) is one of the algorithms for measuring similarity between two temporal sequences, which may vary in speed.

In laymans terms, DTW tries to find the minimal error sequences of two input vectors whereas these two sequences may vary in speed. The output sequences normally do not share the same length as the input vectors since datapoints are normally repeated to reach maximum similarity.

Caclulation

Given two vectors x and y the base calculation searches for a path through a n x m matrix (m, n are the input vector lengths) where the elements at ij are calculated by the distance to between vector element xi and yj plus the previous calculation column. The distance function may be L2, Abs dist or Kullback Leibler distance calculation.

There also exists a faster implementation of the DTW algorithm that recursively calculates the DTW path through the matrix in 2 steps reducing the needed calculation O(n^2) to (n*log(n)).

The class also supports a maximum search depth to steere the maximum allowed temporal change.

Interface description

   type
     TDynamicTimeWarpDistMethod = (dtwSquared, dtwAbsolute, dtwSymKullbackLeibler);

   constructor Create(DistMethod : TDynamicTimeWarpDistMethod = dtwSquared);

Initialize the object with one of the distance measurements.

   function DTW(t, r : TDoubleDynArray; var dist : double; MaxSearchWin : integer = 0) : TDoubleDynArray; overload;
   function DTWCorr(t, r : TDoubleDynArray; MaxSearchWin : integer = 0) : double; overload; 
   function DTW(t, r : IMatrix; var dist : double; MaxSearchWin : integer = 0) : IMatrix; overload;
   function DTWCorr(t, r : IMatrix; MaxSearchWin : integer = 0) : double; overload;  // calculate the correlation coefficient between both warped vectors

Applies the standard O(n^2) DTW algorithm on the vectors t and r. The MaxSearchWin param defines the maximum search depth aka the maximum allowed temporal change (0 is complete). Note that the lower the value (but greater than 0) the faster the outcome is. The *corr functions calculated the DTW correlation coefficent between the two vectors. dist returns the calculated distance between the two vectors.

   function FastDTW(x, y : IMatrix; var dist : double; Radius : integer = 1)  : IMatrix; overload; // applies fastdtw
   function FastDTWCorr(t, r : IMatrix; Radius : integer = 1) : double; overload;  // calculate the correlation coefficient between both warped vectors
   function FastDTWCorr(t, r : IMatrix; var dist : double; Radius : integer = 1) : double; overload;  

Implements the fast O(n*log(n)) algorithm on the input vectors x, y (or t, r). Radius defines the maximum search radius like the MaxSearchWin param but since the size varies from each iteration it's a bit different than the "whole" algorithm.

The last results are stored in the properties W1 and W2.

Some details

There exists a SSE optimzed version of DTW. Set the class var UseSSE to true before instanciating the object to speed up the calculation. Note that this variable is set in the InitMathFunctions or InitSSEOptFunctions.

Examples

The example is take from the test application and shows how the DTW algorithm works on a "chirp" signal (varying frequency as function of time) and a sine:

   procedure TestDTWChirp;
   var x : TDoubleDynArray;
       y : TDoubleDynArray;
       counter : integer; 
       dtw : TDynamicTimeWarp;
       xv, yV : IMatrix;
       dist : double;
   begin
        SetLength(x, 1000);
        SetLength(y, 400);
        for counter := 0 to Length(x) - 1 do
            x[counter] := cos(2*pi*sqr( (3*(counter + 1)/1000) ));
        for counter := 0 to Length(y) - 1 do
            y[counter] := cos(2*pi*9*(counter + 1)/400);


        xv := TDoubleMatrix.Create(x, Length(x), 1);
        yv := TDoubleMatrix.Create(y, Length(y), 1);

        dtw := TDynamicTimeWarp.Create;
        try
           dtw.DTW(xv, yv, dist);

           Writeln(Format('Distance: %.4f', [dist]));
        finally
               dtw.Free;
        end;
   end;
Clone this wiki locally