/// <summary> /// Returns scalar product, where specified shifted on specified value /// </summary> /// <param name="shift">Cycle shift value</param> public Complex ScalarProduct(ComplexSequence seq, int shift = 0) { if (m_complexSequence.Length != seq.m_complexSequence.Length) { throw new Exception("Lenght must be equals"); } if (shift < 0 && shift >= m_complexSequence.Length) { throw new Exception("Shift must be positive and less than sequence len"); } int segmentCount = m_complexSequence.Length; Complex result = new Complex(); for (int i = 0, i2 = shift; i < segmentCount; i++, i2++) { if (i2 >= segmentCount) { i2 -= segmentCount; } result += m_complexSequence[i].HermitScalarProduct(seq.m_complexSequence[i2]); } return(result); }
/// <remarks> /// Best performance achieved when familiar contour len are equal between it and with specified contour /// </remarks> public Match GetMatch(Contour contour, bool fillComarativeInfo = false) { if (m_familiarContours == null) { return(null); } Match bestMatch = null; foreach (var familiar in m_familiarContours) { ComplexSequence bringed = contour; if (contour.Points.Length != familiar.Contour.Points.Length) { bringed = contour.BringLength(familiar.Contour.Points.Length); } Match currentMatch = GetPotentialMatch(familiar, bringed); if (m_checkBothDirections) { Match currentMatchRevesed = GetPotentialMatch(familiar, bringed.Reverse()); if (currentMatchRevesed != null) { if (currentMatch == null || currentMatchRevesed.MaxNSP.AbsoluteValue() > currentMatch.MaxNSP.AbsoluteValue()) { currentMatch = currentMatchRevesed; currentMatch.ReverseUsed = true; } } } if (currentMatch != null) { if (bestMatch == null || currentMatch.MaxNSP.AbsoluteValue() > bestMatch.MaxNSP.AbsoluteValue()) { currentMatch.SourceContour = contour; bestMatch = currentMatch; } if (fillComarativeInfo) { familiar.MaxNSP = currentMatch.MaxNSP; familiar.ReverseUsed = currentMatch.ReverseUsed; familiar.ACF_NSP = currentMatch.ACF_NSP; } } } return(bestMatch); }
/// <summary> /// Returns scalar product divided by the product of contours lenght /// </summary> public Complex NormalizedScalarProduct(ComplexSequence contour, int shift = 0) { // NOTE: Performace can be improved by rewriting this code where will be used // only one for-cycle passage instead three (2xNorm + 1xScalarProduct) float normProduct = Norm() * contour.Norm(); Complex scalarProduct = ScalarProduct(contour, shift); return(scalarProduct / normProduct); }
/// <summary> /// Return maximal (by absolute value) value of normalized correlation fucntion /// </summary> public Complex MaximalNormalizedScalarProduct(ComplexSequence second) { Complex maxNsp = new Complex(0, 0); for (int i = 0; i < m_complexSequence.Length; i++) { Complex nsp = this.NormalizedScalarProduct(second, i); if (nsp.AbsoluteValue() > maxNsp.AbsoluteValue()) { maxNsp = nsp; } } return(maxNsp); }
private Match GetPotentialMatch(ContourInformation familiar, ComplexSequence bringed) { Complex ACF_NSP = familiar.Contour.ACF.AsComplexSequence().NormalizedScalarProduct(bringed.ACF.AsComplexSequence()); if (ACF_NSP.AbsoluteValue() > m_minACF_NSP) { Complex maxNSP = familiar.Contour.MaximalNormalizedScalarProduct(bringed); if (maxNSP.AbsoluteValue() > m_minNsp) { return(new Match() { ACF_NSP = ACF_NSP, MaxNSP = maxNSP, FamiliarContour = familiar }); } } return(null); }