From 37bd9b67deb64115302e7ed37eed02dd617aeed0 Mon Sep 17 00:00:00 2001 From: Jurgen Van Gael Date: Tue, 13 Jul 2010 05:59:56 +0800 Subject: [PATCH] Reformatting of Vector.Norm and Vector.Normalize code. --- .../LinearAlgebra/Double/DenseVector.cs | 85 +++++++----------- .../LinearAlgebra/Double/Matrix.Arithmetic.cs | 4 +- .../LinearAlgebra/Double/SparseVector.cs | 29 +++--- src/Numerics/LinearAlgebra/Double/Vector.cs | 89 ++++++------------- .../Double/MatrixTests.Arithmetic.cs | 4 +- .../Double/VectorTests.Norm.cs | 13 +-- 6 files changed, 84 insertions(+), 140 deletions(-) diff --git a/src/Numerics/LinearAlgebra/Double/DenseVector.cs b/src/Numerics/LinearAlgebra/Double/DenseVector.cs index cee08c40..4a8d7cb9 100644 --- a/src/Numerics/LinearAlgebra/Double/DenseVector.cs +++ b/src/Numerics/LinearAlgebra/Double/DenseVector.cs @@ -1195,75 +1195,52 @@ namespace MathNet.Numerics.LinearAlgebra.Double #region Vector Norms - /// - /// Euclidean Norm also known as 2-Norm. - /// - /// Scalar ret = sqrt(sum(this[i]^2)) - public override double Norm() - { - var sum = 0.0; - - for (var i = 0; i < Data.Length; i++) - { - sum = SpecialFunctions.Hypotenuse(sum, Data[i]); - } - - return sum; - } - - /// - /// 1-Norm also known as Manhattan Norm or Taxicab Norm. - /// - /// Scalar ret = sum(abs(this[i])) - public override double Norm1() - { - return CommonParallel.Aggregate( - 0, - Count, - index => Math.Abs(Data[index])); - } - /// /// Computes the p-Norm. /// /// The p value. /// Scalar ret = (sum(abs(this[i])^p))^(1/p) - public override double NormP(int p) + public override double Norm(double p) { - if (1 > p) + if (p < 0.0) { throw new ArgumentOutOfRangeException("p"); } - - if (1 == p) + else if (1.0 == p) { - return Norm1(); + return CommonParallel.Aggregate( + 0, + Count, + index => Math.Abs(Data[index])); } - - if (2 == p) + else if (2.0 == p) { - return Norm(); - } + var sum = 0.0; - var sum = CommonParallel.Aggregate( - 0, - Count, - index => Math.Pow(Math.Abs(Data[index]), p)); + for (var i = 0; i < Data.Length; i++) + { + sum = SpecialFunctions.Hypotenuse(sum, Data[i]); + } - return Math.Pow(sum, 1.0 / p); - } + return sum; + } + else if (Double.IsPositiveInfinity(p)) + { + return CommonParallel.Select( + 0, + Count, + (index, localData) => localData = Math.Max(localData, Math.Abs(Data[index])), + Math.Max); + } + else + { + var sum = CommonParallel.Aggregate( + 0, + Count, + index => Math.Pow(Math.Abs(Data[index]), p)); - /// - /// Infinity Norm. - /// - /// Scalar ret = max(abs(this[i])) - public override double NormInfinity() - { - return CommonParallel.Select( - 0, - Count, - (index, localData) => localData = Math.Max(localData, Math.Abs(Data[index])), - Math.Max); + return Math.Pow(sum, 1.0 / p); + } } #endregion diff --git a/src/Numerics/LinearAlgebra/Double/Matrix.Arithmetic.cs b/src/Numerics/LinearAlgebra/Double/Matrix.Arithmetic.cs index 1ee9c6b2..d67e700d 100644 --- a/src/Numerics/LinearAlgebra/Double/Matrix.Arithmetic.cs +++ b/src/Numerics/LinearAlgebra/Double/Matrix.Arithmetic.cs @@ -948,7 +948,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double i => { var coli = Column(i); - var norm = coli.NormP(p); + var norm = coli.Norm(p); for (var j = 0; j < RowCount; j++) { ret[j, i] = coli[j] / norm; @@ -977,7 +977,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double j => { var rowj = Row(j); - var norm = rowj.NormP(p); + var norm = rowj.Norm(p); for (var i = 0; i < RowCount; i++) { ret[i, j] = rowj[j] / norm; diff --git a/src/Numerics/LinearAlgebra/Double/SparseVector.cs b/src/Numerics/LinearAlgebra/Double/SparseVector.cs index 6c77b4bf..8a386359 100644 --- a/src/Numerics/LinearAlgebra/Double/SparseVector.cs +++ b/src/Numerics/LinearAlgebra/Double/SparseVector.cs @@ -1296,28 +1296,25 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// /// The p value. /// Scalar ret = (sum(abs(this[i])^p))^(1/p) - public override double NormP(int p) + public override double Norm(double p) { if (1 > p) { throw new ArgumentOutOfRangeException("p"); } + else if (Double.IsPositiveInfinity(p)) + { + return CommonParallel.Select(0, NonZerosCount, (index, localData) => localData = Math.Max(localData, Math.Abs(_nonZeroValues[index])), Math.Max); + } + else + { + var sum = CommonParallel.Aggregate( + 0, + NonZerosCount, + index => Math.Pow(Math.Abs(_nonZeroValues[index]), p)); - var sum = CommonParallel.Aggregate( - 0, - NonZerosCount, - index => Math.Pow(Math.Abs(_nonZeroValues[index]), p)); - - return Math.Pow(sum, 1.0 / p); - } - - /// - /// Infinity Norm. - /// - /// Scalar ret = max(abs(this[i])) - public override double NormInfinity() - { - return CommonParallel.Select(0, NonZerosCount, (index, localData) => localData = Math.Max(localData, Math.Abs(_nonZeroValues[index])), Math.Max); + return Math.Pow(sum, 1.0 / p); + } } #endregion diff --git a/src/Numerics/LinearAlgebra/Double/Vector.cs b/src/Numerics/LinearAlgebra/Double/Vector.cs index 47699566..60831009 100644 --- a/src/Numerics/LinearAlgebra/Double/Vector.cs +++ b/src/Numerics/LinearAlgebra/Double/Vector.cs @@ -1112,40 +1112,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double #region Vector Norms - /// - /// Euclidean Norm also known as 2-Norm. - /// - /// - /// Scalar ret = sqrt(sum(this[i]^2)) - /// - public virtual double Norm() - { - return NormP(2); - } - - /// - /// Squared Euclidean 2-Norm. - /// - /// - /// Scalar ret = sum(this[i]^2) - /// - public virtual double SquaredNorm() - { - var norm = Norm(); - return norm * norm; - } - - /// - /// 1-Norm also known as Manhattan Norm or Taxicab Norm. - /// - /// - /// Scalar ret = sum(abs(this[i])) - /// - public virtual double Norm1() - { - return NormP(1); - } - /// /// Computes the p-Norm. /// @@ -1155,45 +1121,48 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// /// Scalar ret = (sum(abs(this[i])^p))^(1/p) /// - public virtual double NormP(int p) + public virtual double Norm(double p) { - if (1 > p) + if (p < 0.0) { throw new ArgumentOutOfRangeException("p"); } + else if (Double.IsPositiveInfinity(p)) + { + return CommonParallel.Select( + 0, + Count, + (index, localData) => localData = Math.Max(localData, Math.Abs(this[index])), + Math.Max); + } + else + { + var sum = CommonParallel.Aggregate( + 0, + Count, + index => Math.Pow(Math.Abs(this[index]), p)); - var sum = CommonParallel.Aggregate( - 0, - Count, - index => Math.Pow(Math.Abs(this[index]), p)); - - return Math.Pow(sum, 1.0 / p); + return Math.Pow(sum, 1.0 / p); + } } /// - /// Infinity Norm. + /// Normalizes this vector to a unit vector with respect to the p-norm. /// + /// + /// The p value. + /// /// - /// Scalar ret = max(abs(this[i])) + /// This vector normalized to a unit vector with respect to the p-norm. /// - public virtual double NormInfinity() + public virtual Vector Normalize(double p) { - return CommonParallel.Select( - 0, - Count, - (index, localData) => localData = Math.Max(localData, Math.Abs(this[index])), - Math.Max); - } + if (p < 0.0) + { + throw new ArgumentOutOfRangeException("p"); + } - /// - /// Normalizes this vector to a unit vector with respect to the Euclidean 2-Norm. - /// - /// - /// This vector normalized to a unit vector with respect to the Euclidean 2-Norm. - /// - public virtual Vector Normalize() - { - var norm = Norm(); + var norm = Norm(p); var clone = Clone(); if (norm == 0.0) { diff --git a/src/UnitTests/LinearAlgebraTests/Double/MatrixTests.Arithmetic.cs b/src/UnitTests/LinearAlgebraTests/Double/MatrixTests.Arithmetic.cs index 76cadd55..5aa83c8d 100644 --- a/src/UnitTests/LinearAlgebraTests/Double/MatrixTests.Arithmetic.cs +++ b/src/UnitTests/LinearAlgebraTests/Double/MatrixTests.Arithmetic.cs @@ -632,7 +632,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double for (var j = 0; j < result.ColumnCount; j++) { var col = result.Column(j); - Assert.AreApproximatelyEqual(1.0, col.NormP(pValue), 10e-12); + Assert.AreApproximatelyEqual(1.0, col.Norm(pValue), 10e-12); } } @@ -646,7 +646,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double for (var i = 0; i < matrix.RowCount; i++) { var row = matrix.Row(i); - Assert.AreApproximatelyEqual(1.0, row.NormP(pValue), 10e-12); + Assert.AreApproximatelyEqual(1.0, row.Norm(pValue), 10e-12); } } diff --git a/src/UnitTests/LinearAlgebraTests/Double/VectorTests.Norm.cs b/src/UnitTests/LinearAlgebraTests/Double/VectorTests.Norm.cs index c94ea48e..64d1b9cc 100644 --- a/src/UnitTests/LinearAlgebraTests/Double/VectorTests.Norm.cs +++ b/src/UnitTests/LinearAlgebraTests/Double/VectorTests.Norm.cs @@ -30,6 +30,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double { + using System; using MbUnit.Framework; public abstract partial class VectorTests @@ -38,21 +39,21 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double public void CanComputeNorm() { var vector = CreateVector(_data); - AssertHelpers.AlmostEqual(7.416198487095663, vector.Norm(), 15); + AssertHelpers.AlmostEqual(7.416198487095663, vector.Norm(2), 15); } [Test] public void CanComputeNorm1() { var vector = CreateVector(_data); - AssertHelpers.AlmostEqual(15.0, vector.Norm1(), 15); + AssertHelpers.AlmostEqual(15.0, vector.Norm(1), 15); } [Test] public void CanComputeSquareNorm() { var vector = CreateVector(_data); - AssertHelpers.AlmostEqual(55.0, vector.SquaredNorm(), 15); + AssertHelpers.AlmostEqual(55.0, vector.Norm(2) * vector.Norm(2), 15); } [Test] @@ -63,14 +64,14 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double public void CanComputeNormP(int p, double expected) { var vector = CreateVector(_data); - AssertHelpers.AlmostEqual(expected, vector.NormP(p), 15); + AssertHelpers.AlmostEqual(expected, vector.Norm(p), 15); } [Test] public void CanComputeNormInfinity() { var vector = CreateVector(_data); - AssertHelpers.AlmostEqual(5.0, vector.NormInfinity(), 15); + AssertHelpers.AlmostEqual(5.0, vector.Norm(Double.PositiveInfinity), 15); } [Test] @@ -78,7 +79,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double public void CanNormalizeVector() { var vector = CreateVector(_data); - var result = vector.Normalize(); + var result = vector.Normalize(2); AssertHelpers.AlmostEqual(0.134839972492648, result[0], 14); AssertHelpers.AlmostEqual(0.269679944985297, result[1], 14); AssertHelpers.AlmostEqual(0.404519917477945, result[2], 14);