void divide( const float *arrayA, const float *arrayB, float *result, size_t length ) { vDSP_vdiv( const_cast<float *>( arrayA ), 1, const_cast<float *>( arrayB ), 1, result, 1, length ); }
Float32 DTW32_getSimilarityScore(DTW32 *self, Float32 *inputData, size_t inputRowCount, Float32 *comparisonData, size_t comparisonDataRowCount, size_t currentColumnCount) { // Float32_printContiguous2DArray(inputData, inputRowCount, currentColumnCount, "input"); // Float32_printContiguous2DArray(comparisonData, comparisonDataRowCount, currentColumnCount, "compare"); Float32 similarity = INFINITY; self->currentInputRowCount = inputRowCount; self->currentComparisonDataRowCount = comparisonDataRowCount; vDSP_vsq(inputData, 1, self->inputTemp, 1, inputRowCount * currentColumnCount); vDSP_vsq(comparisonData, 1, self->comparisonDataTemp, 1, comparisonDataRowCount * currentColumnCount); vDSP_mtrans(self->inputTemp, 1, self->multiplicationTemp, 1, currentColumnCount, inputRowCount); vDSP_mmul(self->ones, 1, self->multiplicationTemp, 1, self->inputTemp, 1, 1, inputRowCount, currentColumnCount); vDSP_mtrans(self->comparisonDataTemp, 1, self->multiplicationTemp, 1, currentColumnCount, comparisonDataRowCount); vDSP_mmul(self->ones, 1, self->multiplicationTemp, 1, self->comparisonDataTemp, 1, 1, comparisonDataRowCount, currentColumnCount); const int elementCountInput = (int)inputRowCount; const int elementCountComparisonData = (int)comparisonDataRowCount; vvsqrtf(self->inputTemp, self->inputTemp, &elementCountInput); vvsqrtf(self->comparisonDataTemp, self->comparisonDataTemp, &elementCountComparisonData); cblas_sgemm(CblasRowMajor, CblasNoTrans, CblasTrans, (SInt32)inputRowCount, (SInt32)comparisonDataRowCount, 1, 1.0, self->inputTemp, 1, self->comparisonDataTemp, 1, 0., self->normalisationMatrix, (SInt32)comparisonDataRowCount); cblas_sgemm(CblasRowMajor, CblasNoTrans, CblasTrans, (SInt32)inputRowCount, (SInt32)comparisonDataRowCount, (SInt32)currentColumnCount, 1.0, inputData, (SInt32)currentColumnCount, comparisonData, (SInt32)currentColumnCount, 0., self->distanceMatrix, (SInt32)comparisonDataRowCount); vDSP_vdiv(self->normalisationMatrix, 1, self->distanceMatrix, 1, self->distanceMatrix, 1, inputRowCount * comparisonDataRowCount); // Float32_printContiguous2DArray(self->distanceMatrix, inputRowCount, comparisonDataRowCount, "norm"); Float32 minusOne = -1.f; vDSP_vsma(self->distanceMatrix, 1, &minusOne, self->ones, 1, self->distanceMatrix, 1, inputRowCount * comparisonDataRowCount); // Float32_printContiguous2DArray(self->distanceMatrix, inputRowCount, comparisonDataRowCount, "norm"); vDSP_mmov(self->distanceMatrix, &self->globalDistanceMatrix[comparisonDataRowCount + 2], comparisonDataRowCount, inputRowCount, comparisonDataRowCount, comparisonDataRowCount + 1); Float32 nan = NAN; vDSP_vfill(&nan, &self->globalDistanceMatrix[1], 1, comparisonDataRowCount); vDSP_vfill(&nan, &self->globalDistanceMatrix[comparisonDataRowCount + 1], comparisonDataRowCount + 1, inputRowCount); Float32 comparisonArray[3] = {0}; for (size_t i = 0; i < inputRowCount; ++i) { for (size_t j = 0; j < comparisonDataRowCount; ++j) { comparisonArray[0] = self->globalDistanceMatrix[i * (comparisonDataRowCount + 1) + j]; comparisonArray[1] = self->globalDistanceMatrix[i * (comparisonDataRowCount + 1) + (j + 1)]; comparisonArray[2] = self->globalDistanceMatrix[(i + 1) * (comparisonDataRowCount + 1) + j]; Float32 dmax; size_t index; vDSP_minvi(comparisonArray, 1, &dmax, &index, 3); self->phi[(i * comparisonDataRowCount) + j] = index + 1; self->globalDistanceMatrix[(i + 1) * (comparisonDataRowCount + 1) + (j + 1)] = self->globalDistanceMatrix[(i + 1) * (comparisonDataRowCount + 1) + (j + 1)] + dmax; } } similarity = self->globalDistanceMatrix[(comparisonDataRowCount + 1) * (inputRowCount + 1) - 1]; return similarity; }