Browse Source

Reformatting of Vector.Norm and Vector.Normalize code.

la-knuth
Jurgen Van Gael 16 years ago
parent
commit
37bd9b67de
  1. 85
      src/Numerics/LinearAlgebra/Double/DenseVector.cs
  2. 4
      src/Numerics/LinearAlgebra/Double/Matrix.Arithmetic.cs
  3. 29
      src/Numerics/LinearAlgebra/Double/SparseVector.cs
  4. 89
      src/Numerics/LinearAlgebra/Double/Vector.cs
  5. 4
      src/UnitTests/LinearAlgebraTests/Double/MatrixTests.Arithmetic.cs
  6. 13
      src/UnitTests/LinearAlgebraTests/Double/VectorTests.Norm.cs

85
src/Numerics/LinearAlgebra/Double/DenseVector.cs

@ -1195,75 +1195,52 @@ namespace MathNet.Numerics.LinearAlgebra.Double
#region Vector Norms #region Vector Norms
/// <summary>
/// Euclidean Norm also known as 2-Norm.
/// </summary>
/// <returns>Scalar <c>ret = sqrt(sum(this[i]^2))</c></returns>
public override double Norm()
{
var sum = 0.0;
for (var i = 0; i < Data.Length; i++)
{
sum = SpecialFunctions.Hypotenuse(sum, Data[i]);
}
return sum;
}
/// <summary>
/// 1-Norm also known as Manhattan Norm or Taxicab Norm.
/// </summary>
/// <returns>Scalar <c>ret = sum(abs(this[i]))</c></returns>
public override double Norm1()
{
return CommonParallel.Aggregate(
0,
Count,
index => Math.Abs(Data[index]));
}
/// <summary> /// <summary>
/// Computes the p-Norm. /// Computes the p-Norm.
/// </summary> /// </summary>
/// <param name="p">The p value.</param> /// <param name="p">The p value.</param>
/// <returns>Scalar <c>ret = (sum(abs(this[i])^p))^(1/p)</c></returns> /// <returns>Scalar <c>ret = (sum(abs(this[i])^p))^(1/p)</c></returns>
public override double NormP(int p) public override double Norm(double p)
{ {
if (1 > p) if (p < 0.0)
{ {
throw new ArgumentOutOfRangeException("p"); throw new ArgumentOutOfRangeException("p");
} }
else if (1.0 == p)
if (1 == p)
{ {
return Norm1(); return CommonParallel.Aggregate(
0,
Count,
index => Math.Abs(Data[index]));
} }
else if (2.0 == p)
if (2 == p)
{ {
return Norm(); var sum = 0.0;
}
var sum = CommonParallel.Aggregate( for (var i = 0; i < Data.Length; i++)
0, {
Count, sum = SpecialFunctions.Hypotenuse(sum, Data[i]);
index => Math.Pow(Math.Abs(Data[index]), p)); }
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));
/// <summary> return Math.Pow(sum, 1.0 / p);
/// Infinity Norm. }
/// </summary>
/// <returns>Scalar <c>ret = max(abs(this[i]))</c></returns>
public override double NormInfinity()
{
return CommonParallel.Select(
0,
Count,
(index, localData) => localData = Math.Max(localData, Math.Abs(Data[index])),
Math.Max);
} }
#endregion #endregion

4
src/Numerics/LinearAlgebra/Double/Matrix.Arithmetic.cs

@ -948,7 +948,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
i => i =>
{ {
var coli = Column(i); var coli = Column(i);
var norm = coli.NormP(p); var norm = coli.Norm(p);
for (var j = 0; j < RowCount; j++) for (var j = 0; j < RowCount; j++)
{ {
ret[j, i] = coli[j] / norm; ret[j, i] = coli[j] / norm;
@ -977,7 +977,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
j => j =>
{ {
var rowj = Row(j); var rowj = Row(j);
var norm = rowj.NormP(p); var norm = rowj.Norm(p);
for (var i = 0; i < RowCount; i++) for (var i = 0; i < RowCount; i++)
{ {
ret[i, j] = rowj[j] / norm; ret[i, j] = rowj[j] / norm;

29
src/Numerics/LinearAlgebra/Double/SparseVector.cs

@ -1296,28 +1296,25 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// </summary> /// </summary>
/// <param name="p">The p value.</param> /// <param name="p">The p value.</param>
/// <returns>Scalar <c>ret = (sum(abs(this[i])^p))^(1/p)</c></returns> /// <returns>Scalar <c>ret = (sum(abs(this[i])^p))^(1/p)</c></returns>
public override double NormP(int p) public override double Norm(double p)
{ {
if (1 > p) if (1 > p)
{ {
throw new ArgumentOutOfRangeException("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( return Math.Pow(sum, 1.0 / p);
0, }
NonZerosCount,
index => Math.Pow(Math.Abs(_nonZeroValues[index]), p));
return Math.Pow(sum, 1.0 / p);
}
/// <summary>
/// Infinity Norm.
/// </summary>
/// <returns>Scalar <c>ret = max(abs(this[i]))</c></returns>
public override double NormInfinity()
{
return CommonParallel.Select(0, NonZerosCount, (index, localData) => localData = Math.Max(localData, Math.Abs(_nonZeroValues[index])), Math.Max);
} }
#endregion #endregion

89
src/Numerics/LinearAlgebra/Double/Vector.cs

@ -1112,40 +1112,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double
#region Vector Norms #region Vector Norms
/// <summary>
/// Euclidean Norm also known as 2-Norm.
/// </summary>
/// <returns>
/// <c>Scalar ret = sqrt(sum(this[i]^2))</c>
/// </returns>
public virtual double Norm()
{
return NormP(2);
}
/// <summary>
/// Squared Euclidean 2-Norm.
/// </summary>
/// <returns>
/// <c>Scalar ret = sum(this[i]^2)</c>
/// </returns>
public virtual double SquaredNorm()
{
var norm = Norm();
return norm * norm;
}
/// <summary>
/// 1-Norm also known as Manhattan Norm or Taxicab Norm.
/// </summary>
/// <returns>
/// <c>Scalar ret = sum(abs(this[i]))</c>
/// </returns>
public virtual double Norm1()
{
return NormP(1);
}
/// <summary> /// <summary>
/// Computes the p-Norm. /// Computes the p-Norm.
/// </summary> /// </summary>
@ -1155,45 +1121,48 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns> /// <returns>
/// <c>Scalar ret = (sum(abs(this[i])^p))^(1/p)</c> /// <c>Scalar ret = (sum(abs(this[i])^p))^(1/p)</c>
/// </returns> /// </returns>
public virtual double NormP(int p) public virtual double Norm(double p)
{ {
if (1 > p) if (p < 0.0)
{ {
throw new ArgumentOutOfRangeException("p"); 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( return Math.Pow(sum, 1.0 / p);
0, }
Count,
index => Math.Pow(Math.Abs(this[index]), p));
return Math.Pow(sum, 1.0 / p);
} }
/// <summary> /// <summary>
/// Infinity Norm. /// Normalizes this vector to a unit vector with respect to the p-norm.
/// </summary> /// </summary>
/// <param name="p">
/// The p value.
/// </param>
/// <returns> /// <returns>
/// <c>Scalar ret = max(abs(this[i]))</c> /// This vector normalized to a unit vector with respect to the p-norm.
/// </returns> /// </returns>
public virtual double NormInfinity() public virtual Vector Normalize(double p)
{ {
return CommonParallel.Select( if (p < 0.0)
0, {
Count, throw new ArgumentOutOfRangeException("p");
(index, localData) => localData = Math.Max(localData, Math.Abs(this[index])), }
Math.Max);
}
/// <summary> var norm = Norm(p);
/// Normalizes this vector to a unit vector with respect to the Euclidean 2-Norm.
/// </summary>
/// <returns>
/// This vector normalized to a unit vector with respect to the Euclidean 2-Norm.
/// </returns>
public virtual Vector Normalize()
{
var norm = Norm();
var clone = Clone(); var clone = Clone();
if (norm == 0.0) if (norm == 0.0)
{ {

4
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++) for (var j = 0; j < result.ColumnCount; j++)
{ {
var col = result.Column(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++) for (var i = 0; i < matrix.RowCount; i++)
{ {
var row = matrix.Row(i); var row = matrix.Row(i);
Assert.AreApproximatelyEqual(1.0, row.NormP(pValue), 10e-12); Assert.AreApproximatelyEqual(1.0, row.Norm(pValue), 10e-12);
} }
} }

13
src/UnitTests/LinearAlgebraTests/Double/VectorTests.Norm.cs

@ -30,6 +30,7 @@
namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
{ {
using System;
using MbUnit.Framework; using MbUnit.Framework;
public abstract partial class VectorTests public abstract partial class VectorTests
@ -38,21 +39,21 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
public void CanComputeNorm() public void CanComputeNorm()
{ {
var vector = CreateVector(_data); var vector = CreateVector(_data);
AssertHelpers.AlmostEqual(7.416198487095663, vector.Norm(), 15); AssertHelpers.AlmostEqual(7.416198487095663, vector.Norm(2), 15);
} }
[Test] [Test]
public void CanComputeNorm1() public void CanComputeNorm1()
{ {
var vector = CreateVector(_data); var vector = CreateVector(_data);
AssertHelpers.AlmostEqual(15.0, vector.Norm1(), 15); AssertHelpers.AlmostEqual(15.0, vector.Norm(1), 15);
} }
[Test] [Test]
public void CanComputeSquareNorm() public void CanComputeSquareNorm()
{ {
var vector = CreateVector(_data); var vector = CreateVector(_data);
AssertHelpers.AlmostEqual(55.0, vector.SquaredNorm(), 15); AssertHelpers.AlmostEqual(55.0, vector.Norm(2) * vector.Norm(2), 15);
} }
[Test] [Test]
@ -63,14 +64,14 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
public void CanComputeNormP(int p, double expected) public void CanComputeNormP(int p, double expected)
{ {
var vector = CreateVector(_data); var vector = CreateVector(_data);
AssertHelpers.AlmostEqual(expected, vector.NormP(p), 15); AssertHelpers.AlmostEqual(expected, vector.Norm(p), 15);
} }
[Test] [Test]
public void CanComputeNormInfinity() public void CanComputeNormInfinity()
{ {
var vector = CreateVector(_data); var vector = CreateVector(_data);
AssertHelpers.AlmostEqual(5.0, vector.NormInfinity(), 15); AssertHelpers.AlmostEqual(5.0, vector.Norm(Double.PositiveInfinity), 15);
} }
[Test] [Test]
@ -78,7 +79,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
public void CanNormalizeVector() public void CanNormalizeVector()
{ {
var vector = CreateVector(_data); var vector = CreateVector(_data);
var result = vector.Normalize(); var result = vector.Normalize(2);
AssertHelpers.AlmostEqual(0.134839972492648, result[0], 14); AssertHelpers.AlmostEqual(0.134839972492648, result[0], 14);
AssertHelpers.AlmostEqual(0.269679944985297, result[1], 14); AssertHelpers.AlmostEqual(0.269679944985297, result[1], 14);
AssertHelpers.AlmostEqual(0.404519917477945, result[2], 14); AssertHelpers.AlmostEqual(0.404519917477945, result[2], 14);

Loading…
Cancel
Save