namespace VisualMath.Accord.Math { /// /// Static class Distance. Defines a set of extension methods defining distance measures. /// /// public static class Distance { /// /// Gets the Square Mahalanobis distance between two points. /// /// A point in space. /// A point in space. /// /// The inverse of the covariance matrix of the distribution for the two points x and y. /// /// The Square Mahalanobis distance between x and y. public static double SquareMahalanobis(this double[] x, double[] y, double[,] precision) { double[] d = new double[x.Length]; for (int i = 0; i < x.Length; i++) d[i] = x[i] - y[i]; return d.InnerProduct(precision.Multiply(d)); } /// /// Gets the Mahalanobis distance between two points. /// /// A point in space. /// A point in space. /// /// The inverse of the covariance matrix of the distribution for the two points x and y. /// /// The Mahalanobis distance between x and y. public static double Mahalanobis(this double[] x, double[] y, double[,] precision) { return System.Math.Sqrt(SquareMahalanobis(x, y, precision)); } /// /// Gets the Manhattan distance between two points. /// /// A point in space. /// A point in space. /// The manhattan distance between x and y. public static double Manhattan(this double[] x, double[] y) { double sum = 0.0; for (int i = 0; i < x.Length; i++) sum += System.Math.Abs(x[i] - y[i]); return sum; } /// /// Gets the Square Euclidean distance between two points. /// /// A point in space. /// A point in space. /// The Square Euclidean distance between x and y. public static double SquareEuclidean(this double[] x, double[] y) { double d = 0.0, u; for (int i = 0; i < x.Length; i++) { u = x[i] - y[i]; d += u * u; } return d; } /// /// Gets the Euclidean distance between two points. /// /// A point in space. /// A point in space. /// The Euclidean distance between x and y. public static double Euclidean(this double[] x, double[] y) { return System.Math.Sqrt(SquareEuclidean(x, y)); } /// /// Gets the Modulo-m distance between two integers a and b. /// public static int Modular(int a, int b, int modulo) { return System.Math.Min(Tools.Mod(a - b, modulo), Tools.Mod(b - a, modulo)); } /// /// Bhattacharyya distance between two normalized histograms. /// /// A normalized histogram. /// A normalized histogram. /// The Bhattacharya distance between the two histograms. public static double Bhattacharyya(double[] histogram1, double[] histogram2) { int bins = histogram1.Length; // histogram bins double b = 0; // Bhattacharyya's coefficient for (int i = 0; i < bins; i++) b += System.Math.Sqrt(histogram1[i]) * System.Math.Sqrt(histogram2[i]); // bhattacharyya distance between the two distributions return System.Math.Sqrt(1.0 - b); } /// /// Bhattacharyya distance between two gaussian distributions. /// /// Mean for the first distribution. /// Covariance matrix for the first distribution. /// Mean for the second distribution. /// Covariance matrix for the second distribution. /// The Bhattacharia distance between the two distributions. public static double Bhattacharyya(double[] mean1, double[,] sigma1, double[] mean2, double[,] sigma2) { int n = sigma1.GetLength(0); // P = (sigma1+sigma2)/2 double[,] P = new double[n, n]; for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) P[i, j] = (sigma1[i, j] + sigma2[i, j]) / 2.0; double detP = P.Determinant(); double detP1 = sigma1.Determinant(); double detP2 = sigma2.Determinant(); return (1.0 / 8.0) * SquareMahalanobis(mean2, mean1, Matrix.Inverse(P)) + (0.5) * System.Math.Log(detP / System.Math.Sqrt(detP1 * detP2)); } } }