diff --git a/src/Numerics/Distance.cs b/src/Numerics/Distance.cs index b5819f12..da1b5082 100644 --- a/src/Numerics/Distance.cs +++ b/src/Numerics/Distance.cs @@ -202,36 +202,6 @@ namespace MathNet.Numerics return SAD(a, b); } - /// - /// Canberra Distance, a weighted version of the L1-norm of the difference. - /// - public static double Canberra(double[] a, double[] b) - { - if (a.Length != b.Length) throw new ArgumentException(Resources.ArgumentVectorsSameLength); - - double sum = 0d; - for (var i = 0; i < a.Length; i++) - { - sum += Math.Abs(a[i] - b[i])/(Math.Abs(a[i]) + Math.Abs(b[i])); - } - return sum; - } - - /// - /// Canberra Distance, a weighted version of the L1-norm of the difference. - /// - public static double Canberra(float[] a, float[] b) - { - if (a.Length != b.Length) throw new ArgumentException(Resources.ArgumentVectorsSameLength); - - float sum = 0f; - for (var i = 0; i < a.Length; i++) - { - sum += Math.Abs(a[i] - b[i]) / (Math.Abs(a[i]) + Math.Abs(b[i])); - } - return sum; - } - /// /// Chebyshev Distance, i.e. the Infinity-norm of the difference. /// @@ -276,6 +246,82 @@ namespace MathNet.Numerics return max; } + /// + /// Minkowski Distance, i.e. the generalized p-norm of the difference. + /// + public static double Minkowski(double p, Vector a, Vector b) where T : struct, IEquatable, IFormattable + { + return (a - b).Norm(p); + } + + /// + /// Minkowski Distance, i.e. the generalized p-norm of the difference. + /// + public static double Minkowski(double p, double[] a, double[] b) + { + if (a.Length != b.Length) throw new ArgumentException(Resources.ArgumentVectorsSameLength); + if (p < 0d) throw new ArgumentOutOfRangeException("p"); + if (p == 1d) return Manhattan(a, b); + if (p == 2d) return Euclidean(a, b); + if (double.IsPositiveInfinity(p)) return Chebyshev(a, b); + + double sum = 0d; + for (var i = 0; i < a.Length; i++) + { + sum += Math.Pow(Math.Abs(a[i] - b[i]), p); + } + return Math.Pow(sum, 1.0 / p); + } + + /// + /// Minkowski Distance, i.e. the generalized p-norm of the difference. + /// + public static float Minkowski(double p, float[] a, float[] b) + { + if (a.Length != b.Length) throw new ArgumentException(Resources.ArgumentVectorsSameLength); + if (p < 0d) throw new ArgumentOutOfRangeException("p"); + if (p == 1d) return Manhattan(a, b); + if (p == 2d) return Euclidean(a, b); + if (double.IsPositiveInfinity(p)) return Chebyshev(a, b); + + double sum = 0d; + for (var i = 0; i < a.Length; i++) + { + sum += Math.Pow(Math.Abs(a[i] - b[i]), p); + } + return (float) Math.Pow(sum, 1.0/p); + } + + /// + /// Canberra Distance, a weighted version of the L1-norm of the difference. + /// + public static double Canberra(double[] a, double[] b) + { + if (a.Length != b.Length) throw new ArgumentException(Resources.ArgumentVectorsSameLength); + + double sum = 0d; + for (var i = 0; i < a.Length; i++) + { + sum += Math.Abs(a[i] - b[i]) / (Math.Abs(a[i]) + Math.Abs(b[i])); + } + return sum; + } + + /// + /// Canberra Distance, a weighted version of the L1-norm of the difference. + /// + public static float Canberra(float[] a, float[] b) + { + if (a.Length != b.Length) throw new ArgumentException(Resources.ArgumentVectorsSameLength); + + float sum = 0f; + for (var i = 0; i < a.Length; i++) + { + sum += Math.Abs(a[i] - b[i]) / (Math.Abs(a[i]) + Math.Abs(b[i])); + } + return sum; + } + /// /// Hamming Distance, i.e. the number of positions that have different values in the vectors. ///