/// <summary> /// The bhattacharyya distance. /// </summary> /// <param name="observedIsotopicPeakList"> /// The observed isotopic peak list. /// </param> /// <param name="expectedIsotopicPeakList"> /// The actual isotopic peak list. /// </param> /// <returns> /// The <see cref="double"/>. /// </returns> private static double BhattacharyyaDistance(List<double> observedIsotopicPeakList, List<Peak> expectedIsotopicPeakList) { // calculate angle between two isotopic vectors in the isotopic space double[] actualIsotopicPeakListArray = expectedIsotopicPeakList.Select(x => (double)x.Height).ToArray(); Vector<double> A = new DenseVector(observedIsotopicPeakList.ToArray()); Vector<double> B = new DenseVector(actualIsotopicPeakListArray); A = A.Normalize(2); B = B.Normalize(2); Vector<double> C = A.PointwiseMultiply(B); // Pointwise sqrt. Implements here because Math.Net.2.5 doesn't supports Pointwise exp getting Math.Net 3.5 introducces // package compatibility issues with Informed Proteomics / Multidimensional peak finding, etc. // TODO: Use PointwiseExponent after getting Math.net 3.5 double[] cArray = C.ToArray(); int size = cArray.Count(); double sum = 0; for (int i = 0; i < size; i++) { cArray[i] = Math.Sqrt(cArray[i]); sum += cArray[i]; } return sum; }
/// <summary> /// The bhattacharyya distance. /// </summary> /// <param name="observedIsotopicPeakList"> /// The observed isotopic peak list. /// </param> /// <param name="expectedIsotopicPeakList"> /// The actual isotopic peak list. /// </param> /// <returns> /// The <see cref="double"/>. /// </returns> private static double EuclideanAlternative(List<double> observedIsotopicPeakList, List<Peak> expectedIsotopicPeakList) { // calculate angle between two isotopic vectors in the isotopic space double[] expectedIsotopicPeakIntensityArray = expectedIsotopicPeakList.Select(x => (double)x.Height).ToArray(); Vector<double> A = new DenseVector(observedIsotopicPeakList.ToArray()); Vector<double> B = new DenseVector(expectedIsotopicPeakIntensityArray); A = A.Normalize(2); B = B.Normalize(2); // calculate the euclidean distance between theoretical distribution and observed pattern double isotopicScore = 0; for (int i = 1; i < expectedIsotopicPeakList.Count; i++) { double diff = A[i] - B[i]; isotopicScore += diff * diff; } // Map the score to [0, 1] return ScoreUtil.MapToZeroOneTrignometry(Math.Sqrt(isotopicScore), true, 0.03); }
private void computeTransform() { Func<SkeletonPoint, Vector<double>> conv = (sp) => new DenseVector(new double[] { sp.X, sp.Y, sp.Z }); p0 = conv(dBlue.Value); var p1 = conv(dRed.Value); var p2 = conv(dYellow.Value); f2 = (p1 - p0).Normalize(1); f1 = (p2 - p0).Normalize(1); f1 = (f1 - (f1.DotProduct(f2) * f2)).Normalize(1); f3 = new DenseVector(new double[] { f1[1] * f2[2] - f1[2] * f2[1], f1[2] * f2[0] - f1[0] * f2[2], f1[0] * f2[1] - f1[1] * f2[0] }); f3 = f3.Normalize(1); IsValid = true; }