/// <summary> /// Global distance D(X,Y) between two sequences of vectors. /// </summary> /// /// <param name="locals">The current thread local storage.</param> /// <param name="sequence1">A sequence of vectors.</param> /// <param name="sequence2">A sequence of vectors.</param> /// /// <returns>The global distance between X and Y.</returns> /// private unsafe double D(Locals locals, double[] sequence1, double[] sequence2) { // Get the number of vectors in each sequence. The vectors // have been projected, so the length is augmented by one. int vectorSize = length + 1; int vectorCount1 = sequence1.Length / vectorSize; int vectorCount2 = sequence2.Length / vectorSize; // Application of the Dynamic Time Warping // algorithm by using dynamic programming. if (locals.m < vectorCount2 || locals.n < vectorCount1) { locals.Create(vectorCount1, vectorCount2); } double[,] DTW = locals.DTW; fixed(double *start1 = sequence1) fixed(double *start2 = sequence2) { double *vector1 = start1; for (int i = 0; i < vectorCount1; i++, vector1 += vectorSize) { double *vector2 = start2; for (int j = 0; j < vectorCount2; j++, vector2 += vectorSize) { double prod = 0; // inner product for (int k = 0; k < vectorSize; k++) { prod += vector1[k] * vector2[k]; } // Return the arc-cosine of the inner product double cost = Math.Acos(prod > 1 ? 1 : (prod < -1 ? -1 : prod)); double insertion = DTW[i, j + 1]; double deletion = DTW[i + 1, j]; double match = DTW[i, j]; double min = (insertion < deletion ? (insertion < match ? insertion : match) : (deletion < match ? deletion : match)); DTW[i + 1, j + 1] = cost + min; } } } return(DTW[vectorCount1, vectorCount2]); // return the minimum global distance }
/// <summary> /// Global distance D(X,Y) between two sequences of vectors. /// </summary> /// /// <param name="locals">The current thread local storage.</param> /// <param name="sequence1">A sequence of vectors.</param> /// <param name="sequence2">A sequence of vectors.</param> /// /// <returns>The global distance between X and Y.</returns> /// private double D(Locals locals, TInput[] sequence1, TInput[] sequence2) { // Get the number of vectors in each sequence. The vectors // have been projected, so the length is augmented by one. int vectorCount1 = sequence1.Length; int vectorCount2 = sequence2.Length; // Application of the Dynamic Time Warping // algorithm by using dynamic programming. if (locals.m < vectorCount2 || locals.n < vectorCount1) { locals.Create(vectorCount1, vectorCount2); } double[,] DTW = locals.DTW; for (int i = 0; i < sequence1.Length; i++) { for (int j = 0; j < sequence2.Length; j++) { // Compute the distance between the sequences double cost = distance.Distance(sequence1[i], sequence2[j]); double insertion = DTW[i, j + 1]; double deletion = DTW[i + 1, j]; double match = DTW[i, j]; double min = (insertion < deletion ? (insertion < match ? insertion : match) : (deletion < match ? deletion : match)); DTW[i + 1, j + 1] = cost + min; } } return(DTW[vectorCount1, vectorCount2]); // return the minimum global distance }
/// <summary> /// Global distance D(X,Y) between two sequences of vectors. /// </summary> /// /// <param name="locals">The current thread local storage.</param> /// <param name="sequence1">A sequence of vectors.</param> /// <param name="sequence2">A sequence of vectors.</param> /// /// <returns>The global distance between X and Y.</returns> /// private unsafe double D(Locals locals, double[] sequence1, double[] sequence2) { // Get the number of vectors in each sequence. The vectors // have been projected, so the length is augmented by one. int vectorSize = length + 1; int vectorCount1 = sequence1.Length / vectorSize; int vectorCount2 = sequence2.Length / vectorSize; // Application of the Dynamic Time Warping // algorithm by using dynamic programming. if (locals.m < vectorCount2 || locals.n < vectorCount1) locals.Create(vectorCount1, vectorCount2); double[,] DTW = locals.DTW; fixed (double* start1 = sequence1) fixed (double* start2 = sequence2) { double* vector1 = start1; for (int i = 0; i < vectorCount1; i++, vector1 += vectorSize) { double* vector2 = start2; for (int j = 0; j < vectorCount2; j++, vector2 += vectorSize) { double prod = 0; // inner product for (int k = 0; k < vectorSize; k++) prod += vector1[k] * vector2[k]; // Return the arc-cosine of the inner product double cost = Math.Acos(prod > 1 ? 1 : (prod < -1 ? -1 : prod)); double insertion = DTW[i, j + 1]; double deletion = DTW[i + 1, j]; double match = DTW[i, j]; double min = (insertion < deletion ? (insertion < match ? insertion : match) : (deletion < match ? deletion : match)); DTW[i + 1, j + 1] = cost + min; } } } return DTW[vectorCount1, vectorCount2]; // return the minimum global distance }