/// <summary> /// Checks whether a function is a real metric distance, i.e. respects /// the triangle inequality. Please note that a function can still pass /// this test and not respect the triangle inequality. /// </summary> /// public static bool IsMetric(Func <int[], int[], double> value) { // Direct test double z = value(new[] { 1 }, new[] { 1 }); if (z > 2 || z < 0) { return(false); } int size = 3; int[] zero = new int[size]; foreach (var a in Combinatorics.Sequences(3, size, inPlace: true)) { foreach (var b in Combinatorics.Sequences(3, size, inPlace: true)) { double dza = value(zero, a); double dzb = value(zero, b); double dab = value(a, b); if (dab > dza + dzb) { return(false); } double daz = value(a, zero); double dbz = value(b, zero); double dba = value(b, a); if (daz != dza || dbz != dzb || dab != dba) { return(false); } } } return(true); }
/// <summary> /// Creates a vector containing every index that can be used to /// address a given <paramref name="array"/>, in order. /// </summary> /// /// <param name="array">The array whose indices will be returned.</param> /// /// <returns> /// An enumerable object that can be used to iterate over all /// positions of the given <paramref name="array">System.Array</paramref>. /// </returns> /// /// <example> /// <code> /// double[,] a = /// { /// { 5.3, 2.3 }, /// { 4.2, 9.2 } /// }; /// /// foreach (int[] idx in Indices.From(a)) /// { /// // Get the current element /// double e = (double)a.GetValue(idx); /// } /// </code> /// </example> /// public static IEnumerable <int[]> From(this Array array) { int[] dimensions = array.GetDimensions(); return(Combinatorics.Sequences(dimensions, inPlace: true)); }
/// <summary> /// Creates a vector containing every index that can be used to /// address a given <paramref name="array"/>, in order. /// </summary> /// /// <param name="array">The array whose indices will be returned.</param> /// <param name="deep">Pass true to retrieve all dimensions of the array, /// even if it contains nested arrays (as in jagged matrices).</param> /// <param name="max">Bases computations on the maximum length possible for /// each dimension (in case the jagged matrices has different lengths).</param> /// /// <returns> /// An enumerable object that can be used to iterate over all /// positions of the given <paramref name="array">System.Array</paramref>. /// </returns> /// /// <example> /// <code> /// double[,] a = /// { /// { 5.3, 2.3 }, /// { 4.2, 9.2 } /// }; /// /// foreach (int[] idx in a.GetIndices()) /// { /// // Get the current element /// double e = (double)a.GetValue(idx); /// } /// </code> /// </example> /// /// <seealso cref="Accord.Math.Vector.GetIndices{T}(T[])"/> /// public static IEnumerable <int[]> GetIndices(this Array array, bool deep = false, bool max = false) { return(Combinatorics.Sequences(array.GetLength(deep, max))); }
/// <summary> /// Creates a vector containing every index that can be used to /// address a given <paramref name="array"/>, in order. /// </summary> /// /// <param name="array">The array whose indices will be returned.</param> /// /// <returns> /// An enumerable object that can be used to iterate over all /// positions of the given <paramref name="array">System.Array</paramref>. /// </returns> /// /// <example> /// <code> /// double[,] a = /// { /// { 5.3, 2.3 }, /// { 4.2, 9.2 } /// }; /// /// foreach (int[] idx in a.GetIndices()) /// { /// // Get the current element /// double e = (double)a.GetValue(idx); /// } /// </code> /// </example> /// /// <seealso cref="Accord.Math.Vector.GetIndices{T}(T[])"/> /// public static IEnumerable <int[]> GetIndices(this Array array) { return(Combinatorics.Sequences(array.GetLength(), inPlace: true)); }