Browse Source

Providers: double-valued matrix norms

pull/163/merge
Christoph Ruegg 13 years ago
parent
commit
778b8151a5
  1. 6
      src/Numerics/LinearAlgebra/Complex/DenseMatrix.cs
  2. 6
      src/Numerics/LinearAlgebra/Complex32/DenseMatrix.cs
  3. 4
      src/Numerics/Providers/LinearAlgebra/ILinearAlgebraProvider.cs
  4. 38
      src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Complex.cs
  5. 49
      src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Complex32.cs
  6. 34
      src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Double.cs
  7. 42
      src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Single.cs
  8. 12
      src/Numerics/Providers/LinearAlgebra/Mkl/MklLinearAlgebraProvider.cs
  9. 4
      src/UnitTests/LinearAlgebraProviderTests/Complex/LinearAlgebraProviderTests.cs
  10. 4
      src/UnitTests/LinearAlgebraProviderTests/Complex32/LinearAlgebraProviderTests.cs
  11. 6
      src/UnitTests/LinearAlgebraTests/Complex32/MatrixTests.cs
  12. 12
      src/UnitTests/LinearAlgebraTests/Single/MatrixTests.cs

6
src/Numerics/LinearAlgebra/Complex/DenseMatrix.cs

@ -430,21 +430,21 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
/// <returns>The L1 norm of the matrix.</returns>
public override double L1Norm()
{
return Control.LinearAlgebraProvider.MatrixNorm(Norm.OneNorm, _rowCount, _columnCount, _values).Real;
return Control.LinearAlgebraProvider.MatrixNorm(Norm.OneNorm, _rowCount, _columnCount, _values);
}
/// <summary>Calculates the infinity norm of this matrix.</summary>
/// <returns>The infinity norm of this matrix.</returns>
public override double InfinityNorm()
{
return Control.LinearAlgebraProvider.MatrixNorm(Norm.InfinityNorm, _rowCount, _columnCount, _values).Real;
return Control.LinearAlgebraProvider.MatrixNorm(Norm.InfinityNorm, _rowCount, _columnCount, _values);
}
/// <summary>Calculates the Frobenius norm of this matrix.</summary>
/// <returns>The Frobenius norm of this matrix.</returns>
public override double FrobeniusNorm()
{
return Control.LinearAlgebraProvider.MatrixNorm(Norm.FrobeniusNorm, _rowCount, _columnCount, _values).Real;
return Control.LinearAlgebraProvider.MatrixNorm(Norm.FrobeniusNorm, _rowCount, _columnCount, _values);
}
/// <summary>

6
src/Numerics/LinearAlgebra/Complex32/DenseMatrix.cs

@ -425,21 +425,21 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
/// <returns>The L1 norm of the matrix.</returns>
public override double L1Norm()
{
return Control.LinearAlgebraProvider.MatrixNorm(Norm.OneNorm, _rowCount, _columnCount, _values).Real;
return Control.LinearAlgebraProvider.MatrixNorm(Norm.OneNorm, _rowCount, _columnCount, _values);
}
/// <summary>Calculates the infinity norm of this matrix.</summary>
/// <returns>The infinity norm of this matrix.</returns>
public override double InfinityNorm()
{
return Control.LinearAlgebraProvider.MatrixNorm(Norm.InfinityNorm, _rowCount, _columnCount, _values).Real;
return Control.LinearAlgebraProvider.MatrixNorm(Norm.InfinityNorm, _rowCount, _columnCount, _values);
}
/// <summary>Calculates the Frobenius norm of this matrix.</summary>
/// <returns>The Frobenius norm of this matrix.</returns>
public override double FrobeniusNorm()
{
return Control.LinearAlgebraProvider.MatrixNorm(Norm.FrobeniusNorm, _rowCount, _columnCount, _values).Real;
return Control.LinearAlgebraProvider.MatrixNorm(Norm.FrobeniusNorm, _rowCount, _columnCount, _values);
}
/// <summary>

4
src/Numerics/Providers/LinearAlgebra/ILinearAlgebraProvider.cs

@ -201,7 +201,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <returns>
/// The requested <see cref="Norm"/> of the matrix.
/// </returns>
T MatrixNorm(Norm norm, int rows, int columns, T[] matrix);
double MatrixNorm(Norm norm, int rows, int columns, T[] matrix);
/// <summary>
/// Computes the requested <see cref="Norm"/> of the matrix.
@ -215,7 +215,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <returns>
/// The requested <see cref="Norm"/> of the matrix.
/// </returns>
T MatrixNorm(Norm norm, int rows, int columns, T[] matrix, TNorm[] work);
double MatrixNorm(Norm norm, int rows, int columns, T[] matrix, TNorm[] work);
/// <summary>
/// Multiples two matrices. <c>result = x * y</c>

38
src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Complex.cs

@ -413,12 +413,12 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <returns>
/// The requested <see cref="Norm"/> of the matrix.
/// </returns>
public virtual Complex MatrixNorm(Norm norm, int rows, int columns, Complex[] matrix)
public virtual double MatrixNorm(Norm norm, int rows, int columns, Complex[] matrix)
{
var ret = 0.0;
switch (norm)
{
case Norm.OneNorm:
var norm1 = 0d;
for (var j = 0; j < columns; j++)
{
var s = 0.0;
@ -426,23 +426,21 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
{
s += matrix[(j*rows) + i].Magnitude;
}
ret = Math.Max(ret, s);
norm1 = Math.Max(norm1, s);
}
break;
return norm1;
case Norm.LargestAbsoluteValue:
var normMax = 0d;
for (var i = 0; i < rows; i++)
{
for (var j = 0; j < columns; j++)
{
ret = Math.Max(matrix[(j*rows) + i].Magnitude, ret);
normMax = Math.Max(matrix[(j * rows) + i].Magnitude, normMax);
}
}
break;
return normMax;
case Norm.InfinityNorm:
var normInf = 0d;
for (var i = 0; i < rows; i++)
{
var s = 0.0;
@ -450,25 +448,21 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
{
s += matrix[(j*rows) + i].Magnitude;
}
ret = Math.Max(ret, s);
normInf = Math.Max(normInf, s);
}
break;
return normInf;
case Norm.FrobeniusNorm:
var aat = new Complex[rows*rows];
MatrixMultiplyWithUpdate(Transpose.DontTranspose, Transpose.ConjugateTranspose, 1.0, matrix, rows, columns, matrix, rows, columns, 0.0, aat);
var normF = 0d;
for (var i = 0; i < rows; i++)
{
ret += aat[(i*rows) + i].Magnitude;
normF += aat[(i * rows) + i].Magnitude;
}
ret = Math.Sqrt(ret);
break;
return Math.Sqrt(normF);
default:
throw new NotSupportedException();
}
return ret;
}
/// <summary>
@ -483,7 +477,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <returns>
/// The requested <see cref="Norm"/> of the matrix.
/// </returns>
public virtual Complex MatrixNorm(Norm norm, int rows, int columns, Complex[] matrix, double[] work)
public virtual double MatrixNorm(Norm norm, int rows, int columns, Complex[] matrix, double[] work)
{
return MatrixNorm(norm, rows, columns, matrix);
}

49
src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Complex32.cs

@ -408,65 +408,58 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="rows">The number of rows.</param>
/// <param name="columns">The number of columns.</param>
/// <param name="matrix">The matrix to compute the norm from.</param>
/// <returns>
/// The requested <see cref="Norm"/> of the matrix.
/// </returns>
public virtual Complex32 MatrixNorm(Norm norm, int rows, int columns, Complex32[] matrix)
/// <returns>The requested <see cref="Norm"/> of the matrix.</returns>
public virtual double MatrixNorm(Norm norm, int rows, int columns, Complex32[] matrix)
{
var ret = 0.0;
switch (norm)
{
case Norm.OneNorm:
var norm1 = 0d;
for (var j = 0; j < columns; j++)
{
var s = 0.0;
var s = 0d;
for (var i = 0; i < rows; i++)
{
s += matrix[(j*rows) + i].Magnitude;
}
ret = Math.Max(ret, s);
norm1 = Math.Max(norm1, s);
}
break;
return norm1;
case Norm.LargestAbsoluteValue:
var normMax = 0d;
for (var i = 0; i < rows; i++)
{
for (var j = 0; j < columns; j++)
{
ret = Math.Max(matrix[(j*rows) + i].Magnitude, ret);
normMax = Math.Max(matrix[(j * rows) + i].Magnitude, normMax);
}
}
break;
return normMax;
case Norm.InfinityNorm:
var normInf = 0d;
for (var i = 0; i < rows; i++)
{
var s = 0.0;
var s = 0d;
for (var j = 0; j < columns; j++)
{
s += matrix[(j*rows) + i].Magnitude;
}
ret = Math.Max(ret, s);
normInf = Math.Max(normInf, s);
}
break;
return normInf;
case Norm.FrobeniusNorm:
var aat = new Complex32[rows*rows];
MatrixMultiplyWithUpdate(Transpose.DontTranspose, Transpose.ConjugateTranspose, 1.0f, matrix, rows, columns, matrix, rows, columns, 0.0f, aat);
var normF = 0d;
for (var i = 0; i < rows; i++)
{
ret += aat[(i*rows) + i].Magnitude;
normF += aat[(i * rows) + i].Magnitude;
}
ret = Math.Sqrt(ret);
break;
return Math.Sqrt(normF);
default:
throw new NotSupportedException();
}
return Convert.ToSingle(ret);
}
/// <summary>
@ -478,10 +471,8 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="matrix">The matrix to compute the norm from.</param>
/// <param name="work">The work array. Only used when <see cref="Norm.InfinityNorm"/>
/// and needs to be have a length of at least M (number of rows of <paramref name="matrix"/>.</param>
/// <returns>
/// The requested <see cref="Norm"/> of the matrix.
/// </returns>
public virtual Complex32 MatrixNorm(Norm norm, int rows, int columns, Complex32[] matrix, float[] work)
/// <returns>The requested <see cref="Norm"/> of the matrix.</returns>
public virtual double MatrixNorm(Norm norm, int rows, int columns, Complex32[] matrix, float[] work)
{
return MatrixNorm(norm, rows, columns, matrix);
}

34
src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Double.cs

@ -410,10 +410,10 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// </returns>
public virtual double MatrixNorm(Norm norm, int rows, int columns, double[] matrix)
{
var ret = 0.0;
switch (norm)
{
case Norm.OneNorm:
var norm1 = 0d;
for (var j = 0; j < columns; j++)
{
var s = 0.0;
@ -421,23 +421,21 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
{
s += Math.Abs(matrix[(j*rows) + i]);
}
ret = Math.Max(ret, s);
norm1 = Math.Max(norm1, s);
}
break;
return norm1;
case Norm.LargestAbsoluteValue:
var normMax = 0d;
for (var i = 0; i < rows; i++)
{
for (var j = 0; j < columns; j++)
{
ret = Math.Max(Math.Abs(matrix[(j*rows) + i]), ret);
normMax = Math.Max(Math.Abs(matrix[(j * rows) + i]), normMax);
}
}
break;
return normMax;
case Norm.InfinityNorm:
var normInf = 0d;
for (var i = 0; i < rows; i++)
{
var s = 0.0;
@ -445,25 +443,21 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
{
s += Math.Abs(matrix[(j*rows) + i]);
}
ret = Math.Max(ret, s);
normInf = Math.Max(normInf, s);
}
break;
return normInf;
case Norm.FrobeniusNorm:
var aat = new double[rows*rows];
MatrixMultiplyWithUpdate(Transpose.DontTranspose, Transpose.Transpose, 1.0, matrix, rows, columns, matrix, rows, columns, 0.0, aat);
var normF = 0d;
for (var i = 0; i < rows; i++)
{
ret += Math.Abs(aat[(i*rows) + i]);
normF += Math.Abs(aat[(i * rows) + i]);
}
ret = Math.Sqrt(ret);
break;
return Math.Sqrt(normF);
default:
throw new NotSupportedException();
}
return ret;
}
/// <summary>

42
src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Single.cs

@ -408,62 +408,56 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <returns>
/// The requested <see cref="Norm"/> of the matrix.
/// </returns>
public virtual float MatrixNorm(Norm norm, int rows, int columns, float[] matrix)
public virtual double MatrixNorm(Norm norm, int rows, int columns, float[] matrix)
{
var ret = 0.0;
switch (norm)
{
case Norm.OneNorm:
var norm1 = 0d;
for (var j = 0; j < columns; j++)
{
var s = 0.0;
var s = 0d;
for (var i = 0; i < rows; i++)
{
s += Math.Abs(matrix[(j*rows) + i]);
}
ret = Math.Max(ret, s);
norm1 = Math.Max(norm1, s);
}
break;
return norm1;
case Norm.LargestAbsoluteValue:
var normMax = 0d;
for (var i = 0; i < rows; i++)
{
for (var j = 0; j < columns; j++)
{
ret = Math.Max(Math.Abs(matrix[(j*rows) + i]), ret);
normMax = Math.Max(Math.Abs(matrix[(j * rows) + i]), normMax);
}
}
break;
return normMax;
case Norm.InfinityNorm:
var normInf = 0d;
for (var i = 0; i < rows; i++)
{
var s = 0.0;
var s = 0d;
for (var j = 0; j < columns; j++)
{
s += Math.Abs(matrix[(j*rows) + i]);
}
ret = Math.Max(ret, s);
normInf = Math.Max(normInf, s);
}
break;
return normInf;
case Norm.FrobeniusNorm:
var aat = new float[rows*rows];
MatrixMultiplyWithUpdate(Transpose.DontTranspose, Transpose.Transpose, 1.0f, matrix, rows, columns, matrix, rows, columns, 0.0f, aat);
var normF = 0d;
for (var i = 0; i < rows; i++)
{
ret += Math.Abs(aat[(i*rows) + i]);
normF += Math.Abs(aat[(i * rows) + i]);
}
ret = Math.Sqrt(ret);
break;
return Math.Sqrt(normF);
default:
throw new NotSupportedException();
}
return Convert.ToSingle(ret);
}
/// <summary>
@ -478,7 +472,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <returns>
/// The requested <see cref="Norm"/> of the matrix.
/// </returns>
public virtual float MatrixNorm(Norm norm, int rows, int columns, float[] matrix, float[] work)
public virtual double MatrixNorm(Norm norm, int rows, int columns, float[] matrix, float[] work)
{
return MatrixNorm(norm, rows, columns, matrix);
}

12
src/Numerics/Providers/LinearAlgebra/Mkl/MklLinearAlgebraProvider.cs

@ -53,7 +53,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.Mkl
/// The requested <see cref="Norm"/> of the matrix.
/// </returns>
[SecuritySafeCritical]
public override float MatrixNorm(Norm norm, int rows, int columns, float[] matrix)
public override double MatrixNorm(Norm norm, int rows, int columns, float[] matrix)
{
if (matrix == null)
{
@ -92,7 +92,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.Mkl
/// The requested <see cref="Norm"/> of the matrix.
/// </returns>
[SecuritySafeCritical]
public override float MatrixNorm(Norm norm, int rows, int columns, float[] matrix, float[] work)
public override double MatrixNorm(Norm norm, int rows, int columns, float[] matrix, float[] work)
{
if (matrix == null)
{
@ -213,7 +213,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.Mkl
/// The requested <see cref="Norm"/> of the matrix.
/// </returns>
[SecuritySafeCritical]
public override Complex32 MatrixNorm(Norm norm, int rows, int columns, Complex32[] matrix)
public override double MatrixNorm(Norm norm, int rows, int columns, Complex32[] matrix)
{
if (matrix == null)
{
@ -252,7 +252,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.Mkl
/// The requested <see cref="Norm"/> of the matrix.
/// </returns>
[SecuritySafeCritical]
public override Complex32 MatrixNorm(Norm norm, int rows, int columns, Complex32[] matrix, float[] work)
public override double MatrixNorm(Norm norm, int rows, int columns, Complex32[] matrix, float[] work)
{
if (matrix == null)
{
@ -293,7 +293,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.Mkl
/// The requested <see cref="Norm"/> of the matrix.
/// </returns>
[SecuritySafeCritical]
public override Complex MatrixNorm(Norm norm, int rows, int columns, Complex[] matrix)
public override double MatrixNorm(Norm norm, int rows, int columns, Complex[] matrix)
{
if (matrix == null)
{
@ -332,7 +332,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.Mkl
/// The requested <see cref="Norm"/> of the matrix.
/// </returns>
[SecuritySafeCritical]
public override Complex MatrixNorm(Norm norm, int rows, int columns, Complex[] matrix, double[] work)
public override double MatrixNorm(Norm norm, int rows, int columns, Complex[] matrix, double[] work)
{
if (matrix == null)
{

4
src/UnitTests/LinearAlgebraProviderTests/Complex/LinearAlgebraProviderTests.cs

@ -229,7 +229,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraProviderTests.Complex
var matrix = _matrices["Square3x3"];
var work = new double[matrix.RowCount];
var norm = Control.LinearAlgebraProvider.MatrixNorm(Norm.InfinityNorm, matrix.RowCount, matrix.ColumnCount, matrix.Values, work);
Assert.AreEqual(16.5, norm.Real);
Assert.AreEqual(16.5, norm);
}
/// <summary>
@ -265,7 +265,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraProviderTests.Complex
var matrix = _matrices["Square3x3"];
var work = new double[18];
var norm = Control.LinearAlgebraProvider.MatrixNorm(Norm.InfinityNorm, matrix.RowCount, matrix.ColumnCount, matrix.Values, work);
Assert.AreEqual(16.5, norm.Real);
Assert.AreEqual(16.5, norm);
}
/// <summary>

4
src/UnitTests/LinearAlgebraProviderTests/Complex32/LinearAlgebraProviderTests.cs

@ -225,7 +225,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraProviderTests.Complex32
var matrix = _matrices["Square3x3"];
var work = new float[matrix.RowCount];
var norm = Control.LinearAlgebraProvider.MatrixNorm(Norm.InfinityNorm, matrix.RowCount, matrix.ColumnCount, matrix.Values, work);
Assert.AreEqual(16.5, norm.Real);
Assert.AreEqual(16.5, norm);
}
/// <summary>
@ -261,7 +261,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraProviderTests.Complex32
var matrix = _matrices["Square3x3"];
var work = new float[18];
var norm = Control.LinearAlgebraProvider.MatrixNorm(Norm.InfinityNorm, matrix.RowCount, matrix.ColumnCount, matrix.Values);
Assert.AreEqual(16.5, norm.Real);
Assert.AreEqual(16.5, norm);
}
/// <summary>

6
src/UnitTests/LinearAlgebraTests/Complex32/MatrixTests.cs

@ -124,13 +124,13 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32
public virtual void CanComputeL1Norm()
{
var matrix = TestMatrices["Square3x3"];
AssertHelpers.AlmostEqualRelative(12.5401248f, matrix.L1Norm(), 7);
AssertHelpers.AlmostEqualRelative(12.5401248f, matrix.L1Norm(), 6);
matrix = TestMatrices["Wide2x3"];
AssertHelpers.AlmostEqualRelative(5.8647971f, matrix.L1Norm(), 7);
AssertHelpers.AlmostEqualRelative(5.8647971f, matrix.L1Norm(), 6);
matrix = TestMatrices["Tall3x2"];
AssertHelpers.AlmostEqualRelative(9.4933860f, matrix.L1Norm(), 7);
AssertHelpers.AlmostEqualRelative(9.4933860f, matrix.L1Norm(), 6);
}
/// <summary>

12
src/UnitTests/LinearAlgebraTests/Single/MatrixTests.cs

@ -66,13 +66,13 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single
public virtual void CanComputeFrobeniusNorm()
{
var matrix = TestMatrices["Square3x3"];
AssertHelpers.AlmostEqualRelative(10.77775486824598f, matrix.FrobeniusNorm(), 7);
AssertHelpers.AlmostEqualRelative(10.77775486824598f, matrix.FrobeniusNorm(), 6);
matrix = TestMatrices["Wide2x3"];
AssertHelpers.AlmostEqualRelative(4.79478883789474f, matrix.FrobeniusNorm(), 7);
AssertHelpers.AlmostEqualRelative(4.79478883789474f, matrix.FrobeniusNorm(), 6);
matrix = TestMatrices["Tall3x2"];
AssertHelpers.AlmostEqualRelative(7.54122006044115f, matrix.FrobeniusNorm(), 7);
AssertHelpers.AlmostEqualRelative(7.54122006044115f, matrix.FrobeniusNorm(), 6);
}
/// <summary>
@ -98,13 +98,13 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single
public virtual void CanComputeL1Norm()
{
var matrix = TestMatrices["Square3x3"];
Assert.AreEqual(12.1f, matrix.L1Norm());
AssertHelpers.AlmostEqualRelative(12.1f, matrix.L1Norm(), 6);
matrix = TestMatrices["Wide2x3"];
Assert.AreEqual(5.5f, matrix.L1Norm());
AssertHelpers.AlmostEqualRelative(5.5f, matrix.L1Norm(), 6);
matrix = TestMatrices["Tall3x2"];
Assert.AreEqual(8.8f, matrix.L1Norm());
AssertHelpers.AlmostEqualRelative(8.8f, matrix.L1Norm(), 6);
}
/// <summary>

Loading…
Cancel
Save