Browse Source

Vector: proper L1, L2 and infinity norms

optimization-1
Christoph Ruegg 13 years ago
parent
commit
55f85a60d3
  1. 8
      src/Examples/LinearAlgebra/MatrixNorms.cs
  2. 18
      src/Numerics/Distance.cs
  3. 87
      src/Numerics/LinearAlgebra/Complex/DenseVector.cs
  4. 2
      src/Numerics/LinearAlgebra/Complex/Factorization/UserGramSchmidt.cs
  5. 2
      src/Numerics/LinearAlgebra/Complex/Solvers/Iterative/MlkBiCgStab.cs
  6. 4
      src/Numerics/LinearAlgebra/Complex/Solvers/Iterative/TFQMR.cs
  7. 2
      src/Numerics/LinearAlgebra/Complex/Solvers/Preconditioners/Ilutp.cs
  8. 2
      src/Numerics/LinearAlgebra/Complex/Solvers/StopCriterium/DivergenceStopCriterium.cs
  9. 4
      src/Numerics/LinearAlgebra/Complex/Solvers/StopCriterium/FailureStopCriterium.cs
  10. 4
      src/Numerics/LinearAlgebra/Complex/Solvers/StopCriterium/ResidualStopCriterium.cs
  11. 79
      src/Numerics/LinearAlgebra/Complex/SparseVector.cs
  12. 44
      src/Numerics/LinearAlgebra/Complex/Vector.cs
  13. 87
      src/Numerics/LinearAlgebra/Complex32/DenseVector.cs
  14. 2
      src/Numerics/LinearAlgebra/Complex32/Factorization/UserGramSchmidt.cs
  15. 2
      src/Numerics/LinearAlgebra/Complex32/Solvers/Iterative/MlkBiCgStab.cs
  16. 4
      src/Numerics/LinearAlgebra/Complex32/Solvers/Iterative/TFQMR.cs
  17. 2
      src/Numerics/LinearAlgebra/Complex32/Solvers/Preconditioners/Ilutp.cs
  18. 2
      src/Numerics/LinearAlgebra/Complex32/Solvers/StopCriterium/DivergenceStopCriterium.cs
  19. 4
      src/Numerics/LinearAlgebra/Complex32/Solvers/StopCriterium/FailureStopCriterium.cs
  20. 4
      src/Numerics/LinearAlgebra/Complex32/Solvers/StopCriterium/ResidualStopCriterium.cs
  21. 81
      src/Numerics/LinearAlgebra/Complex32/SparseVector.cs
  22. 46
      src/Numerics/LinearAlgebra/Complex32/Vector.cs
  23. 92
      src/Numerics/LinearAlgebra/Double/DenseVector.cs
  24. 2
      src/Numerics/LinearAlgebra/Double/Factorization/UserGramSchmidt.cs
  25. 2
      src/Numerics/LinearAlgebra/Double/Solvers/Iterative/MlkBiCgStab.cs
  26. 4
      src/Numerics/LinearAlgebra/Double/Solvers/Iterative/TFQMR.cs
  27. 2
      src/Numerics/LinearAlgebra/Double/Solvers/Preconditioners/Ilutp.cs
  28. 2
      src/Numerics/LinearAlgebra/Double/Solvers/StopCriterium/DivergenceStopCriterium.cs
  29. 4
      src/Numerics/LinearAlgebra/Double/Solvers/StopCriterium/FailureStopCriterium.cs
  30. 4
      src/Numerics/LinearAlgebra/Double/Solvers/StopCriterium/ResidualStopCriterium.cs
  31. 81
      src/Numerics/LinearAlgebra/Double/SparseVector.cs
  32. 56
      src/Numerics/LinearAlgebra/Double/Vector.cs
  33. 95
      src/Numerics/LinearAlgebra/Single/DenseVector.cs
  34. 2
      src/Numerics/LinearAlgebra/Single/Factorization/UserGramSchmidt.cs
  35. 2
      src/Numerics/LinearAlgebra/Single/Solvers/Iterative/MlkBiCgStab.cs
  36. 4
      src/Numerics/LinearAlgebra/Single/Solvers/Iterative/TFQMR.cs
  37. 2
      src/Numerics/LinearAlgebra/Single/Solvers/Preconditioners/Ilutp.cs
  38. 2
      src/Numerics/LinearAlgebra/Single/Solvers/StopCriterium/DivergenceStopCriterium.cs
  39. 4
      src/Numerics/LinearAlgebra/Single/Solvers/StopCriterium/FailureStopCriterium.cs
  40. 4
      src/Numerics/LinearAlgebra/Single/Solvers/StopCriterium/ResidualStopCriterium.cs
  41. 81
      src/Numerics/LinearAlgebra/Single/SparseVector.cs
  42. 56
      src/Numerics/LinearAlgebra/Single/Vector.cs
  43. 28
      src/Numerics/LinearAlgebra/Vector.Arithmetic.cs
  44. 8
      src/Numerics/RootFinding/Broyden.cs
  45. 4
      src/UnitTests/LinearAlgebraTests/Complex/VectorTests.Norm.cs
  46. 10
      src/UnitTests/LinearAlgebraTests/Complex32/VectorTests.Norm.cs
  47. 4
      src/UnitTests/LinearAlgebraTests/Double/VectorTests.Norm.cs
  48. 4
      src/UnitTests/LinearAlgebraTests/Single/VectorTests.Norm.cs

8
src/Examples/LinearAlgebra/MatrixNorms.cs

@ -97,7 +97,7 @@ namespace Examples.LinearAlgebraExamples
Console.WriteLine(@"5. Normalize matrix columns: before normalize"); Console.WriteLine(@"5. Normalize matrix columns: before normalize");
foreach (var keyValuePair in matrix.ColumnEnumerator()) 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(); Console.WriteLine();
@ -105,7 +105,7 @@ namespace Examples.LinearAlgebraExamples
Console.WriteLine(@"5. Normalize matrix columns: after normalize"); Console.WriteLine(@"5. Normalize matrix columns: after normalize");
foreach (var keyValuePair in normalized.ColumnEnumerator()) 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(); Console.WriteLine();
@ -114,7 +114,7 @@ namespace Examples.LinearAlgebraExamples
Console.WriteLine(@"6. Normalize matrix rows: before normalize"); Console.WriteLine(@"6. Normalize matrix rows: before normalize");
foreach (var keyValuePair in matrix.RowEnumerator()) 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(); Console.WriteLine();
@ -122,7 +122,7 @@ namespace Examples.LinearAlgebraExamples
Console.WriteLine(@"6. Normalize matrix rows: after normalize"); Console.WriteLine(@"6. Normalize matrix rows: after normalize");
foreach (var keyValuePair in normalized.RowEnumerator()) 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());
} }
} }
} }

18
src/Numerics/Distance.cs

@ -41,7 +41,7 @@ namespace MathNet.Numerics
/// </summary> /// </summary>
public static double SAD(Vector<double> a, Vector<double> b) public static double SAD(Vector<double> a, Vector<double> b)
{ {
return (a - b).SumMagnitudes(); return (a - b).L1Norm();
} }
/// <summary> /// <summary>
@ -49,7 +49,7 @@ namespace MathNet.Numerics
/// </summary> /// </summary>
public static float SAD(Vector<float> a, Vector<float> b) public static float SAD(Vector<float> a, Vector<float> b)
{ {
return (a - b).SumMagnitudes(); return (a - b).L1Norm();
} }
/// <summary> /// <summary>
@ -87,7 +87,7 @@ namespace MathNet.Numerics
/// </summary> /// </summary>
public static double MAE(Vector<double> a, Vector<double> b) public static double MAE(Vector<double> a, Vector<double> b)
{ {
return SAD(a, b)/a.Count; return (a - b).L1Norm()/a.Count;
} }
/// <summary> /// <summary>
@ -95,7 +95,7 @@ namespace MathNet.Numerics
/// </summary> /// </summary>
public static float MAE(Vector<float> a, Vector<float> b) public static float MAE(Vector<float> a, Vector<float> b)
{ {
return SAD(a, b)/a.Count; return (a - b).L1Norm()/a.Count;
} }
/// <summary> /// <summary>
@ -119,7 +119,7 @@ namespace MathNet.Numerics
/// </summary> /// </summary>
public static double SSD(Vector<double> a, Vector<double> b) public static double SSD(Vector<double> a, Vector<double> b)
{ {
var norm = (a - b).Norm(2d); var norm = (a - b).L2Norm();
return norm*norm; return norm*norm;
} }
@ -128,7 +128,7 @@ namespace MathNet.Numerics
/// </summary> /// </summary>
public static float SSD(Vector<float> a, Vector<float> b) public static float SSD(Vector<float> a, Vector<float> b)
{ {
var norm = (a - b).Norm(2d); var norm = (a - b).L2Norm();
return norm*norm; return norm*norm;
} }
@ -157,7 +157,8 @@ namespace MathNet.Numerics
/// </summary> /// </summary>
public static double MSE(Vector<double> a, Vector<double> b) public static double MSE(Vector<double> a, Vector<double> b)
{ {
return SSD(a, b)/a.Count; var norm = (a - b).L2Norm();
return norm*norm/a.Count;
} }
/// <summary> /// <summary>
@ -165,7 +166,8 @@ namespace MathNet.Numerics
/// </summary> /// </summary>
public static float MSE(Vector<float> a, Vector<float> b) public static float MSE(Vector<float> a, Vector<float> b)
{ {
return SSD(a, b)/a.Count; var norm = (a - b).L2Norm();
return norm*norm/a.Count;
} }
/// <summary> /// <summary>

87
src/Numerics/LinearAlgebra/Complex/DenseVector.cs

@ -565,31 +565,67 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
public override Complex Sum() public override Complex Sum()
{ {
var sum = Complex.Zero; var sum = Complex.Zero;
for (var i = 0; i < _length; i++) for (var i = 0; i < _length; i++)
{ {
sum += _values[i]; sum += _values[i];
} }
return sum; return sum;
} }
/// <summary> /// <summary>
/// Computes the sum of the absolute value of the vector's elements. /// Calculates the L1 norm of the vector, also known as Manhattan norm.
/// </summary> /// </summary>
/// <returns>The sum of the absolute value of the vector's elements.</returns> /// <returns>The sum of the absolute values.</returns>
public override Complex SumMagnitudes() public override Complex L1Norm()
{ {
var sum = Complex.Zero; var sum = Complex.Zero;
for (var i = 0; i < _length; i++) for (var i = 0; i < _length; i++)
{ {
sum += _values[i].Magnitude; sum += _values[i].Magnitude;
} }
return sum; return sum;
} }
/// <summary>
/// Calculates the L2 norm of the vector, also known as Euclidean norm.
/// </summary>
/// <returns>The square root of the sum of the squared values.</returns>
public override Complex L2Norm()
{
// TODO: native provider
return _values.Aggregate(Complex.Zero, SpecialFunctions.Hypotenuse).Magnitude;
}
/// <summary>
/// Calculates the infinity norm of the vector.
/// </summary>
/// <returns>The square root of the sum of the squared values.</returns>
public override Complex InfinityNorm()
{
return CommonParallel.Aggregate(_values, (i, v) => v.Magnitude, Math.Max, 0d);
}
/// <summary>
/// Computes the p-Norm.
/// </summary>
/// <param name="p">The p value.</param>
/// <returns>Scalar <c>ret = (sum(abs(this[i])^p))^(1/p)</c></returns>
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);
}
/// <summary> /// <summary>
/// Pointwise divide this vector with another vector and stores the result into the result vector. /// Pointwise divide this vector with another vector and stores the result into the result vector.
/// </summary> /// </summary>
@ -678,43 +714,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
return OuterProduct(this, v); return OuterProduct(this, v);
} }
/// <summary>
/// Computes the p-Norm.
/// </summary>
/// <param name="p">The p value.</param>
/// <returns>Scalar <c>ret = (sum(abs(this[i])^p))^(1/p)</c></returns>
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 #region Parse Functions
/// <summary> /// <summary>

2
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++) 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) if (norm == 0.0)
{ {
throw new ArgumentException(Resources.ArgumentMatrixNotRankDeficient); throw new ArgumentException(Resources.ArgumentMatrixNotRankDeficient);

2
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)); result.Add((Vector)orthogonalMatrix.Column(i));
// Normalize the result vector // 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; return result;

4
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); var temp2 = new DenseVector(input.Count);
// Initialize // Initialize
var startNorm = input.Norm(2); var startNorm = input.L2Norm();
// Define the scalars // Define the scalars
Complex alpha = 0; Complex alpha = 0;
@ -350,7 +350,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
yinternal.Add(temp, d); yinternal.Add(temp, d);
// theta = ||pseudoResiduals||_2 / tau // theta = ||pseudoResiduals||_2 / tau
theta = pseudoResiduals.Norm(2).Real/tau; theta = pseudoResiduals.L2Norm().Real / tau;
var c = 1/Math.Sqrt(1 + (theta*theta)); var c = 1/Math.Sqrt(1 + (theta*theta));
// tau = tau * theta * c // tau = tau * theta * c

2
src/Numerics/LinearAlgebra/Complex/Solvers/Preconditioners/Ilutp.cs

@ -394,7 +394,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Preconditioners
// pivot the row // pivot the row
PivotRow(workVector); PivotRow(workVector);
var vectorNorm = workVector.Norm(Double.PositiveInfinity); var vectorNorm = workVector.InfinityNorm();
// for j = 1, .. , i - 1) // for j = 1, .. , i - 1)
for (var j = 0; j < i; j++) for (var j = 0; j < i; j++)

2
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 // 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. // 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. // Check if we have NaN's. If so we've gone way beyond normal divergence.
// Stop the iteration. // Stop the iteration.

4
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 // Store the infinity norms of both the solution and residual vectors
var residualNorm = residualVector.Norm(double.PositiveInfinity); var residualNorm = residualVector.InfinityNorm();
var solutionNorm = solutionVector.Norm(double.PositiveInfinity); var solutionNorm = solutionVector.InfinityNorm();
if (double.IsNaN(solutionNorm.Real) || double.IsNaN(residualNorm.Real)) if (double.IsNaN(solutionNorm.Real) || double.IsNaN(residualNorm.Real))
{ {

4
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 // Store the infinity norms of both the solution and residual vectors
// These values will be used to calculate the relative drop in residuals // These values will be used to calculate the relative drop in residuals
// later on. // later on.
var residualNorm = residualVector.Norm(double.PositiveInfinity); var residualNorm = residualVector.InfinityNorm();
// Check the residuals by calculating: // Check the residuals by calculating:
// ||r_i|| <= stop_tol * ||b|| // ||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. // First check that we have real numbers not NaN's.
// NaN's can occur when the iterative process diverges so we // NaN's can occur when the iterative process diverges so we

79
src/Numerics/LinearAlgebra/Complex/SparseVector.cs

@ -729,25 +729,58 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
{ {
result += _storage.Values[i]; result += _storage.Values[i];
} }
return result; return result;
} }
/// <summary> /// <summary>
/// Computes the sum of the absolute value of the vector's elements. /// Calculates the L1 norm of the vector, also known as Manhattan norm.
/// </summary> /// </summary>
/// <returns>The sum of the absolute value of the vector's elements.</returns> /// <returns>The sum of the absolute values.</returns>
public override Complex SumMagnitudes() public override Complex L1Norm()
{ {
double result = 0; double result = 0;
for (var i = 0; i < _storage.ValueCount; i++) for (var i = 0; i < _storage.ValueCount; i++)
{ {
result += _storage.Values[i].Magnitude; result += _storage.Values[i].Magnitude;
} }
return result; return result;
} }
/// <summary>
/// Calculates the infinity norm of the vector.
/// </summary>
/// <returns>The square root of the sum of the squared values.</returns>
public override Complex InfinityNorm()
{
return CommonParallel.Aggregate(0, _storage.ValueCount, i => _storage.Values[i].Magnitude, Math.Max, 0d);
}
/// <summary>
/// Computes the p-Norm.
/// </summary>
/// <param name="p">The p value.</param>
/// <returns>Scalar <c>ret = (sum(abs(this[i])^p))^(1/p)</c></returns>
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);
}
/// <summary> /// <summary>
/// Pointwise multiplies this vector with another vector and stores the result into the result vector. /// Pointwise multiplies this vector with another vector and stores the result into the result vector.
/// </summary> /// </summary>
@ -843,42 +876,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
return OuterProduct(this, v); return OuterProduct(this, v);
} }
/// <summary>
/// Computes the p-Norm.
/// </summary>
/// <param name="p">The p value.</param>
/// <returns>Scalar <c>ret = (sum(abs(this[i])^p))^(1/p)</c></returns>
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 #region Parse Functions
/// <summary> /// <summary>

44
src/Numerics/LinearAlgebra/Complex/Vector.cs

@ -317,31 +317,45 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
public override Complex Sum() public override Complex Sum()
{ {
var sum = Complex.Zero; var sum = Complex.Zero;
for (var i = 0; i < Count; i++) for (var i = 0; i < Count; i++)
{ {
sum += At(i); sum += At(i);
} }
return sum; return sum;
} }
/// <summary> /// <summary>
/// Computes the sum of the absolute value of the vector's elements. /// Calculates the L1 norm of the vector, also known as Manhattan norm.
/// </summary> /// </summary>
/// <returns>The sum of the absolute value of the vector's elements.</returns> /// <returns>The sum of the absolute values.</returns>
public override Complex SumMagnitudes() public override Complex L1Norm()
{ {
var sum = Complex.Zero; var sum = Complex.Zero;
for (var i = 0; i < Count; i++) for (var i = 0; i < Count; i++)
{ {
sum += At(i).Magnitude; sum += At(i).Magnitude;
} }
return sum; return sum;
} }
/// <summary>
/// Calculates the L2 norm of the vector, also known as Euclidean norm.
/// </summary>
/// <returns>The square root of the sum of the squared values.</returns>
public override Complex L2Norm()
{
return DoConjugateDotProduct(this).SquareRoot();
}
/// <summary>
/// Calculates the infinity norm of the vector.
/// </summary>
/// <returns>The square root of the sum of the squared values.</returns>
public override Complex InfinityNorm()
{
return CommonParallel.Aggregate(0, Count, i => At(i).Magnitude, Math.Max, 0d);
}
/// <summary> /// <summary>
/// Computes the p-Norm. /// Computes the p-Norm.
/// </summary> /// </summary>
@ -353,23 +367,17 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
/// </returns> /// </returns>
public override Complex Norm(double p) public override Complex Norm(double p)
{ {
if (p < 0.0) if (p < 0d) throw new ArgumentOutOfRangeException("p");
{
throw new ArgumentOutOfRangeException("p");
}
if (double.IsPositiveInfinity(p)) if (p == 1d) return L1Norm();
{ if (p == 2d) return L2Norm();
return CommonParallel.Aggregate(0, Count, i => At(i).Magnitude, Math.Max, 0d); if (double.IsPositiveInfinity(p)) return InfinityNorm();
}
var sum = 0.0;
var sum = 0d;
for (var index = 0; index < Count; index++) for (var index = 0; index < Count; index++)
{ {
sum += Math.Pow(At(index).Magnitude, p); sum += Math.Pow(At(index).Magnitude, p);
} }
return Math.Pow(sum, 1.0 / p); return Math.Pow(sum, 1.0 / p);
} }

87
src/Numerics/LinearAlgebra/Complex32/DenseVector.cs

@ -560,31 +560,67 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
public override Complex32 Sum() public override Complex32 Sum()
{ {
var sum = Complex32.Zero; var sum = Complex32.Zero;
for (var i = 0; i < _length; i++) for (var i = 0; i < _length; i++)
{ {
sum += _values[i]; sum += _values[i];
} }
return sum; return sum;
} }
/// <summary> /// <summary>
/// Computes the sum of the absolute value of the vector's elements. /// Calculates the L1 norm of the vector, also known as Manhattan norm.
/// </summary> /// </summary>
/// <returns>The sum of the absolute value of the vector's elements.</returns> /// <returns>The sum of the absolute values.</returns>
public override Complex32 SumMagnitudes() public override Complex32 L1Norm()
{ {
var sum = Complex32.Zero; var sum = Complex32.Zero;
for (var i = 0; i < _length; i++) for (var i = 0; i < _length; i++)
{ {
sum += _values[i].Magnitude; sum += _values[i].Magnitude;
} }
return sum; return sum;
} }
/// <summary>
/// Calculates the L2 norm of the vector, also known as Euclidean norm.
/// </summary>
/// <returns>The square root of the sum of the squared values.</returns>
public override Complex32 L2Norm()
{
// TODO: native provider
return _values.Aggregate(Complex32.Zero, SpecialFunctions.Hypotenuse).Magnitude;
}
/// <summary>
/// Calculates the infinity norm of the vector.
/// </summary>
/// <returns>The square root of the sum of the squared values.</returns>
public override Complex32 InfinityNorm()
{
return CommonParallel.Aggregate(_values, (i, v) => v.Magnitude, Math.Max, 0f);
}
/// <summary>
/// Computes the p-Norm.
/// </summary>
/// <param name="p">The p value.</param>
/// <returns>Scalar <c>ret = (sum(abs(this[i])^p))^(1/p)</c></returns>
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);
}
/// <summary> /// <summary>
/// Pointwise divide this vector with another vector and stores the result into the result vector. /// Pointwise divide this vector with another vector and stores the result into the result vector.
/// </summary> /// </summary>
@ -673,43 +709,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
return OuterProduct(this, v); return OuterProduct(this, v);
} }
/// <summary>
/// Computes the p-Norm.
/// </summary>
/// <param name="p">The p value.</param>
/// <returns>Scalar <c>ret = (sum(abs(this[i])^p))^(1/p)</c></returns>
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 #region Parse Functions
/// <summary> /// <summary>

2
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++) 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) if (norm == 0.0f)
{ {
throw new ArgumentException(Resources.ArgumentMatrixNotRankDeficient); throw new ArgumentException(Resources.ArgumentMatrixNotRankDeficient);

2
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)); result.Add((Vector)orthogonalMatrix.Column(i));
// Normalize the result vector // 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; return result;

4
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); var temp2 = new DenseVector(input.Count);
// Initialize // Initialize
var startNorm = input.Norm(2); var startNorm = input.L2Norm();
// Define the scalars // Define the scalars
Complex32 alpha = 0; Complex32 alpha = 0;
@ -350,7 +350,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
yinternal.Add(temp, d); yinternal.Add(temp, d);
// theta = ||pseudoResiduals||_2 / tau // theta = ||pseudoResiduals||_2 / tau
theta = pseudoResiduals.Norm(2).Real/tau; theta = pseudoResiduals.L2Norm().Real / tau;
var c = 1/(float) Math.Sqrt(1 + (theta*theta)); var c = 1/(float) Math.Sqrt(1 + (theta*theta));
// tau = tau * theta * c // tau = tau * theta * c

2
src/Numerics/LinearAlgebra/Complex32/Solvers/Preconditioners/Ilutp.cs

@ -389,7 +389,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Preconditioners
// pivot the row // pivot the row
PivotRow(workVector); PivotRow(workVector);
var vectorNorm = workVector.Norm(Double.PositiveInfinity); var vectorNorm = workVector.InfinityNorm();
// for j = 1, .. , i - 1) // for j = 1, .. , i - 1)
for (var j = 0; j < i; j++) for (var j = 0; j < i; j++)

2
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 // 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. // 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. // Check if we have NaN's. If so we've gone way beyond normal divergence.
// Stop the iteration. // Stop the iteration.

4
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 // Store the infinity norms of both the solution and residual vectors
var residualNorm = residualVector.Norm(float.PositiveInfinity); var residualNorm = residualVector.InfinityNorm();
var solutionNorm = solutionVector.Norm(float.PositiveInfinity); var solutionNorm = solutionVector.InfinityNorm();
if (float.IsNaN(solutionNorm.Real) || float.IsNaN(residualNorm.Real)) if (float.IsNaN(solutionNorm.Real) || float.IsNaN(residualNorm.Real))
{ {

4
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 // Store the infinity norms of both the solution and residual vectors
// These values will be used to calculate the relative drop in residuals // These values will be used to calculate the relative drop in residuals
// later on. // later on.
var residualNorm = residualVector.Norm(float.PositiveInfinity); var residualNorm = residualVector.InfinityNorm();
// Check the residuals by calculating: // Check the residuals by calculating:
// ||r_i|| <= stop_tol * ||b|| // ||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. // First check that we have real numbers not NaN's.
// NaN's can occur when the iterative process diverges so we // NaN's can occur when the iterative process diverges so we

81
src/Numerics/LinearAlgebra/Complex32/SparseVector.cs

@ -724,25 +724,58 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
{ {
result += _storage.Values[i]; result += _storage.Values[i];
} }
return result; return result;
} }
/// <summary> /// <summary>
/// Computes the sum of the absolute value of the vector's elements. /// Calculates the L1 norm of the vector, also known as Manhattan norm.
/// </summary> /// </summary>
/// <returns>The sum of the absolute value of the vector's elements.</returns> /// <returns>The sum of the absolute values.</returns>
public override Complex32 SumMagnitudes() public override Complex32 L1Norm()
{ {
var result = 0.0f; var result = 0f;
for (var i = 0; i < _storage.ValueCount; i++) for (var i = 0; i < _storage.ValueCount; i++)
{ {
result += _storage.Values[i].Magnitude; result += _storage.Values[i].Magnitude;
} }
return result; return result;
} }
/// <summary>
/// Calculates the infinity norm of the vector.
/// </summary>
/// <returns>The square root of the sum of the squared values.</returns>
public override Complex32 InfinityNorm()
{
return CommonParallel.Aggregate(0, _storage.ValueCount, i => _storage.Values[i].Magnitude, Math.Max, 0f);
}
/// <summary>
/// Computes the p-Norm.
/// </summary>
/// <param name="p">The p value.</param>
/// <returns>Scalar <c>ret = (sum(abs(this[i])^p))^(1/p)</c></returns>
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);
}
/// <summary> /// <summary>
/// Pointwise multiplies this vector with another vector and stores the result into the result vector. /// Pointwise multiplies this vector with another vector and stores the result into the result vector.
/// </summary> /// </summary>
@ -838,42 +871,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
return OuterProduct(this, v); return OuterProduct(this, v);
} }
/// <summary>
/// Computes the p-Norm.
/// </summary>
/// <param name="p">The p value.</param>
/// <returns>Scalar <c>ret = (sum(abs(this[i])^p))^(1/p)</c></returns>
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 #region Parse Functions
/// <summary> /// <summary>

46
src/Numerics/LinearAlgebra/Complex32/Vector.cs

@ -312,31 +312,45 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
public override Complex32 Sum() public override Complex32 Sum()
{ {
var sum = Complex32.Zero; var sum = Complex32.Zero;
for (var i = 0; i < Count; i++) for (var i = 0; i < Count; i++)
{ {
sum += At(i); sum += At(i);
} }
return sum; return sum;
} }
/// <summary> /// <summary>
/// Computes the sum of the absolute value of the vector's elements. /// Calculates the L1 norm of the vector, also known as Manhattan norm.
/// </summary> /// </summary>
/// <returns>The sum of the absolute value of the vector's elements.</returns> /// <returns>The sum of the absolute values.</returns>
public override Complex32 SumMagnitudes() public override Complex32 L1Norm()
{ {
var sum = Complex32.Zero; var sum = Complex32.Zero;
for (var i = 0; i < Count; i++) for (var i = 0; i < Count; i++)
{ {
sum += At(i).Magnitude; sum += At(i).Magnitude;
} }
return sum; return sum;
} }
/// <summary>
/// Calculates the L2 norm of the vector, also known as Euclidean norm.
/// </summary>
/// <returns>The square root of the sum of the squared values.</returns>
public override Complex32 L2Norm()
{
return DoConjugateDotProduct(this).SquareRoot();
}
/// <summary>
/// Calculates the infinity norm of the vector.
/// </summary>
/// <returns>The square root of the sum of the squared values.</returns>
public override Complex32 InfinityNorm()
{
return CommonParallel.Aggregate(0, Count, i => At(i).Magnitude, Math.Max, 0f);
}
/// <summary> /// <summary>
/// Computes the p-Norm. /// Computes the p-Norm.
/// </summary> /// </summary>
@ -348,24 +362,18 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
/// </returns> /// </returns>
public override Complex32 Norm(double p) public override Complex32 Norm(double p)
{ {
if (p < 0.0) if (p < 0d) throw new ArgumentOutOfRangeException("p");
{
throw new ArgumentOutOfRangeException("p");
}
if (double.IsPositiveInfinity(p)) if (p == 1d) return L1Norm();
{ if (p == 2d) return L2Norm();
return CommonParallel.Aggregate(0, Count, i => At(i).Magnitude, Math.Max, 0f); if (double.IsPositiveInfinity(p)) return InfinityNorm();
}
var sum = 0.0;
var sum = 0d;
for (var index = 0; index < Count; index++) for (var index = 0; index < Count; index++)
{ {
sum += Math.Pow(At(index).Magnitude, p); sum += Math.Pow(At(index).Magnitude, p);
} }
return (float) Math.Pow(sum, 1.0/p);
return (float)Math.Pow(sum, 1.0 / p);
} }
/// <summary> /// <summary>

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

@ -632,31 +632,67 @@ namespace MathNet.Numerics.LinearAlgebra.Double
public override double Sum() public override double Sum()
{ {
var sum = 0.0; var sum = 0.0;
for (var index = 0; index < _length; index++) for (var index = 0; index < _length; index++)
{ {
sum += _values[index]; sum += _values[index];
} }
return sum; return sum;
} }
/// <summary> /// <summary>
/// Computes the sum of the absolute value of the vector's elements. /// Calculates the L1 norm of the vector, also known as Manhattan norm.
/// </summary> /// </summary>
/// <returns>The sum of the absolute value of the vector's elements.</returns> /// <returns>The sum of the absolute values.</returns>
public override double SumMagnitudes() public override double L1Norm()
{ {
var sum = 0.0; var sum = 0d;
for (var index = 0; index < _length; index++) for (var index = 0; index < _length; index++)
{ {
sum += Math.Abs(_values[index]); sum += Math.Abs(_values[index]);
} }
return sum; return sum;
} }
/// <summary>
/// Calculates the L2 norm of the vector, also known as Euclidean norm.
/// </summary>
/// <returns>The square root of the sum of the squared values.</returns>
public override double L2Norm()
{
// TODO: native provider
return _values.Aggregate(0d, SpecialFunctions.Hypotenuse);
}
/// <summary>
/// Calculates the infinity norm of the vector.
/// </summary>
/// <returns>The square root of the sum of the squared values.</returns>
public override double InfinityNorm()
{
return CommonParallel.Aggregate(_values, (i, v) => Math.Abs(v), Math.Max, 0d);
}
/// <summary>
/// Computes the p-Norm.
/// </summary>
/// <param name="p">The p value.</param>
/// <returns>Scalar <c>ret = (sum(abs(this[i])^p))^(1/p)</c></returns>
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);
}
/// <summary> /// <summary>
/// Pointwise divide this vector with another vector and stores the result into the result vector. /// Pointwise divide this vector with another vector and stores the result into the result vector.
/// </summary> /// </summary>
@ -745,46 +781,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double
return OuterProduct(this, v); return OuterProduct(this, v);
} }
#region Vector Norms
/// <summary>
/// Computes the p-Norm.
/// </summary>
/// <param name="p">The p value.</param>
/// <returns>Scalar <c>ret = (sum(abs(this[i])^p))^(1/p)</c></returns>
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 #region Parse Functions
/// <summary> /// <summary>

2
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++) 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) if (norm == 0.0)
{ {
throw new ArgumentException(Resources.ArgumentMatrixNotRankDeficient); throw new ArgumentException(Resources.ArgumentMatrixNotRankDeficient);

2
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)); result.Add((Vector)orthogonalMatrix.Column(i));
// Normalize the result vector // 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; return result;

4
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); var temp2 = new DenseVector(input.Count);
// Initialize // Initialize
var startNorm = input.Norm(2); var startNorm = input.L2Norm();
// Define the scalars // Define the scalars
double alpha = 0; double alpha = 0;
@ -348,7 +348,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
yinternal.Add(temp, d); yinternal.Add(temp, d);
// theta = ||pseudoResiduals||_2 / tau // theta = ||pseudoResiduals||_2 / tau
theta = pseudoResiduals.Norm(2) / tau; theta = pseudoResiduals.L2Norm() / tau;
var c = 1 / Math.Sqrt(1 + (theta * theta)); var c = 1 / Math.Sqrt(1 + (theta * theta));
// tau = tau * theta * c // tau = tau * theta * c

2
src/Numerics/LinearAlgebra/Double/Solvers/Preconditioners/Ilutp.cs

@ -388,7 +388,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
// pivot the row // pivot the row
PivotRow(workVector); PivotRow(workVector);
var vectorNorm = workVector.Norm(Double.PositiveInfinity); var vectorNorm = workVector.InfinityNorm();
// for j = 1, .. , i - 1) // for j = 1, .. , i - 1)
for (var j = 0; j < i; j++) for (var j = 0; j < i; j++)

2
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 // 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. // 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. // Check if we have NaN's. If so we've gone way beyond normal divergence.
// Stop the iteration. // Stop the iteration.

4
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 // Store the infinity norms of both the solution and residual vectors
var residualNorm = residualVector.Norm(double.PositiveInfinity); var residualNorm = residualVector.InfinityNorm();
var solutionNorm = solutionVector.Norm(double.PositiveInfinity); var solutionNorm = solutionVector.InfinityNorm();
if (double.IsNaN(solutionNorm) || double.IsNaN(residualNorm)) if (double.IsNaN(solutionNorm) || double.IsNaN(residualNorm))
{ {

4
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 // Store the infinity norms of both the solution and residual vectors
// These values will be used to calculate the relative drop in residuals // These values will be used to calculate the relative drop in residuals
// later on. // later on.
var residualNorm = residualVector.Norm(double.PositiveInfinity); var residualNorm = residualVector.InfinityNorm();
// Check the residuals by calculating: // Check the residuals by calculating:
// ||r_i|| <= stop_tol * ||b|| // ||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. // First check that we have real numbers not NaN's.
// NaN's can occur when the iterative process diverges so we // NaN's can occur when the iterative process diverges so we

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

@ -734,25 +734,58 @@ namespace MathNet.Numerics.LinearAlgebra.Double
{ {
result += _storage.Values[i]; result += _storage.Values[i];
} }
return result; return result;
} }
/// <summary> /// <summary>
/// Computes the sum of the absolute value of the vector's elements. /// Calculates the L1 norm of the vector, also known as Manhattan norm.
/// </summary> /// </summary>
/// <returns>The sum of the absolute value of the vector's elements.</returns> /// <returns>The sum of the absolute values.</returns>
public override double SumMagnitudes() public override double L1Norm()
{ {
double result = 0; var result = 0d;
for (var i = 0; i < _storage.ValueCount; i++) for (var i = 0; i < _storage.ValueCount; i++)
{ {
result += Math.Abs(_storage.Values[i]); result += Math.Abs(_storage.Values[i]);
} }
return result; return result;
} }
/// <summary>
/// Calculates the infinity norm of the vector.
/// </summary>
/// <returns>The square root of the sum of the squared values.</returns>
public override double InfinityNorm()
{
return CommonParallel.Aggregate(0, _storage.ValueCount, i => Math.Abs(_storage.Values[i]), Math.Max, 0d);
}
/// <summary>
/// Computes the p-Norm.
/// </summary>
/// <param name="p">The p value.</param>
/// <returns>Scalar <c>ret = (sum(abs(this[i])^p))^(1/p)</c></returns>
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);
}
/// <summary> /// <summary>
/// Pointwise multiplies this vector with another vector and stores the result into the result vector. /// Pointwise multiplies this vector with another vector and stores the result into the result vector.
/// </summary> /// </summary>
@ -845,42 +878,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double
return OuterProduct(this, v); return OuterProduct(this, v);
} }
/// <summary>
/// Computes the p-Norm.
/// </summary>
/// <param name="p">The p value.</param>
/// <returns>Scalar <c>ret = (sum(abs(this[i])^p))^(1/p)</c></returns>
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 #region Parse Functions
/// <summary> /// <summary>

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

@ -211,6 +211,16 @@ namespace MathNet.Numerics.LinearAlgebra.Double
return dot; return dot;
} }
/// <summary>
/// Computes the dot product between the conjugate of this vector and another vector.
/// </summary>
/// <param name="other">The other vector.</param>
/// <returns>The sum of conj(a[i])*b[i] for all i.</returns>
protected override sealed double DoConjugateDotProduct(Vector<double> other)
{
return DoDotProduct(other);
}
/// <summary> /// <summary>
/// Computes the modulus for each element of the vector for the given divisor. /// Computes the modulus for each element of the vector for the given divisor.
/// </summary> /// </summary>
@ -304,31 +314,45 @@ namespace MathNet.Numerics.LinearAlgebra.Double
public override double Sum() public override double Sum()
{ {
var sum = 0.0; var sum = 0.0;
for (var i = 0; i < Count; i++) for (var i = 0; i < Count; i++)
{ {
sum += At(i); sum += At(i);
} }
return sum; return sum;
} }
/// <summary> /// <summary>
/// Computes the sum of the absolute value of the vector's elements. /// Calculates the L1 norm of the vector, also known as Manhattan norm.
/// </summary> /// </summary>
/// <returns>The sum of the absolute value of the vector's elements.</returns> /// <returns>The sum of the absolute values.</returns>
public override double SumMagnitudes() public override double L1Norm()
{ {
var sum = 0.0; var sum = 0.0;
for (var i = 0; i < Count; i++) for (var i = 0; i < Count; i++)
{ {
sum += Math.Abs(At(i)); sum += Math.Abs(At(i));
} }
return sum; return sum;
} }
/// <summary>
/// Calculates the L2 norm of the vector, also known as Euclidean norm.
/// </summary>
/// <returns>The square root of the sum of the squared values.</returns>
public override double L2Norm()
{
return Math.Sqrt(DoDotProduct(this));
}
/// <summary>
/// Calculates the infinity norm of the vector.
/// </summary>
/// <returns>The square root of the sum of the squared values.</returns>
public override double InfinityNorm()
{
return CommonParallel.Aggregate(0, Count, i => Math.Abs(At(i)), Math.Max, 0d);
}
/// <summary> /// <summary>
/// Computes the p-Norm. /// Computes the p-Norm.
/// </summary> /// </summary>
@ -340,24 +364,18 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// </returns> /// </returns>
public override double Norm(double p) public override double Norm(double p)
{ {
if (p < 0.0) if (p < 0d) throw new ArgumentOutOfRangeException("p");
{
throw new ArgumentOutOfRangeException("p");
}
if (double.IsPositiveInfinity(p)) if (p == 1d) return L1Norm();
{ if (p == 2d) return L2Norm();
return CommonParallel.Aggregate(0, Count, i => Math.Abs(At(i)), Math.Max, 0d); if (double.IsPositiveInfinity(p)) return InfinityNorm();
}
var sum = 0.0;
var sum = 0d;
for (var index = 0; index < Count; index++) for (var index = 0; index < Count; index++)
{ {
sum += Math.Pow(Math.Abs(At(index)), p); sum += Math.Pow(Math.Abs(At(index)), p);
} }
return Math.Pow(sum, 1.0/p);
return Math.Pow(sum, 1.0 / p);
} }
/// <summary> /// <summary>

95
src/Numerics/LinearAlgebra/Single/DenseVector.cs

@ -620,32 +620,68 @@ namespace MathNet.Numerics.LinearAlgebra.Single
/// <returns>The sum of the vector's elements.</returns> /// <returns>The sum of the vector's elements.</returns>
public override float Sum() public override float Sum()
{ {
var sum = 0.0f; var sum = 0f;
for (var i = 0; i < _length; i++) for (var i = 0; i < _length; i++)
{ {
sum += _values[i]; sum += _values[i];
} }
return sum; return sum;
} }
/// <summary> /// <summary>
/// Computes the sum of the absolute value of the vector's elements. /// Calculates the L1 norm of the vector, also known as Manhattan norm.
/// </summary> /// </summary>
/// <returns>The sum of the absolute value of the vector's elements.</returns> /// <returns>The sum of the absolute values.</returns>
public override float SumMagnitudes() public override float L1Norm()
{ {
var sum = 0.0f; var sum = 0f;
for (var i = 0; i < _length; i++) for (var i = 0; i < _length; i++)
{ {
sum += Math.Abs(_values[i]); sum += Math.Abs(_values[i]);
} }
return sum; return sum;
} }
/// <summary>
/// Calculates the L2 norm of the vector, also known as Euclidean norm.
/// </summary>
/// <returns>The square root of the sum of the squared values.</returns>
public override float L2Norm()
{
// TODO: native provider
return _values.Aggregate(0f, SpecialFunctions.Hypotenuse);
}
/// <summary>
/// Calculates the infinity norm of the vector.
/// </summary>
/// <returns>The square root of the sum of the squared values.</returns>
public override float InfinityNorm()
{
return CommonParallel.Aggregate(_values, (i, v) => Math.Abs(v), Math.Max, 0f);
}
/// <summary>
/// Computes the p-Norm.
/// </summary>
/// <param name="p">The p value.</param>
/// <returns>Scalar <c>ret = (sum(abs(this[i])^p))^(1/p)</c></returns>
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);
}
/// <summary> /// <summary>
/// Pointwise divide this vector with another vector and stores the result into the result vector. /// Pointwise divide this vector with another vector and stores the result into the result vector.
/// </summary> /// </summary>
@ -734,47 +770,6 @@ namespace MathNet.Numerics.LinearAlgebra.Single
return OuterProduct(this, v); return OuterProduct(this, v);
} }
#region Vector Norms
/// <summary>
/// Computes the p-Norm.
/// </summary>
/// <param name="p">The p value.</param>
/// <returns>Scalar <c>ret = (sum(abs(this[i])^p))^(1/p)</c></returns>
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 #region Parse Functions
/// <summary> /// <summary>

2
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++) 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) if (norm == 0.0)
{ {
throw new ArgumentException(Resources.ArgumentMatrixNotRankDeficient); throw new ArgumentException(Resources.ArgumentMatrixNotRankDeficient);

2
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)); result.Add((Vector)orthogonalMatrix.Column(i));
// Normalize the result vector // 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; return result;

4
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); var temp2 = new DenseVector(input.Count);
// Initialize // Initialize
var startNorm = input.Norm(2); var startNorm = input.L2Norm();
// Define the scalars // Define the scalars
float alpha = 0; float alpha = 0;
@ -348,7 +348,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
yinternal.Add(temp, d); yinternal.Add(temp, d);
// theta = ||pseudoResiduals||_2 / tau // theta = ||pseudoResiduals||_2 / tau
theta = pseudoResiduals.Norm(2)/tau; theta = pseudoResiduals.L2Norm()/tau;
var c = 1/(float) Math.Sqrt(1 + (theta*theta)); var c = 1/(float) Math.Sqrt(1 + (theta*theta));
// tau = tau * theta * c // tau = tau * theta * c

2
src/Numerics/LinearAlgebra/Single/Solvers/Preconditioners/Ilutp.cs

@ -388,7 +388,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Preconditioners
// pivot the row // pivot the row
PivotRow(workVector); PivotRow(workVector);
var vectorNorm = workVector.Norm(Double.PositiveInfinity); var vectorNorm = workVector.InfinityNorm();
// for j = 1, .. , i - 1) // for j = 1, .. , i - 1)
for (var j = 0; j < i; j++) for (var j = 0; j < i; j++)

2
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 // 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. // 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. // Check if we have NaN's. If so we've gone way beyond normal divergence.
// Stop the iteration. // Stop the iteration.

4
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 // Store the infinity norms of both the solution and residual vectors
var residualNorm = residualVector.Norm(double.PositiveInfinity); var residualNorm = residualVector.InfinityNorm();
var solutionNorm = solutionVector.Norm(double.PositiveInfinity); var solutionNorm = solutionVector.InfinityNorm();
if (float.IsNaN(solutionNorm) || float.IsNaN(residualNorm)) if (float.IsNaN(solutionNorm) || float.IsNaN(residualNorm))
{ {

4
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 // Store the infinity norms of both the solution and residual vectors
// These values will be used to calculate the relative drop in residuals // These values will be used to calculate the relative drop in residuals
// later on. // later on.
var residualNorm = residualVector.Norm(float.PositiveInfinity); var residualNorm = residualVector.InfinityNorm();
// Check the residuals by calculating: // Check the residuals by calculating:
// ||r_i|| <= stop_tol * ||b|| // ||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. // First check that we have real numbers not NaN's.
// NaN's can occur when the iterative process diverges so we // NaN's can occur when the iterative process diverges so we

81
src/Numerics/LinearAlgebra/Single/SparseVector.cs

@ -735,25 +735,58 @@ namespace MathNet.Numerics.LinearAlgebra.Single
{ {
result += _storage.Values[i]; result += _storage.Values[i];
} }
return result; return result;
} }
/// <summary> /// <summary>
/// Computes the sum of the absolute value of the vector's elements. /// Calculates the L1 norm of the vector, also known as Manhattan norm.
/// </summary> /// </summary>
/// <returns>The sum of the absolute value of the vector's elements.</returns> /// <returns>The sum of the absolute values.</returns>
public override float SumMagnitudes() public override float L1Norm()
{ {
var result = 0.0f; var result = 0f;
for (var i = 0; i < _storage.ValueCount; i++) for (var i = 0; i < _storage.ValueCount; i++)
{ {
result += Math.Abs(_storage.Values[i]); result += Math.Abs(_storage.Values[i]);
} }
return result; return result;
} }
/// <summary>
/// Calculates the infinity norm of the vector.
/// </summary>
/// <returns>The square root of the sum of the squared values.</returns>
public override float InfinityNorm()
{
return CommonParallel.Aggregate(0, _storage.ValueCount, i => Math.Abs(_storage.Values[i]), Math.Max, 0f);
}
/// <summary>
/// Computes the p-Norm.
/// </summary>
/// <param name="p">The p value.</param>
/// <returns>Scalar <c>ret = (sum(abs(this[i])^p))^(1/p)</c></returns>
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);
}
/// <summary> /// <summary>
/// Pointwise multiplies this vector with another vector and stores the result into the result vector. /// Pointwise multiplies this vector with another vector and stores the result into the result vector.
/// </summary> /// </summary>
@ -849,42 +882,6 @@ namespace MathNet.Numerics.LinearAlgebra.Single
return OuterProduct(this, v); return OuterProduct(this, v);
} }
/// <summary>
/// Computes the p-Norm.
/// </summary>
/// <param name="p">The p value.</param>
/// <returns>Scalar <c>ret = (sum(abs(this[i])^p))^(1/p)</c></returns>
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 #region Parse Functions
/// <summary> /// <summary>

56
src/Numerics/LinearAlgebra/Single/Vector.cs

@ -211,6 +211,16 @@ namespace MathNet.Numerics.LinearAlgebra.Single
return dot; return dot;
} }
/// <summary>
/// Computes the dot product between the conjugate of this vector and another vector.
/// </summary>
/// <param name="other">The other vector.</param>
/// <returns>The sum of conj(a[i])*b[i] for all i.</returns>
protected override sealed float DoConjugateDotProduct(Vector<float> other)
{
return DoDotProduct(other);
}
/// <summary> /// <summary>
/// Computes the modulus for each element of the vector for the given divisor. /// Computes the modulus for each element of the vector for the given divisor.
/// </summary> /// </summary>
@ -304,31 +314,45 @@ namespace MathNet.Numerics.LinearAlgebra.Single
public override float Sum() public override float Sum()
{ {
var sum = 0.0f; var sum = 0.0f;
for (var i = 0; i < Count; i++) for (var i = 0; i < Count; i++)
{ {
sum += At(i); sum += At(i);
} }
return sum; return sum;
} }
/// <summary> /// <summary>
/// Computes the sum of the absolute value of the vector's elements. /// Calculates the L1 norm of the vector, also known as Manhattan norm.
/// </summary> /// </summary>
/// <returns>The sum of the absolute value of the vector's elements.</returns> /// <returns>The sum of the absolute values.</returns>
public override float SumMagnitudes() public override float L1Norm()
{ {
var sum = 0.0f; var sum = 0.0f;
for (var i = 0; i < Count; i++) for (var i = 0; i < Count; i++)
{ {
sum += Math.Abs(At(i)); sum += Math.Abs(At(i));
} }
return sum; return sum;
} }
/// <summary>
/// Calculates the L2 norm of the vector, also known as Euclidean norm.
/// </summary>
/// <returns>The square root of the sum of the squared values.</returns>
public override float L2Norm()
{
return (float)Math.Sqrt(DoDotProduct(this));
}
/// <summary>
/// Calculates the infinity norm of the vector.
/// </summary>
/// <returns>The square root of the sum of the squared values.</returns>
public override float InfinityNorm()
{
return CommonParallel.Aggregate(0, Count, i => Math.Abs(At(i)), Math.Max, 0f);
}
/// <summary> /// <summary>
/// Computes the p-Norm. /// Computes the p-Norm.
/// </summary> /// </summary>
@ -340,24 +364,18 @@ namespace MathNet.Numerics.LinearAlgebra.Single
/// </returns> /// </returns>
public override float Norm(double p) public override float Norm(double p)
{ {
if (p < 0.0) if (p < 0d) throw new ArgumentOutOfRangeException("p");
{
throw new ArgumentOutOfRangeException("p");
}
if (float.IsPositiveInfinity((float)p)) if (p == 1d) return L1Norm();
{ if (p == 2d) return L2Norm();
return CommonParallel.Aggregate(0, Count, i => Math.Abs(At(i)), Math.Max, 0f); if (double.IsPositiveInfinity(p)) return InfinityNorm();
}
var sum = 0.0;
var sum = 0d;
for (var index = 0; index < Count; index++) for (var index = 0; index < Count; index++)
{ {
sum += Math.Pow(Math.Abs(At(index)), p); sum += Math.Pow(Math.Abs(At(index)), p);
} }
return (float) Math.Pow(sum, 1.0/p);
return (float)Math.Pow(sum, 1.0 / p);
} }
/// <summary> /// <summary>

28
src/Numerics/LinearAlgebra/Vector.Arithmetic.cs

@ -105,10 +105,7 @@ namespace MathNet.Numerics.LinearAlgebra
/// </summary> /// </summary>
/// <param name="other">The other vector.</param> /// <param name="other">The other vector.</param>
/// <returns>The sum of conj(a[i])*b[i] for all i.</returns> /// <returns>The sum of conj(a[i])*b[i] for all i.</returns>
protected virtual T DoConjugateDotProduct(Vector<T> other) protected abstract T DoConjugateDotProduct(Vector<T> other);
{
return DoDotProduct(other);
}
/// <summary> /// <summary>
/// Divides each element of the vector by a scalar and stores the result in the result vector. /// 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); return OuterProduct(this, v);
} }
/// <summary>
/// Calculates the L1 norm of the vector, also known as Manhattan norm.
/// </summary>
/// <returns>The sum of the absolute values.</returns>
public abstract T L1Norm();
/// <summary>
/// Calculates the L2 norm of the vector, also known as Euclidean norm.
/// </summary>
/// <returns>The square root of the sum of the squared values.</returns>
public abstract T L2Norm();
/// <summary>
/// Calculates the infinity norm of the vector.
/// </summary>
/// <returns>The square root of the sum of the squared values.</returns>
public abstract T InfinityNorm();
/// <summary> /// <summary>
/// Computes the p-Norm. /// Computes the p-Norm.
/// </summary> /// </summary>
@ -813,6 +828,9 @@ namespace MathNet.Numerics.LinearAlgebra
/// Computes the sum of the absolute value of the vector's elements. /// Computes the sum of the absolute value of the vector's elements.
/// </summary> /// </summary>
/// <returns>The sum of the absolute value of the vector's elements.</returns> /// <returns>The sum of the absolute value of the vector's elements.</returns>
public abstract T SumMagnitudes(); public T SumMagnitudes()
{
return L1Norm();
}
} }
} }

8
src/Numerics/RootFinding/Broyden.cs

@ -71,7 +71,7 @@ namespace MathNet.Numerics.RootFinding
double[] y0 = f(initialGuess); double[] y0 = f(initialGuess);
var y = new DenseVector(y0); var y = new DenseVector(y0);
double g = y.Norm(2); double g = y.L2Norm();
Matrix<double> B = CalculateApproximateJacobian(f, initialGuess, y0); Matrix<double> B = CalculateApproximateJacobian(f, initialGuess, y0);
@ -80,7 +80,7 @@ namespace MathNet.Numerics.RootFinding
var dx = (DenseVector) (-B.LU().Solve(y)); var dx = (DenseVector) (-B.LU().Solve(y));
var xnew = x + dx; var xnew = x + dx;
var ynew = new DenseVector(f(xnew.Values)); var ynew = new DenseVector(f(xnew.Values));
double gnew = ynew.Norm(2); double gnew = ynew.L2Norm();
if (gnew > g) if (gnew > g)
{ {
@ -90,7 +90,7 @@ namespace MathNet.Numerics.RootFinding
dx = scale*dx; dx = scale*dx;
xnew = x + dx; xnew = x + dx;
ynew = new DenseVector(f(xnew.Values)); ynew = new DenseVector(f(xnew.Values));
gnew = ynew.Norm(2); gnew = ynew.L2Norm();
} }
if (gnew < accuracy) if (gnew < accuracy)
@ -101,7 +101,7 @@ namespace MathNet.Numerics.RootFinding
// update Jacobian B // update Jacobian B
DenseVector dF = ynew - y; DenseVector dF = ynew - y;
Matrix<double> dB = (dF - B.Multiply(dx)).ToColumnMatrix()*dx.Multiply(1.0/Math.Pow(dx.Norm(2), 2)).ToRowMatrix(); Matrix<double> dB = (dF - B.Multiply(dx)).ToColumnMatrix() * dx.Multiply(1.0 / Math.Pow(dx.L2Norm(), 2)).ToRowMatrix();
B = B + dB; B = B + dB;
x = xnew; x = xnew;

4
src/UnitTests/LinearAlgebraTests/Complex/VectorTests.Norm.cs

@ -42,6 +42,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex
public void CanComputeNorm() public void CanComputeNorm()
{ {
var vector = CreateVector(Data); var vector = CreateVector(Data);
AssertHelpers.AlmostEqual(7.74596669241483, vector.L2Norm(), 15);
AssertHelpers.AlmostEqual(7.74596669241483, vector.Norm(2), 15); AssertHelpers.AlmostEqual(7.74596669241483, vector.Norm(2), 15);
} }
@ -52,6 +53,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex
public void CanComputeNorm1() public void CanComputeNorm1()
{ {
var vector = CreateVector(Data); var vector = CreateVector(Data);
AssertHelpers.AlmostEqual(16.0346843392517, vector.L1Norm(), 15);
AssertHelpers.AlmostEqual(16.0346843392517, vector.Norm(1), 15); AssertHelpers.AlmostEqual(16.0346843392517, vector.Norm(1), 15);
} }
@ -62,6 +64,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex
public void CanComputeSquareNorm() public void CanComputeSquareNorm()
{ {
var vector = CreateVector(Data); var vector = CreateVector(Data);
AssertHelpers.AlmostEqual(60.0, vector.L2Norm() * vector.L2Norm(), 15);
AssertHelpers.AlmostEqual(60.0, vector.Norm(2) * vector.Norm(2), 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() public void CanComputeNormInfinity()
{ {
var vector = CreateVector(Data); var vector = CreateVector(Data);
AssertHelpers.AlmostEqual(5.09901951359279, vector.InfinityNorm(), 14);
AssertHelpers.AlmostEqual(5.09901951359279, vector.Norm(Double.PositiveInfinity), 14); AssertHelpers.AlmostEqual(5.09901951359279, vector.Norm(Double.PositiveInfinity), 14);
} }

10
src/UnitTests/LinearAlgebraTests/Complex32/VectorTests.Norm.cs

@ -42,7 +42,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32
public void CanComputeNorm() public void CanComputeNorm()
{ {
var vector = CreateVector(Data); 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);
} }
/// <summary> /// <summary>
@ -52,7 +53,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32
public void CanComputeNorm1() public void CanComputeNorm1()
{ {
var vector = CreateVector(Data); 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);
} }
/// <summary> /// <summary>
@ -62,7 +64,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32
public void CanComputeSquareNorm() public void CanComputeSquareNorm()
{ {
var vector = CreateVector(Data); 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);
} }
/// <summary> /// <summary>
@ -87,6 +90,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32
public void CanComputeNormInfinity() public void CanComputeNormInfinity()
{ {
var vector = CreateVector(Data); var vector = CreateVector(Data);
AssertHelpers.AlmostEqual(5.0990195, vector.InfinityNorm().Real, 7);
AssertHelpers.AlmostEqual(5.0990195, vector.Norm(Single.PositiveInfinity).Real, 7); AssertHelpers.AlmostEqual(5.0990195, vector.Norm(Single.PositiveInfinity).Real, 7);
} }

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

@ -41,6 +41,7 @@ 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.L2Norm(), 15);
AssertHelpers.AlmostEqual(7.416198487095663, vector.Norm(2), 15); AssertHelpers.AlmostEqual(7.416198487095663, vector.Norm(2), 15);
} }
@ -51,6 +52,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
public void CanComputeNorm1() public void CanComputeNorm1()
{ {
var vector = CreateVector(Data); var vector = CreateVector(Data);
AssertHelpers.AlmostEqual(15.0, vector.L1Norm(), 15);
AssertHelpers.AlmostEqual(15.0, vector.Norm(1), 15); AssertHelpers.AlmostEqual(15.0, vector.Norm(1), 15);
} }
@ -61,6 +63,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
public void CanComputeSquareNorm() public void CanComputeSquareNorm()
{ {
var vector = CreateVector(Data); var vector = CreateVector(Data);
AssertHelpers.AlmostEqual(55.0, vector.L2Norm() * vector.L2Norm(), 15);
AssertHelpers.AlmostEqual(55.0, vector.Norm(2) * vector.Norm(2), 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() public void CanComputeNormInfinity()
{ {
var vector = CreateVector(Data); var vector = CreateVector(Data);
AssertHelpers.AlmostEqual(5.0, vector.InfinityNorm(), 15);
AssertHelpers.AlmostEqual(5.0, vector.Norm(Double.PositiveInfinity), 15); AssertHelpers.AlmostEqual(5.0, vector.Norm(Double.PositiveInfinity), 15);
} }

4
src/UnitTests/LinearAlgebraTests/Single/VectorTests.Norm.cs

@ -41,6 +41,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single
public void CanComputeNorm() public void CanComputeNorm()
{ {
var vector = CreateVector(Data); var vector = CreateVector(Data);
AssertHelpers.AlmostEqual(7.416198487095663f, vector.L2Norm(), 6);
AssertHelpers.AlmostEqual(7.416198487095663f, vector.Norm(2), 6); AssertHelpers.AlmostEqual(7.416198487095663f, vector.Norm(2), 6);
} }
@ -51,6 +52,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single
public void CanComputeNorm1() public void CanComputeNorm1()
{ {
var vector = CreateVector(Data); var vector = CreateVector(Data);
AssertHelpers.AlmostEqual(15.0f, vector.L1Norm(), 7);
AssertHelpers.AlmostEqual(15.0f, vector.Norm(1), 7); AssertHelpers.AlmostEqual(15.0f, vector.Norm(1), 7);
} }
@ -61,6 +63,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single
public void CanComputeSquareNorm() public void CanComputeSquareNorm()
{ {
var vector = CreateVector(Data); var vector = CreateVector(Data);
AssertHelpers.AlmostEqual(55.0f, vector.L2Norm() * vector.L2Norm(), 6);
AssertHelpers.AlmostEqual(55.0f, vector.Norm(2) * vector.Norm(2), 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() public void CanComputeNormInfinity()
{ {
var vector = CreateVector(Data); var vector = CreateVector(Data);
AssertHelpers.AlmostEqual(5.0f, vector.InfinityNorm(), 7);
AssertHelpers.AlmostEqual(5.0f, vector.Norm(Single.PositiveInfinity), 7); AssertHelpers.AlmostEqual(5.0f, vector.Norm(Single.PositiveInfinity), 7);
} }

Loading…
Cancel
Save