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 69d76661..065d1de3 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 0708eb65..0d3d827d 100644 --- a/src/Numerics/LinearAlgebra/Complex/DenseVector.cs +++ b/src/Numerics/LinearAlgebra/Complex/DenseVector.cs @@ -565,31 +565,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. /// @@ -678,43 +714,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 a392853c..d4291bf0 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 b2989111..bec572d4 100644 --- a/src/Numerics/LinearAlgebra/Complex/Solvers/Iterative/MlkBiCgStab.cs +++ b/src/Numerics/LinearAlgebra/Complex/Solvers/Iterative/MlkBiCgStab.cs @@ -681,7 +681,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 cf5de4fe..1b2f9953 100644 --- a/src/Numerics/LinearAlgebra/Complex/Solvers/Iterative/TFQMR.cs +++ b/src/Numerics/LinearAlgebra/Complex/Solvers/Iterative/TFQMR.cs @@ -284,7 +284,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; @@ -350,7 +350,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 5771201b..312060ee 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 b9c23ffc..ebe6b045 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 f64b30b3..261bb3ea 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 8c85c31e..6e561899 100644 --- a/src/Numerics/LinearAlgebra/Complex/SparseVector.cs +++ b/src/Numerics/LinearAlgebra/Complex/SparseVector.cs @@ -729,25 +729,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. /// @@ -843,42 +876,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 21cf2018..f29fddc5 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 d23d3ae7..99a3a8e7 100644 --- a/src/Numerics/LinearAlgebra/Complex32/DenseVector.cs +++ b/src/Numerics/LinearAlgebra/Complex32/DenseVector.cs @@ -560,31 +560,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. /// @@ -673,43 +709,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 8829274c..06049a46 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 6d63e28a..45512f67 100644 --- a/src/Numerics/LinearAlgebra/Complex32/Solvers/Iterative/MlkBiCgStab.cs +++ b/src/Numerics/LinearAlgebra/Complex32/Solvers/Iterative/MlkBiCgStab.cs @@ -681,7 +681,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 daa378a9..93b1139a 100644 --- a/src/Numerics/LinearAlgebra/Complex32/Solvers/Iterative/TFQMR.cs +++ b/src/Numerics/LinearAlgebra/Complex32/Solvers/Iterative/TFQMR.cs @@ -284,7 +284,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; @@ -350,7 +350,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 c5e1b12a..5f908fd9 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 f312444a..a76ac310 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(float.PositiveInfinity); - var solutionNorm = solutionVector.Norm(float.PositiveInfinity); + var residualNorm = residualVector.InfinityNorm(); + var solutionNorm = solutionVector.InfinityNorm(); if (float.IsNaN(solutionNorm.Real) || float.IsNaN(residualNorm.Real)) { diff --git a/src/Numerics/LinearAlgebra/Complex32/Solvers/StopCriterium/ResidualStopCriterium.cs b/src/Numerics/LinearAlgebra/Complex32/Solvers/StopCriterium/ResidualStopCriterium.cs index b26aeea6..04a0ae0a 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 8a79e8e3..5e57a58f 100644 --- a/src/Numerics/LinearAlgebra/Complex32/SparseVector.cs +++ b/src/Numerics/LinearAlgebra/Complex32/SparseVector.cs @@ -724,25 +724,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. /// @@ -838,42 +871,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 8b8c6039..fbc56bbb 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 ac57bbce..630c0a53 100644 --- a/src/Numerics/LinearAlgebra/Double/DenseVector.cs +++ b/src/Numerics/LinearAlgebra/Double/DenseVector.cs @@ -632,31 +632,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. /// @@ -745,46 +781,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 1773a852..571aadef 100644 --- a/src/Numerics/LinearAlgebra/Double/Factorization/UserGramSchmidt.cs +++ b/src/Numerics/LinearAlgebra/Double/Factorization/UserGramSchmidt.cs @@ -67,7 +67,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 8cb55b2a..9b3b3871 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 5d27d473..6ca31885 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 273bac12..bfaab1d6 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 93534927..91197f1b 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 d084ed50..578812e7 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 86eb822e..d88eae3c 100644 --- a/src/Numerics/LinearAlgebra/Double/SparseVector.cs +++ b/src/Numerics/LinearAlgebra/Double/SparseVector.cs @@ -734,25 +734,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. /// @@ -845,42 +878,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 e0b3d62f..462863ad 100644 --- a/src/Numerics/LinearAlgebra/Double/Vector.cs +++ b/src/Numerics/LinearAlgebra/Double/Vector.cs @@ -211,6 +211,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. /// @@ -304,31 +314,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. /// @@ -340,24 +364,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/Single/DenseVector.cs b/src/Numerics/LinearAlgebra/Single/DenseVector.cs index 8ad16f12..85f7fadf 100644 --- a/src/Numerics/LinearAlgebra/Single/DenseVector.cs +++ b/src/Numerics/LinearAlgebra/Single/DenseVector.cs @@ -620,32 +620,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. /// @@ -734,47 +770,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 2b33f843..6b2fd1b2 100644 --- a/src/Numerics/LinearAlgebra/Single/Factorization/UserGramSchmidt.cs +++ b/src/Numerics/LinearAlgebra/Single/Factorization/UserGramSchmidt.cs @@ -67,7 +67,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 8cb4e003..e72bf8b0 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 ecb6428d..fdd8c3f0 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 9df1458b..bf5e7fc3 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 19907563..8e339b8d 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 (float.IsNaN(solutionNorm) || float.IsNaN(residualNorm)) { diff --git a/src/Numerics/LinearAlgebra/Single/Solvers/StopCriterium/ResidualStopCriterium.cs b/src/Numerics/LinearAlgebra/Single/Solvers/StopCriterium/ResidualStopCriterium.cs index 5d6ad077..49d0a2cc 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 f8ea1b20..cb9d5dc2 100644 --- a/src/Numerics/LinearAlgebra/Single/SparseVector.cs +++ b/src/Numerics/LinearAlgebra/Single/SparseVector.cs @@ -735,25 +735,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. /// @@ -849,42 +882,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 e33f2fcd..a85660ff 100644 --- a/src/Numerics/LinearAlgebra/Single/Vector.cs +++ b/src/Numerics/LinearAlgebra/Single/Vector.cs @@ -211,6 +211,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. /// @@ -304,31 +314,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. /// @@ -340,24 +364,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/LinearAlgebra/Vector.Arithmetic.cs b/src/Numerics/LinearAlgebra/Vector.Arithmetic.cs index ed42157e..a9b37d04 100644 --- a/src/Numerics/LinearAlgebra/Vector.Arithmetic.cs +++ b/src/Numerics/LinearAlgebra/Vector.Arithmetic.cs @@ -105,10 +105,7 @@ namespace MathNet.Numerics.LinearAlgebra /// /// 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. @@ -735,6 +732,24 @@ namespace MathNet.Numerics.LinearAlgebra 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. /// @@ -813,6 +828,9 @@ namespace MathNet.Numerics.LinearAlgebra /// 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/RootFinding/Broyden.cs b/src/Numerics/RootFinding/Broyden.cs index 1570224c..41131c9b 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); }