Browse Source

Linear Algebra: Matrix Rank should use effective epsilon #334

Previously it was using the normalized epsilon at 1.0.
See http://discuss.mathdotnet.com/t/wrong-compute-of-the-matrix-rank/120
for discussion.
netstandard
Christoph Ruegg 11 years ago
parent
commit
35f12a62e6
  1. 18
      src/Numerics/LinearAlgebra/Complex/DenseVector.cs
  2. 2
      src/Numerics/LinearAlgebra/Complex/Factorization/Svd.cs
  3. 2
      src/Numerics/LinearAlgebra/Complex/Vector.cs
  4. 18
      src/Numerics/LinearAlgebra/Complex32/DenseVector.cs
  5. 2
      src/Numerics/LinearAlgebra/Complex32/Factorization/Svd.cs
  6. 2
      src/Numerics/LinearAlgebra/Complex32/Vector.cs
  7. 18
      src/Numerics/LinearAlgebra/Double/DenseVector.cs
  8. 2
      src/Numerics/LinearAlgebra/Double/Factorization/Svd.cs
  9. 18
      src/Numerics/LinearAlgebra/Single/DenseVector.cs
  10. 2
      src/Numerics/LinearAlgebra/Single/Factorization/Svd.cs
  11. 14
      src/UnitTests/LinearAlgebraTests/Double/Factorization/SvdTests.cs
  12. 14
      src/UnitTests/LinearAlgebraTests/Single/Factorization/SvdTests.cs

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

@ -519,24 +519,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
return index; return index;
} }
/// <summary>
/// Returns the value of the absolute minimum element.
/// </summary>
/// <returns>The value of the absolute minimum element.</returns>
public override Complex AbsoluteMinimum()
{
return _values[AbsoluteMinimumIndex()].Magnitude;
}
/// <summary>
/// Returns the value of the absolute maximum element.
/// </summary>
/// <returns>The value of the absolute maximum element.</returns>
public override Complex AbsoluteMaximum()
{
return _values[AbsoluteMaximumIndex()].Magnitude;
}
/// <summary> /// <summary>
/// Returns the index of the absolute maximum element. /// Returns the index of the absolute maximum element.
/// </summary> /// </summary>

2
src/Numerics/LinearAlgebra/Complex/Factorization/Svd.cs

@ -71,7 +71,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Factorization
{ {
get get
{ {
double tolerance = Precision.DoublePrecision*Math.Max(U.RowCount, VT.RowCount); double tolerance = Precision.EpsilonOf(S.AbsoluteMaximum().Magnitude)*Math.Max(U.RowCount, VT.RowCount);
return S.Count(t => t.Magnitude > tolerance); return S.Count(t => t.Magnitude > tolerance);
} }
} }

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

@ -323,7 +323,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
/// Returns the value of the absolute minimum element. /// Returns the value of the absolute minimum element.
/// </summary> /// </summary>
/// <returns>The value of the absolute minimum element.</returns> /// <returns>The value of the absolute minimum element.</returns>
public override Complex AbsoluteMinimum() public sealed override Complex AbsoluteMinimum()
{ {
return At(AbsoluteMinimumIndex()).Magnitude; return At(AbsoluteMinimumIndex()).Magnitude;
} }

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

@ -514,24 +514,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
return index; return index;
} }
/// <summary>
/// Returns the value of the absolute minimum element.
/// </summary>
/// <returns>The value of the absolute minimum element.</returns>
public override Complex32 AbsoluteMinimum()
{
return _values[AbsoluteMinimumIndex()].Magnitude;
}
/// <summary>
/// Returns the value of the absolute maximum element.
/// </summary>
/// <returns>The value of the absolute maximum element.</returns>
public override Complex32 AbsoluteMaximum()
{
return _values[AbsoluteMaximumIndex()].Magnitude;
}
/// <summary> /// <summary>
/// Returns the index of the absolute maximum element. /// Returns the index of the absolute maximum element.
/// </summary> /// </summary>

2
src/Numerics/LinearAlgebra/Complex32/Factorization/Svd.cs

@ -66,7 +66,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Factorization
{ {
get get
{ {
double tolerance = Precision.SinglePrecision*Math.Max(U.RowCount, VT.RowCount); double tolerance = Precision.EpsilonOf(S.AbsoluteMaximum().Magnitude)*Math.Max(U.RowCount, VT.RowCount);
return S.Count(t => t.Magnitude > tolerance); return S.Count(t => t.Magnitude > tolerance);
} }
} }

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

@ -318,7 +318,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
/// Returns the value of the absolute minimum element. /// Returns the value of the absolute minimum element.
/// </summary> /// </summary>
/// <returns>The value of the absolute minimum element.</returns> /// <returns>The value of the absolute minimum element.</returns>
public override Complex32 AbsoluteMinimum() public sealed override Complex32 AbsoluteMinimum()
{ {
return At(AbsoluteMinimumIndex()).Magnitude; return At(AbsoluteMinimumIndex()).Magnitude;
} }

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

@ -556,24 +556,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double
return index; return index;
} }
/// <summary>
/// Returns the value of the absolute minimum element.
/// </summary>
/// <returns>The value of the absolute minimum element.</returns>
public override double AbsoluteMinimum()
{
return Math.Abs(_values[AbsoluteMinimumIndex()]);
}
/// <summary>
/// Returns the value of the absolute maximum element.
/// </summary>
/// <returns>The value of the absolute maximum element.</returns>
public override double AbsoluteMaximum()
{
return Math.Abs(_values[AbsoluteMaximumIndex()]);
}
/// <summary> /// <summary>
/// Returns the index of the absolute maximum element. /// Returns the index of the absolute maximum element.
/// </summary> /// </summary>

2
src/Numerics/LinearAlgebra/Double/Factorization/Svd.cs

@ -64,7 +64,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
{ {
get get
{ {
double tolerance = Precision.DoublePrecision*Math.Max(U.RowCount, VT.RowCount); double tolerance = Precision.EpsilonOf(S.Maximum())*Math.Max(U.RowCount, VT.RowCount);
return S.Count(t => Math.Abs(t) > tolerance); return S.Count(t => Math.Abs(t) > tolerance);
} }
} }

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

@ -546,24 +546,6 @@ namespace MathNet.Numerics.LinearAlgebra.Single
return index; return index;
} }
/// <summary>
/// Returns the value of the absolute minimum element.
/// </summary>
/// <returns>The value of the absolute minimum element.</returns>
public override float AbsoluteMinimum()
{
return Math.Abs(_values[AbsoluteMinimumIndex()]);
}
/// <summary>
/// Returns the value of the absolute maximum element.
/// </summary>
/// <returns>The value of the absolute maximum element.</returns>
public override float AbsoluteMaximum()
{
return Math.Abs(_values[AbsoluteMaximumIndex()]);
}
/// <summary> /// <summary>
/// Returns the index of the absolute maximum element. /// Returns the index of the absolute maximum element.
/// </summary> /// </summary>

2
src/Numerics/LinearAlgebra/Single/Factorization/Svd.cs

@ -64,7 +64,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Factorization
{ {
get get
{ {
double tolerance = Precision.SinglePrecision*Math.Max(U.RowCount, VT.RowCount); double tolerance = Precision.EpsilonOf(S.Maximum())*Math.Max(U.RowCount, VT.RowCount);
return S.Count(t => Math.Abs(t) > tolerance); return S.Count(t => Math.Abs(t) > tolerance);
} }
} }

14
src/UnitTests/LinearAlgebraTests/Double/Factorization/SvdTests.cs

@ -180,6 +180,20 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization
Assert.AreEqual(factorSvd.Rank, order - 1); Assert.AreEqual(factorSvd.Rank, order - 1);
} }
[Test]
public void RankAcceptance()
{
// http://discuss.mathdotnet.com/t/wrong-compute-of-the-matrix-rank/120
Matrix<double> m = DenseMatrix.OfArray(new double[,] {
{ 4, 4, 1, 3 },
{ 1,-2, 1, 0 },
{ 4, 0, 2, 2 },
{ 7, 6, 2, 5 } });
Assert.That(m.Svd(true).Rank, Is.EqualTo(2));
Assert.That(m.Svd(false).Rank, Is.EqualTo(2));
}
/// <summary> /// <summary>
/// Solve for matrix if vectors are not computed throws <c>InvalidOperationException</c>. /// Solve for matrix if vectors are not computed throws <c>InvalidOperationException</c>.
/// </summary> /// </summary>

14
src/UnitTests/LinearAlgebraTests/Single/Factorization/SvdTests.cs

@ -180,6 +180,20 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization
Assert.AreEqual(factorSvd.Rank, order - 1); Assert.AreEqual(factorSvd.Rank, order - 1);
} }
[Test]
public void RankAcceptance()
{
// http://discuss.mathdotnet.com/t/wrong-compute-of-the-matrix-rank/120
Matrix<float> m = DenseMatrix.OfArray(new float[,] {
{ 4, 4, 1, 3 },
{ 1,-2, 1, 0 },
{ 4, 0, 2, 2 },
{ 7, 6, 2, 5 } });
Assert.That(m.Svd(true).Rank, Is.EqualTo(2));
Assert.That(m.Svd(false).Rank, Is.EqualTo(2));
}
/// <summary> /// <summary>
/// Solve for matrix if vectors are not computed throws <c>InvalidOperationException</c>. /// Solve for matrix if vectors are not computed throws <c>InvalidOperationException</c>.
/// </summary> /// </summary>

Loading…
Cancel
Save