diff --git a/src/Examples/LinearAlgebra/MatrixNorms.cs b/src/Examples/LinearAlgebra/MatrixNorms.cs index e6afe985..54a837e1 100644 --- a/src/Examples/LinearAlgebra/MatrixNorms.cs +++ b/src/Examples/LinearAlgebra/MatrixNorms.cs @@ -97,7 +97,7 @@ namespace Examples.LinearAlgebraExamples Console.WriteLine(@"5. Normalize matrix columns: before normalize"); foreach (var keyValuePair in matrix.ColumnEnumerator()) { - Console.WriteLine(@"Column {0} 2-nd norm is: {1}", keyValuePair.Item1, keyValuePair.Item2.Norm(2)); + Console.WriteLine(@"Column {0} 2-nd norm is: {1}", keyValuePair.Item1, keyValuePair.Item2.L2Norm()); } Console.WriteLine(); @@ -105,7 +105,7 @@ namespace Examples.LinearAlgebraExamples Console.WriteLine(@"5. Normalize matrix columns: after normalize"); foreach (var keyValuePair in normalized.ColumnEnumerator()) { - Console.WriteLine(@"Column {0} 2-nd norm is: {1}", keyValuePair.Item1, keyValuePair.Item2.Norm(2)); + Console.WriteLine(@"Column {0} 2-nd norm is: {1}", keyValuePair.Item1, keyValuePair.Item2.L2Norm()); } Console.WriteLine(); @@ -114,7 +114,7 @@ namespace Examples.LinearAlgebraExamples Console.WriteLine(@"6. Normalize matrix rows: before normalize"); foreach (var keyValuePair in matrix.RowEnumerator()) { - Console.WriteLine(@"Row {0} 2-nd norm is: {1}", keyValuePair.Item1, keyValuePair.Item2.Norm(2)); + Console.WriteLine(@"Row {0} 2-nd norm is: {1}", keyValuePair.Item1, keyValuePair.Item2.L2Norm()); } Console.WriteLine(); @@ -122,7 +122,7 @@ namespace Examples.LinearAlgebraExamples Console.WriteLine(@"6. Normalize matrix rows: after normalize"); foreach (var keyValuePair in normalized.RowEnumerator()) { - Console.WriteLine(@"Row {0} 2-nd norm is: {1}", keyValuePair.Item1, keyValuePair.Item2.Norm(2)); + Console.WriteLine(@"Row {0} 2-nd norm is: {1}", keyValuePair.Item1, keyValuePair.Item2.L2Norm()); } } } diff --git a/src/Numerics/Distance.cs b/src/Numerics/Distance.cs index 547f1fe6..40422bb7 100644 --- a/src/Numerics/Distance.cs +++ b/src/Numerics/Distance.cs @@ -41,7 +41,7 @@ namespace MathNet.Numerics /// public static double SAD(Vector a, Vector b) { - return (a - b).SumMagnitudes(); + return (a - b).L1Norm(); } /// @@ -49,7 +49,7 @@ namespace MathNet.Numerics /// public static float SAD(Vector a, Vector b) { - return (a - b).SumMagnitudes(); + return (a - b).L1Norm(); } /// @@ -87,7 +87,7 @@ namespace MathNet.Numerics /// public static double MAE(Vector a, Vector b) { - return SAD(a, b)/a.Count; + return (a - b).L1Norm()/a.Count; } /// @@ -95,7 +95,7 @@ namespace MathNet.Numerics /// public static float MAE(Vector a, Vector b) { - return SAD(a, b)/a.Count; + return (a - b).L1Norm()/a.Count; } /// @@ -119,7 +119,7 @@ namespace MathNet.Numerics /// public static double SSD(Vector a, Vector b) { - var norm = (a - b).Norm(2d); + var norm = (a - b).L2Norm(); return norm*norm; } @@ -128,7 +128,7 @@ namespace MathNet.Numerics /// public static float SSD(Vector a, Vector b) { - var norm = (a - b).Norm(2d); + var norm = (a - b).L2Norm(); return norm*norm; } @@ -157,7 +157,8 @@ namespace MathNet.Numerics /// public static double MSE(Vector a, Vector b) { - return SSD(a, b)/a.Count; + var norm = (a - b).L2Norm(); + return norm*norm/a.Count; } /// @@ -165,7 +166,8 @@ namespace MathNet.Numerics /// public static float MSE(Vector a, Vector b) { - return SSD(a, b)/a.Count; + var norm = (a - b).L2Norm(); + return norm*norm/a.Count; } /// diff --git a/src/Numerics/LinearAlgebra/Complex/DenseVector.cs b/src/Numerics/LinearAlgebra/Complex/DenseVector.cs index 4c827b26..57eb0556 100644 --- a/src/Numerics/LinearAlgebra/Complex/DenseVector.cs +++ b/src/Numerics/LinearAlgebra/Complex/DenseVector.cs @@ -599,31 +599,67 @@ namespace MathNet.Numerics.LinearAlgebra.Complex public override Complex Sum() { var sum = Complex.Zero; - for (var i = 0; i < _length; i++) { sum += _values[i]; } - return sum; } /// - /// Computes the sum of the absolute value of the vector's elements. + /// Calculates the L1 norm of the vector, also known as Manhattan norm. /// - /// The sum of the absolute value of the vector's elements. - public override Complex SumMagnitudes() + /// The sum of the absolute values. + public override Complex L1Norm() { var sum = Complex.Zero; - for (var i = 0; i < _length; i++) { sum += _values[i].Magnitude; } - return sum; } + /// + /// Calculates the L2 norm of the vector, also known as Euclidean norm. + /// + /// The square root of the sum of the squared values. + public override Complex L2Norm() + { + // TODO: native provider + return _values.Aggregate(Complex.Zero, SpecialFunctions.Hypotenuse).Magnitude; + } + + /// + /// Calculates the infinity norm of the vector. + /// + /// The square root of the sum of the squared values. + public override Complex InfinityNorm() + { + return CommonParallel.Aggregate(_values, (i, v) => v.Magnitude, Math.Max, 0d); + } + + /// + /// Computes the p-Norm. + /// + /// The p value. + /// Scalar ret = (sum(abs(this[i])^p))^(1/p) + public override Complex Norm(double p) + { + if (p < 0d) throw new ArgumentOutOfRangeException("p"); + + if (p == 1d) return L1Norm(); + if (p == 2d) return L2Norm(); + if (Double.IsPositiveInfinity(p)) return InfinityNorm(); + + var sum = 0d; + for (var i = 0; i < _length; i++) + { + sum += Math.Pow(_values[i].Magnitude, p); + } + return Math.Pow(sum, 1.0 / p); + } + /// /// Pointwise divide this vector with another vector and stores the result into the result vector. /// @@ -712,43 +748,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex return OuterProduct(this, v); } - /// - /// Computes the p-Norm. - /// - /// The p value. - /// Scalar ret = (sum(abs(this[i])^p))^(1/p) - public override Complex Norm(double p) - { - if (p < 0.0) - { - throw new ArgumentOutOfRangeException("p"); - } - - if (1.0 == p) - { - return SumMagnitudes(); - } - - if (2.0 == p) - { - return _values.Aggregate(Complex.Zero, SpecialFunctions.Hypotenuse).Magnitude; - } - - if (Double.IsPositiveInfinity(p)) - { - return CommonParallel.Aggregate(_values, (i, v) => v.Magnitude, Math.Max, 0d); - } - - var sum = 0.0; - - for (var i = 0; i < _length; i++) - { - sum += Math.Pow(_values[i].Magnitude, p); - } - - return Math.Pow(sum, 1.0 / p); - } - #region Parse Functions /// diff --git a/src/Numerics/LinearAlgebra/Complex/Factorization/UserGramSchmidt.cs b/src/Numerics/LinearAlgebra/Complex/Factorization/UserGramSchmidt.cs index 22a9311f..1ecf6886 100644 --- a/src/Numerics/LinearAlgebra/Complex/Factorization/UserGramSchmidt.cs +++ b/src/Numerics/LinearAlgebra/Complex/Factorization/UserGramSchmidt.cs @@ -74,7 +74,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization for (var k = 0; k < MatrixQ.ColumnCount; k++) { - var norm = MatrixQ.Column(k).Norm(2); + var norm = MatrixQ.Column(k).L2Norm(); if (norm == 0.0) { throw new ArgumentException(Resources.ArgumentMatrixNotRankDeficient); diff --git a/src/Numerics/LinearAlgebra/Complex/Solvers/Iterative/MlkBiCgStab.cs b/src/Numerics/LinearAlgebra/Complex/Solvers/Iterative/MlkBiCgStab.cs index f6d0f7db..8e4c9ccc 100644 --- a/src/Numerics/LinearAlgebra/Complex/Solvers/Iterative/MlkBiCgStab.cs +++ b/src/Numerics/LinearAlgebra/Complex/Solvers/Iterative/MlkBiCgStab.cs @@ -680,7 +680,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative result.Add((Vector)orthogonalMatrix.Column(i)); // Normalize the result vector - result[i].Multiply(1 / result[i].Norm(2), result[i]); + result[i].Multiply(1 / result[i].L2Norm(), result[i]); } return result; diff --git a/src/Numerics/LinearAlgebra/Complex/Solvers/Iterative/TFQMR.cs b/src/Numerics/LinearAlgebra/Complex/Solvers/Iterative/TFQMR.cs index 785411ec..a9f125d8 100644 --- a/src/Numerics/LinearAlgebra/Complex/Solvers/Iterative/TFQMR.cs +++ b/src/Numerics/LinearAlgebra/Complex/Solvers/Iterative/TFQMR.cs @@ -283,7 +283,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative var temp2 = new DenseVector(input.Count); // Initialize - var startNorm = input.Norm(2); + var startNorm = input.L2Norm(); // Define the scalars Complex alpha = 0; @@ -349,7 +349,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative yinternal.Add(temp, d); // theta = ||pseudoResiduals||_2 / tau - theta = pseudoResiduals.Norm(2).Real/tau; + theta = pseudoResiduals.L2Norm().Real / tau; var c = 1/Math.Sqrt(1 + (theta*theta)); // tau = tau * theta * c diff --git a/src/Numerics/LinearAlgebra/Complex/Solvers/Preconditioners/Ilutp.cs b/src/Numerics/LinearAlgebra/Complex/Solvers/Preconditioners/Ilutp.cs index b0e9c71c..dbc49216 100644 --- a/src/Numerics/LinearAlgebra/Complex/Solvers/Preconditioners/Ilutp.cs +++ b/src/Numerics/LinearAlgebra/Complex/Solvers/Preconditioners/Ilutp.cs @@ -394,7 +394,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Preconditioners // pivot the row PivotRow(workVector); - var vectorNorm = workVector.Norm(Double.PositiveInfinity); + var vectorNorm = workVector.InfinityNorm(); // for j = 1, .. , i - 1) for (var j = 0; j < i; j++) diff --git a/src/Numerics/LinearAlgebra/Complex/Solvers/StopCriterium/DivergenceStopCriterium.cs b/src/Numerics/LinearAlgebra/Complex/Solvers/StopCriterium/DivergenceStopCriterium.cs index f2454e9b..4d3f4fa4 100644 --- a/src/Numerics/LinearAlgebra/Complex/Solvers/StopCriterium/DivergenceStopCriterium.cs +++ b/src/Numerics/LinearAlgebra/Complex/Solvers/StopCriterium/DivergenceStopCriterium.cs @@ -250,7 +250,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.StopCriterium // Store the infinity norms of both the solution and residual vectors // These values will be used to calculate the relative drop in residuals later on. - _residualHistory[_residualHistory.Length - 1] = residualVector.Norm(Double.PositiveInfinity).Real; + _residualHistory[_residualHistory.Length - 1] = residualVector.InfinityNorm().Real; // Check if we have NaN's. If so we've gone way beyond normal divergence. // Stop the iteration. diff --git a/src/Numerics/LinearAlgebra/Complex/Solvers/StopCriterium/FailureStopCriterium.cs b/src/Numerics/LinearAlgebra/Complex/Solvers/StopCriterium/FailureStopCriterium.cs index dbcdbdb8..4fdd295e 100644 --- a/src/Numerics/LinearAlgebra/Complex/Solvers/StopCriterium/FailureStopCriterium.cs +++ b/src/Numerics/LinearAlgebra/Complex/Solvers/StopCriterium/FailureStopCriterium.cs @@ -105,8 +105,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.StopCriterium } // Store the infinity norms of both the solution and residual vectors - var residualNorm = residualVector.Norm(Double.PositiveInfinity); - var solutionNorm = solutionVector.Norm(Double.PositiveInfinity); + var residualNorm = residualVector.InfinityNorm(); + var solutionNorm = solutionVector.InfinityNorm(); if (Double.IsNaN(solutionNorm.Real) || Double.IsNaN(residualNorm.Real)) { diff --git a/src/Numerics/LinearAlgebra/Complex/Solvers/StopCriterium/ResidualStopCriterium.cs b/src/Numerics/LinearAlgebra/Complex/Solvers/StopCriterium/ResidualStopCriterium.cs index 21812d83..a2234457 100644 --- a/src/Numerics/LinearAlgebra/Complex/Solvers/StopCriterium/ResidualStopCriterium.cs +++ b/src/Numerics/LinearAlgebra/Complex/Solvers/StopCriterium/ResidualStopCriterium.cs @@ -257,11 +257,11 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.StopCriterium // Store the infinity norms of both the solution and residual vectors // These values will be used to calculate the relative drop in residuals // later on. - var residualNorm = residualVector.Norm(Double.PositiveInfinity); + var residualNorm = residualVector.InfinityNorm(); // Check the residuals by calculating: // ||r_i|| <= stop_tol * ||b|| - var stopCriterium = ComputeStopCriterium(sourceVector.Norm(Double.PositiveInfinity).Real); + var stopCriterium = ComputeStopCriterium(sourceVector.InfinityNorm().Real); // First check that we have real numbers not NaN's. // NaN's can occur when the iterative process diverges so we diff --git a/src/Numerics/LinearAlgebra/Complex/SparseVector.cs b/src/Numerics/LinearAlgebra/Complex/SparseVector.cs index 89960c70..78c4f1d0 100644 --- a/src/Numerics/LinearAlgebra/Complex/SparseVector.cs +++ b/src/Numerics/LinearAlgebra/Complex/SparseVector.cs @@ -763,25 +763,58 @@ namespace MathNet.Numerics.LinearAlgebra.Complex { result += _storage.Values[i]; } - return result; } /// - /// Computes the sum of the absolute value of the vector's elements. + /// Calculates the L1 norm of the vector, also known as Manhattan norm. /// - /// The sum of the absolute value of the vector's elements. - public override Complex SumMagnitudes() + /// The sum of the absolute values. + public override Complex L1Norm() { double result = 0; for (var i = 0; i < _storage.ValueCount; i++) { result += _storage.Values[i].Magnitude; } - return result; } + /// + /// Calculates the infinity norm of the vector. + /// + /// The square root of the sum of the squared values. + public override Complex InfinityNorm() + { + return CommonParallel.Aggregate(0, _storage.ValueCount, i => _storage.Values[i].Magnitude, Math.Max, 0d); + } + + /// + /// Computes the p-Norm. + /// + /// The p value. + /// Scalar ret = (sum(abs(this[i])^p))^(1/p) + public override Complex Norm(double p) + { + if (p < 0d) throw new ArgumentOutOfRangeException("p"); + + if (_storage.ValueCount == 0) + { + return Complex.Zero; + } + + if (p == 1d) return L1Norm(); + if (p == 2d) return L2Norm(); + if (Double.IsPositiveInfinity(p)) return InfinityNorm(); + + var sum = 0d; + for (var index = 0; index < _storage.ValueCount; index++) + { + sum += Math.Pow(_storage.Values[index].Magnitude, p); + } + return Math.Pow(sum, 1.0 / p); + } + /// /// Pointwise multiplies this vector with another vector and stores the result into the result vector. /// @@ -877,42 +910,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex return OuterProduct(this, v); } - /// - /// Computes the p-Norm. - /// - /// The p value. - /// Scalar ret = (sum(abs(this[i])^p))^(1/p) - public override Complex Norm(double p) - { - if (1 > p) - { - throw new ArgumentOutOfRangeException("p"); - } - - if (_storage.ValueCount == 0) - { - return 0.0; - } - - if (2.0 == p) - { - return _storage.Values.Aggregate(Complex.Zero, SpecialFunctions.Hypotenuse).Magnitude; - } - - if (Double.IsPositiveInfinity(p)) - { - return CommonParallel.Aggregate(0, _storage.ValueCount, i => _storage.Values[i].Magnitude, Math.Max, 0d); - } - - var sum = 0.0; - for (var index = 0; index < _storage.ValueCount; index++) - { - sum += Math.Pow(_storage.Values[index].Magnitude, p); - } - - return Math.Pow(sum, 1.0 / p); - } - #region Parse Functions /// diff --git a/src/Numerics/LinearAlgebra/Complex/Vector.cs b/src/Numerics/LinearAlgebra/Complex/Vector.cs index 065a15ec..e7b713f5 100644 --- a/src/Numerics/LinearAlgebra/Complex/Vector.cs +++ b/src/Numerics/LinearAlgebra/Complex/Vector.cs @@ -317,31 +317,45 @@ namespace MathNet.Numerics.LinearAlgebra.Complex public override Complex Sum() { var sum = Complex.Zero; - for (var i = 0; i < Count; i++) { sum += At(i); } - return sum; } /// - /// Computes the sum of the absolute value of the vector's elements. + /// Calculates the L1 norm of the vector, also known as Manhattan norm. /// - /// The sum of the absolute value of the vector's elements. - public override Complex SumMagnitudes() + /// The sum of the absolute values. + public override Complex L1Norm() { var sum = Complex.Zero; - for (var i = 0; i < Count; i++) { sum += At(i).Magnitude; } - return sum; } + /// + /// Calculates the L2 norm of the vector, also known as Euclidean norm. + /// + /// The square root of the sum of the squared values. + public override Complex L2Norm() + { + return DoConjugateDotProduct(this).SquareRoot(); + } + + /// + /// Calculates the infinity norm of the vector. + /// + /// The square root of the sum of the squared values. + public override Complex InfinityNorm() + { + return CommonParallel.Aggregate(0, Count, i => At(i).Magnitude, Math.Max, 0d); + } + /// /// Computes the p-Norm. /// @@ -353,23 +367,17 @@ namespace MathNet.Numerics.LinearAlgebra.Complex /// public override Complex Norm(double p) { - if (p < 0.0) - { - throw new ArgumentOutOfRangeException("p"); - } + if (p < 0d) throw new ArgumentOutOfRangeException("p"); - if (double.IsPositiveInfinity(p)) - { - return CommonParallel.Aggregate(0, Count, i => At(i).Magnitude, Math.Max, 0d); - } - - var sum = 0.0; + if (p == 1d) return L1Norm(); + if (p == 2d) return L2Norm(); + if (Double.IsPositiveInfinity(p)) return InfinityNorm(); + var sum = 0d; for (var index = 0; index < Count; index++) { sum += Math.Pow(At(index).Magnitude, p); } - return Math.Pow(sum, 1.0 / p); } diff --git a/src/Numerics/LinearAlgebra/Complex32/DenseVector.cs b/src/Numerics/LinearAlgebra/Complex32/DenseVector.cs index ca651380..7c8acc23 100644 --- a/src/Numerics/LinearAlgebra/Complex32/DenseVector.cs +++ b/src/Numerics/LinearAlgebra/Complex32/DenseVector.cs @@ -594,31 +594,67 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 public override Complex32 Sum() { var sum = Complex32.Zero; - for (var i = 0; i < _length; i++) { sum += _values[i]; } - return sum; } /// - /// Computes the sum of the absolute value of the vector's elements. + /// Calculates the L1 norm of the vector, also known as Manhattan norm. /// - /// The sum of the absolute value of the vector's elements. - public override Complex32 SumMagnitudes() + /// The sum of the absolute values. + public override Complex32 L1Norm() { var sum = Complex32.Zero; - for (var i = 0; i < _length; i++) { sum += _values[i].Magnitude; } - return sum; } + /// + /// Calculates the L2 norm of the vector, also known as Euclidean norm. + /// + /// The square root of the sum of the squared values. + public override Complex32 L2Norm() + { + // TODO: native provider + return _values.Aggregate(Complex32.Zero, SpecialFunctions.Hypotenuse).Magnitude; + } + + /// + /// Calculates the infinity norm of the vector. + /// + /// The square root of the sum of the squared values. + public override Complex32 InfinityNorm() + { + return CommonParallel.Aggregate(_values, (i, v) => v.Magnitude, Math.Max, 0f); + } + + /// + /// Computes the p-Norm. + /// + /// The p value. + /// Scalar ret = (sum(abs(this[i])^p))^(1/p) + public override Complex32 Norm(double p) + { + if (p < 0d) throw new ArgumentOutOfRangeException("p"); + + if (p == 1d) return L1Norm(); + if (p == 2d) return L2Norm(); + if (Double.IsPositiveInfinity(p)) return InfinityNorm(); + + var sum = 0d; + for (var i = 0; i < _length; i++) + { + sum += Math.Pow(_values[i].Magnitude, p); + } + return (float)Math.Pow(sum, 1.0 / p); + } + /// /// Pointwise divide this vector with another vector and stores the result into the result vector. /// @@ -707,43 +743,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 return OuterProduct(this, v); } - /// - /// Computes the p-Norm. - /// - /// The p value. - /// Scalar ret = (sum(abs(this[i])^p))^(1/p) - public override Complex32 Norm(double p) - { - if (p < 0.0) - { - throw new ArgumentOutOfRangeException("p"); - } - - if (1.0 == p) - { - return SumMagnitudes(); - } - - if (2.0 == p) - { - return _values.Aggregate(Complex32.Zero, SpecialFunctions.Hypotenuse).Magnitude; - } - - if (Double.IsPositiveInfinity(p)) - { - return CommonParallel.Aggregate(_values, (i, v) => v.Magnitude, Math.Max, 0f); - } - - var sum = 0.0; - - for (var i = 0; i < _length; i++) - { - sum += Math.Pow(_values[i].Magnitude, p); - } - - return (float)Math.Pow(sum, 1.0 / p); - } - #region Parse Functions /// diff --git a/src/Numerics/LinearAlgebra/Complex32/Factorization/UserGramSchmidt.cs b/src/Numerics/LinearAlgebra/Complex32/Factorization/UserGramSchmidt.cs index 01bb3013..aacb7ede 100644 --- a/src/Numerics/LinearAlgebra/Complex32/Factorization/UserGramSchmidt.cs +++ b/src/Numerics/LinearAlgebra/Complex32/Factorization/UserGramSchmidt.cs @@ -69,7 +69,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization for (var k = 0; k < MatrixQ.ColumnCount; k++) { - var norm = MatrixQ.Column(k).Norm(2).Real; + var norm = MatrixQ.Column(k).L2Norm().Real; if (norm == 0.0f) { throw new ArgumentException(Resources.ArgumentMatrixNotRankDeficient); diff --git a/src/Numerics/LinearAlgebra/Complex32/Solvers/Iterative/MlkBiCgStab.cs b/src/Numerics/LinearAlgebra/Complex32/Solvers/Iterative/MlkBiCgStab.cs index 9908b787..e164fbb9 100644 --- a/src/Numerics/LinearAlgebra/Complex32/Solvers/Iterative/MlkBiCgStab.cs +++ b/src/Numerics/LinearAlgebra/Complex32/Solvers/Iterative/MlkBiCgStab.cs @@ -680,7 +680,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative result.Add((Vector)orthogonalMatrix.Column(i)); // Normalize the result vector - result[i].Multiply(1 / result[i].Norm(2).Real, result[i]); + result[i].Multiply(1 / result[i].L2Norm().Real, result[i]); } return result; diff --git a/src/Numerics/LinearAlgebra/Complex32/Solvers/Iterative/TFQMR.cs b/src/Numerics/LinearAlgebra/Complex32/Solvers/Iterative/TFQMR.cs index 7090da14..64911e68 100644 --- a/src/Numerics/LinearAlgebra/Complex32/Solvers/Iterative/TFQMR.cs +++ b/src/Numerics/LinearAlgebra/Complex32/Solvers/Iterative/TFQMR.cs @@ -283,7 +283,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative var temp2 = new DenseVector(input.Count); // Initialize - var startNorm = input.Norm(2); + var startNorm = input.L2Norm(); // Define the scalars Complex32 alpha = 0; @@ -349,7 +349,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative yinternal.Add(temp, d); // theta = ||pseudoResiduals||_2 / tau - theta = pseudoResiduals.Norm(2).Real/tau; + theta = pseudoResiduals.L2Norm().Real / tau; var c = 1/(float) Math.Sqrt(1 + (theta*theta)); // tau = tau * theta * c diff --git a/src/Numerics/LinearAlgebra/Complex32/Solvers/Preconditioners/Ilutp.cs b/src/Numerics/LinearAlgebra/Complex32/Solvers/Preconditioners/Ilutp.cs index fcae64d4..fe82cc9c 100644 --- a/src/Numerics/LinearAlgebra/Complex32/Solvers/Preconditioners/Ilutp.cs +++ b/src/Numerics/LinearAlgebra/Complex32/Solvers/Preconditioners/Ilutp.cs @@ -389,7 +389,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Preconditioners // pivot the row PivotRow(workVector); - var vectorNorm = workVector.Norm(Double.PositiveInfinity); + var vectorNorm = workVector.InfinityNorm(); // for j = 1, .. , i - 1) for (var j = 0; j < i; j++) diff --git a/src/Numerics/LinearAlgebra/Complex32/Solvers/StopCriterium/DivergenceStopCriterium.cs b/src/Numerics/LinearAlgebra/Complex32/Solvers/StopCriterium/DivergenceStopCriterium.cs index 5c0852dc..be2a9894 100644 --- a/src/Numerics/LinearAlgebra/Complex32/Solvers/StopCriterium/DivergenceStopCriterium.cs +++ b/src/Numerics/LinearAlgebra/Complex32/Solvers/StopCriterium/DivergenceStopCriterium.cs @@ -250,7 +250,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.StopCriterium // Store the infinity norms of both the solution and residual vectors // These values will be used to calculate the relative drop in residuals later on. - _residualHistory[_residualHistory.Length - 1] = residualVector.Norm(Double.PositiveInfinity).Real; + _residualHistory[_residualHistory.Length - 1] = residualVector.InfinityNorm().Real; // Check if we have NaN's. If so we've gone way beyond normal divergence. // Stop the iteration. diff --git a/src/Numerics/LinearAlgebra/Complex32/Solvers/StopCriterium/FailureStopCriterium.cs b/src/Numerics/LinearAlgebra/Complex32/Solvers/StopCriterium/FailureStopCriterium.cs index e2a48213..e157752a 100644 --- a/src/Numerics/LinearAlgebra/Complex32/Solvers/StopCriterium/FailureStopCriterium.cs +++ b/src/Numerics/LinearAlgebra/Complex32/Solvers/StopCriterium/FailureStopCriterium.cs @@ -105,8 +105,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.StopCriterium } // Store the infinity norms of both the solution and residual vectors - var residualNorm = residualVector.Norm(Double.PositiveInfinity); - var solutionNorm = solutionVector.Norm(Double.PositiveInfinity); + var residualNorm = residualVector.InfinityNorm(); + var solutionNorm = solutionVector.InfinityNorm(); if (Single.IsNaN(solutionNorm.Real) || Single.IsNaN(residualNorm.Real)) { diff --git a/src/Numerics/LinearAlgebra/Complex32/Solvers/StopCriterium/ResidualStopCriterium.cs b/src/Numerics/LinearAlgebra/Complex32/Solvers/StopCriterium/ResidualStopCriterium.cs index fa4d5afa..e35595e2 100644 --- a/src/Numerics/LinearAlgebra/Complex32/Solvers/StopCriterium/ResidualStopCriterium.cs +++ b/src/Numerics/LinearAlgebra/Complex32/Solvers/StopCriterium/ResidualStopCriterium.cs @@ -257,11 +257,11 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.StopCriterium // Store the infinity norms of both the solution and residual vectors // These values will be used to calculate the relative drop in residuals // later on. - var residualNorm = residualVector.Norm(float.PositiveInfinity); + var residualNorm = residualVector.InfinityNorm(); // Check the residuals by calculating: // ||r_i|| <= stop_tol * ||b|| - var stopCriterium = ComputeStopCriterium(sourceVector.Norm(float.PositiveInfinity).Real); + var stopCriterium = ComputeStopCriterium(sourceVector.InfinityNorm().Real); // First check that we have real numbers not NaN's. // NaN's can occur when the iterative process diverges so we diff --git a/src/Numerics/LinearAlgebra/Complex32/SparseVector.cs b/src/Numerics/LinearAlgebra/Complex32/SparseVector.cs index 4e200f62..e5b02add 100644 --- a/src/Numerics/LinearAlgebra/Complex32/SparseVector.cs +++ b/src/Numerics/LinearAlgebra/Complex32/SparseVector.cs @@ -758,25 +758,58 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 { result += _storage.Values[i]; } - return result; } /// - /// Computes the sum of the absolute value of the vector's elements. + /// Calculates the L1 norm of the vector, also known as Manhattan norm. /// - /// The sum of the absolute value of the vector's elements. - public override Complex32 SumMagnitudes() + /// The sum of the absolute values. + public override Complex32 L1Norm() { - var result = 0.0f; + var result = 0f; for (var i = 0; i < _storage.ValueCount; i++) { result += _storage.Values[i].Magnitude; } - return result; } + /// + /// Calculates the infinity norm of the vector. + /// + /// The square root of the sum of the squared values. + public override Complex32 InfinityNorm() + { + return CommonParallel.Aggregate(0, _storage.ValueCount, i => _storage.Values[i].Magnitude, Math.Max, 0f); + } + + /// + /// Computes the p-Norm. + /// + /// The p value. + /// Scalar ret = (sum(abs(this[i])^p))^(1/p) + public override Complex32 Norm(double p) + { + if (p < 0d) throw new ArgumentOutOfRangeException("p"); + + if (_storage.ValueCount == 0) + { + return Complex32.Zero; + } + + if (p == 1d) return L1Norm(); + if (p == 2d) return L2Norm(); + if (Double.IsPositiveInfinity(p)) return InfinityNorm(); + + var sum = 0d; + for (var index = 0; index < _storage.ValueCount; index++) + { + sum += Math.Pow(_storage.Values[index].Magnitude, p); + } + return (float)Math.Pow(sum, 1.0 / p); + } + /// /// Pointwise multiplies this vector with another vector and stores the result into the result vector. /// @@ -872,42 +905,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 return OuterProduct(this, v); } - /// - /// Computes the p-Norm. - /// - /// The p value. - /// Scalar ret = (sum(abs(this[i])^p))^(1/p) - public override Complex32 Norm(double p) - { - if (1 > p) - { - throw new ArgumentOutOfRangeException("p"); - } - - if (_storage.ValueCount == 0) - { - return Complex32.Zero; - } - - if (2.0 == p) - { - return _storage.Values.Aggregate(Complex32.Zero, SpecialFunctions.Hypotenuse).Magnitude; - } - - if (Double.IsPositiveInfinity(p)) - { - return CommonParallel.Aggregate(0, _storage.ValueCount, i => _storage.Values[i].Magnitude, Math.Max, 0f); - } - - var sum = 0.0; - for (var index = 0; index < _storage.ValueCount; index++) - { - sum += Math.Pow(_storage.Values[index].Magnitude, p); - } - - return (float)Math.Pow(sum, 1.0 / p); - } - #region Parse Functions /// diff --git a/src/Numerics/LinearAlgebra/Complex32/Vector.cs b/src/Numerics/LinearAlgebra/Complex32/Vector.cs index a50fb1d2..ae4e05b2 100644 --- a/src/Numerics/LinearAlgebra/Complex32/Vector.cs +++ b/src/Numerics/LinearAlgebra/Complex32/Vector.cs @@ -312,31 +312,45 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 public override Complex32 Sum() { var sum = Complex32.Zero; - for (var i = 0; i < Count; i++) { sum += At(i); } - return sum; } /// - /// Computes the sum of the absolute value of the vector's elements. + /// Calculates the L1 norm of the vector, also known as Manhattan norm. /// - /// The sum of the absolute value of the vector's elements. - public override Complex32 SumMagnitudes() + /// The sum of the absolute values. + public override Complex32 L1Norm() { var sum = Complex32.Zero; - for (var i = 0; i < Count; i++) { sum += At(i).Magnitude; } - return sum; } + /// + /// Calculates the L2 norm of the vector, also known as Euclidean norm. + /// + /// The square root of the sum of the squared values. + public override Complex32 L2Norm() + { + return DoConjugateDotProduct(this).SquareRoot(); + } + + /// + /// Calculates the infinity norm of the vector. + /// + /// The square root of the sum of the squared values. + public override Complex32 InfinityNorm() + { + return CommonParallel.Aggregate(0, Count, i => At(i).Magnitude, Math.Max, 0f); + } + /// /// Computes the p-Norm. /// @@ -348,24 +362,18 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 /// public override Complex32 Norm(double p) { - if (p < 0.0) - { - throw new ArgumentOutOfRangeException("p"); - } + if (p < 0d) throw new ArgumentOutOfRangeException("p"); - if (double.IsPositiveInfinity(p)) - { - return CommonParallel.Aggregate(0, Count, i => At(i).Magnitude, Math.Max, 0f); - } - - var sum = 0.0; + if (p == 1d) return L1Norm(); + if (p == 2d) return L2Norm(); + if (Double.IsPositiveInfinity(p)) return InfinityNorm(); + var sum = 0d; for (var index = 0; index < Count; index++) { sum += Math.Pow(At(index).Magnitude, p); } - - return (float)Math.Pow(sum, 1.0 / p); + return (float) Math.Pow(sum, 1.0/p); } /// diff --git a/src/Numerics/LinearAlgebra/Double/DenseVector.cs b/src/Numerics/LinearAlgebra/Double/DenseVector.cs index 0afd2d49..147fe557 100644 --- a/src/Numerics/LinearAlgebra/Double/DenseVector.cs +++ b/src/Numerics/LinearAlgebra/Double/DenseVector.cs @@ -667,31 +667,67 @@ namespace MathNet.Numerics.LinearAlgebra.Double public override double Sum() { var sum = 0.0; - for (var index = 0; index < _length; index++) { sum += _values[index]; } - return sum; } /// - /// Computes the sum of the absolute value of the vector's elements. + /// Calculates the L1 norm of the vector, also known as Manhattan norm. /// - /// The sum of the absolute value of the vector's elements. - public override double SumMagnitudes() + /// The sum of the absolute values. + public override double L1Norm() { - var sum = 0.0; - + var sum = 0d; for (var index = 0; index < _length; index++) { sum += Math.Abs(_values[index]); } - return sum; } + /// + /// Calculates the L2 norm of the vector, also known as Euclidean norm. + /// + /// The square root of the sum of the squared values. + public override double L2Norm() + { + // TODO: native provider + return _values.Aggregate(0d, SpecialFunctions.Hypotenuse); + } + + /// + /// Calculates the infinity norm of the vector. + /// + /// The square root of the sum of the squared values. + public override double InfinityNorm() + { + return CommonParallel.Aggregate(_values, (i, v) => Math.Abs(v), Math.Max, 0d); + } + + /// + /// Computes the p-Norm. + /// + /// The p value. + /// Scalar ret = (sum(abs(this[i])^p))^(1/p) + public override double Norm(double p) + { + if (p < 0d) throw new ArgumentOutOfRangeException("p"); + + if (p == 1d) return L1Norm(); + if (p == 2d) return L2Norm(); + if (Double.IsPositiveInfinity(p)) return InfinityNorm(); + + var sum = 0d; + for (var index = 0; index < _length; index++) + { + sum += Math.Pow(Math.Abs(_values[index]), p); + } + return Math.Pow(sum, 1.0 / p); + } + /// /// Pointwise divide this vector with another vector and stores the result into the result vector. /// @@ -780,46 +816,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double return OuterProduct(this, v); } - #region Vector Norms - - /// - /// Computes the p-Norm. - /// - /// The p value. - /// Scalar ret = (sum(abs(this[i])^p))^(1/p) - public override double Norm(double p) - { - if (p < 0.0) - { - throw new ArgumentOutOfRangeException("p"); - } - - if (1.0 == p) - { - return SumMagnitudes(); - } - - if (2.0 == p) - { - return _values.Aggregate(0.0, SpecialFunctions.Hypotenuse); - } - - if (Double.IsPositiveInfinity(p)) - { - return CommonParallel.Aggregate(_values, (i, v) => Math.Abs(v), Math.Max, 0d); - } - - var sum = 0.0; - for (var index = 0; index < _length; index++) - { - sum += Math.Pow(Math.Abs(_values[index]), p); - } - - return Math.Pow(sum, 1.0 / p); - } - - #endregion - #region Parse Functions /// diff --git a/src/Numerics/LinearAlgebra/Double/Factorization/UserGramSchmidt.cs b/src/Numerics/LinearAlgebra/Double/Factorization/UserGramSchmidt.cs index c3c6fe6a..f37de65e 100644 --- a/src/Numerics/LinearAlgebra/Double/Factorization/UserGramSchmidt.cs +++ b/src/Numerics/LinearAlgebra/Double/Factorization/UserGramSchmidt.cs @@ -68,7 +68,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization for (var k = 0; k < MatrixQ.ColumnCount; k++) { - var norm = MatrixQ.Column(k).Norm(2); + var norm = MatrixQ.Column(k).L2Norm(); if (norm == 0.0) { throw new ArgumentException(Resources.ArgumentMatrixNotRankDeficient); diff --git a/src/Numerics/LinearAlgebra/Double/Solvers/Iterative/MlkBiCgStab.cs b/src/Numerics/LinearAlgebra/Double/Solvers/Iterative/MlkBiCgStab.cs index 9f776611..0f693a1e 100644 --- a/src/Numerics/LinearAlgebra/Double/Solvers/Iterative/MlkBiCgStab.cs +++ b/src/Numerics/LinearAlgebra/Double/Solvers/Iterative/MlkBiCgStab.cs @@ -673,7 +673,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative result.Add((Vector)orthogonalMatrix.Column(i)); // Normalize the result vector - result[i].Multiply(1 / result[i].Norm(2), result[i]); + result[i].Multiply(1 / result[i].L2Norm(), result[i]); } return result; diff --git a/src/Numerics/LinearAlgebra/Double/Solvers/Iterative/TFQMR.cs b/src/Numerics/LinearAlgebra/Double/Solvers/Iterative/TFQMR.cs index a89a586b..b7b385cf 100644 --- a/src/Numerics/LinearAlgebra/Double/Solvers/Iterative/TFQMR.cs +++ b/src/Numerics/LinearAlgebra/Double/Solvers/Iterative/TFQMR.cs @@ -282,7 +282,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative var temp2 = new DenseVector(input.Count); // Initialize - var startNorm = input.Norm(2); + var startNorm = input.L2Norm(); // Define the scalars double alpha = 0; @@ -348,7 +348,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative yinternal.Add(temp, d); // theta = ||pseudoResiduals||_2 / tau - theta = pseudoResiduals.Norm(2) / tau; + theta = pseudoResiduals.L2Norm() / tau; var c = 1 / Math.Sqrt(1 + (theta * theta)); // tau = tau * theta * c diff --git a/src/Numerics/LinearAlgebra/Double/Solvers/Preconditioners/Ilutp.cs b/src/Numerics/LinearAlgebra/Double/Solvers/Preconditioners/Ilutp.cs index ec5e567c..9be4b79a 100644 --- a/src/Numerics/LinearAlgebra/Double/Solvers/Preconditioners/Ilutp.cs +++ b/src/Numerics/LinearAlgebra/Double/Solvers/Preconditioners/Ilutp.cs @@ -388,7 +388,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners // pivot the row PivotRow(workVector); - var vectorNorm = workVector.Norm(Double.PositiveInfinity); + var vectorNorm = workVector.InfinityNorm(); // for j = 1, .. , i - 1) for (var j = 0; j < i; j++) diff --git a/src/Numerics/LinearAlgebra/Double/Solvers/StopCriterium/DivergenceStopCriterium.cs b/src/Numerics/LinearAlgebra/Double/Solvers/StopCriterium/DivergenceStopCriterium.cs index a6b9db1f..ed5371ef 100644 --- a/src/Numerics/LinearAlgebra/Double/Solvers/StopCriterium/DivergenceStopCriterium.cs +++ b/src/Numerics/LinearAlgebra/Double/Solvers/StopCriterium/DivergenceStopCriterium.cs @@ -250,7 +250,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium // Store the infinity norms of both the solution and residual vectors // These values will be used to calculate the relative drop in residuals later on. - _residualHistory[_residualHistory.Length - 1] = residualVector.Norm(Double.PositiveInfinity); + _residualHistory[_residualHistory.Length - 1] = residualVector.InfinityNorm(); // Check if we have NaN's. If so we've gone way beyond normal divergence. // Stop the iteration. diff --git a/src/Numerics/LinearAlgebra/Double/Solvers/StopCriterium/FailureStopCriterium.cs b/src/Numerics/LinearAlgebra/Double/Solvers/StopCriterium/FailureStopCriterium.cs index 5e447746..1754d06d 100644 --- a/src/Numerics/LinearAlgebra/Double/Solvers/StopCriterium/FailureStopCriterium.cs +++ b/src/Numerics/LinearAlgebra/Double/Solvers/StopCriterium/FailureStopCriterium.cs @@ -105,8 +105,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium } // Store the infinity norms of both the solution and residual vectors - var residualNorm = residualVector.Norm(Double.PositiveInfinity); - var solutionNorm = solutionVector.Norm(Double.PositiveInfinity); + var residualNorm = residualVector.InfinityNorm(); + var solutionNorm = solutionVector.InfinityNorm(); if (Double.IsNaN(solutionNorm) || Double.IsNaN(residualNorm)) { diff --git a/src/Numerics/LinearAlgebra/Double/Solvers/StopCriterium/ResidualStopCriterium.cs b/src/Numerics/LinearAlgebra/Double/Solvers/StopCriterium/ResidualStopCriterium.cs index 5c6b187d..bfe229a9 100644 --- a/src/Numerics/LinearAlgebra/Double/Solvers/StopCriterium/ResidualStopCriterium.cs +++ b/src/Numerics/LinearAlgebra/Double/Solvers/StopCriterium/ResidualStopCriterium.cs @@ -257,11 +257,11 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium // Store the infinity norms of both the solution and residual vectors // These values will be used to calculate the relative drop in residuals // later on. - var residualNorm = residualVector.Norm(Double.PositiveInfinity); + var residualNorm = residualVector.InfinityNorm(); // Check the residuals by calculating: // ||r_i|| <= stop_tol * ||b|| - var stopCriterium = ComputeStopCriterium(sourceVector.Norm(Double.PositiveInfinity)); + var stopCriterium = ComputeStopCriterium(sourceVector.InfinityNorm()); // First check that we have real numbers not NaN's. // NaN's can occur when the iterative process diverges so we diff --git a/src/Numerics/LinearAlgebra/Double/SparseVector.cs b/src/Numerics/LinearAlgebra/Double/SparseVector.cs index ea8a6e3c..3413cad7 100644 --- a/src/Numerics/LinearAlgebra/Double/SparseVector.cs +++ b/src/Numerics/LinearAlgebra/Double/SparseVector.cs @@ -769,25 +769,58 @@ namespace MathNet.Numerics.LinearAlgebra.Double { result += _storage.Values[i]; } - return result; } /// - /// Computes the sum of the absolute value of the vector's elements. + /// Calculates the L1 norm of the vector, also known as Manhattan norm. /// - /// The sum of the absolute value of the vector's elements. - public override double SumMagnitudes() + /// The sum of the absolute values. + public override double L1Norm() { - double result = 0; + var result = 0d; for (var i = 0; i < _storage.ValueCount; i++) { result += Math.Abs(_storage.Values[i]); } - return result; } + /// + /// Calculates the infinity norm of the vector. + /// + /// The square root of the sum of the squared values. + public override double InfinityNorm() + { + return CommonParallel.Aggregate(0, _storage.ValueCount, i => Math.Abs(_storage.Values[i]), Math.Max, 0d); + } + + /// + /// Computes the p-Norm. + /// + /// The p value. + /// Scalar ret = (sum(abs(this[i])^p))^(1/p) + public override double Norm(double p) + { + if (p < 0d) throw new ArgumentOutOfRangeException("p"); + + if (_storage.ValueCount == 0) + { + return 0d; + } + + if (p == 1d) return L1Norm(); + if (p == 2d) return L2Norm(); + if (Double.IsPositiveInfinity(p)) return InfinityNorm(); + + var sum = 0d; + for (var index = 0; index < _storage.ValueCount; index++) + { + sum += Math.Pow(Math.Abs(_storage.Values[index]), p); + } + return Math.Pow(sum, 1.0 / p); + } + /// /// Pointwise multiplies this vector with another vector and stores the result into the result vector. /// @@ -880,42 +913,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double return OuterProduct(this, v); } - /// - /// Computes the p-Norm. - /// - /// The p value. - /// Scalar ret = (sum(abs(this[i])^p))^(1/p) - public override double Norm(double p) - { - if (1 > p) - { - throw new ArgumentOutOfRangeException("p"); - } - - if (_storage.ValueCount == 0) - { - return 0.0; - } - - if (2.0 == p) - { - return _storage.Values.Aggregate(0.0, SpecialFunctions.Hypotenuse); - } - - if (Double.IsPositiveInfinity(p)) - { - return CommonParallel.Aggregate(0, _storage.ValueCount, i => Math.Abs(_storage.Values[i]), Math.Max, 0d); - } - - var sum = 0.0; - for (var index = 0; index < _storage.ValueCount; index++) - { - sum += Math.Pow(Math.Abs(_storage.Values[index]), p); - } - - return Math.Pow(sum, 1.0 / p); - } - #region Parse Functions /// diff --git a/src/Numerics/LinearAlgebra/Double/Vector.cs b/src/Numerics/LinearAlgebra/Double/Vector.cs index 2b78436a..f7a63bea 100644 --- a/src/Numerics/LinearAlgebra/Double/Vector.cs +++ b/src/Numerics/LinearAlgebra/Double/Vector.cs @@ -212,6 +212,16 @@ namespace MathNet.Numerics.LinearAlgebra.Double return dot; } + /// + /// Computes the dot product between the conjugate of this vector and another vector. + /// + /// The other vector. + /// The sum of conj(a[i])*b[i] for all i. + protected override sealed double DoConjugateDotProduct(Vector other) + { + return DoDotProduct(other); + } + /// /// Computes the modulus for each element of the vector for the given divisor. /// @@ -305,31 +315,45 @@ namespace MathNet.Numerics.LinearAlgebra.Double public override double Sum() { var sum = 0.0; - for (var i = 0; i < Count; i++) { sum += At(i); } - return sum; } /// - /// Computes the sum of the absolute value of the vector's elements. + /// Calculates the L1 norm of the vector, also known as Manhattan norm. /// - /// The sum of the absolute value of the vector's elements. - public override double SumMagnitudes() + /// The sum of the absolute values. + public override double L1Norm() { var sum = 0.0; - for (var i = 0; i < Count; i++) { sum += Math.Abs(At(i)); } - return sum; } + /// + /// Calculates the L2 norm of the vector, also known as Euclidean norm. + /// + /// The square root of the sum of the squared values. + public override double L2Norm() + { + return Math.Sqrt(DoDotProduct(this)); + } + + /// + /// Calculates the infinity norm of the vector. + /// + /// The square root of the sum of the squared values. + public override double InfinityNorm() + { + return CommonParallel.Aggregate(0, Count, i => Math.Abs(At(i)), Math.Max, 0d); + } + /// /// Computes the p-Norm. /// @@ -341,24 +365,18 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// public override double Norm(double p) { - if (p < 0.0) - { - throw new ArgumentOutOfRangeException("p"); - } + if (p < 0d) throw new ArgumentOutOfRangeException("p"); - if (Double.IsPositiveInfinity(p)) - { - return CommonParallel.Aggregate(0, Count, i => Math.Abs(At(i)), Math.Max, 0d); - } - - var sum = 0.0; + if (p == 1d) return L1Norm(); + if (p == 2d) return L2Norm(); + if (Double.IsPositiveInfinity(p)) return InfinityNorm(); + var sum = 0d; for (var index = 0; index < Count; index++) { sum += Math.Pow(Math.Abs(At(index)), p); } - - return Math.Pow(sum, 1.0 / p); + return Math.Pow(sum, 1.0/p); } /// diff --git a/src/Numerics/LinearAlgebra/Generic/Vector.Arithmetic.cs b/src/Numerics/LinearAlgebra/Generic/Vector.Arithmetic.cs index 6054a8c0..ae74970c 100644 --- a/src/Numerics/LinearAlgebra/Generic/Vector.Arithmetic.cs +++ b/src/Numerics/LinearAlgebra/Generic/Vector.Arithmetic.cs @@ -105,10 +105,7 @@ namespace MathNet.Numerics.LinearAlgebra.Generic /// /// The other vector. /// The sum of conj(a[i])*b[i] for all i. - protected virtual T DoConjugateDotProduct(Vector other) - { - return DoDotProduct(other); - } + protected abstract T DoConjugateDotProduct(Vector other); /// /// Divides each element of the vector by a scalar and stores the result in the result vector. @@ -899,6 +896,24 @@ namespace MathNet.Numerics.LinearAlgebra.Generic return OuterProduct(this, v); } + /// + /// Calculates the L1 norm of the vector, also known as Manhattan norm. + /// + /// The sum of the absolute values. + public abstract T L1Norm(); + + /// + /// Calculates the L2 norm of the vector, also known as Euclidean norm. + /// + /// The square root of the sum of the squared values. + public abstract T L2Norm(); + + /// + /// Calculates the infinity norm of the vector. + /// + /// The square root of the sum of the squared values. + public abstract T InfinityNorm(); + /// /// Computes the p-Norm. /// @@ -977,6 +992,9 @@ namespace MathNet.Numerics.LinearAlgebra.Generic /// Computes the sum of the absolute value of the vector's elements. /// /// The sum of the absolute value of the vector's elements. - public abstract T SumMagnitudes(); + public T SumMagnitudes() + { + return L1Norm(); + } } } diff --git a/src/Numerics/LinearAlgebra/Single/DenseVector.cs b/src/Numerics/LinearAlgebra/Single/DenseVector.cs index fc9a2969..9c5c697b 100644 --- a/src/Numerics/LinearAlgebra/Single/DenseVector.cs +++ b/src/Numerics/LinearAlgebra/Single/DenseVector.cs @@ -655,32 +655,68 @@ namespace MathNet.Numerics.LinearAlgebra.Single /// The sum of the vector's elements. public override float Sum() { - var sum = 0.0f; - + var sum = 0f; for (var i = 0; i < _length; i++) { sum += _values[i]; } - return sum; } /// - /// Computes the sum of the absolute value of the vector's elements. + /// Calculates the L1 norm of the vector, also known as Manhattan norm. /// - /// The sum of the absolute value of the vector's elements. - public override float SumMagnitudes() + /// The sum of the absolute values. + public override float L1Norm() { - var sum = 0.0f; - + var sum = 0f; for (var i = 0; i < _length; i++) { sum += Math.Abs(_values[i]); } - return sum; } + /// + /// Calculates the L2 norm of the vector, also known as Euclidean norm. + /// + /// The square root of the sum of the squared values. + public override float L2Norm() + { + // TODO: native provider + return _values.Aggregate(0f, SpecialFunctions.Hypotenuse); + } + + /// + /// Calculates the infinity norm of the vector. + /// + /// The square root of the sum of the squared values. + public override float InfinityNorm() + { + return CommonParallel.Aggregate(_values, (i, v) => Math.Abs(v), Math.Max, 0f); + } + + /// + /// Computes the p-Norm. + /// + /// The p value. + /// Scalar ret = (sum(abs(this[i])^p))^(1/p) + public override float Norm(double p) + { + if (p < 0d) throw new ArgumentOutOfRangeException("p"); + + if (p == 1d) return L1Norm(); + if (p == 2d) return L2Norm(); + if (Double.IsPositiveInfinity(p)) return InfinityNorm(); + + var sum = 0d; + for (var index = 0; index < _length; index++) + { + sum += Math.Pow(Math.Abs(_values[index]), p); + } + return (float)Math.Pow(sum, 1.0 / p); + } + /// /// Pointwise divide this vector with another vector and stores the result into the result vector. /// @@ -769,47 +805,6 @@ namespace MathNet.Numerics.LinearAlgebra.Single return OuterProduct(this, v); } - #region Vector Norms - - /// - /// Computes the p-Norm. - /// - /// The p value. - /// Scalar ret = (sum(abs(this[i])^p))^(1/p) - public override float Norm(double p) - { - if (p < 0.0) - { - throw new ArgumentOutOfRangeException("p"); - } - - if (1.0 == p) - { - return SumMagnitudes(); - } - - if (2.0 == p) - { - return _values.Aggregate(0f, SpecialFunctions.Hypotenuse); - } - - if (Double.IsPositiveInfinity(p)) - { - return CommonParallel.Aggregate(_values, (i, v) => Math.Abs(v), Math.Max, 0f); - } - - var sum = 0.0; - - for (var index = 0; index < _length; index++) - { - sum += Math.Pow(Math.Abs(_values[index]), p); - } - - return (float)Math.Pow(sum, 1.0 / p); - } - - #endregion - #region Parse Functions /// diff --git a/src/Numerics/LinearAlgebra/Single/Factorization/UserGramSchmidt.cs b/src/Numerics/LinearAlgebra/Single/Factorization/UserGramSchmidt.cs index 0dbd9ca3..b24b1c07 100644 --- a/src/Numerics/LinearAlgebra/Single/Factorization/UserGramSchmidt.cs +++ b/src/Numerics/LinearAlgebra/Single/Factorization/UserGramSchmidt.cs @@ -68,7 +68,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization for (var k = 0; k < MatrixQ.ColumnCount; k++) { - var norm = MatrixQ.Column(k).Norm(2); + var norm = MatrixQ.Column(k).L2Norm(); if (norm == 0.0) { throw new ArgumentException(Resources.ArgumentMatrixNotRankDeficient); diff --git a/src/Numerics/LinearAlgebra/Single/Solvers/Iterative/MlkBiCgStab.cs b/src/Numerics/LinearAlgebra/Single/Solvers/Iterative/MlkBiCgStab.cs index 056b1195..dcf296e4 100644 --- a/src/Numerics/LinearAlgebra/Single/Solvers/Iterative/MlkBiCgStab.cs +++ b/src/Numerics/LinearAlgebra/Single/Solvers/Iterative/MlkBiCgStab.cs @@ -676,7 +676,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative result.Add((Vector)orthogonalMatrix.Column(i)); // Normalize the result vector - result[i].Multiply(1 / result[i].Norm(2), result[i]); + result[i].Multiply(1 / result[i].L2Norm(), result[i]); } return result; diff --git a/src/Numerics/LinearAlgebra/Single/Solvers/Iterative/TFQMR.cs b/src/Numerics/LinearAlgebra/Single/Solvers/Iterative/TFQMR.cs index 59c19827..d1828819 100644 --- a/src/Numerics/LinearAlgebra/Single/Solvers/Iterative/TFQMR.cs +++ b/src/Numerics/LinearAlgebra/Single/Solvers/Iterative/TFQMR.cs @@ -282,7 +282,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative var temp2 = new DenseVector(input.Count); // Initialize - var startNorm = input.Norm(2); + var startNorm = input.L2Norm(); // Define the scalars float alpha = 0; @@ -348,7 +348,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative yinternal.Add(temp, d); // theta = ||pseudoResiduals||_2 / tau - theta = pseudoResiduals.Norm(2)/tau; + theta = pseudoResiduals.L2Norm()/tau; var c = 1/(float) Math.Sqrt(1 + (theta*theta)); // tau = tau * theta * c diff --git a/src/Numerics/LinearAlgebra/Single/Solvers/Preconditioners/Ilutp.cs b/src/Numerics/LinearAlgebra/Single/Solvers/Preconditioners/Ilutp.cs index 8198d799..040ebe67 100644 --- a/src/Numerics/LinearAlgebra/Single/Solvers/Preconditioners/Ilutp.cs +++ b/src/Numerics/LinearAlgebra/Single/Solvers/Preconditioners/Ilutp.cs @@ -388,7 +388,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Preconditioners // pivot the row PivotRow(workVector); - var vectorNorm = workVector.Norm(Double.PositiveInfinity); + var vectorNorm = workVector.InfinityNorm(); // for j = 1, .. , i - 1) for (var j = 0; j < i; j++) diff --git a/src/Numerics/LinearAlgebra/Single/Solvers/StopCriterium/DivergenceStopCriterium.cs b/src/Numerics/LinearAlgebra/Single/Solvers/StopCriterium/DivergenceStopCriterium.cs index 8da980ed..e96e531c 100644 --- a/src/Numerics/LinearAlgebra/Single/Solvers/StopCriterium/DivergenceStopCriterium.cs +++ b/src/Numerics/LinearAlgebra/Single/Solvers/StopCriterium/DivergenceStopCriterium.cs @@ -250,7 +250,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.StopCriterium // Store the infinity norms of both the solution and residual vectors // These values will be used to calculate the relative drop in residuals later on. - _residualHistory[_residualHistory.Length - 1] = residualVector.Norm(Double.PositiveInfinity); + _residualHistory[_residualHistory.Length - 1] = residualVector.InfinityNorm(); // Check if we have NaN's. If so we've gone way beyond normal divergence. // Stop the iteration. diff --git a/src/Numerics/LinearAlgebra/Single/Solvers/StopCriterium/FailureStopCriterium.cs b/src/Numerics/LinearAlgebra/Single/Solvers/StopCriterium/FailureStopCriterium.cs index 92a4cc98..1497d819 100644 --- a/src/Numerics/LinearAlgebra/Single/Solvers/StopCriterium/FailureStopCriterium.cs +++ b/src/Numerics/LinearAlgebra/Single/Solvers/StopCriterium/FailureStopCriterium.cs @@ -105,8 +105,8 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.StopCriterium } // Store the infinity norms of both the solution and residual vectors - var residualNorm = residualVector.Norm(Double.PositiveInfinity); - var solutionNorm = solutionVector.Norm(Double.PositiveInfinity); + var residualNorm = residualVector.InfinityNorm(); + var solutionNorm = solutionVector.InfinityNorm(); if (Double.IsNaN(solutionNorm) || Double.IsNaN(residualNorm)) { diff --git a/src/Numerics/LinearAlgebra/Single/Solvers/StopCriterium/ResidualStopCriterium.cs b/src/Numerics/LinearAlgebra/Single/Solvers/StopCriterium/ResidualStopCriterium.cs index 8cead811..a5a4296b 100644 --- a/src/Numerics/LinearAlgebra/Single/Solvers/StopCriterium/ResidualStopCriterium.cs +++ b/src/Numerics/LinearAlgebra/Single/Solvers/StopCriterium/ResidualStopCriterium.cs @@ -257,11 +257,11 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.StopCriterium // Store the infinity norms of both the solution and residual vectors // These values will be used to calculate the relative drop in residuals // later on. - var residualNorm = residualVector.Norm(float.PositiveInfinity); + var residualNorm = residualVector.InfinityNorm(); // Check the residuals by calculating: // ||r_i|| <= stop_tol * ||b|| - var stopCriterium = ComputeStopCriterium(sourceVector.Norm(float.PositiveInfinity)); + var stopCriterium = ComputeStopCriterium(sourceVector.InfinityNorm()); // First check that we have real numbers not NaN's. // NaN's can occur when the iterative process diverges so we diff --git a/src/Numerics/LinearAlgebra/Single/SparseVector.cs b/src/Numerics/LinearAlgebra/Single/SparseVector.cs index 9c1db4b9..e088b923 100644 --- a/src/Numerics/LinearAlgebra/Single/SparseVector.cs +++ b/src/Numerics/LinearAlgebra/Single/SparseVector.cs @@ -770,25 +770,58 @@ namespace MathNet.Numerics.LinearAlgebra.Single { result += _storage.Values[i]; } - return result; } /// - /// Computes the sum of the absolute value of the vector's elements. + /// Calculates the L1 norm of the vector, also known as Manhattan norm. /// - /// The sum of the absolute value of the vector's elements. - public override float SumMagnitudes() + /// The sum of the absolute values. + public override float L1Norm() { - var result = 0.0f; + var result = 0f; for (var i = 0; i < _storage.ValueCount; i++) { result += Math.Abs(_storage.Values[i]); } - return result; } + /// + /// Calculates the infinity norm of the vector. + /// + /// The square root of the sum of the squared values. + public override float InfinityNorm() + { + return CommonParallel.Aggregate(0, _storage.ValueCount, i => Math.Abs(_storage.Values[i]), Math.Max, 0f); + } + + /// + /// Computes the p-Norm. + /// + /// The p value. + /// Scalar ret = (sum(abs(this[i])^p))^(1/p) + public override float Norm(double p) + { + if (p < 0d) throw new ArgumentOutOfRangeException("p"); + + if (_storage.ValueCount == 0) + { + return 0f; + } + + if (p == 1d) return L1Norm(); + if (p == 2d) return L2Norm(); + if (Double.IsPositiveInfinity(p)) return InfinityNorm(); + + var sum = 0d; + for (var index = 0; index < _storage.ValueCount; index++) + { + sum += Math.Pow(Math.Abs(_storage.Values[index]), p); + } + return (float)Math.Pow(sum, 1.0 / p); + } + /// /// Pointwise multiplies this vector with another vector and stores the result into the result vector. /// @@ -884,42 +917,6 @@ namespace MathNet.Numerics.LinearAlgebra.Single return OuterProduct(this, v); } - /// - /// Computes the p-Norm. - /// - /// The p value. - /// Scalar ret = (sum(abs(this[i])^p))^(1/p) - public override float Norm(double p) - { - if (1 > p) - { - throw new ArgumentOutOfRangeException("p"); - } - - if (_storage.ValueCount == 0) - { - return 0.0f; - } - - if (2.0 == p) - { - return _storage.Values.Aggregate(0f, SpecialFunctions.Hypotenuse); - } - - if (Double.IsPositiveInfinity(p)) - { - return CommonParallel.Aggregate(0, _storage.ValueCount, i => Math.Abs(_storage.Values[i]), Math.Max, 0f); - } - - var sum = 0.0; - for (var index = 0; index < _storage.ValueCount; index++) - { - sum += Math.Pow(Math.Abs(_storage.Values[index]), p); - } - - return (float)Math.Pow(sum, 1.0 / p); - } - #region Parse Functions /// diff --git a/src/Numerics/LinearAlgebra/Single/Vector.cs b/src/Numerics/LinearAlgebra/Single/Vector.cs index 58012194..7164f1fc 100644 --- a/src/Numerics/LinearAlgebra/Single/Vector.cs +++ b/src/Numerics/LinearAlgebra/Single/Vector.cs @@ -212,6 +212,16 @@ namespace MathNet.Numerics.LinearAlgebra.Single return dot; } + /// + /// Computes the dot product between the conjugate of this vector and another vector. + /// + /// The other vector. + /// The sum of conj(a[i])*b[i] for all i. + protected override sealed float DoConjugateDotProduct(Vector other) + { + return DoDotProduct(other); + } + /// /// Computes the modulus for each element of the vector for the given divisor. /// @@ -305,31 +315,45 @@ namespace MathNet.Numerics.LinearAlgebra.Single public override float Sum() { var sum = 0.0f; - for (var i = 0; i < Count; i++) { sum += At(i); } - return sum; } /// - /// Computes the sum of the absolute value of the vector's elements. + /// Calculates the L1 norm of the vector, also known as Manhattan norm. /// - /// The sum of the absolute value of the vector's elements. - public override float SumMagnitudes() + /// The sum of the absolute values. + public override float L1Norm() { var sum = 0.0f; - for (var i = 0; i < Count; i++) { sum += Math.Abs(At(i)); } - return sum; } + /// + /// Calculates the L2 norm of the vector, also known as Euclidean norm. + /// + /// The square root of the sum of the squared values. + public override float L2Norm() + { + return (float)Math.Sqrt(DoDotProduct(this)); + } + + /// + /// Calculates the infinity norm of the vector. + /// + /// The square root of the sum of the squared values. + public override float InfinityNorm() + { + return CommonParallel.Aggregate(0, Count, i => Math.Abs(At(i)), Math.Max, 0f); + } + /// /// Computes the p-Norm. /// @@ -341,24 +365,18 @@ namespace MathNet.Numerics.LinearAlgebra.Single /// public override float Norm(double p) { - if (p < 0.0) - { - throw new ArgumentOutOfRangeException("p"); - } + if (p < 0d) throw new ArgumentOutOfRangeException("p"); - if (float.IsPositiveInfinity((float)p)) - { - return CommonParallel.Aggregate(0, Count, i => Math.Abs(At(i)), Math.Max, 0f); - } - - var sum = 0.0; + if (p == 1d) return L1Norm(); + if (p == 2d) return L2Norm(); + if (Double.IsPositiveInfinity(p)) return InfinityNorm(); + var sum = 0d; for (var index = 0; index < Count; index++) { sum += Math.Pow(Math.Abs(At(index)), p); } - - return (float)Math.Pow(sum, 1.0 / p); + return (float) Math.Pow(sum, 1.0/p); } /// diff --git a/src/Numerics/RootFinding/Broyden.cs b/src/Numerics/RootFinding/Broyden.cs index ee62255a..cdd840d3 100644 --- a/src/Numerics/RootFinding/Broyden.cs +++ b/src/Numerics/RootFinding/Broyden.cs @@ -71,7 +71,7 @@ namespace MathNet.Numerics.RootFinding double[] y0 = f(initialGuess); var y = new DenseVector(y0); - double g = y.Norm(2); + double g = y.L2Norm(); Matrix B = CalculateApproximateJacobian(f, initialGuess, y0); @@ -80,7 +80,7 @@ namespace MathNet.Numerics.RootFinding var dx = (DenseVector) (-B.LU().Solve(y)); var xnew = x + dx; var ynew = new DenseVector(f(xnew.Values)); - double gnew = ynew.Norm(2); + double gnew = ynew.L2Norm(); if (gnew > g) { @@ -90,7 +90,7 @@ namespace MathNet.Numerics.RootFinding dx = scale*dx; xnew = x + dx; ynew = new DenseVector(f(xnew.Values)); - gnew = ynew.Norm(2); + gnew = ynew.L2Norm(); } if (gnew < accuracy) @@ -101,7 +101,7 @@ namespace MathNet.Numerics.RootFinding // update Jacobian B DenseVector dF = ynew - y; - Matrix dB = (dF - B.Multiply(dx)).ToColumnMatrix()*dx.Multiply(1.0/Math.Pow(dx.Norm(2), 2)).ToRowMatrix(); + Matrix dB = (dF - B.Multiply(dx)).ToColumnMatrix() * dx.Multiply(1.0 / Math.Pow(dx.L2Norm(), 2)).ToRowMatrix(); B = B + dB; x = xnew; diff --git a/src/UnitTests/LinearAlgebraTests/Complex/VectorTests.Norm.cs b/src/UnitTests/LinearAlgebraTests/Complex/VectorTests.Norm.cs index eb94ed97..78b97eda 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex/VectorTests.Norm.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex/VectorTests.Norm.cs @@ -42,6 +42,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex public void CanComputeNorm() { var vector = CreateVector(Data); + AssertHelpers.AlmostEqual(7.74596669241483, vector.L2Norm(), 15); AssertHelpers.AlmostEqual(7.74596669241483, vector.Norm(2), 15); } @@ -52,6 +53,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex public void CanComputeNorm1() { var vector = CreateVector(Data); + AssertHelpers.AlmostEqual(16.0346843392517, vector.L1Norm(), 15); AssertHelpers.AlmostEqual(16.0346843392517, vector.Norm(1), 15); } @@ -62,6 +64,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex public void CanComputeSquareNorm() { var vector = CreateVector(Data); + AssertHelpers.AlmostEqual(60.0, vector.L2Norm() * vector.L2Norm(), 15); AssertHelpers.AlmostEqual(60.0, vector.Norm(2) * vector.Norm(2), 15); } @@ -87,6 +90,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex public void CanComputeNormInfinity() { var vector = CreateVector(Data); + AssertHelpers.AlmostEqual(5.09901951359279, vector.InfinityNorm(), 14); AssertHelpers.AlmostEqual(5.09901951359279, vector.Norm(Double.PositiveInfinity), 14); } diff --git a/src/UnitTests/LinearAlgebraTests/Complex32/VectorTests.Norm.cs b/src/UnitTests/LinearAlgebraTests/Complex32/VectorTests.Norm.cs index a20c2654..1a84355c 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex32/VectorTests.Norm.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex32/VectorTests.Norm.cs @@ -42,7 +42,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32 public void CanComputeNorm() { var vector = CreateVector(Data); - AssertHelpers.AlmostEqual(7.7459666f, vector.Norm(2).Real, 7); + AssertHelpers.AlmostEqual(7.745966692414833770f, vector.L2Norm(), 6); + AssertHelpers.AlmostEqual(7.745966692414833770f, vector.Norm(2), 6); } /// @@ -52,7 +53,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32 public void CanComputeNorm1() { var vector = CreateVector(Data); - AssertHelpers.AlmostEqual(16.0346843f, vector.Norm(1).Real, 7); + AssertHelpers.AlmostEqual(16.0346843392517094570f, vector.L1Norm(), 7); + AssertHelpers.AlmostEqual(16.0346843392517094570f, vector.Norm(1), 7); } /// @@ -62,7 +64,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32 public void CanComputeSquareNorm() { var vector = CreateVector(Data); - AssertHelpers.AlmostEqual(60f, vector.Norm(2).Real * vector.Norm(2).Real, 6); + AssertHelpers.AlmostEqual(60f, vector.L2Norm() * vector.L2Norm(), 6); + AssertHelpers.AlmostEqual(60f, vector.Norm(2) * vector.Norm(2), 6); } /// @@ -87,6 +90,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32 public void CanComputeNormInfinity() { var vector = CreateVector(Data); + AssertHelpers.AlmostEqual(5.0990195, vector.InfinityNorm().Real, 7); AssertHelpers.AlmostEqual(5.0990195, vector.Norm(Single.PositiveInfinity).Real, 7); } diff --git a/src/UnitTests/LinearAlgebraTests/Double/VectorTests.Norm.cs b/src/UnitTests/LinearAlgebraTests/Double/VectorTests.Norm.cs index 596182dd..b6276e2a 100644 --- a/src/UnitTests/LinearAlgebraTests/Double/VectorTests.Norm.cs +++ b/src/UnitTests/LinearAlgebraTests/Double/VectorTests.Norm.cs @@ -41,6 +41,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double public void CanComputeNorm() { var vector = CreateVector(Data); + AssertHelpers.AlmostEqual(7.416198487095663, vector.L2Norm(), 15); AssertHelpers.AlmostEqual(7.416198487095663, vector.Norm(2), 15); } @@ -51,6 +52,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double public void CanComputeNorm1() { var vector = CreateVector(Data); + AssertHelpers.AlmostEqual(15.0, vector.L1Norm(), 15); AssertHelpers.AlmostEqual(15.0, vector.Norm(1), 15); } @@ -61,6 +63,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double public void CanComputeSquareNorm() { var vector = CreateVector(Data); + AssertHelpers.AlmostEqual(55.0, vector.L2Norm() * vector.L2Norm(), 15); AssertHelpers.AlmostEqual(55.0, vector.Norm(2) * vector.Norm(2), 15); } @@ -86,6 +89,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double public void CanComputeNormInfinity() { var vector = CreateVector(Data); + AssertHelpers.AlmostEqual(5.0, vector.InfinityNorm(), 15); AssertHelpers.AlmostEqual(5.0, vector.Norm(Double.PositiveInfinity), 15); } diff --git a/src/UnitTests/LinearAlgebraTests/Single/VectorTests.Norm.cs b/src/UnitTests/LinearAlgebraTests/Single/VectorTests.Norm.cs index c8d218c2..97ec4d7e 100644 --- a/src/UnitTests/LinearAlgebraTests/Single/VectorTests.Norm.cs +++ b/src/UnitTests/LinearAlgebraTests/Single/VectorTests.Norm.cs @@ -41,6 +41,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single public void CanComputeNorm() { var vector = CreateVector(Data); + AssertHelpers.AlmostEqual(7.416198487095663f, vector.L2Norm(), 6); AssertHelpers.AlmostEqual(7.416198487095663f, vector.Norm(2), 6); } @@ -51,6 +52,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single public void CanComputeNorm1() { var vector = CreateVector(Data); + AssertHelpers.AlmostEqual(15.0f, vector.L1Norm(), 7); AssertHelpers.AlmostEqual(15.0f, vector.Norm(1), 7); } @@ -61,6 +63,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single public void CanComputeSquareNorm() { var vector = CreateVector(Data); + AssertHelpers.AlmostEqual(55.0f, vector.L2Norm() * vector.L2Norm(), 6); AssertHelpers.AlmostEqual(55.0f, vector.Norm(2) * vector.Norm(2), 6); } @@ -86,6 +89,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single public void CanComputeNormInfinity() { var vector = CreateVector(Data); + AssertHelpers.AlmostEqual(5.0f, vector.InfinityNorm(), 7); AssertHelpers.AlmostEqual(5.0f, vector.Norm(Single.PositiveInfinity), 7); }