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
}