Browse Source

LA: replace complicated OO iterative solver states with simple enum

optimization-1
Christoph Ruegg 13 years ago
parent
commit
cc8d89dd8b
  1. 14
      src/Numerics/LinearAlgebra/Complex/Solvers/BiCgStab.cs
  2. 17
      src/Numerics/LinearAlgebra/Complex/Solvers/CompositeSolver.cs
  3. 14
      src/Numerics/LinearAlgebra/Complex/Solvers/GpBiCg.cs
  4. 14
      src/Numerics/LinearAlgebra/Complex/Solvers/MlkBiCgStab.cs
  5. 72
      src/Numerics/LinearAlgebra/Complex/Solvers/StopCriterium/DivergenceStopCriterium.cs
  6. 63
      src/Numerics/LinearAlgebra/Complex/Solvers/StopCriterium/FailureStopCriterium.cs
  7. 95
      src/Numerics/LinearAlgebra/Complex/Solvers/StopCriterium/ResidualStopCriterium.cs
  8. 14
      src/Numerics/LinearAlgebra/Complex/Solvers/TFQMR.cs
  9. 14
      src/Numerics/LinearAlgebra/Complex32/Solvers/BiCgStab.cs
  10. 17
      src/Numerics/LinearAlgebra/Complex32/Solvers/CompositeSolver.cs
  11. 14
      src/Numerics/LinearAlgebra/Complex32/Solvers/GpBiCg.cs
  12. 14
      src/Numerics/LinearAlgebra/Complex32/Solvers/MlkBiCgStab.cs
  13. 72
      src/Numerics/LinearAlgebra/Complex32/Solvers/StopCriterium/DivergenceStopCriterium.cs
  14. 63
      src/Numerics/LinearAlgebra/Complex32/Solvers/StopCriterium/FailureStopCriterium.cs
  15. 91
      src/Numerics/LinearAlgebra/Complex32/Solvers/StopCriterium/ResidualStopCriterium.cs
  16. 14
      src/Numerics/LinearAlgebra/Complex32/Solvers/TFQMR.cs
  17. 14
      src/Numerics/LinearAlgebra/Double/Solvers/BiCgStab.cs
  18. 17
      src/Numerics/LinearAlgebra/Double/Solvers/CompositeSolver.cs
  19. 14
      src/Numerics/LinearAlgebra/Double/Solvers/GpBiCg.cs
  20. 14
      src/Numerics/LinearAlgebra/Double/Solvers/MlkBiCgStab.cs
  21. 52
      src/Numerics/LinearAlgebra/Double/Solvers/StopCriterium/DivergenceStopCriterium.cs
  22. 63
      src/Numerics/LinearAlgebra/Double/Solvers/StopCriterium/FailureStopCriterium.cs
  23. 95
      src/Numerics/LinearAlgebra/Double/Solvers/StopCriterium/ResidualStopCriterium.cs
  24. 14
      src/Numerics/LinearAlgebra/Double/Solvers/TFQMR.cs
  25. 14
      src/Numerics/LinearAlgebra/Single/Solvers/BiCgStab.cs
  26. 17
      src/Numerics/LinearAlgebra/Single/Solvers/CompositeSolver.cs
  27. 14
      src/Numerics/LinearAlgebra/Single/Solvers/GpBiCg.cs
  28. 14
      src/Numerics/LinearAlgebra/Single/Solvers/MlkBiCgStab.cs
  29. 52
      src/Numerics/LinearAlgebra/Single/Solvers/StopCriterium/DivergenceStopCriterium.cs
  30. 59
      src/Numerics/LinearAlgebra/Single/Solvers/StopCriterium/FailureStopCriterium.cs
  31. 95
      src/Numerics/LinearAlgebra/Single/Solvers/StopCriterium/ResidualStopCriterium.cs
  32. 14
      src/Numerics/LinearAlgebra/Single/Solvers/TFQMR.cs
  33. 4
      src/Numerics/LinearAlgebra/Solvers/IIterationStopCriterium.cs
  34. 2
      src/Numerics/LinearAlgebra/Solvers/IIterativeSolver.cs
  35. 56
      src/Numerics/LinearAlgebra/Solvers/IterationCountStopCriterium.cs
  36. 17
      src/Numerics/LinearAlgebra/Solvers/IterationStatus.cs
  37. 26
      src/Numerics/LinearAlgebra/Solvers/Iterator.cs
  38. 49
      src/Numerics/LinearAlgebra/Solvers/Status/CalculationCancelled.cs
  39. 51
      src/Numerics/LinearAlgebra/Solvers/Status/CalculationConverged.cs
  40. 51
      src/Numerics/LinearAlgebra/Solvers/Status/CalculationDiverged.cs
  41. 51
      src/Numerics/LinearAlgebra/Solvers/Status/CalculationFailure.cs
  42. 49
      src/Numerics/LinearAlgebra/Solvers/Status/CalculationIndetermined.cs
  43. 51
      src/Numerics/LinearAlgebra/Solvers/Status/CalculationRunning.cs
  44. 52
      src/Numerics/LinearAlgebra/Solvers/Status/CalculationStoppedWithoutConvergence.cs
  45. 9
      src/Numerics/Numerics.csproj
  46. 81
      src/UnitTests/LinearAlgebraTests/Complex/Solvers/IteratorTest.cs
  47. 34
      src/UnitTests/LinearAlgebraTests/Complex/Solvers/StopCriterium/DivergenceStopCriteriumTest.cs
  48. 36
      src/UnitTests/LinearAlgebraTests/Complex/Solvers/StopCriterium/FailureStopCriteriumTest.cs
  49. 9
      src/UnitTests/LinearAlgebraTests/Complex/Solvers/StopCriterium/IterationCountStopCriteriumTest.cs
  50. 66
      src/UnitTests/LinearAlgebraTests/Complex/Solvers/StopCriterium/ResidualStopCriteriumTest.cs
  51. 81
      src/UnitTests/LinearAlgebraTests/Complex32/Solvers/IteratorTest.cs
  52. 34
      src/UnitTests/LinearAlgebraTests/Complex32/Solvers/StopCriterium/DivergenceStopCriteriumTest.cs
  53. 38
      src/UnitTests/LinearAlgebraTests/Complex32/Solvers/StopCriterium/FailureStopCriteriumTest.cs
  54. 9
      src/UnitTests/LinearAlgebraTests/Complex32/Solvers/StopCriterium/IterationCountStopCriteriumTest.cs
  55. 66
      src/UnitTests/LinearAlgebraTests/Complex32/Solvers/StopCriterium/ResidualStopCriteriumTest.cs
  56. 81
      src/UnitTests/LinearAlgebraTests/Double/Solvers/IteratorTest.cs
  57. 34
      src/UnitTests/LinearAlgebraTests/Double/Solvers/StopCriterium/DivergenceStopCriteriumTest.cs
  58. 36
      src/UnitTests/LinearAlgebraTests/Double/Solvers/StopCriterium/FailureStopCriteriumTest.cs
  59. 9
      src/UnitTests/LinearAlgebraTests/Double/Solvers/StopCriterium/IterationCountStopCriteriumTest.cs
  60. 66
      src/UnitTests/LinearAlgebraTests/Double/Solvers/StopCriterium/ResidualStopCriteriumTest.cs
  61. 81
      src/UnitTests/LinearAlgebraTests/Single/Solvers/IteratorTest.cs
  62. 34
      src/UnitTests/LinearAlgebraTests/Single/Solvers/StopCriterium/DivergenceStopCriteriumTest.cs
  63. 36
      src/UnitTests/LinearAlgebraTests/Single/Solvers/StopCriterium/FailureStopCriteriumTest.cs
  64. 9
      src/UnitTests/LinearAlgebraTests/Single/Solvers/StopCriterium/IterationCountStopCriteriumTest.cs
  65. 66
      src/UnitTests/LinearAlgebraTests/Single/Solvers/StopCriterium/ResidualStopCriteriumTest.cs

14
src/Numerics/LinearAlgebra/Complex/Solvers/BiCgStab.cs

@ -30,7 +30,6 @@
using System;
using MathNet.Numerics.LinearAlgebra.Solvers;
using MathNet.Numerics.LinearAlgebra.Solvers.Status;
using MathNet.Numerics.Properties;
namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
@ -73,12 +72,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
/// </remarks>
public sealed class BiCgStab : IIterativeSolver<Complex>
{
/// <summary>
/// The status used if there is no status, i.e. the solver hasn't run yet and there is no
/// iterator.
/// </summary>
static readonly ICalculationStatus DefaultStatus = new CalculationIndetermined();
/// <summary>
/// The preconditioner that will be used. Can be set to <see langword="null" />, in which case the default
/// pre-conditioner will be used.
@ -188,9 +181,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
/// <summary>
/// Gets the status of the iteration once the calculation is finished.
/// </summary>
public ICalculationStatus IterationResult
public IterationStatus IterationResult
{
get { return (_iterator != null) ? _iterator.Status : DefaultStatus; }
get { return (_iterator != null) ? _iterator.Status : IterationStatus.Indetermined; }
}
/// <summary>
@ -470,7 +463,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
return true;
}
return !_iterator.DetermineStatus(iterationNumber, result, source, residuals).TerminatesCalculation;
var status = _iterator.DetermineStatus(iterationNumber, result, source, residuals);
return status == IterationStatus.Running || status == IterationStatus.Indetermined;
}
/// <summary>

17
src/Numerics/LinearAlgebra/Complex/Solvers/CompositeSolver.cs

@ -34,7 +34,6 @@ using System.IO;
using System.Linq;
using System.Reflection;
using MathNet.Numerics.LinearAlgebra.Solvers;
using MathNet.Numerics.LinearAlgebra.Solvers.Status;
using MathNet.Numerics.Properties;
namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
@ -94,16 +93,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
#endregion
/// <summary>
/// The default status used if the solver is not running.
/// </summary>
static readonly ICalculationStatus NonRunningStatus = new CalculationIndetermined();
/// <summary>
/// The default status used if the solver is running.
/// </summary>
static readonly ICalculationStatus RunningStatus = new CalculationRunning();
#if PORTABLE
private static readonly Dictionary<double, List<IIterativeSolverSetup<Complex>>> SolverSetups = new Dictionary<double, List<IIterativeSolverSetup<Complex>>>();
#else
@ -348,7 +337,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
/// <summary>
/// The status of the calculation.
/// </summary>
ICalculationStatus _status = NonRunningStatus;
IterationStatus _status = IterationStatus.Indetermined;
/// <summary>
/// The iterator that is used to control the iteration process.
@ -394,7 +383,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
/// <summary>
/// Gets the status of the iteration once the calculation is finished.
/// </summary>
public ICalculationStatus IterationResult
public IterationStatus IterationResult
{
get
{
@ -517,7 +506,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
// Switch to the next preconditioner.
// Reset the solution vector to the previous solution
input.CopyTo(internalInput);
_status = RunningStatus;
_status = IterationStatus.Running;
continue;
}

14
src/Numerics/LinearAlgebra/Complex/Solvers/GpBiCg.cs

@ -30,7 +30,6 @@
using System;
using MathNet.Numerics.LinearAlgebra.Solvers;
using MathNet.Numerics.LinearAlgebra.Solvers.Status;
using MathNet.Numerics.Properties;
namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
@ -71,12 +70,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
/// </remarks>
public sealed class GpBiCg : IIterativeSolver<Complex>
{
/// <summary>
/// The status used if there is no status, i.e. the solver hasn't run yet and there is no
/// iterator.
/// </summary>
static readonly ICalculationStatus DefaultStatus = new CalculationIndetermined();
/// <summary>
/// The preconditioner that will be used. Can be set to <c>null</c>, in which case the default
/// pre-conditioner will be used.
@ -236,9 +229,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
/// <summary>
/// Gets the status of the iteration once the calculation is finished.
/// </summary>
public ICalculationStatus IterationResult
public IterationStatus IterationResult
{
get { return (_iterator != null) ? _iterator.Status : DefaultStatus; }
get { return (_iterator != null) ? _iterator.Status : IterationStatus.Indetermined; }
}
/// <summary>
@ -553,7 +546,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
return true;
}
return !_iterator.DetermineStatus(iterationNumber, result, source, residuals).TerminatesCalculation;
var status = _iterator.DetermineStatus(iterationNumber, result, source, residuals);
return status == IterationStatus.Running || status == IterationStatus.Indetermined;
}
/// <summary>

14
src/Numerics/LinearAlgebra/Complex/Solvers/MlkBiCgStab.cs

@ -34,7 +34,6 @@ using System.Diagnostics;
using System.Linq;
using MathNet.Numerics.Distributions;
using MathNet.Numerics.LinearAlgebra.Solvers;
using MathNet.Numerics.LinearAlgebra.Solvers.Status;
using MathNet.Numerics.Properties;
namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
@ -77,12 +76,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
/// </summary>
const int DefaultNumberOfStartingVectors = 50;
/// <summary>
/// The status used if there is no status, i.e. the solver hasn't run yet and there is no
/// iterator.
/// </summary>
static readonly ICalculationStatus DefaultStatus = new CalculationIndetermined();
/// <summary>
/// The preconditioner that will be used. Can be set to <see langword="null" />, in which case the default
/// pre-conditioner will be used.
@ -257,10 +250,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
/// <summary>
/// Gets the status of the iteration once the calculation is finished.
/// </summary>
public ICalculationStatus IterationResult
public IterationStatus IterationResult
{
[DebuggerStepThrough]
get { return (_iterator != null) ? _iterator.Status : DefaultStatus; }
get { return (_iterator != null) ? _iterator.Status : IterationStatus.Indetermined; }
}
/// <summary>
@ -736,7 +729,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
return true;
}
return !_iterator.DetermineStatus(iterationNumber, result, source, residuals).TerminatesCalculation;
var status = _iterator.DetermineStatus(iterationNumber, result, source, residuals);
return status == IterationStatus.Running || status == IterationStatus.Indetermined;
}
/// <summary>

72
src/Numerics/LinearAlgebra/Complex/Solvers/StopCriterium/DivergenceStopCriterium.cs

@ -29,7 +29,6 @@
// </copyright>
using MathNet.Numerics.LinearAlgebra.Solvers;
using MathNet.Numerics.LinearAlgebra.Solvers.Status;
using System;
using System.Diagnostics;
@ -52,7 +51,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.StopCriterium
/// residual may experience before a divergence warning is issued.
/// </summary>
public const double DefaultMaximumRelativeIncrease = 0.08;
/// <summary>
/// Default value for the minimum number of iterations over which
/// the residual must grow before a divergence warning is issued.
@ -63,37 +62,32 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.StopCriterium
/// Defines the default last iteration number. Set to -1 because iterations normally
/// start at 0.
/// </summary>
private const int DefaultLastIterationNumber = -1;
const int DefaultLastIterationNumber = -1;
/// <summary>
/// The default status.
/// </summary>
private static readonly ICalculationStatus DefaultStatus = new CalculationIndetermined();
/// <summary>
/// The maximum relative increase the residual may experience without triggering a divergence warning.
/// </summary>
private double _maximumRelativeIncrease;
double _maximumRelativeIncrease;
/// <summary>
/// The number of iterations over which a residual increase should be tracked before issuing a divergence warning.
/// </summary>
private int _minimumNumberOfIterations;
int _minimumNumberOfIterations;
/// <summary>
/// The status of the calculation
/// </summary>
private ICalculationStatus _status = DefaultStatus;
IterationStatus _status = IterationStatus.Indetermined;
/// <summary>
/// The array that holds the tracking information.
/// </summary>
private double[] _residualHistory;
double[] _residualHistory;
/// <summary>
/// The iteration number of the last iteration.
/// </summary>
private int _lastIteration = DefaultLastIterationNumber;
int _lastIteration = DefaultLastIterationNumber;
/// <summary>
/// Initializes a new instance of the <see cref="DivergenceStopCriterium"/> class with the default maximum
@ -117,7 +111,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.StopCriterium
/// relative increase and the specified minimum number of tracking iterations.
/// </summary>
/// <param name="minimumIterations">The minimum number of iterations over which the residual must grow before a divergence warning is issued. </param>
public DivergenceStopCriterium(int minimumIterations) : this(DefaultMinimumNumberOfIterations, minimumIterations)
public DivergenceStopCriterium(int minimumIterations) : this(DefaultMinimumNumberOfIterations, minimumIterations)
{
}
@ -224,18 +218,13 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.StopCriterium
/// on the invocation of this method. Therefore this method should only be called if the
/// calculation has moved forwards at least one step.
/// </remarks>
public ICalculationStatus DetermineStatus(int iterationNumber, Vector<Complex> solutionVector, Vector<Complex> sourceVector, Vector<Complex> residualVector)
public IterationStatus DetermineStatus(int iterationNumber, Vector<Complex> solutionVector, Vector<Complex> sourceVector, Vector<Complex> residualVector)
{
if (iterationNumber < 0)
{
throw new ArgumentOutOfRangeException("iterationNumber");
}
if (residualVector == null)
{
throw new ArgumentNullException("residualVector");
}
if (_lastIteration >= iterationNumber)
{
// We have already stored the actual last iteration number
@ -263,19 +252,12 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.StopCriterium
// Stop the iteration.
if (double.IsNaN(_residualHistory[_residualHistory.Length - 1]))
{
SetStatusToDiverged();
_status = IterationStatus.Diverged;
return _status;
}
// Check if we are diverging and if so set the status
if (IsDiverging())
{
SetStatusToDiverged();
}
else
{
SetStatusToRunning();
}
_status = IsDiverging() ? IterationStatus.Diverged : IterationStatus.Running;
_lastIteration = iterationNumber;
return _status;
@ -285,7 +267,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.StopCriterium
/// Detect if solution is diverging
/// </summary>
/// <returns><c>true</c> if diverging, otherwise <c>false</c></returns>
private bool IsDiverging()
bool IsDiverging()
{
// Run for each variable
for (var i = 1; i < _residualHistory.Length; i++)
@ -295,7 +277,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.StopCriterium
// Divergence is occurring if:
// - the last residual is larger than the previous one
// - the relative increase of the residual is larger than the setting allows
if ((difference < 0) || (_residualHistory[i - 1] * (1 + _maximumRelativeIncrease) >= _residualHistory[i]))
if ((difference < 0) || (_residualHistory[i - 1]*(1 + _maximumRelativeIncrease) >= _residualHistory[i]))
{
// No divergence taking place within the required number of iterations
// So reset and stop the iteration. There is no way we can get to the
@ -310,7 +292,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.StopCriterium
/// <summary>
/// Gets required history Length
/// </summary>
private int RequiredHistoryLength
int RequiredHistoryLength
{
[DebuggerStepThrough]
get
@ -319,32 +301,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.StopCriterium
}
}
/// <summary>
/// Set status to <see cref="CalculationDiverged"/>
/// </summary>
private void SetStatusToDiverged()
{
if (!(_status is CalculationDiverged))
{
_status = new CalculationDiverged();
}
}
/// <summary>
/// Set status to <see cref="CalculationRunning"/>
/// </summary>
private void SetStatusToRunning()
{
if (!(_status is CalculationRunning))
{
_status = new CalculationRunning();
}
}
/// <summary>
/// Gets the current calculation status.
/// </summary>
public ICalculationStatus Status
public IterationStatus Status
{
[DebuggerStepThrough]
get
@ -358,7 +318,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.StopCriterium
/// </summary>
public void ResetToPrecalculationState()
{
_status = DefaultStatus;
_status = IterationStatus.Indetermined;
_lastIteration = DefaultLastIterationNumber;
_residualHistory = null;
}

63
src/Numerics/LinearAlgebra/Complex/Solvers/StopCriterium/FailureStopCriterium.cs

@ -28,11 +28,10 @@
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
using MathNet.Numerics.LinearAlgebra.Solvers;
using MathNet.Numerics.LinearAlgebra.Solvers.Status;
using MathNet.Numerics.Properties;
using System;
using System.Diagnostics;
using MathNet.Numerics.LinearAlgebra.Solvers;
using MathNet.Numerics.Properties;
namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.StopCriterium
{
@ -52,22 +51,17 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.StopCriterium
/// Defines the default last iteration number. Set to -1 because iterations normally
/// start at 0.
/// </summary>
private const int DefaultLastIterationNumber = -1;
/// <summary>
/// The default status.
/// </summary>
private static readonly ICalculationStatus DefaultStatus = new CalculationIndetermined();
const int DefaultLastIterationNumber = -1;
/// <summary>
/// The status of the calculation
/// </summary>
private ICalculationStatus _status = DefaultStatus;
IterationStatus _status = IterationStatus.Indetermined;
/// <summary>
/// The iteration number of the last iteration.
/// </summary>
private int _lastIteration = DefaultLastIterationNumber;
int _lastIteration = DefaultLastIterationNumber;
/// <summary>
/// Determines the status of the iterative calculation based on the stop criteria stored
@ -82,23 +76,13 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.StopCriterium
/// on the invocation of this method. Therefore this method should only be called if the
/// calculation has moved forwards at least one step.
/// </remarks>
public ICalculationStatus DetermineStatus(int iterationNumber, Vector<Complex> solutionVector, Vector<Complex> sourceVector, Vector<Complex> residualVector)
public IterationStatus DetermineStatus(int iterationNumber, Vector<Complex> solutionVector, Vector<Complex> sourceVector, Vector<Complex> residualVector)
{
if (iterationNumber < 0)
{
throw new ArgumentOutOfRangeException("iterationNumber");
}
if (solutionVector == null)
{
throw new ArgumentNullException("solutionVector");
}
if (residualVector == null)
{
throw new ArgumentNullException("residualVector");
}
if (solutionVector.Count != residualVector.Count)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength);
@ -115,45 +99,16 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.StopCriterium
var residualNorm = residualVector.InfinityNorm();
var solutionNorm = solutionVector.InfinityNorm();
if (double.IsNaN(solutionNorm.Real) || double.IsNaN(residualNorm.Real))
{
SetStatusToFailed();
}
else
{
SetStatusToRunning();
}
_status = double.IsNaN(solutionNorm.Real) || double.IsNaN(residualNorm.Real) ? IterationStatus.Failure : IterationStatus.Running;
_lastIteration = iterationNumber;
return _status;
}
/// <summary>
/// Set status to <see cref="CalculationFailure"/>
/// </summary>
private void SetStatusToFailed()
{
if (!(_status is CalculationFailure))
{
_status = new CalculationFailure();
}
}
/// <summary>
/// Set status to <see cref="CalculationRunning"/>
/// </summary>
private void SetStatusToRunning()
{
if (!(_status is CalculationRunning))
{
_status = new CalculationRunning();
}
}
/// <summary>
/// Gets the current calculation status.
/// </summary>
public ICalculationStatus Status
public IterationStatus Status
{
[DebuggerStepThrough]
get
@ -167,7 +122,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.StopCriterium
/// </summary>
public void ResetToPrecalculationState()
{
_status = DefaultStatus;
_status = IterationStatus.Indetermined;
_lastIteration = DefaultLastIterationNumber;
}

95
src/Numerics/LinearAlgebra/Complex/Solvers/StopCriterium/ResidualStopCriterium.cs

@ -28,11 +28,10 @@
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
using MathNet.Numerics.LinearAlgebra.Solvers;
using MathNet.Numerics.LinearAlgebra.Solvers.Status;
using MathNet.Numerics.Properties;
using System;
using System.Diagnostics;
using MathNet.Numerics.LinearAlgebra.Solvers;
using MathNet.Numerics.Properties;
namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.StopCriterium
{
@ -61,38 +60,33 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.StopCriterium
/// <summary>
/// Defines the default last iteration number. Set to -1 because iterations normally start at 0.
/// </summary>
private const int DefaultLastIterationNumber = -1;
/// <summary>
/// The default status.
/// </summary>
private static readonly ICalculationStatus DefaultStatus = new CalculationIndetermined();
const int DefaultLastIterationNumber = -1;
/// <summary>
/// The maximum value for the residual below which the calculation is considered converged.
/// </summary>
private double _maximum;
double _maximum;
/// <summary>
/// The minimum number of iterations for which the residual has to be below the maximum before
/// the calculation is considered converged.
/// </summary>
private int _minimumIterationsBelowMaximum;
int _minimumIterationsBelowMaximum;
/// <summary>
/// The status of the calculation
/// </summary>
private ICalculationStatus _status = DefaultStatus;
IterationStatus _status = IterationStatus.Indetermined;
/// <summary>
/// The number of iterations since the residuals got below the maximum.
/// </summary>
private int _iterationCount;
int _iterationCount;
/// <summary>
/// The iteration number of the last iteration.
/// </summary>
private int _lastIteration = DefaultLastIterationNumber;
int _lastIteration = DefaultLastIterationNumber;
/// <summary>
/// Initializes a new instance of the <see cref="ResidualStopCriterium"/> class with the default maximum
@ -229,28 +223,13 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.StopCriterium
/// on the invocation of this method. Therefore this method should only be called if the
/// calculation has moved forwards at least one step.
/// </remarks>
public ICalculationStatus DetermineStatus(int iterationNumber, Vector<Complex> solutionVector, Vector<Complex> sourceVector, Vector<Complex> residualVector)
public IterationStatus DetermineStatus(int iterationNumber, Vector<Complex> solutionVector, Vector<Complex> sourceVector, Vector<Complex> residualVector)
{
if (iterationNumber < 0)
{
throw new ArgumentOutOfRangeException("iterationNumber");
}
if (solutionVector == null)
{
throw new ArgumentNullException("solutionVector");
}
if (sourceVector == null)
{
throw new ArgumentNullException("sourceVector");
}
if (residualVector == null)
{
throw new ArgumentNullException("residualVector");
}
if (solutionVector.Count != sourceVector.Count)
{
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "sourceVector");
@ -265,7 +244,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.StopCriterium
// These values will be used to calculate the relative drop in residuals
// later on.
var residualNorm = residualVector.InfinityNorm();
// Check the residuals by calculating:
// ||r_i|| <= stop_tol * ||b||
var stopCriterium = ComputeStopCriterium(sourceVector.InfinityNorm().Real);
@ -276,7 +255,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.StopCriterium
if (double.IsNaN(stopCriterium) || double.IsNaN(residualNorm.Real))
{
_iterationCount = 0;
SetStatusToDiverged();
_status = IterationStatus.Diverged;
return _status;
}
@ -288,20 +267,13 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.StopCriterium
if (_lastIteration <= iterationNumber)
{
_iterationCount = iterationNumber - _lastIteration;
if (_iterationCount >= _minimumIterationsBelowMaximum)
{
SetStatusToConverged();
}
else
{
SetStatusToRunning();
}
_status = _iterationCount >= _minimumIterationsBelowMaximum ? IterationStatus.Converged : IterationStatus.Running;
}
}
else
{
_iterationCount = 0;
SetStatusToRunning();
_status = IterationStatus.Running;
}
_lastIteration = iterationNumber;
@ -313,7 +285,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.StopCriterium
/// </summary>
/// <param name="solutionNorm">Solution vector norm</param>
/// <returns>Criterium value</returns>
private double ComputeStopCriterium(double solutionNorm)
double ComputeStopCriterium(double solutionNorm)
{
// This is criterium 1 from Templates for the solution of linear systems.
// The problem with this criterium is that it's not limiting enough. For now
@ -321,46 +293,13 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.StopCriterium
// return mMaximumResidual * (System.Math.Abs(mMatrixNorm) * System.Math.Abs(solutionNorm) + System.Math.Abs(mVectorNorm));
// For now use criterium 2 from Templates for the solution of linear systems. See page 60.
return _maximum * Math.Abs(solutionNorm);
}
/// <summary>
/// Set status to <see cref="CalculationDiverged"/>
/// </summary>
private void SetStatusToDiverged()
{
if (!(_status is CalculationDiverged))
{
_status = new CalculationDiverged();
}
}
/// <summary>
/// Set status to <see cref="CalculationConverged"/>
/// </summary>
private void SetStatusToConverged()
{
if (!(_status is CalculationConverged))
{
_status = new CalculationConverged();
}
}
/// <summary>
/// Set status to <see cref="CalculationRunning"/>
/// </summary>
private void SetStatusToRunning()
{
if (!(_status is CalculationRunning))
{
_status = new CalculationRunning();
}
return _maximum*Math.Abs(solutionNorm);
}
/// <summary>
/// Gets the current calculation status.
/// </summary>
public ICalculationStatus Status
public IterationStatus Status
{
[DebuggerStepThrough]
get
@ -374,7 +313,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.StopCriterium
/// </summary>
public void ResetToPrecalculationState()
{
_status = DefaultStatus;
_status = IterationStatus.Indetermined;
_iterationCount = 0;
_lastIteration = DefaultLastIterationNumber;
}

14
src/Numerics/LinearAlgebra/Complex/Solvers/TFQMR.cs

@ -30,7 +30,6 @@
using System;
using MathNet.Numerics.LinearAlgebra.Solvers;
using MathNet.Numerics.LinearAlgebra.Solvers.Status;
using MathNet.Numerics.Properties;
namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
@ -62,12 +61,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
/// </remarks>
public sealed class TFQMR : IIterativeSolver<Complex>
{
/// <summary>
/// The status used if there is no status, i.e. the solver hasn't run yet and there is no
/// iterator.
/// </summary>
static readonly ICalculationStatus DefaultStatus = new CalculationIndetermined();
/// <summary>
/// The preconditioner that will be used. Can be set to <see langword="null" />, in which case the default
/// pre-conditioner will be used.
@ -177,9 +170,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
/// <summary>
/// Gets the status of the iteration once the calculation is finished.
/// </summary>
public ICalculationStatus IterationResult
public IterationStatus IterationResult
{
get { return (_iterator != null) ? _iterator.Status : DefaultStatus; }
get { return (_iterator != null) ? _iterator.Status : IterationStatus.Indetermined; }
}
/// <summary>
@ -460,7 +453,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
return true;
}
return !_iterator.DetermineStatus(iterationNumber, result, source, residuals).TerminatesCalculation;
var status = _iterator.DetermineStatus(iterationNumber, result, source, residuals);
return status == IterationStatus.Running || status == IterationStatus.Indetermined;
}
/// <summary>

14
src/Numerics/LinearAlgebra/Complex32/Solvers/BiCgStab.cs

@ -30,7 +30,6 @@
using System;
using MathNet.Numerics.LinearAlgebra.Solvers;
using MathNet.Numerics.LinearAlgebra.Solvers.Status;
using MathNet.Numerics.Properties;
namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
@ -66,12 +65,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
/// </remarks>
public sealed class BiCgStab : IIterativeSolver<Numerics.Complex32>
{
/// <summary>
/// The status used if there is no status, i.e. the solver hasn't run yet and there is no
/// iterator.
/// </summary>
static readonly ICalculationStatus DefaultStatus = new CalculationIndetermined();
/// <summary>
/// The preconditioner that will be used. Can be set to <see langword="null" />, in which case the default
/// pre-conditioner will be used.
@ -181,9 +174,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
/// <summary>
/// Gets the status of the iteration once the calculation is finished.
/// </summary>
public ICalculationStatus IterationResult
public IterationStatus IterationResult
{
get { return (_iterator != null) ? _iterator.Status : DefaultStatus; }
get { return (_iterator != null) ? _iterator.Status : IterationStatus.Indetermined; }
}
/// <summary>
@ -463,7 +456,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
return true;
}
return !_iterator.DetermineStatus(iterationNumber, result, source, residuals).TerminatesCalculation;
var status = _iterator.DetermineStatus(iterationNumber, result, source, residuals);
return status == IterationStatus.Running || status == IterationStatus.Indetermined;
}
/// <summary>

17
src/Numerics/LinearAlgebra/Complex32/Solvers/CompositeSolver.cs

@ -34,7 +34,6 @@ using System.IO;
using System.Linq;
using System.Reflection;
using MathNet.Numerics.LinearAlgebra.Solvers;
using MathNet.Numerics.LinearAlgebra.Solvers.Status;
using MathNet.Numerics.Properties;
namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
@ -86,16 +85,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
#endregion
/// <summary>
/// The default status used if the solver is not running.
/// </summary>
static readonly ICalculationStatus NonRunningStatus = new CalculationIndetermined();
/// <summary>
/// The default status used if the solver is running.
/// </summary>
static readonly ICalculationStatus RunningStatus = new CalculationRunning();
#if PORTABLE
private static readonly Dictionary<double, List<IIterativeSolverSetup<Complex32>>> SolverSetups = new Dictionary<double, List<IIterativeSolverSetup<Complex32>>>();
#else
@ -340,7 +329,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
/// <summary>
/// The status of the calculation.
/// </summary>
ICalculationStatus _status = NonRunningStatus;
IterationStatus _status = IterationStatus.Indetermined;
/// <summary>
/// The iterator that is used to control the iteration process.
@ -386,7 +375,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
/// <summary>
/// Gets the status of the iteration once the calculation is finished.
/// </summary>
public ICalculationStatus IterationResult
public IterationStatus IterationResult
{
get
{
@ -509,7 +498,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
// Switch to the next preconditioner.
// Reset the solution vector to the previous solution
input.CopyTo(internalInput);
_status = RunningStatus;
_status = IterationStatus.Running;
continue;
}

14
src/Numerics/LinearAlgebra/Complex32/Solvers/GpBiCg.cs

@ -30,7 +30,6 @@
using System;
using MathNet.Numerics.LinearAlgebra.Solvers;
using MathNet.Numerics.LinearAlgebra.Solvers.Status;
using MathNet.Numerics.Properties;
namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
@ -64,12 +63,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
/// </remarks>
public sealed class GpBiCg : IIterativeSolver<Numerics.Complex32>
{
/// <summary>
/// The status used if there is no status, i.e. the solver hasn't run yet and there is no
/// iterator.
/// </summary>
static readonly ICalculationStatus DefaultStatus = new CalculationIndetermined();
/// <summary>
/// The preconditioner that will be used. Can be set to <c>null</c>, in which case the default
/// pre-conditioner will be used.
@ -229,9 +222,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
/// <summary>
/// Gets the status of the iteration once the calculation is finished.
/// </summary>
public ICalculationStatus IterationResult
public IterationStatus IterationResult
{
get { return (_iterator != null) ? _iterator.Status : DefaultStatus; }
get { return (_iterator != null) ? _iterator.Status : IterationStatus.Indetermined; }
}
/// <summary>
@ -551,7 +544,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
return true;
}
return !_iterator.DetermineStatus(iterationNumber, result, source, residuals).TerminatesCalculation;
var status = _iterator.DetermineStatus(iterationNumber, result, source, residuals);
return status == IterationStatus.Running || status == IterationStatus.Indetermined;
}
/// <summary>

14
src/Numerics/LinearAlgebra/Complex32/Solvers/MlkBiCgStab.cs

@ -34,7 +34,6 @@ using System.Diagnostics;
using System.Linq;
using MathNet.Numerics.Distributions;
using MathNet.Numerics.LinearAlgebra.Solvers;
using MathNet.Numerics.LinearAlgebra.Solvers.Status;
using MathNet.Numerics.Properties;
namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
@ -69,12 +68,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
/// </summary>
const int DefaultNumberOfStartingVectors = 50;
/// <summary>
/// The status used if there is no status, i.e. the solver hasn't run yet and there is no
/// iterator.
/// </summary>
static readonly ICalculationStatus DefaultStatus = new CalculationIndetermined();
/// <summary>
/// The preconditioner that will be used. Can be set to <see langword="null" />, in which case the default
/// pre-conditioner will be used.
@ -249,10 +242,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
/// <summary>
/// Gets the status of the iteration once the calculation is finished.
/// </summary>
public ICalculationStatus IterationResult
public IterationStatus IterationResult
{
[DebuggerStepThrough]
get { return (_iterator != null) ? _iterator.Status : DefaultStatus; }
get { return (_iterator != null) ? _iterator.Status : IterationStatus.Indetermined; }
}
/// <summary>
@ -733,7 +726,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
return true;
}
return !_iterator.DetermineStatus(iterationNumber, result, source, residuals).TerminatesCalculation;
var status = _iterator.DetermineStatus(iterationNumber, result, source, residuals);
return status == IterationStatus.Running || status == IterationStatus.Indetermined;
}
/// <summary>

72
src/Numerics/LinearAlgebra/Complex32/Solvers/StopCriterium/DivergenceStopCriterium.cs

@ -29,7 +29,6 @@
// </copyright>
using MathNet.Numerics.LinearAlgebra.Solvers;
using MathNet.Numerics.LinearAlgebra.Solvers.Status;
using System;
using System.Diagnostics;
@ -47,7 +46,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.StopCriterium
/// residual may experience before a divergence warning is issued.
/// </summary>
public const double DefaultMaximumRelativeIncrease = 0.08;
/// <summary>
/// Default value for the minimum number of iterations over which
/// the residual must grow before a divergence warning is issued.
@ -58,37 +57,32 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.StopCriterium
/// Defines the default last iteration number. Set to -1 because iterations normally
/// start at 0.
/// </summary>
private const int DefaultLastIterationNumber = -1;
const int DefaultLastIterationNumber = -1;
/// <summary>
/// The default status.
/// </summary>
private static readonly ICalculationStatus DefaultStatus = new CalculationIndetermined();
/// <summary>
/// The maximum relative increase the residual may experience without triggering a divergence warning.
/// </summary>
private double _maximumRelativeIncrease;
double _maximumRelativeIncrease;
/// <summary>
/// The number of iterations over which a residual increase should be tracked before issuing a divergence warning.
/// </summary>
private int _minimumNumberOfIterations;
int _minimumNumberOfIterations;
/// <summary>
/// The status of the calculation
/// </summary>
private ICalculationStatus _status = DefaultStatus;
IterationStatus _status = IterationStatus.Indetermined;
/// <summary>
/// The array that holds the tracking information.
/// </summary>
private double[] _residualHistory;
double[] _residualHistory;
/// <summary>
/// The iteration number of the last iteration.
/// </summary>
private int _lastIteration = DefaultLastIterationNumber;
int _lastIteration = DefaultLastIterationNumber;
/// <summary>
/// Initializes a new instance of the <see cref="DivergenceStopCriterium"/> class with the default maximum
@ -112,7 +106,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.StopCriterium
/// relative increase and the specified minimum number of tracking iterations.
/// </summary>
/// <param name="minimumIterations">The minimum number of iterations over which the residual must grow before a divergence warning is issued. </param>
public DivergenceStopCriterium(int minimumIterations) : this(DefaultMinimumNumberOfIterations, minimumIterations)
public DivergenceStopCriterium(int minimumIterations) : this(DefaultMinimumNumberOfIterations, minimumIterations)
{
}
@ -219,18 +213,13 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.StopCriterium
/// on the invocation of this method. Therefore this method should only be called if the
/// calculation has moved forwards at least one step.
/// </remarks>
public ICalculationStatus DetermineStatus(int iterationNumber, Vector<Complex32> solutionVector, Vector<Complex32> sourceVector, Vector<Complex32> residualVector)
public IterationStatus DetermineStatus(int iterationNumber, Vector<Complex32> solutionVector, Vector<Complex32> sourceVector, Vector<Complex32> residualVector)
{
if (iterationNumber < 0)
{
throw new ArgumentOutOfRangeException("iterationNumber");
}
if (residualVector == null)
{
throw new ArgumentNullException("residualVector");
}
if (_lastIteration >= iterationNumber)
{
// We have already stored the actual last iteration number
@ -258,19 +247,12 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.StopCriterium
// Stop the iteration.
if (double.IsNaN(_residualHistory[_residualHistory.Length - 1]))
{
SetStatusToDiverged();
_status = IterationStatus.Diverged;
return _status;
}
// Check if we are diverging and if so set the status
if (IsDiverging())
{
SetStatusToDiverged();
}
else
{
SetStatusToRunning();
}
_status = IsDiverging() ? IterationStatus.Diverged : IterationStatus.Running;
_lastIteration = iterationNumber;
return _status;
@ -280,7 +262,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.StopCriterium
/// Detect if solution is diverging
/// </summary>
/// <returns><c>true</c> if diverging, otherwise <c>false</c></returns>
private bool IsDiverging()
bool IsDiverging()
{
// Run for each variable
for (var i = 1; i < _residualHistory.Length; i++)
@ -290,7 +272,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.StopCriterium
// Divergence is occurring if:
// - the last residual is larger than the previous one
// - the relative increase of the residual is larger than the setting allows
if ((difference < 0) || (_residualHistory[i - 1] * (1 + _maximumRelativeIncrease) >= _residualHistory[i]))
if ((difference < 0) || (_residualHistory[i - 1]*(1 + _maximumRelativeIncrease) >= _residualHistory[i]))
{
// No divergence taking place within the required number of iterations
// So reset and stop the iteration. There is no way we can get to the
@ -305,7 +287,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.StopCriterium
/// <summary>
/// Gets required history Length
/// </summary>
private int RequiredHistoryLength
int RequiredHistoryLength
{
[DebuggerStepThrough]
get
@ -314,32 +296,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.StopCriterium
}
}
/// <summary>
/// Set status to <see cref="CalculationDiverged"/>
/// </summary>
private void SetStatusToDiverged()
{
if (!(_status is CalculationDiverged))
{
_status = new CalculationDiverged();
}
}
/// <summary>
/// Set status to <see cref="CalculationRunning"/>
/// </summary>
private void SetStatusToRunning()
{
if (!(_status is CalculationRunning))
{
_status = new CalculationRunning();
}
}
/// <summary>
/// Gets the current calculation status.
/// </summary>
public ICalculationStatus Status
public IterationStatus Status
{
[DebuggerStepThrough]
get
@ -353,7 +313,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.StopCriterium
/// </summary>
public void ResetToPrecalculationState()
{
_status = DefaultStatus;
_status = IterationStatus.Indetermined;
_lastIteration = DefaultLastIterationNumber;
_residualHistory = null;
}

63
src/Numerics/LinearAlgebra/Complex32/Solvers/StopCriterium/FailureStopCriterium.cs

@ -28,11 +28,10 @@
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
using MathNet.Numerics.LinearAlgebra.Solvers;
using MathNet.Numerics.LinearAlgebra.Solvers.Status;
using MathNet.Numerics.Properties;
using System;
using System.Diagnostics;
using MathNet.Numerics.LinearAlgebra.Solvers;
using MathNet.Numerics.Properties;
namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.StopCriterium
{
@ -47,22 +46,17 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.StopCriterium
/// Defines the default last iteration number. Set to -1 because iterations normally
/// start at 0.
/// </summary>
private const int DefaultLastIterationNumber = -1;
/// <summary>
/// The default status.
/// </summary>
private static readonly ICalculationStatus DefaultStatus = new CalculationIndetermined();
const int DefaultLastIterationNumber = -1;
/// <summary>
/// The status of the calculation
/// </summary>
private ICalculationStatus _status = DefaultStatus;
IterationStatus _status = IterationStatus.Indetermined;
/// <summary>
/// The iteration number of the last iteration.
/// </summary>
private int _lastIteration = DefaultLastIterationNumber;
int _lastIteration = DefaultLastIterationNumber;
/// <summary>
/// Determines the status of the iterative calculation based on the stop criteria stored
@ -77,23 +71,13 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.StopCriterium
/// on the invocation of this method. Therefore this method should only be called if the
/// calculation has moved forwards at least one step.
/// </remarks>
public ICalculationStatus DetermineStatus(int iterationNumber, Vector<Complex32> solutionVector, Vector<Complex32> sourceVector, Vector<Complex32> residualVector)
public IterationStatus DetermineStatus(int iterationNumber, Vector<Complex32> solutionVector, Vector<Complex32> sourceVector, Vector<Complex32> residualVector)
{
if (iterationNumber < 0)
{
throw new ArgumentOutOfRangeException("iterationNumber");
}
if (solutionVector == null)
{
throw new ArgumentNullException("solutionVector");
}
if (residualVector == null)
{
throw new ArgumentNullException("residualVector");
}
if (solutionVector.Count != residualVector.Count)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength);
@ -110,45 +94,16 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.StopCriterium
var residualNorm = residualVector.InfinityNorm();
var solutionNorm = solutionVector.InfinityNorm();
if (float.IsNaN(solutionNorm.Real) || float.IsNaN(residualNorm.Real))
{
SetStatusToFailed();
}
else
{
SetStatusToRunning();
}
_status = float.IsNaN(solutionNorm.Real) || float.IsNaN(residualNorm.Real) ? IterationStatus.Failure : IterationStatus.Running;
_lastIteration = iterationNumber;
return _status;
}
/// <summary>
/// Set status to <see cref="CalculationFailure"/>
/// </summary>
private void SetStatusToFailed()
{
if (!(_status is CalculationFailure))
{
_status = new CalculationFailure();
}
}
/// <summary>
/// Set status to <see cref="CalculationRunning"/>
/// </summary>
private void SetStatusToRunning()
{
if (!(_status is CalculationRunning))
{
_status = new CalculationRunning();
}
}
/// <summary>
/// Gets the current calculation status.
/// </summary>
public ICalculationStatus Status
public IterationStatus Status
{
[DebuggerStepThrough]
get
@ -162,7 +117,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.StopCriterium
/// </summary>
public void ResetToPrecalculationState()
{
_status = DefaultStatus;
_status = IterationStatus.Indetermined;
_lastIteration = DefaultLastIterationNumber;
}

91
src/Numerics/LinearAlgebra/Complex32/Solvers/StopCriterium/ResidualStopCriterium.cs

@ -31,7 +31,6 @@
using System;
using System.Diagnostics;
using MathNet.Numerics.LinearAlgebra.Solvers;
using MathNet.Numerics.LinearAlgebra.Solvers.Status;
using MathNet.Numerics.Properties;
namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.StopCriterium
@ -56,38 +55,33 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.StopCriterium
/// <summary>
/// Defines the default last iteration number. Set to -1 because iterations normally start at 0.
/// </summary>
private const int DefaultLastIterationNumber = -1;
/// <summary>
/// The default status.
/// </summary>
private static readonly ICalculationStatus DefaultStatus = new CalculationIndetermined();
const int DefaultLastIterationNumber = -1;
/// <summary>
/// The maximum value for the residual below which the calculation is considered converged.
/// </summary>
private float _maximum;
float _maximum;
/// <summary>
/// The minimum number of iterations for which the residual has to be below the maximum before
/// the calculation is considered converged.
/// </summary>
private int _minimumIterationsBelowMaximum;
int _minimumIterationsBelowMaximum;
/// <summary>
/// The status of the calculation
/// </summary>
private ICalculationStatus _status = DefaultStatus;
IterationStatus _status = IterationStatus.Indetermined;
/// <summary>
/// The number of iterations since the residuals got below the maximum.
/// </summary>
private int _iterationCount;
int _iterationCount;
/// <summary>
/// The iteration number of the last iteration.
/// </summary>
private int _lastIteration = DefaultLastIterationNumber;
int _lastIteration = DefaultLastIterationNumber;
/// <summary>
/// Initializes a new instance of the <see cref="ResidualStopCriterium"/> class with the default maximum
@ -224,28 +218,13 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.StopCriterium
/// on the invocation of this method. Therefore this method should only be called if the
/// calculation has moved forwards at least one step.
/// </remarks>
public ICalculationStatus DetermineStatus(int iterationNumber, Vector<Complex32> solutionVector, Vector<Complex32> sourceVector, Vector<Complex32> residualVector)
public IterationStatus DetermineStatus(int iterationNumber, Vector<Complex32> solutionVector, Vector<Complex32> sourceVector, Vector<Complex32> residualVector)
{
if (iterationNumber < 0)
{
throw new ArgumentOutOfRangeException("iterationNumber");
}
if (solutionVector == null)
{
throw new ArgumentNullException("solutionVector");
}
if (sourceVector == null)
{
throw new ArgumentNullException("sourceVector");
}
if (residualVector == null)
{
throw new ArgumentNullException("residualVector");
}
if (solutionVector.Count != sourceVector.Count)
{
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "sourceVector");
@ -260,7 +239,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.StopCriterium
// These values will be used to calculate the relative drop in residuals
// later on.
var residualNorm = residualVector.InfinityNorm();
// Check the residuals by calculating:
// ||r_i|| <= stop_tol * ||b||
var stopCriterium = ComputeStopCriterium(sourceVector.InfinityNorm().Real);
@ -271,7 +250,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.StopCriterium
if (float.IsNaN(stopCriterium) || float.IsNaN(residualNorm.Real))
{
_iterationCount = 0;
SetStatusToDiverged();
_status = IterationStatus.Diverged;
return _status;
}
@ -283,20 +262,13 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.StopCriterium
if (_lastIteration <= iterationNumber)
{
_iterationCount = iterationNumber - _lastIteration;
if (_iterationCount >= _minimumIterationsBelowMaximum)
{
SetStatusToConverged();
}
else
{
SetStatusToRunning();
}
_status = _iterationCount >= _minimumIterationsBelowMaximum ? IterationStatus.Converged : IterationStatus.Running;
}
}
else
{
_iterationCount = 0;
SetStatusToRunning();
_status = IterationStatus.Running;
}
_lastIteration = iterationNumber;
@ -308,7 +280,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.StopCriterium
/// </summary>
/// <param name="solutionNorm">Solution vector norm</param>
/// <returns>Criterium value</returns>
private float ComputeStopCriterium(float solutionNorm)
float ComputeStopCriterium(float solutionNorm)
{
// This is criterium 1 from Templates for the solution of linear systems.
// The problem with this criterium is that it's not limiting enough. For now
@ -316,46 +288,13 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.StopCriterium
// return mMaximumResidual * (System.Math.Abs(mMatrixNorm) * System.Math.Abs(solutionNorm) + System.Math.Abs(mVectorNorm));
// For now use criterium 2 from Templates for the solution of linear systems. See page 60.
return _maximum * Math.Abs(solutionNorm);
}
/// <summary>
/// Set status to <see cref="CalculationDiverged"/>
/// </summary>
private void SetStatusToDiverged()
{
if (!(_status is CalculationDiverged))
{
_status = new CalculationDiverged();
}
}
/// <summary>
/// Set status to <see cref="CalculationConverged"/>
/// </summary>
private void SetStatusToConverged()
{
if (!(_status is CalculationConverged))
{
_status = new CalculationConverged();
}
}
/// <summary>
/// Set status to <see cref="CalculationRunning"/>
/// </summary>
private void SetStatusToRunning()
{
if (!(_status is CalculationRunning))
{
_status = new CalculationRunning();
}
return _maximum*Math.Abs(solutionNorm);
}
/// <summary>
/// Gets the current calculation status.
/// </summary>
public ICalculationStatus Status
public IterationStatus Status
{
[DebuggerStepThrough]
get
@ -369,7 +308,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.StopCriterium
/// </summary>
public void ResetToPrecalculationState()
{
_status = DefaultStatus;
_status = IterationStatus.Indetermined;
_iterationCount = 0;
_lastIteration = DefaultLastIterationNumber;
}

14
src/Numerics/LinearAlgebra/Complex32/Solvers/TFQMR.cs

@ -30,7 +30,6 @@
using System;
using MathNet.Numerics.LinearAlgebra.Solvers;
using MathNet.Numerics.LinearAlgebra.Solvers.Status;
using MathNet.Numerics.Properties;
namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
@ -54,12 +53,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
/// </remarks>
public sealed class TFQMR : IIterativeSolver<Numerics.Complex32>
{
/// <summary>
/// The status used if there is no status, i.e. the solver hasn't run yet and there is no
/// iterator.
/// </summary>
static readonly ICalculationStatus DefaultStatus = new CalculationIndetermined();
/// <summary>
/// The preconditioner that will be used. Can be set to <see langword="null" />, in which case the default
/// pre-conditioner will be used.
@ -169,9 +162,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
/// <summary>
/// Gets the status of the iteration once the calculation is finished.
/// </summary>
public ICalculationStatus IterationResult
public IterationStatus IterationResult
{
get { return (_iterator != null) ? _iterator.Status : DefaultStatus; }
get { return (_iterator != null) ? _iterator.Status : IterationStatus.Indetermined; }
}
/// <summary>
@ -457,7 +450,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
return true;
}
return !_iterator.DetermineStatus(iterationNumber, result, source, residuals).TerminatesCalculation;
var status = _iterator.DetermineStatus(iterationNumber, result, source, residuals);
return status == IterationStatus.Running || status == IterationStatus.Indetermined;
}
/// <summary>

14
src/Numerics/LinearAlgebra/Double/Solvers/BiCgStab.cs

@ -30,7 +30,6 @@
using System;
using MathNet.Numerics.LinearAlgebra.Solvers;
using MathNet.Numerics.LinearAlgebra.Solvers.Status;
using MathNet.Numerics.Properties;
namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
@ -66,12 +65,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
/// </remarks>
public sealed class BiCgStab : IIterativeSolver<double>
{
/// <summary>
/// The status used if there is no status, i.e. the solver hasn't run yet and there is no
/// iterator.
/// </summary>
static readonly ICalculationStatus DefaultStatus = new CalculationIndetermined();
/// <summary>
/// The preconditioner that will be used. Can be set to <see langword="null" />, in which case the default
/// pre-conditioner will be used.
@ -180,11 +173,11 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
/// <summary>
/// Gets the status of the iteration once the calculation is finished.
/// </summary>
public ICalculationStatus IterationResult
public IterationStatus IterationResult
{
get
{
return (_iterator != null) ? _iterator.Status : DefaultStatus;
return (_iterator != null) ? _iterator.Status : IterationStatus.Indetermined;
}
}
@ -465,7 +458,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
return true;
}
return !_iterator.DetermineStatus(iterationNumber, result, source, residuals).TerminatesCalculation;
var status = _iterator.DetermineStatus(iterationNumber, result, source, residuals);
return status == IterationStatus.Running || status == IterationStatus.Indetermined;
}
/// <summary>

17
src/Numerics/LinearAlgebra/Double/Solvers/CompositeSolver.cs

@ -34,7 +34,6 @@ using System.IO;
using System.Linq;
using System.Reflection;
using MathNet.Numerics.LinearAlgebra.Solvers;
using MathNet.Numerics.LinearAlgebra.Solvers.Status;
using MathNet.Numerics.Properties;
namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
@ -83,16 +82,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
#endregion
/// <summary>
/// The default status used if the solver is not running.
/// </summary>
static readonly ICalculationStatus NonRunningStatus = new CalculationIndetermined();
/// <summary>
/// The default status used if the solver is running.
/// </summary>
static readonly ICalculationStatus RunningStatus = new CalculationRunning();
#if PORTABLE
private static readonly Dictionary<double, List<IIterativeSolverSetup<double>>> SolverSetups = new Dictionary<double, List<IIterativeSolverSetup<double>>>();
#else
@ -337,7 +326,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
/// <summary>
/// The status of the calculation.
/// </summary>
ICalculationStatus _status = NonRunningStatus;
IterationStatus _status = IterationStatus.Indetermined;
/// <summary>
/// The iterator that is used to control the iteration process.
@ -383,7 +372,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
/// <summary>
/// Gets the status of the iteration once the calculation is finished.
/// </summary>
public ICalculationStatus IterationResult
public IterationStatus IterationResult
{
get
{
@ -506,7 +495,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
// Switch to the next preconditioner.
// Reset the solution vector to the previous solution
input.CopyTo(internalInput);
_status = RunningStatus;
_status = IterationStatus.Running;
continue;
}

14
src/Numerics/LinearAlgebra/Double/Solvers/GpBiCg.cs

@ -30,7 +30,6 @@
using System;
using MathNet.Numerics.LinearAlgebra.Solvers;
using MathNet.Numerics.LinearAlgebra.Solvers.Status;
using MathNet.Numerics.Properties;
namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
@ -64,12 +63,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
/// </remarks>
public sealed class GpBiCg : IIterativeSolver<double>
{
/// <summary>
/// The status used if there is no status, i.e. the solver hasn't run yet and there is no
/// iterator.
/// </summary>
static readonly ICalculationStatus DefaultStatus = new CalculationIndetermined();
/// <summary>
/// The preconditioner that will be used. Can be set to <c>null</c>, in which case the default
/// pre-conditioner will be used.
@ -234,11 +227,11 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
/// <summary>
/// Gets the status of the iteration once the calculation is finished.
/// </summary>
public ICalculationStatus IterationResult
public IterationStatus IterationResult
{
get
{
return (_iterator != null) ? _iterator.Status : DefaultStatus;
return (_iterator != null) ? _iterator.Status : IterationStatus.Indetermined;
}
}
@ -559,7 +552,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
return true;
}
return !_iterator.DetermineStatus(iterationNumber, result, source, residuals).TerminatesCalculation;
var status = _iterator.DetermineStatus(iterationNumber, result, source, residuals);
return status == IterationStatus.Running || status == IterationStatus.Indetermined;
}
/// <summary>

14
src/Numerics/LinearAlgebra/Double/Solvers/MlkBiCgStab.cs

@ -34,7 +34,6 @@ using System.Diagnostics;
using System.Linq;
using MathNet.Numerics.Distributions;
using MathNet.Numerics.LinearAlgebra.Solvers;
using MathNet.Numerics.LinearAlgebra.Solvers.Status;
using MathNet.Numerics.Properties;
namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
@ -69,12 +68,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
/// </summary>
const int DefaultNumberOfStartingVectors = 50;
/// <summary>
/// The status used if there is no status, i.e. the solver hasn't run yet and there is no
/// iterator.
/// </summary>
static readonly ICalculationStatus DefaultStatus = new CalculationIndetermined();
/// <summary>
/// The preconditioner that will be used. Can be set to <see langword="null" />, in which case the default
/// pre-conditioner will be used.
@ -254,12 +247,12 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
/// <summary>
/// Gets the status of the iteration once the calculation is finished.
/// </summary>
public ICalculationStatus IterationResult
public IterationStatus IterationResult
{
[DebuggerStepThrough]
get
{
return (_iterator != null) ? _iterator.Status : DefaultStatus;
return (_iterator != null) ? _iterator.Status : IterationStatus.Indetermined;
}
}
@ -735,7 +728,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
return true;
}
return !_iterator.DetermineStatus(iterationNumber, result, source, residuals).TerminatesCalculation;
var status = _iterator.DetermineStatus(iterationNumber, result, source, residuals);
return status == IterationStatus.Running || status == IterationStatus.Indetermined;
}
/// <summary>

52
src/Numerics/LinearAlgebra/Double/Solvers/StopCriterium/DivergenceStopCriterium.cs

@ -29,7 +29,6 @@
// </copyright>
using MathNet.Numerics.LinearAlgebra.Solvers;
using MathNet.Numerics.LinearAlgebra.Solvers.Status;
using System;
using System.Diagnostics;
@ -58,11 +57,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium
/// </summary>
private const int DefaultLastIterationNumber = -1;
/// <summary>
/// The default status.
/// </summary>
private static readonly ICalculationStatus DefaultStatus = new CalculationIndetermined();
/// <summary>
/// The maximum relative increase the residual may experience without triggering a divergence warning.
/// </summary>
@ -76,7 +70,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium
/// <summary>
/// The status of the calculation
/// </summary>
private ICalculationStatus _status = DefaultStatus;
private IterationStatus _status = IterationStatus.Indetermined;
/// <summary>
/// The array that holds the tracking information.
@ -217,18 +211,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium
/// on the invocation of this method. Therefore this method should only be called if the
/// calculation has moved forwards at least one step.
/// </remarks>
public ICalculationStatus DetermineStatus(int iterationNumber, Vector<double> solutionVector, Vector<double> sourceVector, Vector<double> residualVector)
public IterationStatus DetermineStatus(int iterationNumber, Vector<double> solutionVector, Vector<double> sourceVector, Vector<double> residualVector)
{
if (iterationNumber < 0)
{
throw new ArgumentOutOfRangeException("iterationNumber");
}
if (residualVector == null)
{
throw new ArgumentNullException("residualVector");
}
if (_lastIteration >= iterationNumber)
{
// We have already stored the actual last iteration number
@ -256,19 +245,12 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium
// Stop the iteration.
if (double.IsNaN(_residualHistory[_residualHistory.Length - 1]))
{
SetStatusToDiverged();
_status = IterationStatus.Diverged;
return _status;
}
// Check if we are diverging and if so set the status
if (IsDiverging())
{
SetStatusToDiverged();
}
else
{
SetStatusToRunning();
}
_status = IsDiverging() ? IterationStatus.Diverged : IterationStatus.Running;
_lastIteration = iterationNumber;
return _status;
@ -312,32 +294,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium
}
}
/// <summary>
/// Set status to <see cref="CalculationDiverged"/>
/// </summary>
private void SetStatusToDiverged()
{
if (!(_status is CalculationDiverged))
{
_status = new CalculationDiverged();
}
}
/// <summary>
/// Set status to <see cref="CalculationRunning"/>
/// </summary>
private void SetStatusToRunning()
{
if (!(_status is CalculationRunning))
{
_status = new CalculationRunning();
}
}
/// <summary>
/// Gets the current calculation status.
/// </summary>
public ICalculationStatus Status
public IterationStatus Status
{
[DebuggerStepThrough]
get
@ -351,7 +311,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium
/// </summary>
public void ResetToPrecalculationState()
{
_status = DefaultStatus;
_status = IterationStatus.Indetermined;
_lastIteration = DefaultLastIterationNumber;
_residualHistory = null;
}

63
src/Numerics/LinearAlgebra/Double/Solvers/StopCriterium/FailureStopCriterium.cs

@ -28,11 +28,10 @@
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
using MathNet.Numerics.LinearAlgebra.Solvers;
using MathNet.Numerics.LinearAlgebra.Solvers.Status;
using MathNet.Numerics.Properties;
using System;
using System.Diagnostics;
using MathNet.Numerics.LinearAlgebra.Solvers;
using MathNet.Numerics.Properties;
namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium
{
@ -45,22 +44,17 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium
/// Defines the default last iteration number. Set to -1 because iterations normally
/// start at 0.
/// </summary>
private const int DefaultLastIterationNumber = -1;
/// <summary>
/// The default status.
/// </summary>
private static readonly ICalculationStatus DefaultStatus = new CalculationIndetermined();
const int DefaultLastIterationNumber = -1;
/// <summary>
/// The status of the calculation
/// </summary>
private ICalculationStatus _status = DefaultStatus;
IterationStatus _status = IterationStatus.Indetermined;
/// <summary>
/// The iteration number of the last iteration.
/// </summary>
private int _lastIteration = DefaultLastIterationNumber;
int _lastIteration = DefaultLastIterationNumber;
/// <summary>
/// Determines the status of the iterative calculation based on the stop criteria stored
@ -75,23 +69,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium
/// on the invocation of this method. Therefore this method should only be called if the
/// calculation has moved forwards at least one step.
/// </remarks>
public ICalculationStatus DetermineStatus(int iterationNumber, Vector<double> solutionVector, Vector<double> sourceVector, Vector<double> residualVector)
public IterationStatus DetermineStatus(int iterationNumber, Vector<double> solutionVector, Vector<double> sourceVector, Vector<double> residualVector)
{
if (iterationNumber < 0)
{
throw new ArgumentOutOfRangeException("iterationNumber");
}
if (solutionVector == null)
{
throw new ArgumentNullException("solutionVector");
}
if (residualVector == null)
{
throw new ArgumentNullException("residualVector");
}
if (solutionVector.Count != residualVector.Count)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength);
@ -108,45 +92,16 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium
var residualNorm = residualVector.InfinityNorm();
var solutionNorm = solutionVector.InfinityNorm();
if (double.IsNaN(solutionNorm) || double.IsNaN(residualNorm))
{
SetStatusToFailed();
}
else
{
SetStatusToRunning();
}
_status = double.IsNaN(solutionNorm) || double.IsNaN(residualNorm) ? IterationStatus.Failure : IterationStatus.Running;
_lastIteration = iterationNumber;
return _status;
}
/// <summary>
/// Set status to <see cref="CalculationFailure"/>
/// </summary>
private void SetStatusToFailed()
{
if (!(_status is CalculationFailure))
{
_status = new CalculationFailure();
}
}
/// <summary>
/// Set status to <see cref="CalculationRunning"/>
/// </summary>
private void SetStatusToRunning()
{
if (!(_status is CalculationRunning))
{
_status = new CalculationRunning();
}
}
/// <summary>
/// Gets the current calculation status.
/// </summary>
public ICalculationStatus Status
public IterationStatus Status
{
[DebuggerStepThrough]
get
@ -160,7 +115,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium
/// </summary>
public void ResetToPrecalculationState()
{
_status = DefaultStatus;
_status = IterationStatus.Indetermined;
_lastIteration = DefaultLastIterationNumber;
}

95
src/Numerics/LinearAlgebra/Double/Solvers/StopCriterium/ResidualStopCriterium.cs

@ -28,11 +28,10 @@
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
using MathNet.Numerics.LinearAlgebra.Solvers;
using MathNet.Numerics.LinearAlgebra.Solvers.Status;
using MathNet.Numerics.Properties;
using System;
using System.Diagnostics;
using MathNet.Numerics.LinearAlgebra.Solvers;
using MathNet.Numerics.Properties;
namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium
{
@ -54,38 +53,33 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium
/// <summary>
/// Defines the default last iteration number. Set to -1 because iterations normally start at 0.
/// </summary>
private const int DefaultLastIterationNumber = -1;
/// <summary>
/// The default status.
/// </summary>
private static readonly ICalculationStatus DefaultStatus = new CalculationIndetermined();
const int DefaultLastIterationNumber = -1;
/// <summary>
/// The maximum value for the residual below which the calculation is considered converged.
/// </summary>
private double _maximum;
double _maximum;
/// <summary>
/// The minimum number of iterations for which the residual has to be below the maximum before
/// the calculation is considered converged.
/// </summary>
private int _minimumIterationsBelowMaximum;
int _minimumIterationsBelowMaximum;
/// <summary>
/// The status of the calculation
/// </summary>
private ICalculationStatus _status = DefaultStatus;
IterationStatus _status = IterationStatus.Indetermined;
/// <summary>
/// The number of iterations since the residuals got below the maximum.
/// </summary>
private int _iterationCount;
int _iterationCount;
/// <summary>
/// The iteration number of the last iteration.
/// </summary>
private int _lastIteration = DefaultLastIterationNumber;
int _lastIteration = DefaultLastIterationNumber;
/// <summary>
/// Initializes a new instance of the <see cref="ResidualStopCriterium"/> class with the default maximum
@ -222,28 +216,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium
/// on the invocation of this method. Therefore this method should only be called if the
/// calculation has moved forwards at least one step.
/// </remarks>
public ICalculationStatus DetermineStatus(int iterationNumber, Vector<double> solutionVector, Vector<double> sourceVector, Vector<double> residualVector)
public IterationStatus DetermineStatus(int iterationNumber, Vector<double> solutionVector, Vector<double> sourceVector, Vector<double> residualVector)
{
if (iterationNumber < 0)
{
throw new ArgumentOutOfRangeException("iterationNumber");
}
if (solutionVector == null)
{
throw new ArgumentNullException("solutionVector");
}
if (sourceVector == null)
{
throw new ArgumentNullException("sourceVector");
}
if (residualVector == null)
{
throw new ArgumentNullException("residualVector");
}
if (solutionVector.Count != sourceVector.Count)
{
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "sourceVector");
@ -258,7 +237,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium
// These values will be used to calculate the relative drop in residuals
// later on.
var residualNorm = residualVector.InfinityNorm();
// Check the residuals by calculating:
// ||r_i|| <= stop_tol * ||b||
var stopCriterium = ComputeStopCriterium(sourceVector.InfinityNorm());
@ -269,7 +248,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium
if (double.IsNaN(stopCriterium) || double.IsNaN(residualNorm))
{
_iterationCount = 0;
SetStatusToDiverged();
_status = IterationStatus.Diverged;
return _status;
}
@ -281,20 +260,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium
if (_lastIteration <= iterationNumber)
{
_iterationCount = iterationNumber - _lastIteration;
if (_iterationCount >= _minimumIterationsBelowMaximum)
{
SetStatusToConverged();
}
else
{
SetStatusToRunning();
}
_status = _iterationCount >= _minimumIterationsBelowMaximum ? IterationStatus.Converged : IterationStatus.Running;
}
}
else
{
_iterationCount = 0;
SetStatusToRunning();
_status = IterationStatus.Running;
}
_lastIteration = iterationNumber;
@ -306,7 +278,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium
/// </summary>
/// <param name="solutionNorm">Solution vector norm</param>
/// <returns>Criterium value</returns>
private double ComputeStopCriterium(double solutionNorm)
double ComputeStopCriterium(double solutionNorm)
{
// This is criterium 1 from Templates for the solution of linear systems.
// The problem with this criterium is that it's not limiting enough. For now
@ -314,46 +286,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium
// return mMaximumResidual * (System.Math.Abs(mMatrixNorm) * System.Math.Abs(solutionNorm) + System.Math.Abs(mVectorNorm));
// For now use criterium 2 from Templates for the solution of linear systems. See page 60.
return _maximum * Math.Abs(solutionNorm);
}
/// <summary>
/// Set status to <see cref="CalculationDiverged"/>
/// </summary>
private void SetStatusToDiverged()
{
if (!(_status is CalculationDiverged))
{
_status = new CalculationDiverged();
}
}
/// <summary>
/// Set status to <see cref="CalculationConverged"/>
/// </summary>
private void SetStatusToConverged()
{
if (!(_status is CalculationConverged))
{
_status = new CalculationConverged();
}
}
/// <summary>
/// Set status to <see cref="CalculationRunning"/>
/// </summary>
private void SetStatusToRunning()
{
if (!(_status is CalculationRunning))
{
_status = new CalculationRunning();
}
return _maximum*Math.Abs(solutionNorm);
}
/// <summary>
/// Gets the current calculation status.
/// </summary>
public ICalculationStatus Status
public IterationStatus Status
{
[DebuggerStepThrough]
get
@ -367,7 +306,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium
/// </summary>
public void ResetToPrecalculationState()
{
_status = DefaultStatus;
_status = IterationStatus.Indetermined;
_iterationCount = 0;
_lastIteration = DefaultLastIterationNumber;
}

14
src/Numerics/LinearAlgebra/Double/Solvers/TFQMR.cs

@ -30,7 +30,6 @@
using System;
using MathNet.Numerics.LinearAlgebra.Solvers;
using MathNet.Numerics.LinearAlgebra.Solvers.Status;
using MathNet.Numerics.Properties;
namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
@ -54,12 +53,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
/// </remarks>
public sealed class TFQMR : IIterativeSolver<double>
{
/// <summary>
/// The status used if there is no status, i.e. the solver hasn't run yet and there is no
/// iterator.
/// </summary>
static readonly ICalculationStatus DefaultStatus = new CalculationIndetermined();
/// <summary>
/// The preconditioner that will be used. Can be set to <see langword="null" />, in which case the default
/// pre-conditioner will be used.
@ -168,11 +161,11 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
/// <summary>
/// Gets the status of the iteration once the calculation is finished.
/// </summary>
public ICalculationStatus IterationResult
public IterationStatus IterationResult
{
get
{
return (_iterator != null) ? _iterator.Status : DefaultStatus;
return (_iterator != null) ? _iterator.Status : IterationStatus.Indetermined;
}
}
@ -459,7 +452,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
return true;
}
return !_iterator.DetermineStatus(iterationNumber, result, source, residuals).TerminatesCalculation;
var status = _iterator.DetermineStatus(iterationNumber, result, source, residuals);
return status == IterationStatus.Running || status == IterationStatus.Indetermined;
}
/// <summary>

14
src/Numerics/LinearAlgebra/Single/Solvers/BiCgStab.cs

@ -30,7 +30,6 @@
using System;
using MathNet.Numerics.LinearAlgebra.Solvers;
using MathNet.Numerics.LinearAlgebra.Solvers.Status;
using MathNet.Numerics.Properties;
namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
@ -66,12 +65,6 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
/// </remarks>
public sealed class BiCgStab : IIterativeSolver<float>
{
/// <summary>
/// The status used if there is no status, i.e. the solver hasn't run yet and there is no
/// iterator.
/// </summary>
static readonly ICalculationStatus DefaultStatus = new CalculationIndetermined();
/// <summary>
/// The preconditioner that will be used. Can be set to <see langword="null" />, in which case the default
/// pre-conditioner will be used.
@ -180,11 +173,11 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
/// <summary>
/// Gets the status of the iteration once the calculation is finished.
/// </summary>
public ICalculationStatus IterationResult
public IterationStatus IterationResult
{
get
{
return (_iterator != null) ? _iterator.Status : DefaultStatus;
return (_iterator != null) ? _iterator.Status : IterationStatus.Indetermined;
}
}
@ -465,7 +458,8 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
return true;
}
return !_iterator.DetermineStatus(iterationNumber, result, source, residuals).TerminatesCalculation;
var status = _iterator.DetermineStatus(iterationNumber, result, source, residuals);
return status == IterationStatus.Running || status == IterationStatus.Indetermined;
}
/// <summary>

17
src/Numerics/LinearAlgebra/Single/Solvers/CompositeSolver.cs

@ -34,7 +34,6 @@ using System.IO;
using System.Linq;
using System.Reflection;
using MathNet.Numerics.LinearAlgebra.Solvers;
using MathNet.Numerics.LinearAlgebra.Solvers.Status;
using MathNet.Numerics.Properties;
namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
@ -86,16 +85,6 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
#endregion
/// <summary>
/// The default status used if the solver is not running.
/// </summary>
static readonly ICalculationStatus NonRunningStatus = new CalculationIndetermined();
/// <summary>
/// The default status used if the solver is running.
/// </summary>
static readonly ICalculationStatus RunningStatus = new CalculationRunning();
#if PORTABLE
private static readonly Dictionary<double, List<IIterativeSolverSetup<float>>> SolverSetups = new Dictionary<double, List<IIterativeSolverSetup<float>>>();
#else
@ -340,7 +329,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
/// <summary>
/// The status of the calculation.
/// </summary>
ICalculationStatus _status = NonRunningStatus;
IterationStatus _status = IterationStatus.Indetermined;
/// <summary>
/// The iterator that is used to control the iteration process.
@ -386,7 +375,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
/// <summary>
/// Gets the status of the iteration once the calculation is finished.
/// </summary>
public ICalculationStatus IterationResult
public IterationStatus IterationResult
{
get
{
@ -509,7 +498,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
// Switch to the next preconditioner.
// Reset the solution vector to the previous solution
input.CopyTo(internalInput);
_status = RunningStatus;
_status = IterationStatus.Running;
continue;
}

14
src/Numerics/LinearAlgebra/Single/Solvers/GpBiCg.cs

@ -30,7 +30,6 @@
using System;
using MathNet.Numerics.LinearAlgebra.Solvers;
using MathNet.Numerics.LinearAlgebra.Solvers.Status;
using MathNet.Numerics.Properties;
namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
@ -64,12 +63,6 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
/// </remarks>
public sealed class GpBiCg : IIterativeSolver<float>
{
/// <summary>
/// The status used if there is no status, i.e. the solver hasn't run yet and there is no
/// iterator.
/// </summary>
static readonly ICalculationStatus DefaultStatus = new CalculationIndetermined();
/// <summary>
/// The preconditioner that will be used. Can be set to <c>null</c>, in which case the default
/// pre-conditioner will be used.
@ -229,9 +222,9 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
/// <summary>
/// Gets the status of the iteration once the calculation is finished.
/// </summary>
public ICalculationStatus IterationResult
public IterationStatus IterationResult
{
get { return (_iterator != null) ? _iterator.Status : DefaultStatus; }
get { return (_iterator != null) ? _iterator.Status : IterationStatus.Indetermined; }
}
/// <summary>
@ -551,7 +544,8 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
return true;
}
return !_iterator.DetermineStatus(iterationNumber, result, source, residuals).TerminatesCalculation;
var status = _iterator.DetermineStatus(iterationNumber, result, source, residuals);
return status == IterationStatus.Running || status == IterationStatus.Indetermined;
}
/// <summary>

14
src/Numerics/LinearAlgebra/Single/Solvers/MlkBiCgStab.cs

@ -33,7 +33,6 @@ using System.Collections.Generic;
using System.Diagnostics;
using MathNet.Numerics.Distributions;
using MathNet.Numerics.LinearAlgebra.Solvers;
using MathNet.Numerics.LinearAlgebra.Solvers.Status;
using MathNet.Numerics.Properties;
namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
@ -68,12 +67,6 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
/// </summary>
const int DefaultNumberOfStartingVectors = 50;
/// <summary>
/// The status used if there is no status, i.e. the solver hasn't run yet and there is no
/// iterator.
/// </summary>
static readonly ICalculationStatus DefaultStatus = new CalculationIndetermined();
/// <summary>
/// The preconditioner that will be used. Can be set to <see langword="null" />, in which case the default
/// pre-conditioner will be used.
@ -253,12 +246,12 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
/// <summary>
/// Gets the status of the iteration once the calculation is finished.
/// </summary>
public ICalculationStatus IterationResult
public IterationStatus IterationResult
{
[DebuggerStepThrough]
get
{
return (_iterator != null) ? _iterator.Status : DefaultStatus;
return (_iterator != null) ? _iterator.Status : IterationStatus.Indetermined;
}
}
@ -738,7 +731,8 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
return true;
}
return !_iterator.DetermineStatus(iterationNumber, result, source, residuals).TerminatesCalculation;
var status = _iterator.DetermineStatus(iterationNumber, result, source, residuals);
return status == IterationStatus.Running || status == IterationStatus.Indetermined;
}
/// <summary>

52
src/Numerics/LinearAlgebra/Single/Solvers/StopCriterium/DivergenceStopCriterium.cs

@ -29,7 +29,6 @@
// </copyright>
using MathNet.Numerics.LinearAlgebra.Solvers;
using MathNet.Numerics.LinearAlgebra.Solvers.Status;
using System;
using System.Diagnostics;
@ -58,11 +57,6 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.StopCriterium
/// </summary>
private const int DefaultLastIterationNumber = -1;
/// <summary>
/// The default status.
/// </summary>
private static readonly ICalculationStatus DefaultStatus = new CalculationIndetermined();
/// <summary>
/// The maximum relative increase the residual may experience without triggering a divergence warning.
/// </summary>
@ -76,7 +70,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.StopCriterium
/// <summary>
/// The status of the calculation
/// </summary>
private ICalculationStatus _status = DefaultStatus;
private IterationStatus _status = IterationStatus.Indetermined;
/// <summary>
/// The array that holds the tracking information.
@ -217,18 +211,13 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.StopCriterium
/// on the invocation of this method. Therefore this method should only be called if the
/// calculation has moved forwards at least one step.
/// </remarks>
public ICalculationStatus DetermineStatus(int iterationNumber, Vector<float> solutionVector, Vector<float> sourceVector, Vector<float> residualVector)
public IterationStatus DetermineStatus(int iterationNumber, Vector<float> solutionVector, Vector<float> sourceVector, Vector<float> residualVector)
{
if (iterationNumber < 0)
{
throw new ArgumentOutOfRangeException("iterationNumber");
}
if (residualVector == null)
{
throw new ArgumentNullException("residualVector");
}
if (_lastIteration >= iterationNumber)
{
// We have already stored the actual last iteration number
@ -256,19 +245,12 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.StopCriterium
// Stop the iteration.
if (double.IsNaN(_residualHistory[_residualHistory.Length - 1]))
{
SetStatusToDiverged();
_status = IterationStatus.Diverged;
return _status;
}
// Check if we are diverging and if so set the status
if (IsDiverging())
{
SetStatusToDiverged();
}
else
{
SetStatusToRunning();
}
_status = IsDiverging() ? IterationStatus.Diverged : IterationStatus.Running;
_lastIteration = iterationNumber;
return _status;
@ -312,32 +294,10 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.StopCriterium
}
}
/// <summary>
/// Set status to <see cref="CalculationDiverged"/>
/// </summary>
private void SetStatusToDiverged()
{
if (!(_status is CalculationDiverged))
{
_status = new CalculationDiverged();
}
}
/// <summary>
/// Set status to <see cref="CalculationRunning"/>
/// </summary>
private void SetStatusToRunning()
{
if (!(_status is CalculationRunning))
{
_status = new CalculationRunning();
}
}
/// <summary>
/// Gets the current calculation status.
/// </summary>
public ICalculationStatus Status
public IterationStatus Status
{
[DebuggerStepThrough]
get
@ -351,7 +311,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.StopCriterium
/// </summary>
public void ResetToPrecalculationState()
{
_status = DefaultStatus;
_status = IterationStatus.Indetermined;
_lastIteration = DefaultLastIterationNumber;
_residualHistory = null;
}

59
src/Numerics/LinearAlgebra/Single/Solvers/StopCriterium/FailureStopCriterium.cs

@ -28,11 +28,10 @@
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
using MathNet.Numerics.LinearAlgebra.Solvers;
using MathNet.Numerics.LinearAlgebra.Solvers.Status;
using MathNet.Numerics.Properties;
using System;
using System.Diagnostics;
using MathNet.Numerics.LinearAlgebra.Solvers;
using MathNet.Numerics.Properties;
namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.StopCriterium
{
@ -47,15 +46,10 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.StopCriterium
/// </summary>
private const int DefaultLastIterationNumber = -1;
/// <summary>
/// The default status.
/// </summary>
private static readonly ICalculationStatus DefaultStatus = new CalculationIndetermined();
/// <summary>
/// The status of the calculation
/// </summary>
private ICalculationStatus _status = DefaultStatus;
private IterationStatus _status = IterationStatus.Indetermined;
/// <summary>
/// The iteration number of the last iteration.
@ -75,23 +69,13 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.StopCriterium
/// on the invocation of this method. Therefore this method should only be called if the
/// calculation has moved forwards at least one step.
/// </remarks>
public ICalculationStatus DetermineStatus(int iterationNumber, Vector<float> solutionVector, Vector<float> sourceVector, Vector<float> residualVector)
public IterationStatus DetermineStatus(int iterationNumber, Vector<float> solutionVector, Vector<float> sourceVector, Vector<float> residualVector)
{
if (iterationNumber < 0)
{
throw new ArgumentOutOfRangeException("iterationNumber");
}
if (solutionVector == null)
{
throw new ArgumentNullException("solutionVector");
}
if (residualVector == null)
{
throw new ArgumentNullException("residualVector");
}
if (solutionVector.Count != residualVector.Count)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength);
@ -108,45 +92,16 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.StopCriterium
var residualNorm = residualVector.InfinityNorm();
var solutionNorm = solutionVector.InfinityNorm();
if (float.IsNaN(solutionNorm) || float.IsNaN(residualNorm))
{
SetStatusToFailed();
}
else
{
SetStatusToRunning();
}
_status = float.IsNaN(solutionNorm) || float.IsNaN(residualNorm) ? IterationStatus.Failure : IterationStatus.Running;
_lastIteration = iterationNumber;
return _status;
}
/// <summary>
/// Set status to <see cref="CalculationFailure"/>
/// </summary>
private void SetStatusToFailed()
{
if (!(_status is CalculationFailure))
{
_status = new CalculationFailure();
}
}
/// <summary>
/// Set status to <see cref="CalculationRunning"/>
/// </summary>
private void SetStatusToRunning()
{
if (!(_status is CalculationRunning))
{
_status = new CalculationRunning();
}
}
/// <summary>
/// Gets the current calculation status.
/// </summary>
public ICalculationStatus Status
public IterationStatus Status
{
[DebuggerStepThrough]
get
@ -160,7 +115,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.StopCriterium
/// </summary>
public void ResetToPrecalculationState()
{
_status = DefaultStatus;
_status = IterationStatus.Indetermined;
_lastIteration = DefaultLastIterationNumber;
}

95
src/Numerics/LinearAlgebra/Single/Solvers/StopCriterium/ResidualStopCriterium.cs

@ -28,11 +28,10 @@
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
using MathNet.Numerics.LinearAlgebra.Solvers;
using MathNet.Numerics.LinearAlgebra.Solvers.Status;
using MathNet.Numerics.Properties;
using System;
using System.Diagnostics;
using MathNet.Numerics.LinearAlgebra.Solvers;
using MathNet.Numerics.Properties;
namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.StopCriterium
{
@ -54,38 +53,33 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.StopCriterium
/// <summary>
/// Defines the default last iteration number. Set to -1 because iterations normally start at 0.
/// </summary>
private const int DefaultLastIterationNumber = -1;
/// <summary>
/// The default status.
/// </summary>
private static readonly ICalculationStatus DefaultStatus = new CalculationIndetermined();
const int DefaultLastIterationNumber = -1;
/// <summary>
/// The maximum value for the residual below which the calculation is considered converged.
/// </summary>
private float _maximum;
float _maximum;
/// <summary>
/// The minimum number of iterations for which the residual has to be below the maximum before
/// the calculation is considered converged.
/// </summary>
private int _minimumIterationsBelowMaximum;
int _minimumIterationsBelowMaximum;
/// <summary>
/// The status of the calculation
/// </summary>
private ICalculationStatus _status = DefaultStatus;
IterationStatus _status = IterationStatus.Indetermined;
/// <summary>
/// The number of iterations since the residuals got below the maximum.
/// </summary>
private int _iterationCount;
int _iterationCount;
/// <summary>
/// The iteration number of the last iteration.
/// </summary>
private int _lastIteration = DefaultLastIterationNumber;
int _lastIteration = DefaultLastIterationNumber;
/// <summary>
/// Initializes a new instance of the <see cref="ResidualStopCriterium"/> class with the default maximum
@ -222,28 +216,13 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.StopCriterium
/// on the invocation of this method. Therefore this method should only be called if the
/// calculation has moved forwards at least one step.
/// </remarks>
public ICalculationStatus DetermineStatus(int iterationNumber, Vector<float> solutionVector, Vector<float> sourceVector, Vector<float> residualVector)
public IterationStatus DetermineStatus(int iterationNumber, Vector<float> solutionVector, Vector<float> sourceVector, Vector<float> residualVector)
{
if (iterationNumber < 0)
{
throw new ArgumentOutOfRangeException("iterationNumber");
}
if (solutionVector == null)
{
throw new ArgumentNullException("solutionVector");
}
if (sourceVector == null)
{
throw new ArgumentNullException("sourceVector");
}
if (residualVector == null)
{
throw new ArgumentNullException("residualVector");
}
if (solutionVector.Count != sourceVector.Count)
{
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "sourceVector");
@ -258,7 +237,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.StopCriterium
// These values will be used to calculate the relative drop in residuals
// later on.
var residualNorm = residualVector.InfinityNorm();
// Check the residuals by calculating:
// ||r_i|| <= stop_tol * ||b||
var stopCriterium = ComputeStopCriterium(sourceVector.InfinityNorm());
@ -269,7 +248,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.StopCriterium
if (float.IsNaN(stopCriterium) || float.IsNaN(residualNorm))
{
_iterationCount = 0;
SetStatusToDiverged();
_status = IterationStatus.Diverged;
return _status;
}
@ -281,20 +260,13 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.StopCriterium
if (_lastIteration <= iterationNumber)
{
_iterationCount = iterationNumber - _lastIteration;
if (_iterationCount >= _minimumIterationsBelowMaximum)
{
SetStatusToConverged();
}
else
{
SetStatusToRunning();
}
_status = _iterationCount >= _minimumIterationsBelowMaximum ? IterationStatus.Converged : IterationStatus.Running;
}
}
else
{
_iterationCount = 0;
SetStatusToRunning();
_status = IterationStatus.Running;
}
_lastIteration = iterationNumber;
@ -306,7 +278,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.StopCriterium
/// </summary>
/// <param name="solutionNorm">Solution vector norm</param>
/// <returns>Criterium value</returns>
private float ComputeStopCriterium(float solutionNorm)
float ComputeStopCriterium(float solutionNorm)
{
// This is criterium 1 from Templates for the solution of linear systems.
// The problem with this criterium is that it's not limiting enough. For now
@ -314,46 +286,13 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.StopCriterium
// return mMaximumResidual * (System.Math.Abs(mMatrixNorm) * System.Math.Abs(solutionNorm) + System.Math.Abs(mVectorNorm));
// For now use criterium 2 from Templates for the solution of linear systems. See page 60.
return _maximum * Math.Abs(solutionNorm);
}
/// <summary>
/// Set status to <see cref="CalculationDiverged"/>
/// </summary>
private void SetStatusToDiverged()
{
if (!(_status is CalculationDiverged))
{
_status = new CalculationDiverged();
}
}
/// <summary>
/// Set status to <see cref="CalculationConverged"/>
/// </summary>
private void SetStatusToConverged()
{
if (!(_status is CalculationConverged))
{
_status = new CalculationConverged();
}
}
/// <summary>
/// Set status to <see cref="CalculationRunning"/>
/// </summary>
private void SetStatusToRunning()
{
if (!(_status is CalculationRunning))
{
_status = new CalculationRunning();
}
return _maximum*Math.Abs(solutionNorm);
}
/// <summary>
/// Gets the current calculation status.
/// </summary>
public ICalculationStatus Status
public IterationStatus Status
{
[DebuggerStepThrough]
get
@ -367,7 +306,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.StopCriterium
/// </summary>
public void ResetToPrecalculationState()
{
_status = DefaultStatus;
_status = IterationStatus.Indetermined;
_iterationCount = 0;
_lastIteration = DefaultLastIterationNumber;
}

14
src/Numerics/LinearAlgebra/Single/Solvers/TFQMR.cs

@ -30,7 +30,6 @@
using System;
using MathNet.Numerics.LinearAlgebra.Solvers;
using MathNet.Numerics.LinearAlgebra.Solvers.Status;
using MathNet.Numerics.Properties;
namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
@ -54,12 +53,6 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
/// </remarks>
public sealed class TFQMR : IIterativeSolver<float>
{
/// <summary>
/// The status used if there is no status, i.e. the solver hasn't run yet and there is no
/// iterator.
/// </summary>
static readonly ICalculationStatus DefaultStatus = new CalculationIndetermined();
/// <summary>
/// The preconditioner that will be used. Can be set to <see langword="null" />, in which case the default
/// pre-conditioner will be used.
@ -169,9 +162,9 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
/// <summary>
/// Gets the status of the iteration once the calculation is finished.
/// </summary>
public ICalculationStatus IterationResult
public IterationStatus IterationResult
{
get { return (_iterator != null) ? _iterator.Status : DefaultStatus; }
get { return (_iterator != null) ? _iterator.Status : IterationStatus.Indetermined; }
}
/// <summary>
@ -457,7 +450,8 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
return true;
}
return !_iterator.DetermineStatus(iterationNumber, result, source, residuals).TerminatesCalculation;
var status = _iterator.DetermineStatus(iterationNumber, result, source, residuals);
return status == IterationStatus.Running || status == IterationStatus.Indetermined;
}
/// <summary>

4
src/Numerics/LinearAlgebra/Solvers/IIterationStopCriterium.cs

@ -50,13 +50,13 @@ namespace MathNet.Numerics.LinearAlgebra.Solvers
/// on the invocation of this method. Therefore this method should only be called if the
/// calculation has moved forwards at least one step.
/// </remarks>
ICalculationStatus DetermineStatus(int iterationNumber, Vector<T> solutionVector, Vector<T> sourceVector, Vector<T> residualVector);
IterationStatus DetermineStatus(int iterationNumber, Vector<T> solutionVector, Vector<T> sourceVector, Vector<T> residualVector);
/// <summary>
/// Gets the current calculation status.
/// </summary>
/// <remarks><see langword="null" /> is not a legal value. Status should be set in <see cref="DetermineStatus"/> implementation.</remarks>
ICalculationStatus Status { get; }
IterationStatus Status { get; }
/// <summary>
/// Resets the IIterationStopCriterium to the pre-calculation state.

2
src/Numerics/LinearAlgebra/Solvers/IIterativeSolver.cs

@ -55,7 +55,7 @@ namespace MathNet.Numerics.LinearAlgebra.Solvers
/// <summary>
/// Gets the status of the iteration once the calculation is finished.
/// </summary>
ICalculationStatus IterationResult { get; }
IterationStatus IterationResult { get; }
/// <summary>
/// Solves the matrix equation Ax = b, where A is the coefficient matrix, b is the

56
src/Numerics/LinearAlgebra/Solvers/IterationCountStopCriterium.cs

@ -30,7 +30,6 @@
using System;
using System.Diagnostics;
using MathNet.Numerics.LinearAlgebra.Solvers.Status;
namespace MathNet.Numerics.LinearAlgebra.Solvers
{
@ -46,11 +45,6 @@ namespace MathNet.Numerics.LinearAlgebra.Solvers
/// </summary>
public const int DefaultMaximumNumberOfIterations = 1000;
/// <summary>
/// The default status.
/// </summary>
static readonly ICalculationStatus DefaultStatus = new CalculationIndetermined();
/// <summary>
/// The maximum number of iterations the calculation is allowed to perform.
/// </summary>
@ -59,7 +53,7 @@ namespace MathNet.Numerics.LinearAlgebra.Solvers
/// <summary>
/// The status of the calculation
/// </summary>
ICalculationStatus _status = DefaultStatus;
IterationStatus _status = IterationStatus.Indetermined;
/// <summary>
/// Initializes a new instance of the <see cref="IterationCountStopCriterium{T}"/> class with the default maximum
@ -91,7 +85,10 @@ namespace MathNet.Numerics.LinearAlgebra.Solvers
public int MaximumNumberOfIterations
{
[DebuggerStepThrough]
get { return _maximumNumberOfIterations; }
get
{
return _maximumNumberOfIterations;
}
[DebuggerStepThrough]
set
@ -126,53 +123,28 @@ namespace MathNet.Numerics.LinearAlgebra.Solvers
/// on the invocation of this method. Therefore this method should only be called if the
/// calculation has moved forwards at least one step.
/// </remarks>
public ICalculationStatus DetermineStatus(int iterationNumber, Vector<T> solutionVector, Vector<T> sourceVector, Vector<T> residualVector)
public IterationStatus DetermineStatus(int iterationNumber, Vector<T> solutionVector, Vector<T> sourceVector, Vector<T> residualVector)
{
if (iterationNumber < 0)
{
throw new ArgumentOutOfRangeException("iterationNumber");
}
if (iterationNumber >= _maximumNumberOfIterations)
{
SetStatusToFinished();
}
else
{
SetStatusToRunning();
}
return _status;
}
/// <summary>
/// Set status to <see cref="CalculationFailure"/>
/// </summary>
void SetStatusToFinished()
{
if (!(_status is CalculationStoppedWithoutConvergence))
{
_status = new CalculationStoppedWithoutConvergence();
}
}
_status = iterationNumber >= _maximumNumberOfIterations ? IterationStatus.StoppedWithoutConvergence : IterationStatus.Running;
/// <summary>
/// Set status to <see cref="CalculationRunning"/>
/// </summary>
void SetStatusToRunning()
{
if (!(_status is CalculationRunning))
{
_status = new CalculationRunning();
}
return _status;
}
/// <summary>
/// Gets the current calculation status.
/// </summary>
public ICalculationStatus Status
public IterationStatus Status
{
[DebuggerStepThrough]
get { return _status; }
get
{
return _status;
}
}
/// <summary>
@ -180,7 +152,7 @@ namespace MathNet.Numerics.LinearAlgebra.Solvers
/// </summary>
public void ResetToPrecalculationState()
{
_status = DefaultStatus;
_status = IterationStatus.Indetermined;
}
/// <summary>

17
src/Numerics/LinearAlgebra/Solvers/ICalculationStatus.cs → src/Numerics/LinearAlgebra/Solvers/IterationStatus.cs

@ -1,4 +1,4 @@
// <copyright file="ICalculationStatus.cs" company="Math.NET">
// <copyright file="IterationStatus.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
@ -31,13 +31,16 @@
namespace MathNet.Numerics.LinearAlgebra.Solvers
{
/// <summary>
/// Defines the base interface for calculation status objects.
/// Iterative Calculation Status
/// </summary>
public interface ICalculationStatus
public enum IterationStatus
{
/// <summary>
/// Gets a value indicating whether current status warrants stopping the calculation.
/// </summary>
bool TerminatesCalculation { get; }
Indetermined = 0,
Running,
Converged,
Diverged,
StoppedWithoutConvergence,
Cancelled,
Failure
}
}

26
src/Numerics/LinearAlgebra/Solvers/Iterator.cs

@ -31,7 +31,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using MathNet.Numerics.LinearAlgebra.Solvers.Status;
using MathNet.Numerics.Properties;
namespace MathNet.Numerics.LinearAlgebra.Solvers
@ -50,7 +49,7 @@ namespace MathNet.Numerics.LinearAlgebra.Solvers
/// <summary>
/// The status of the iterator.
/// </summary>
ICalculationStatus _status = new CalculationIndetermined();
IterationStatus _status = IterationStatus.Indetermined;
/// <summary>
/// Initializes a new instance of the <see cref="Iterator{T}"/> class with the specified stop criteria.
@ -79,7 +78,7 @@ namespace MathNet.Numerics.LinearAlgebra.Solvers
/// <summary>
/// Gets the current calculation status.
/// </summary>
public ICalculationStatus Status
public IterationStatus Status
{
get { return _status; }
}
@ -89,7 +88,7 @@ namespace MathNet.Numerics.LinearAlgebra.Solvers
/// </summary>
public bool HasConverged
{
get { return _status is CalculationConverged; }
get { return _status == IterationStatus.Converged; }
}
/// <summary>
@ -97,7 +96,7 @@ namespace MathNet.Numerics.LinearAlgebra.Solvers
/// </summary>
public bool HasStoppedWithoutConvergence
{
get { return _status is CalculationStoppedWithoutConvergence; }
get { return _status == IterationStatus.StoppedWithoutConvergence; }
}
/// <summary>
@ -113,7 +112,7 @@ namespace MathNet.Numerics.LinearAlgebra.Solvers
/// on the invocation of this method. Therefore this method should only be called if the
/// calculation has moved forwards at least one step.
/// </remarks>
public ICalculationStatus DetermineStatus(int iterationNumber, Vector<T> solutionVector, Vector<T> sourceVector, Vector<T> residualVector)
public IterationStatus DetermineStatus(int iterationNumber, Vector<T> solutionVector, Vector<T> sourceVector, Vector<T> residualVector)
{
if (_stopCriteria.Count == 0)
{
@ -126,7 +125,7 @@ namespace MathNet.Numerics.LinearAlgebra.Solvers
}
// While we're cancelled we don't call on the stop-criteria.
if (_status is CalculationCancelled)
if (_status == IterationStatus.Cancelled)
{
return _status;
}
@ -140,7 +139,7 @@ namespace MathNet.Numerics.LinearAlgebra.Solvers
// - Indetermined --> keep going
// Anything else:
// Stop looping and set that status
if ((status is CalculationRunning) || (status is CalculationIndetermined))
if ((status == IterationStatus.Running) || (status == IterationStatus.Indetermined))
{
continue;
}
@ -151,10 +150,7 @@ namespace MathNet.Numerics.LinearAlgebra.Solvers
// Got all the way through
// So we're running because we had vectors passed to us.
if (!(_status is CalculationRunning))
{
_status = new CalculationRunning();
}
_status = IterationStatus.Running;
return _status;
}
@ -167,7 +163,7 @@ namespace MathNet.Numerics.LinearAlgebra.Solvers
/// </remarks>
public void Cancel()
{
_status = new CalculationCancelled();
_status = IterationStatus.Cancelled;
}
/// <summary>
@ -175,10 +171,8 @@ namespace MathNet.Numerics.LinearAlgebra.Solvers
/// </summary>
public void Reset()
{
// Reset the status.
_status = new CalculationIndetermined();
_status = IterationStatus.Indetermined;
// Reset the stop-criteria
foreach (var stopCriterium in _stopCriteria)
{
stopCriterium.ResetToPrecalculationState();

49
src/Numerics/LinearAlgebra/Solvers/Status/CalculationCancelled.cs

@ -1,49 +0,0 @@
// <copyright file="CalculationCancelled.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
//
// Copyright (c) 2009-2010 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
namespace MathNet.Numerics.LinearAlgebra.Solvers.Status
{
/// <summary>
/// Indicates that a calculation was cancelled by the user.
/// </summary>
public struct CalculationCancelled : ICalculationStatus
{
/// <summary>
/// Gets a value indicating whether current status warrants stopping the calculation.
/// </summary>
public bool TerminatesCalculation
{
get
{
return true;
}
}
}
}

51
src/Numerics/LinearAlgebra/Solvers/Status/CalculationConverged.cs

@ -1,51 +0,0 @@
// <copyright file="CalculationConverged.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
//
// Copyright (c) 2009-2010 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
namespace MathNet.Numerics.LinearAlgebra.Solvers.Status
{
/// <summary>
/// Indicates that a calculation has converged to the desired convergence levels.
/// </summary>
public struct CalculationConverged : ICalculationStatus
{
/// <summary>
/// Gets a value indicating whether current status warrants stopping the calculation.
/// </summary>
public bool TerminatesCalculation
{
get
{
return true;
}
}
// TODO: CalculationConverged: Should we put the achieved residuals and convergence levels on here?
}
}

51
src/Numerics/LinearAlgebra/Solvers/Status/CalculationDiverged.cs

@ -1,51 +0,0 @@
// <copyright file="CalculationDiverged.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
//
// Copyright (c) 2009-2010 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
namespace MathNet.Numerics.LinearAlgebra.Solvers.Status
{
/// <summary>
/// Indicates that the calculation diverged.
/// </summary>
public struct CalculationDiverged : ICalculationStatus
{
/// <summary>
/// Gets a value indicating whether current status warrants stopping the calculation.
/// </summary>
public bool TerminatesCalculation
{
get
{
return true;
}
}
// TODO: CalculationDiverged - Should we put the residuals on here?
}
}

51
src/Numerics/LinearAlgebra/Solvers/Status/CalculationFailure.cs

@ -1,51 +0,0 @@
// <copyright file="CalculationFailure.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
//
// Copyright (c) 2009-2010 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
namespace MathNet.Numerics.LinearAlgebra.Solvers.Status
{
/// <summary>
/// Indicates that a calculation has failed for some reason.
/// </summary>
public struct CalculationFailure : ICalculationStatus
{
/// <summary>
/// Gets a value indicating whether current status warrants stopping the calculation.
/// </summary>
public bool TerminatesCalculation
{
get
{
return true;
}
}
// TODO: CalcuationFailure - Indicate why the calculation has failed?
}
}

49
src/Numerics/LinearAlgebra/Solvers/Status/CalculationIndetermined.cs

@ -1,49 +0,0 @@
// <copyright file="CalculationIndetermined.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
//
// Copyright (c) 2009-2010 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
namespace MathNet.Numerics.LinearAlgebra.Solvers.Status
{
/// <summary>
/// Indicates that the state of the calculation is indetermined, not started or stopped.
/// </summary>
public struct CalculationIndetermined : ICalculationStatus
{
/// <summary>
/// Gets a value indicating whether current status warrants stopping the calculation.
/// </summary>
public bool TerminatesCalculation
{
get
{
return false;
}
}
}
}

51
src/Numerics/LinearAlgebra/Solvers/Status/CalculationRunning.cs

@ -1,51 +0,0 @@
// <copyright file="CalculationRunning.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
//
// Copyright (c) 2009-2010 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
namespace MathNet.Numerics.LinearAlgebra.Solvers.Status
{
/// <summary>
/// Indicates that the calculation is running and no results are yet known.
/// </summary>
public struct CalculationRunning : ICalculationStatus
{
/// <summary>
/// Gets a value indicating whether current status warrants stopping the calculation.
/// </summary>
public bool TerminatesCalculation
{
get
{
return false;
}
}
// TODO: CalculationRunning - Get current residuals?
}
}

52
src/Numerics/LinearAlgebra/Solvers/Status/CalculationStoppedWithoutConvergence.cs

@ -1,52 +0,0 @@
// <copyright file="CalculationStoppedWithoutConvergence.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
//
// Copyright (c) 2009-2010 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
namespace MathNet.Numerics.LinearAlgebra.Solvers.Status
{
/// <summary>
/// Indicates that the calculation has been stopped due to reaching the stopping
/// limits, but that convergence was not achieved.
/// </summary>
public struct CalculationStoppedWithoutConvergence : ICalculationStatus
{
/// <summary>
/// Gets a value indicating whether current status warrants stopping the calculation.
/// </summary>
public bool TerminatesCalculation
{
get
{
return true;
}
}
// TODO: Indicate which stopping limit was reached?
}
}

9
src/Numerics/Numerics.csproj

@ -123,6 +123,7 @@
<Compile Include="Distributions\Zipf.cs" />
<Compile Include="LinearAlgebra\Builder.cs" />
<Compile Include="LinearAlgebra\Matrix.Factorization.cs" />
<Compile Include="LinearAlgebra\Solvers\IterationStatus.cs" />
<Compile Include="LinearAlgebra\Solvers\Iterator.cs" />
<Compile Include="LinearAlgebra\Solvers\IterationCountStopCriterium.cs" />
<Compile Include="Providers\LinearAlgebra\Acml\AcmlLinearAlgebraProvider.Complex.cs" />
@ -345,14 +346,6 @@
<SubType>Code</SubType>
</Compile>
<Compile Include="LinearAlgebra\Solvers\UnitPreconditioner.cs" />
<Compile Include="LinearAlgebra\Solvers\Status\CalculationCancelled.cs" />
<Compile Include="LinearAlgebra\Solvers\Status\CalculationConverged.cs" />
<Compile Include="LinearAlgebra\Solvers\Status\CalculationDiverged.cs" />
<Compile Include="LinearAlgebra\Solvers\Status\CalculationFailure.cs" />
<Compile Include="LinearAlgebra\Solvers\Status\CalculationIndetermined.cs" />
<Compile Include="LinearAlgebra\Solvers\Status\CalculationRunning.cs" />
<Compile Include="LinearAlgebra\Solvers\Status\CalculationStoppedWithoutConvergence.cs" />
<Compile Include="LinearAlgebra\Solvers\ICalculationStatus.cs" />
<Compile Include="LinearAlgebra\Double\Solvers\StopCriterium\DivergenceStopCriterium.cs" />
<Compile Include="LinearAlgebra\Double\Solvers\StopCriterium\FailureStopCriterium.cs" />
<Compile Include="LinearAlgebra\Double\Solvers\StopCriterium\ResidualStopCriterium.cs" />

81
src/UnitTests/LinearAlgebraTests/Complex/Solvers/IteratorTest.cs

@ -33,7 +33,6 @@ using System.Collections.Generic;
using MathNet.Numerics.LinearAlgebra.Complex;
using MathNet.Numerics.LinearAlgebra.Complex.Solvers.StopCriterium;
using MathNet.Numerics.LinearAlgebra.Solvers;
using MathNet.Numerics.LinearAlgebra.Solvers.Status;
using NUnit.Framework;
namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers
@ -82,72 +81,6 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers
DenseVector.Create(3, i => 6)));
}
/// <summary>
/// Determine status with <c>null</c> solution vector throws <c>ArgumentNullException</c>.
/// </summary>
[Test]
public void DetermineStatusWithNullSolutionVectorThrowsArgumentNullException()
{
var criteria = new List<IIterationStopCriterium<Complex>>
{
new FailureStopCriterium(),
new DivergenceStopCriterium(),
new IterationCountStopCriterium<Complex>(),
new ResidualStopCriterium()
};
var iterator = new Iterator<Complex>(criteria);
Assert.Throws<ArgumentNullException>(() => iterator.DetermineStatus(
1,
null,
DenseVector.Create(3, i => 5),
DenseVector.Create(3, i => 6)));
}
/// <summary>
/// Determine status with <c>null</c> source vector throws <c>ArgumentNullException</c>.
/// </summary>
[Test]
public void DetermineStatusWithNullSourceVectorThrowsArgumentNullException()
{
var criteria = new List<IIterationStopCriterium<Complex>>
{
new FailureStopCriterium(),
new DivergenceStopCriterium(),
new IterationCountStopCriterium<Complex>(),
new ResidualStopCriterium()
};
var iterator = new Iterator<Complex>(criteria);
Assert.Throws<ArgumentNullException>(() => iterator.DetermineStatus(
1,
DenseVector.Create(3, i => 5),
null,
DenseVector.Create(3, i => 6)));
}
/// <summary>
/// Determine status with <c>null</c> residual vector throws <c>ArgumentNullException</c>.
/// </summary>
[Test]
public void DetermineStatusWithNullResidualVectorThrowsArgumentNullException()
{
var criteria = new List<IIterationStopCriterium<Complex>>
{
new FailureStopCriterium(),
new DivergenceStopCriterium(),
new IterationCountStopCriterium<Complex>(),
new ResidualStopCriterium()
};
var iterator = new Iterator<Complex>(criteria);
Assert.Throws<ArgumentNullException>(() => iterator.DetermineStatus(
1,
DenseVector.Create(3, i => 4),
DenseVector.Create(3, i => 5),
null));
}
/// <summary>
/// Can determine status.
/// </summary>
@ -169,7 +102,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers
DenseVector.Create(3, i => 4),
DenseVector.Create(3, i => 4),
DenseVector.Create(3, i => 4));
Assert.IsInstanceOf(typeof (CalculationRunning), iterator.Status, "Incorrect status");
Assert.AreEqual(IterationStatus.Running, iterator.Status, "Incorrect status");
// Second step, should run out of iterations.
iterator.DetermineStatus(
@ -177,7 +110,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers
DenseVector.Create(3, i => 4),
DenseVector.Create(3, i => 4),
DenseVector.Create(3, i => 4));
Assert.IsInstanceOf(typeof (CalculationStoppedWithoutConvergence), iterator.Status, "Incorrect status");
Assert.AreEqual(IterationStatus.StoppedWithoutConvergence, iterator.Status, "Incorrect status");
}
/// <summary>
@ -201,13 +134,13 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers
DenseVector.Create(3, i => 4),
DenseVector.Create(3, i => 4),
DenseVector.Create(3, i => 4));
Assert.IsInstanceOf(typeof (CalculationRunning), iterator.Status, "Incorrect status");
Assert.AreEqual(IterationStatus.Running, iterator.Status, "Incorrect status");
iterator.Reset();
Assert.IsInstanceOf(typeof (CalculationIndetermined), iterator.Status, "Incorrect status");
Assert.IsInstanceOf(typeof (CalculationIndetermined), criteria[0].Status, "Incorrect status");
Assert.IsInstanceOf(typeof (CalculationIndetermined), criteria[1].Status, "Incorrect status");
Assert.IsInstanceOf(typeof (CalculationIndetermined), criteria[2].Status, "Incorrect status");
Assert.AreEqual(IterationStatus.Indetermined, iterator.Status, "Incorrect status");
Assert.AreEqual(IterationStatus.Indetermined, criteria[0].Status, "Incorrect status");
Assert.AreEqual(IterationStatus.Indetermined, criteria[1].Status, "Incorrect status");
Assert.AreEqual(IterationStatus.Indetermined, criteria[2].Status, "Incorrect status");
}
}
}

34
src/UnitTests/LinearAlgebraTests/Complex/Solvers/StopCriterium/DivergenceStopCriteriumTest.cs

@ -28,11 +28,11 @@
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
using System;
using MathNet.Numerics.LinearAlgebra.Complex;
using MathNet.Numerics.LinearAlgebra.Complex.Solvers.StopCriterium;
using MathNet.Numerics.LinearAlgebra.Solvers.Status;
using MathNet.Numerics.LinearAlgebra.Solvers;
using NUnit.Framework;
using System;
namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.StopCriterium
{
@ -119,20 +119,6 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.StopCrit
DenseVector.Create(3, i => 6)));
}
/// <summary>
/// Determine status with <c>null</c> residual vector throws <c>ArgumentNullException</c>.
/// </summary>
[Test]
public void DetermineStatusWithNullResidualVectorThrowsArgumentNullException()
{
var criterium = new DivergenceStopCriterium(0.5, 15);
Assert.Throws<ArgumentNullException>(() => criterium.DetermineStatus(
1,
DenseVector.Create(3, i => 4),
DenseVector.Create(3, i => 5),
null));
}
/// <summary>
/// Can determine status with too few iterations.
/// </summary>
@ -153,7 +139,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.StopCrit
new DenseVector(new[] {new Complex(1.0, 0)}),
new DenseVector(new[] {new Complex((i + 1)*(Increase + 0.1), 0)}));
Assert.IsInstanceOf(typeof (CalculationRunning), status, "Status check fail.");
Assert.AreEqual(IterationStatus.Running, status, "Status check fail.");
}
}
@ -177,7 +163,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.StopCrit
new DenseVector(new[] {new Complex(1.0, 0)}),
new DenseVector(new[] {new Complex((i + 1)*(Increase - 0.01), 0)}));
Assert.IsInstanceOf(typeof (CalculationRunning), status, "Status check fail.");
Assert.AreEqual(IterationStatus.Running, status, "Status check fail.");
}
}
@ -201,7 +187,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.StopCrit
new DenseVector(new[] {new Complex(1.0, 0)}),
new DenseVector(new[] {new Complex((i + 1)*(Increase - 0.01), 0)}));
Assert.IsInstanceOf(typeof (CalculationRunning), status, "Status check fail.");
Assert.AreEqual(IterationStatus.Running, status, "Status check fail.");
}
// Now make it fail by throwing in a NaN
@ -211,7 +197,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.StopCrit
new DenseVector(new[] {new Complex(1.0, 0)}),
new DenseVector(new[] {new Complex(double.NaN, 0)}));
Assert.IsInstanceOf(typeof (CalculationDiverged), status2, "Status check fail.");
Assert.AreEqual(IterationStatus.Diverged, status2, "Status check fail.");
}
/// <summary>
@ -236,7 +222,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.StopCrit
new DenseVector(new[] {new Complex(1.0, 0)}),
new DenseVector(new[] {new Complex(previous, 0)}));
Assert.IsInstanceOf(typeof (CalculationRunning), status, "Status check fail.");
Assert.AreEqual(IterationStatus.Running, status, "Status check fail.");
}
// Add the final residual. Now we should have divergence
@ -247,7 +233,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.StopCrit
new DenseVector(new[] {new Complex(1.0, 0)}),
new DenseVector(new[] {new Complex(previous, 0)}));
Assert.IsInstanceOf(typeof (CalculationDiverged), status2, "Status check fail.");
Assert.AreEqual(IterationStatus.Diverged, status2, "Status check fail.");
}
/// <summary>
@ -268,14 +254,14 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.StopCrit
new DenseVector(new[] {new Complex(1.0, 0)}),
new DenseVector(new[] {new Complex(double.NaN, 0)}));
Assert.IsInstanceOf(typeof (CalculationDiverged), status, "Status check fail.");
Assert.AreEqual(IterationStatus.Diverged, status, "Status check fail.");
// Reset the state
criterium.ResetToPrecalculationState();
Assert.AreEqual(Increase, criterium.MaximumRelativeIncrease, "Incorrect maximum");
Assert.AreEqual(Iterations, criterium.MinimumNumberOfIterations, "Incorrect iteration count");
Assert.IsInstanceOf(typeof (CalculationIndetermined), criterium.Status, "Status check fail.");
Assert.AreEqual(IterationStatus.Indetermined, criterium.Status, "Status check fail.");
}
/// <summary>

36
src/UnitTests/LinearAlgebraTests/Complex/Solvers/StopCriterium/FailureStopCriteriumTest.cs

@ -28,10 +28,10 @@
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
using MathNet.Numerics.LinearAlgebra.Solvers.Status;
using System;
using MathNet.Numerics.LinearAlgebra.Complex;
using MathNet.Numerics.LinearAlgebra.Complex.Solvers.StopCriterium;
using MathNet.Numerics.LinearAlgebra.Solvers;
using NUnit.Framework;
namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.StopCriterium
@ -66,30 +66,6 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.StopCrit
Assert.Throws<ArgumentOutOfRangeException>(() => criterium.DetermineStatus(-1, DenseVector.Create(3, i => 4), DenseVector.Create(3, i => 5), DenseVector.Create(3, i => 6)));
}
/// <summary>
/// Determine status with <c>null</c> solution vector throws <c>ArgumentNullException</c>.
/// </summary>
[Test]
public void DetermineStatusWithNullSolutionVectorThrowsArgumentNullException()
{
var criterium = new FailureStopCriterium();
Assert.IsNotNull(criterium, "There should be a criterium");
Assert.Throws<ArgumentNullException>(() => criterium.DetermineStatus(1, null, DenseVector.Create(3, i => 6), DenseVector.Create(4, i => 4)));
}
/// <summary>
/// Determine status with <c>null</c> residual vector throws <c>ArgumentNullException</c>.
/// </summary>
[Test]
public void DetermineStatusWithNullResidualVectorThrowsArgumentNullException()
{
var criterium = new FailureStopCriterium();
Assert.IsNotNull(criterium, "There should be a criterium");
Assert.Throws<ArgumentNullException>(() => criterium.DetermineStatus(1, DenseVector.Create(3, i => 4), DenseVector.Create(3, i => 6), null));
}
/// <summary>
/// Determine status with non-matching vectors throws <c>ArgumentException</c>.
/// </summary>
@ -116,7 +92,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.StopCrit
var residual = new DenseVector(new[] {new Complex(1000, 0), new Complex(double.NaN, 0), new Complex(2001, 0)});
var status = criterium.DetermineStatus(5, solution, source, residual);
Assert.IsInstanceOf(typeof (CalculationFailure), status, "Should be failed");
Assert.AreEqual(IterationStatus.Failure, status, "Should be failed");
}
/// <summary>
@ -133,7 +109,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.StopCrit
var residual = new DenseVector(new[] {new Complex(1000, 0), new Complex(1000, 0), new Complex(2001, 0)});
var status = criterium.DetermineStatus(5, solution, source, residual);
Assert.IsInstanceOf(typeof (CalculationFailure), status, "Should be failed");
Assert.AreEqual(IterationStatus.Failure, status, "Should be failed");
}
/// <summary>
@ -150,7 +126,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.StopCrit
var residual = new DenseVector(new[] {new Complex(1.0, 0), new Complex(2.0, 0), new Complex(3, 0)});
var status = criterium.DetermineStatus(5, solution, source, residual);
Assert.IsInstanceOf(typeof (CalculationRunning), status, "Should be running");
Assert.AreEqual(IterationStatus.Running, status, "Should be running");
}
/// <summary>
@ -167,10 +143,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.StopCrit
var residual = new DenseVector(new[] {new Complex(1000, 0), new Complex(1000, 0), new Complex(2001, 0)});
var status = criterium.DetermineStatus(5, solution, source, residual);
Assert.IsInstanceOf(typeof (CalculationRunning), status, "Should be running");
Assert.AreEqual(IterationStatus.Running, status, "Should be running");
criterium.ResetToPrecalculationState();
Assert.IsInstanceOf(typeof (CalculationIndetermined), criterium.Status, "Should not have started");
Assert.AreEqual(IterationStatus.Indetermined, criterium.Status, "Should not have started");
}
/// <summary>

9
src/UnitTests/LinearAlgebraTests/Complex/Solvers/StopCriterium/IterationCountStopCriteriumTest.cs

@ -31,7 +31,6 @@
using System;
using MathNet.Numerics.LinearAlgebra.Complex;
using MathNet.Numerics.LinearAlgebra.Solvers;
using MathNet.Numerics.LinearAlgebra.Solvers.Status;
using NUnit.Framework;
namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.StopCriterium
@ -100,10 +99,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.StopCrit
Assert.IsNotNull(criterium, "A criterium should have been created");
var status = criterium.DetermineStatus(5, DenseVector.Create(3, i => 1), DenseVector.Create(3, i => 2), DenseVector.Create(3, i => 3));
Assert.IsInstanceOf(typeof (CalculationRunning), status, "Should be running");
Assert.AreEqual(IterationStatus.Running, status, "Should be running");
var status2 = criterium.DetermineStatus(10, DenseVector.Create(3, i => 1), DenseVector.Create(3, i => 2), DenseVector.Create(3, i => 3));
Assert.IsInstanceOf(typeof (CalculationStoppedWithoutConvergence), status2, "Should be finished");
Assert.AreEqual(IterationStatus.StoppedWithoutConvergence, status2, "Should be finished");
}
/// <summary>
@ -116,10 +115,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.StopCrit
Assert.IsNotNull(criterium, "A criterium should have been created");
var status = criterium.DetermineStatus(5, DenseVector.Create(3, i => 1), DenseVector.Create(3, i => 2), DenseVector.Create(3, i => 3));
Assert.IsInstanceOf(typeof (CalculationRunning), status, "Should be running");
Assert.AreEqual(IterationStatus.Running, status, "Should be running");
criterium.ResetToPrecalculationState();
Assert.IsInstanceOf(typeof (CalculationIndetermined), criterium.Status, "Should not have started");
Assert.AreEqual(IterationStatus.Indetermined, criterium.Status, "Should not have started");
}
/// <summary>

66
src/UnitTests/LinearAlgebraTests/Complex/Solvers/StopCriterium/ResidualStopCriteriumTest.cs

@ -28,11 +28,11 @@
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
using System;
using MathNet.Numerics.LinearAlgebra.Complex;
using MathNet.Numerics.LinearAlgebra.Complex.Solvers.StopCriterium;
using MathNet.Numerics.LinearAlgebra.Solvers.Status;
using MathNet.Numerics.LinearAlgebra.Solvers;
using NUnit.Framework;
using System;
namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.StopCriterium
{
@ -117,54 +117,6 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.StopCrit
DenseVector.Create(3, i => 6)));
}
/// <summary>
/// Determine status with <c>null</c> solution vector throws <c>ArgumentNullException</c>.
/// </summary>
[Test]
public void DetermineStatusWithNullSolutionVectorThrowsArgumentNullException()
{
var criterium = new ResidualStopCriterium(1e-8, 50);
Assert.IsNotNull(criterium, "There should be a criterium");
Assert.Throws<ArgumentNullException>(() => criterium.DetermineStatus(
1,
null,
DenseVector.Create(3, i => 5),
DenseVector.Create(3, i => 6)));
}
/// <summary>
/// Determine status with <c>null</c> source vector throws <c>ArgumentNullException</c>.
/// </summary>
[Test]
public void DetermineStatusWithNullSourceVectorThrowsArgumentNullException()
{
var criterium = new ResidualStopCriterium(1e-8, 50);
Assert.IsNotNull(criterium, "There should be a criterium");
Assert.Throws<ArgumentNullException>(() => criterium.DetermineStatus(
1,
DenseVector.Create(3, i => 4),
null,
DenseVector.Create(3, i => 6)));
}
/// <summary>
/// Determine status with <c>null</c> residual vector throws <c>ArgumentNullException</c>.
/// </summary>
[Test]
public void DetermineStatusWithNullResidualVectorThrowsArgumentNullException()
{
var criterium = new ResidualStopCriterium(1e-8, 50);
Assert.IsNotNull(criterium, "There should be a criterium");
Assert.Throws<ArgumentNullException>(() => criterium.DetermineStatus(
1,
DenseVector.Create(3, i => 4),
DenseVector.Create(3, i => 5),
null));
}
/// <summary>
/// Determine status with non-matching solution vector throws <c>ArgumentException</c>.
/// </summary>
@ -227,7 +179,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.StopCrit
var residual = new DenseVector(new[] {new Complex(1000.0, 1), new Complex(1000.0, 1), new Complex(2001.0, 1)});
var status = criterium.DetermineStatus(5, solution, source, residual);
Assert.IsInstanceOf(typeof (CalculationDiverged), status, "Should be diverged");
Assert.AreEqual(IterationStatus.Diverged, status, "Should be diverged");
}
/// <summary>
@ -244,7 +196,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.StopCrit
var residual = new DenseVector(new[] {new Complex(1000.0, 1), new Complex(double.NaN, 1), new Complex(2001.0, 1)});
var status = criterium.DetermineStatus(5, solution, source, residual);
Assert.IsInstanceOf(typeof (CalculationDiverged), status, "Should be diverged");
Assert.AreEqual(IterationStatus.Diverged, status, "Should be diverged");
}
/// <summary>
@ -265,7 +217,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.StopCrit
var residual = new DenseVector(new[] {Complex.Zero, Complex.Zero, Complex.Zero});
var status = criterium.DetermineStatus(0, solution, source, residual);
Assert.IsInstanceOf(typeof (CalculationConverged), status, "Should be done");
Assert.AreEqual(IterationStatus.Converged, status, "Should be done");
}
/// <summary>
@ -287,10 +239,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.StopCrit
var residual = new DenseVector(new[] {new Complex(0.001, 0), new Complex(0.001, 0), new Complex(0.002, 0)});
var status = criterium.DetermineStatus(5, solution, source, residual);
Assert.IsInstanceOf(typeof (CalculationRunning), status, "Should still be running");
Assert.AreEqual(IterationStatus.Running, status, "Should still be running");
var status2 = criterium.DetermineStatus(16, solution, source, residual);
Assert.IsInstanceOf(typeof (CalculationConverged), status2, "Should be done");
Assert.AreEqual(IterationStatus.Converged, status2, "Should be done");
}
/// <summary>
@ -307,10 +259,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.StopCrit
var residual = new DenseVector(new[] {new Complex(1.000, 0), new Complex(1.000, 0), new Complex(2.001, 0)});
var status = criterium.DetermineStatus(5, solution, source, residual);
Assert.IsInstanceOf(typeof (CalculationRunning), status, "Should be running");
Assert.AreEqual(IterationStatus.Running, status, "Should be running");
criterium.ResetToPrecalculationState();
Assert.IsInstanceOf(typeof (CalculationIndetermined), criterium.Status, "Should not have started");
Assert.AreEqual(IterationStatus.Indetermined, criterium.Status, "Should not have started");
}
/// <summary>

81
src/UnitTests/LinearAlgebraTests/Complex32/Solvers/IteratorTest.cs

@ -33,7 +33,6 @@ using System.Collections.Generic;
using MathNet.Numerics.LinearAlgebra.Complex32;
using MathNet.Numerics.LinearAlgebra.Complex32.Solvers.StopCriterium;
using MathNet.Numerics.LinearAlgebra.Solvers;
using MathNet.Numerics.LinearAlgebra.Solvers.Status;
using NUnit.Framework;
namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers
@ -82,72 +81,6 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers
DenseVector.Create(3, i => 6)));
}
/// <summary>
/// Determine status with <c>null</c> solution vector throws <c>ArgumentNullException</c>.
/// </summary>
[Test]
public void DetermineStatusWithNullSolutionVectorThrowsArgumentNullException()
{
var criteria = new List<IIterationStopCriterium<Complex32>>
{
new FailureStopCriterium(),
new DivergenceStopCriterium(),
new IterationCountStopCriterium<Complex32>(),
new ResidualStopCriterium()
};
var iterator = new Iterator<Complex32>(criteria);
Assert.Throws<ArgumentNullException>(() => iterator.DetermineStatus(
1,
null,
DenseVector.Create(3, i => 5),
DenseVector.Create(3, i => 6)));
}
/// <summary>
/// Determine status with <c>null</c> source vector throws <c>ArgumentNullException</c>.
/// </summary>
[Test]
public void DetermineStatusWithNullSourceVectorThrowsArgumentNullException()
{
var criteria = new List<IIterationStopCriterium<Complex32>>
{
new FailureStopCriterium(),
new DivergenceStopCriterium(),
new IterationCountStopCriterium<Complex32>(),
new ResidualStopCriterium()
};
var iterator = new Iterator<Complex32>(criteria);
Assert.Throws<ArgumentNullException>(() => iterator.DetermineStatus(
1,
DenseVector.Create(3, i => 5),
null,
DenseVector.Create(3, i => 6)));
}
/// <summary>
/// Determine status with <c>null</c> residual vector throws <c>ArgumentNullException</c>.
/// </summary>
[Test]
public void DetermineStatusWithNullResidualVectorThrowsArgumentNullException()
{
var criteria = new List<IIterationStopCriterium<Complex32>>
{
new FailureStopCriterium(),
new DivergenceStopCriterium(),
new IterationCountStopCriterium<Complex32>(),
new ResidualStopCriterium()
};
var iterator = new Iterator<Complex32>(criteria);
Assert.Throws<ArgumentNullException>(() => iterator.DetermineStatus(
1,
DenseVector.Create(3, i => 4),
DenseVector.Create(3, i => 5),
null));
}
/// <summary>
/// Can determine status.
/// </summary>
@ -169,7 +102,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers
DenseVector.Create(3, i => 4),
DenseVector.Create(3, i => 4),
DenseVector.Create(3, i => 4));
Assert.IsInstanceOf(typeof (CalculationRunning), iterator.Status, "Incorrect status");
Assert.AreEqual(IterationStatus.Running, iterator.Status, "Incorrect status");
// Second step, should run out of iterations.
iterator.DetermineStatus(
@ -177,7 +110,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers
DenseVector.Create(3, i => 4),
DenseVector.Create(3, i => 4),
DenseVector.Create(3, i => 4));
Assert.IsInstanceOf(typeof (CalculationStoppedWithoutConvergence), iterator.Status, "Incorrect status");
Assert.AreEqual(IterationStatus.StoppedWithoutConvergence, iterator.Status, "Incorrect status");
}
/// <summary>
@ -201,13 +134,13 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers
DenseVector.Create(3, i => 4),
DenseVector.Create(3, i => 4),
DenseVector.Create(3, i => 4));
Assert.IsInstanceOf(typeof (CalculationRunning), iterator.Status, "Incorrect status");
Assert.AreEqual(IterationStatus.Running, iterator.Status, "Incorrect status");
iterator.Reset();
Assert.IsInstanceOf(typeof (CalculationIndetermined), iterator.Status, "Incorrect status");
Assert.IsInstanceOf(typeof (CalculationIndetermined), criteria[0].Status, "Incorrect status");
Assert.IsInstanceOf(typeof (CalculationIndetermined), criteria[1].Status, "Incorrect status");
Assert.IsInstanceOf(typeof (CalculationIndetermined), criteria[2].Status, "Incorrect status");
Assert.AreEqual(IterationStatus.Indetermined, iterator.Status, "Incorrect status");
Assert.AreEqual(IterationStatus.Indetermined, criteria[0].Status, "Incorrect status");
Assert.AreEqual(IterationStatus.Indetermined, criteria[1].Status, "Incorrect status");
Assert.AreEqual(IterationStatus.Indetermined, criteria[2].Status, "Incorrect status");
}
}
}

34
src/UnitTests/LinearAlgebraTests/Complex32/Solvers/StopCriterium/DivergenceStopCriteriumTest.cs

@ -28,11 +28,11 @@
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
using System;
using MathNet.Numerics.LinearAlgebra.Complex32;
using MathNet.Numerics.LinearAlgebra.Complex32.Solvers.StopCriterium;
using MathNet.Numerics.LinearAlgebra.Solvers.Status;
using MathNet.Numerics.LinearAlgebra.Solvers;
using NUnit.Framework;
using System;
namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.StopCriterium
{
@ -119,20 +119,6 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.StopCr
DenseVector.Create(3, i => 6)));
}
/// <summary>
/// Determine status with <c>null</c> residual vector throws <c>ArgumentNullException</c>.
/// </summary>
[Test]
public void DetermineStatusWithNullResidualVectorThrowsArgumentNullException()
{
var criterium = new DivergenceStopCriterium(0.5, 15);
Assert.Throws<ArgumentNullException>(() => criterium.DetermineStatus(
1,
DenseVector.Create(3, i => 4),
DenseVector.Create(3, i => 5),
null));
}
/// <summary>
/// Can determine status with too few iterations.
/// </summary>
@ -152,7 +138,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.StopCr
new DenseVector(new[] {new Complex32(1.0f, 0)}),
new DenseVector(new[] {new Complex32(1.0f, 0)}),
new DenseVector(new[] {new Complex32((i + 1)*(Increase + 0.1f), 0)}));
Assert.IsInstanceOf(typeof (CalculationRunning), status, "Status check fail.");
Assert.AreEqual(IterationStatus.Running, status, "Status check fail.");
}
}
@ -176,7 +162,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.StopCr
new DenseVector(new[] {new Complex32(1.0f, 0)}),
new DenseVector(new[] {new Complex32((i + 1)*(Increase - 0.01f), 0)}));
Assert.IsInstanceOf(typeof (CalculationRunning), status, "Status check fail.");
Assert.AreEqual(IterationStatus.Running, status, "Status check fail.");
}
}
@ -200,7 +186,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.StopCr
new DenseVector(new[] {new Complex32(1.0f, 0)}),
new DenseVector(new[] {new Complex32((i + 1)*(Increase - 0.01f), 0)}));
Assert.IsInstanceOf(typeof (CalculationRunning), status, "Status check fail.");
Assert.AreEqual(IterationStatus.Running, status, "Status check fail.");
}
// Now make it fail by throwing in a NaN
@ -210,7 +196,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.StopCr
new DenseVector(new[] {new Complex32(1.0f, 0)}),
new DenseVector(new[] {new Complex32(float.NaN, 0)}));
Assert.IsInstanceOf(typeof (CalculationDiverged), status2, "Status check fail.");
Assert.AreEqual(IterationStatus.Diverged, status2, "Status check fail.");
}
/// <summary>
@ -235,7 +221,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.StopCr
new DenseVector(new[] {new Complex32(1.0f, 0)}),
new DenseVector(new[] {new Complex32(previous, 0)}));
Assert.IsInstanceOf(typeof (CalculationRunning), status, "Status check fail.");
Assert.AreEqual(IterationStatus.Running, status, "Status check fail.");
}
// Add the final residual. Now we should have divergence
@ -246,7 +232,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.StopCr
new DenseVector(new[] {new Complex32(1.0f, 0)}),
new DenseVector(new[] {new Complex32(previous, 0)}));
Assert.IsInstanceOf(typeof (CalculationDiverged), status2, "Status check fail.");
Assert.AreEqual(IterationStatus.Diverged, status2, "Status check fail.");
}
/// <summary>
@ -267,14 +253,14 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.StopCr
new DenseVector(new[] {new Complex32(1.0f, 0)}),
new DenseVector(new[] {new Complex32(float.NaN, 0)}));
Assert.IsInstanceOf(typeof (CalculationDiverged), status, "Status check fail.");
Assert.AreEqual(IterationStatus.Diverged, status, "Status check fail.");
// Reset the state
criterium.ResetToPrecalculationState();
Assert.AreEqual(Increase, criterium.MaximumRelativeIncrease, "Incorrect maximum");
Assert.AreEqual(Iterations, criterium.MinimumNumberOfIterations, "Incorrect iteration count");
Assert.IsInstanceOf(typeof (CalculationIndetermined), criterium.Status, "Status check fail.");
Assert.AreEqual(IterationStatus.Indetermined, criterium.Status, "Status check fail.");
}
/// <summary>

38
src/UnitTests/LinearAlgebraTests/Complex32/Solvers/StopCriterium/FailureStopCriteriumTest.cs

@ -28,11 +28,11 @@
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
using System;
using MathNet.Numerics.LinearAlgebra.Complex32;
using MathNet.Numerics.LinearAlgebra.Complex32.Solvers.StopCriterium;
using MathNet.Numerics.LinearAlgebra.Solvers.Status;
using MathNet.Numerics.LinearAlgebra.Solvers;
using NUnit.Framework;
using System;
namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.StopCriterium
{
@ -66,30 +66,6 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.StopCr
Assert.Throws<ArgumentOutOfRangeException>(() => criterium.DetermineStatus(-1, DenseVector.Create(3, i => 4), DenseVector.Create(3, i => 5), DenseVector.Create(3, i => 6)));
}
/// <summary>
/// Determine status with <c>null</c> solution vector throws <c>ArgumentNullException</c>.
/// </summary>
[Test]
public void DetermineStatusWithNullSolutionVectorThrowsArgumentNullException()
{
var criterium = new FailureStopCriterium();
Assert.IsNotNull(criterium, "There should be a criterium");
Assert.Throws<ArgumentNullException>(() => criterium.DetermineStatus(1, null, DenseVector.Create(3, i => 6), DenseVector.Create(4, i => 4)));
}
/// <summary>
/// Determine status with <c>null</c> residual vector throws <c>ArgumentNullException</c>.
/// </summary>
[Test]
public void DetermineStatusWithNullResidualVectorThrowsArgumentNullException()
{
var criterium = new FailureStopCriterium();
Assert.IsNotNull(criterium, "There should be a criterium");
Assert.Throws<ArgumentNullException>(() => criterium.DetermineStatus(1, DenseVector.Create(3, i => 4), DenseVector.Create(3, i => 6), null));
}
/// <summary>
/// Determine status with non-matching vectors throws <c>ArgumentException</c>.
/// </summary>
@ -116,7 +92,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.StopCr
var residual = new DenseVector(new[] {new Complex32(1000, 0), new Complex32(float.NaN, 0), new Complex32(2001, 0)});
var status = criterium.DetermineStatus(5, solution, source, residual);
Assert.IsInstanceOf(typeof (CalculationFailure), status, "Should be failed");
Assert.AreEqual(IterationStatus.Failure, status, "Should be failed");
}
/// <summary>
@ -133,7 +109,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.StopCr
var residual = new DenseVector(new[] {new Complex32(1000, 0), new Complex32(1000, 0), new Complex32(2001, 0)});
var status = criterium.DetermineStatus(5, solution, source, residual);
Assert.IsInstanceOf(typeof (CalculationFailure), status, "Should be failed");
Assert.AreEqual(IterationStatus.Failure, status, "Should be failed");
}
/// <summary>
@ -150,7 +126,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.StopCr
var residual = new DenseVector(new[] {new Complex32(1.0f, 0), new Complex32(2.0f, 0), new Complex32(3, 0)});
var status = criterium.DetermineStatus(5, solution, source, residual);
Assert.IsInstanceOf(typeof (CalculationRunning), status, "Should be running");
Assert.AreEqual(IterationStatus.Running, status, "Should be running");
}
/// <summary>
@ -167,10 +143,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.StopCr
var residual = new DenseVector(new[] {new Complex32(1000, 0), new Complex32(1000, 0), new Complex32(2001, 0)});
var status = criterium.DetermineStatus(5, solution, source, residual);
Assert.IsInstanceOf(typeof (CalculationRunning), status, "Should be running");
Assert.AreEqual(IterationStatus.Running, status, "Should be running");
criterium.ResetToPrecalculationState();
Assert.IsInstanceOf(typeof (CalculationIndetermined), criterium.Status, "Should not have started");
Assert.AreEqual(IterationStatus.Indetermined, criterium.Status, "Should not have started");
}
/// <summary>

9
src/UnitTests/LinearAlgebraTests/Complex32/Solvers/StopCriterium/IterationCountStopCriteriumTest.cs

@ -31,7 +31,6 @@
using System;
using MathNet.Numerics.LinearAlgebra.Complex32;
using MathNet.Numerics.LinearAlgebra.Solvers;
using MathNet.Numerics.LinearAlgebra.Solvers.Status;
using NUnit.Framework;
namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.StopCriterium
@ -100,10 +99,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.StopCr
Assert.IsNotNull(criterium, "A criterium should have been created");
var status = criterium.DetermineStatus(5, DenseVector.Create(3, i => 1), DenseVector.Create(3, i => 2), DenseVector.Create(3, i => 3));
Assert.IsInstanceOf(typeof (CalculationRunning), status, "Should be running");
Assert.AreEqual(IterationStatus.Running, status, "Should be running");
var status2 = criterium.DetermineStatus(10, DenseVector.Create(3, i => 1), DenseVector.Create(3, i => 2), DenseVector.Create(3, i => 3));
Assert.IsInstanceOf(typeof (CalculationStoppedWithoutConvergence), status2, "Should be finished");
Assert.AreEqual(IterationStatus.StoppedWithoutConvergence, status2, "Should be finished");
}
/// <summary>
@ -116,10 +115,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.StopCr
Assert.IsNotNull(criterium, "A criterium should have been created");
var status = criterium.DetermineStatus(5, DenseVector.Create(3, i => 1), DenseVector.Create(3, i => 2), DenseVector.Create(3, i => 3));
Assert.IsInstanceOf(typeof (CalculationRunning), status, "Should be running");
Assert.AreEqual(IterationStatus.Running, status, "Should be running");
criterium.ResetToPrecalculationState();
Assert.IsInstanceOf(typeof (CalculationIndetermined), criterium.Status, "Should not have started");
Assert.AreEqual(IterationStatus.Indetermined, criterium.Status, "Should not have started");
}
/// <summary>

66
src/UnitTests/LinearAlgebraTests/Complex32/Solvers/StopCriterium/ResidualStopCriteriumTest.cs

@ -28,11 +28,11 @@
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
using System;
using MathNet.Numerics.LinearAlgebra.Complex32;
using MathNet.Numerics.LinearAlgebra.Complex32.Solvers.StopCriterium;
using MathNet.Numerics.LinearAlgebra.Solvers.Status;
using MathNet.Numerics.LinearAlgebra.Solvers;
using NUnit.Framework;
using System;
namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.StopCriterium
{
@ -117,54 +117,6 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.StopCr
DenseVector.Create(3, i => 6)));
}
/// <summary>
/// Determine status with <c>null</c> solution vector throws <c>ArgumentNullException</c>.
/// </summary>
[Test]
public void DetermineStatusWithNullSolutionVectorThrowsArgumentNullException()
{
var criterium = new ResidualStopCriterium(1e-6f, 50);
Assert.IsNotNull(criterium, "There should be a criterium");
Assert.Throws<ArgumentNullException>(() => criterium.DetermineStatus(
1,
null,
DenseVector.Create(3, i => 5),
DenseVector.Create(3, i => 6)));
}
/// <summary>
/// Determine status with <c>null</c> source vector throws <c>ArgumentNullException</c>.
/// </summary>
[Test]
public void DetermineStatusWithNullSourceVectorThrowsArgumentNullException()
{
var criterium = new ResidualStopCriterium(1e-6f, 50);
Assert.IsNotNull(criterium, "There should be a criterium");
Assert.Throws<ArgumentNullException>(() => criterium.DetermineStatus(
1,
DenseVector.Create(3, i => 4),
null,
DenseVector.Create(3, i => 6)));
}
/// <summary>
/// Determine status with <c>null</c> residual vector throws <c>ArgumentNullException</c>.
/// </summary>
[Test]
public void DetermineStatusWithNullResidualVectorThrowsArgumentNullException()
{
var criterium = new ResidualStopCriterium(1e-6f, 50);
Assert.IsNotNull(criterium, "There should be a criterium");
Assert.Throws<ArgumentNullException>(() => criterium.DetermineStatus(
1,
DenseVector.Create(3, i => 4),
DenseVector.Create(3, i => 5),
null));
}
/// <summary>
/// Determine status with non-matching solution vector throws <c>ArgumentException</c>.
/// </summary>
@ -227,7 +179,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.StopCr
var residual = new DenseVector(new[] {new Complex32(1000.0f, 1), new Complex32(1000.0f, 1), new Complex32(2001.0f, 1)});
var status = criterium.DetermineStatus(5, solution, source, residual);
Assert.IsInstanceOf(typeof (CalculationDiverged), status, "Should be diverged");
Assert.AreEqual(IterationStatus.Diverged, status, "Should be diverged");
}
/// <summary>
@ -244,7 +196,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.StopCr
var residual = new DenseVector(new[] {new Complex32(1000.0f, 1), new Complex32(float.NaN, 1), new Complex32(2001.0f, 1)});
var status = criterium.DetermineStatus(5, solution, source, residual);
Assert.IsInstanceOf(typeof (CalculationDiverged), status, "Should be diverged");
Assert.AreEqual(IterationStatus.Diverged, status, "Should be diverged");
}
/// <summary>
@ -265,7 +217,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.StopCr
var residual = new DenseVector(new[] {Complex32.Zero, Complex32.Zero, Complex32.Zero});
var status = criterium.DetermineStatus(0, solution, source, residual);
Assert.IsInstanceOf(typeof (CalculationConverged), status, "Should be done");
Assert.AreEqual(IterationStatus.Converged, status, "Should be done");
}
/// <summary>
@ -287,10 +239,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.StopCr
var residual = new DenseVector(new[] {new Complex32(0.001f, 0), new Complex32(0.001f, 0), new Complex32(0.002f, 0)});
var status = criterium.DetermineStatus(5, solution, source, residual);
Assert.IsInstanceOf(typeof (CalculationRunning), status, "Should still be running");
Assert.AreEqual(IterationStatus.Running, status, "Should still be running");
var status2 = criterium.DetermineStatus(16, solution, source, residual);
Assert.IsInstanceOf(typeof (CalculationConverged), status2, "Should be done");
Assert.AreEqual(IterationStatus.Converged, status2, "Should be done");
}
/// <summary>
@ -307,10 +259,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.StopCr
var residual = new DenseVector(new[] {new Complex32(1.000f, 0), new Complex32(1.000f, 0), new Complex32(2.001f, 0)});
var status = criterium.DetermineStatus(5, solution, source, residual);
Assert.IsInstanceOf(typeof (CalculationRunning), status, "Should be running");
Assert.AreEqual(IterationStatus.Running, status, "Should be running");
criterium.ResetToPrecalculationState();
Assert.IsInstanceOf(typeof (CalculationIndetermined), criterium.Status, "Should not have started");
Assert.AreEqual(IterationStatus.Indetermined, criterium.Status, "Should not have started");
}
/// <summary>

81
src/UnitTests/LinearAlgebraTests/Double/Solvers/IteratorTest.cs

@ -33,7 +33,6 @@ using System.Collections.Generic;
using MathNet.Numerics.LinearAlgebra.Double;
using MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium;
using MathNet.Numerics.LinearAlgebra.Solvers;
using MathNet.Numerics.LinearAlgebra.Solvers.Status;
using NUnit.Framework;
namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers
@ -80,72 +79,6 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers
DenseVector.Create(3, i => 6)));
}
/// <summary>
/// Determine status with <c>null</c> solution vector throws <c>ArgumentNullException</c>.
/// </summary>
[Test]
public void DetermineStatusWithNullSolutionVectorThrowsArgumentNullException()
{
var criteria = new List<IIterationStopCriterium<double>>
{
new FailureStopCriterium(),
new DivergenceStopCriterium(),
new IterationCountStopCriterium<double>(),
new ResidualStopCriterium()
};
var iterator = new Iterator<double>(criteria);
Assert.Throws<ArgumentNullException>(() => iterator.DetermineStatus(
1,
null,
DenseVector.Create(3, i => 5),
DenseVector.Create(3, i => 6)));
}
/// <summary>
/// Determine status with <c>null</c> source vector throws <c>ArgumentNullException</c>.
/// </summary>
[Test]
public void DetermineStatusWithNullSourceVectorThrowsArgumentNullException()
{
var criteria = new List<IIterationStopCriterium<double>>
{
new FailureStopCriterium(),
new DivergenceStopCriterium(),
new IterationCountStopCriterium<double>(),
new ResidualStopCriterium()
};
var iterator = new Iterator<double>(criteria);
Assert.Throws<ArgumentNullException>(() => iterator.DetermineStatus(
1,
DenseVector.Create(3, i => 5),
null,
DenseVector.Create(3, i => 6)));
}
/// <summary>
/// Determine status with <c>null</c> residual vector throws <c>ArgumentNullException</c>.
/// </summary>
[Test]
public void DetermineStatusWithNullResidualVectorThrowsArgumentNullException()
{
var criteria = new List<IIterationStopCriterium<double>>
{
new FailureStopCriterium(),
new DivergenceStopCriterium(),
new IterationCountStopCriterium<double>(),
new ResidualStopCriterium()
};
var iterator = new Iterator<double>(criteria);
Assert.Throws<ArgumentNullException>(() => iterator.DetermineStatus(
1,
DenseVector.Create(3, i => 4),
DenseVector.Create(3, i => 5),
null));
}
/// <summary>
/// Can determine status.
/// </summary>
@ -167,7 +100,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers
DenseVector.Create(3, i => 4),
DenseVector.Create(3, i => 4),
DenseVector.Create(3, i => 4));
Assert.IsInstanceOf(typeof (CalculationRunning), iterator.Status, "Incorrect status");
Assert.AreEqual(IterationStatus.Running, iterator.Status, "Incorrect status");
// Second step, should run out of iterations.
iterator.DetermineStatus(
@ -175,7 +108,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers
DenseVector.Create(3, i => 4),
DenseVector.Create(3, i => 4),
DenseVector.Create(3, i => 4));
Assert.IsInstanceOf(typeof (CalculationStoppedWithoutConvergence), iterator.Status, "Incorrect status");
Assert.AreEqual(IterationStatus.StoppedWithoutConvergence, iterator.Status, "Incorrect status");
}
/// <summary>
@ -199,13 +132,13 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers
DenseVector.Create(3, i => 4),
DenseVector.Create(3, i => 4),
DenseVector.Create(3, i => 4));
Assert.IsInstanceOf(typeof (CalculationRunning), iterator.Status, "Incorrect status");
Assert.AreEqual(IterationStatus.Running, iterator.Status, "Incorrect status");
iterator.Reset();
Assert.IsInstanceOf(typeof (CalculationIndetermined), iterator.Status, "Incorrect status");
Assert.IsInstanceOf(typeof (CalculationIndetermined), criteria[0].Status, "Incorrect status");
Assert.IsInstanceOf(typeof (CalculationIndetermined), criteria[1].Status, "Incorrect status");
Assert.IsInstanceOf(typeof (CalculationIndetermined), criteria[2].Status, "Incorrect status");
Assert.AreEqual(IterationStatus.Indetermined, iterator.Status, "Incorrect status");
Assert.AreEqual(IterationStatus.Indetermined, criteria[0].Status, "Incorrect status");
Assert.AreEqual(IterationStatus.Indetermined, criteria[1].Status, "Incorrect status");
Assert.AreEqual(IterationStatus.Indetermined, criteria[2].Status, "Incorrect status");
}
}
}

34
src/UnitTests/LinearAlgebraTests/Double/Solvers/StopCriterium/DivergenceStopCriteriumTest.cs

@ -28,11 +28,11 @@
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
using System;
using MathNet.Numerics.LinearAlgebra.Double;
using MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium;
using MathNet.Numerics.LinearAlgebra.Solvers.Status;
using MathNet.Numerics.LinearAlgebra.Solvers;
using NUnit.Framework;
using System;
namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.StopCriterium
{
@ -117,20 +117,6 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.StopCrite
DenseVector.Create(3, i => 6)));
}
/// <summary>
/// Determine status with <c>null</c> residual vector throws <c>ArgumentNullException</c>.
/// </summary>
[Test]
public void DetermineStatusWithNullResidualVectorThrowsArgumentNullException()
{
var criterium = new DivergenceStopCriterium(0.5, 15);
Assert.Throws<ArgumentNullException>(() => criterium.DetermineStatus(
1,
DenseVector.Create(3, i => 4),
DenseVector.Create(3, i => 5),
null));
}
/// <summary>
/// Can determine status with too few iterations.
/// </summary>
@ -151,7 +137,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.StopCrite
new DenseVector(new[] {1.0}),
new DenseVector(new[] {(i + 1)*(Increase + 0.1)}));
Assert.IsInstanceOf(typeof (CalculationRunning), status, "Status check fail.");
Assert.AreEqual(IterationStatus.Running, status, "Status check fail.");
}
}
@ -175,7 +161,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.StopCrite
new DenseVector(new[] {1.0}),
new DenseVector(new[] {(i + 1)*(Increase - 0.01)}));
Assert.IsInstanceOf(typeof (CalculationRunning), status, "Status check fail.");
Assert.AreEqual(IterationStatus.Running, status, "Status check fail.");
}
}
@ -199,7 +185,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.StopCrite
new DenseVector(new[] {1.0}),
new DenseVector(new[] {(i + 1)*(Increase - 0.01)}));
Assert.IsInstanceOf(typeof (CalculationRunning), status, "Status check fail.");
Assert.AreEqual(IterationStatus.Running, status, "Status check fail.");
}
// Now make it fail by throwing in a NaN
@ -209,7 +195,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.StopCrite
new DenseVector(new[] {1.0}),
new DenseVector(new[] {double.NaN}));
Assert.IsInstanceOf(typeof (CalculationDiverged), status2, "Status check fail.");
Assert.AreEqual(IterationStatus.Diverged, status2, "Status check fail.");
}
/// <summary>
@ -234,7 +220,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.StopCrite
new DenseVector(new[] {1.0}),
new DenseVector(new[] {previous}));
Assert.IsInstanceOf(typeof (CalculationRunning), status, "Status check fail.");
Assert.AreEqual(IterationStatus.Running, status, "Status check fail.");
}
// Add the final residual. Now we should have divergence
@ -245,7 +231,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.StopCrite
new DenseVector(new[] {1.0}),
new DenseVector(new[] {previous}));
Assert.IsInstanceOf(typeof (CalculationDiverged), status2, "Status check fail.");
Assert.AreEqual(IterationStatus.Diverged, status2, "Status check fail.");
}
/// <summary>
@ -266,14 +252,14 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.StopCrite
new DenseVector(new[] {1.0}),
new DenseVector(new[] {double.NaN}));
Assert.IsInstanceOf(typeof (CalculationDiverged), status, "Status check fail.");
Assert.AreEqual(IterationStatus.Diverged, status, "Status check fail.");
// Reset the state
criterium.ResetToPrecalculationState();
Assert.AreEqual(Increase, criterium.MaximumRelativeIncrease, "Incorrect maximum");
Assert.AreEqual(Iterations, criterium.MinimumNumberOfIterations, "Incorrect iteration count");
Assert.IsInstanceOf(typeof (CalculationIndetermined), criterium.Status, "Status check fail.");
Assert.AreEqual(IterationStatus.Indetermined, criterium.Status, "Status check fail.");
}
/// <summary>

36
src/UnitTests/LinearAlgebraTests/Double/Solvers/StopCriterium/FailureStopCriteriumTest.cs

@ -30,7 +30,7 @@
using MathNet.Numerics.LinearAlgebra.Double;
using MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium;
using MathNet.Numerics.LinearAlgebra.Solvers.Status;
using MathNet.Numerics.LinearAlgebra.Solvers;
using NUnit.Framework;
using System;
@ -64,30 +64,6 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.StopCrite
Assert.Throws<ArgumentOutOfRangeException>(() => criterium.DetermineStatus(-1, DenseVector.Create(3, i => 4), DenseVector.Create(3, i => 5), DenseVector.Create(3, i => 6)));
}
/// <summary>
/// Determine status with <c>null</c> solution vector throws <c>ArgumentNullException</c>.
/// </summary>
[Test]
public void DetermineStatusWithNullSolutionVectorThrowsArgumentNullException()
{
var criterium = new FailureStopCriterium();
Assert.IsNotNull(criterium, "There should be a criterium");
Assert.Throws<ArgumentNullException>(() => criterium.DetermineStatus(1, null, DenseVector.Create(3, i => 6), DenseVector.Create(4, i => 4)));
}
/// <summary>
/// Determine status with <c>null</c> residual vector throws <c>ArgumentNullException</c>.
/// </summary>
[Test]
public void DetermineStatusWithNullResidualVectorThrowsArgumentNullException()
{
var criterium = new FailureStopCriterium();
Assert.IsNotNull(criterium, "There should be a criterium");
Assert.Throws<ArgumentNullException>(() => criterium.DetermineStatus(1, DenseVector.Create(3, i => 4), DenseVector.Create(3, i => 6), null));
}
/// <summary>
/// Determine status with non-matching vectors throws <c>ArgumentException</c>.
/// </summary>
@ -114,7 +90,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.StopCrite
var residual = new DenseVector(new[] { 1000, double.NaN, 2001 });
var status = criterium.DetermineStatus(5, solution, source, residual);
Assert.IsInstanceOf(typeof(CalculationFailure), status, "Should be failed");
Assert.AreEqual(IterationStatus.Failure, status, "Should be failed");
}
/// <summary>
@ -131,7 +107,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.StopCrite
var residual = new DenseVector(new[] { 1000.0, 1000.0, 2001.0 });
var status = criterium.DetermineStatus(5, solution, source, residual);
Assert.IsInstanceOf(typeof(CalculationFailure), status, "Should be failed");
Assert.AreEqual(IterationStatus.Failure, status, "Should be failed");
}
/// <summary>
@ -148,7 +124,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.StopCrite
var residual = new DenseVector(new[] { 1.0, 2.0, 3.0 });
var status = criterium.DetermineStatus(5, solution, source, residual);
Assert.IsInstanceOf(typeof(CalculationRunning), status, "Should be running");
Assert.AreEqual(IterationStatus.Running, status, "Should be running");
}
/// <summary>
@ -165,10 +141,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.StopCrite
var residual = new DenseVector(new[] { 1000.0, 1000.0, 2001.0 });
var status = criterium.DetermineStatus(5, solution, source, residual);
Assert.IsInstanceOf(typeof(CalculationRunning), status, "Should be running");
Assert.AreEqual(IterationStatus.Running, status, "Should be running");
criterium.ResetToPrecalculationState();
Assert.IsInstanceOf(typeof(CalculationIndetermined), criterium.Status, "Should not have started");
Assert.AreEqual(IterationStatus.Indetermined, criterium.Status, "Should not have started");
}
/// <summary>

9
src/UnitTests/LinearAlgebraTests/Double/Solvers/StopCriterium/IterationCountStopCriteriumTest.cs

@ -31,7 +31,6 @@
using System;
using MathNet.Numerics.LinearAlgebra.Double;
using MathNet.Numerics.LinearAlgebra.Solvers;
using MathNet.Numerics.LinearAlgebra.Solvers.Status;
using NUnit.Framework;
namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.StopCriterium
@ -98,10 +97,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.StopCrite
Assert.IsNotNull(criterium, "A criterium should have been created");
var status = criterium.DetermineStatus(5, DenseVector.Create(3, i => 1), DenseVector.Create(3, i => 2), DenseVector.Create(3, i => 3));
Assert.IsInstanceOf(typeof (CalculationRunning), status, "Should be running");
Assert.AreEqual(IterationStatus.Running, status, "Should be running");
var status2 = criterium.DetermineStatus(10, DenseVector.Create(3, i => 1), DenseVector.Create(3, i => 2), DenseVector.Create(3, i => 3));
Assert.IsInstanceOf(typeof (CalculationStoppedWithoutConvergence), status2, "Should be finished");
Assert.AreEqual(IterationStatus.StoppedWithoutConvergence, status2, "Should be finished");
}
/// <summary>
@ -114,10 +113,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.StopCrite
Assert.IsNotNull(criterium, "A criterium should have been created");
var status = criterium.DetermineStatus(5, DenseVector.Create(3, i => 1), DenseVector.Create(3, i => 2), DenseVector.Create(3, i => 3));
Assert.IsInstanceOf(typeof (CalculationRunning), status, "Should be running");
Assert.AreEqual(IterationStatus.Running, status, "Should be running");
criterium.ResetToPrecalculationState();
Assert.IsInstanceOf(typeof (CalculationIndetermined), criterium.Status, "Should not have started");
Assert.AreEqual(IterationStatus.Indetermined, criterium.Status, "Should not have started");
}
/// <summary>

66
src/UnitTests/LinearAlgebraTests/Double/Solvers/StopCriterium/ResidualStopCriteriumTest.cs

@ -28,11 +28,11 @@
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
using System;
using MathNet.Numerics.LinearAlgebra.Double;
using MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium;
using MathNet.Numerics.LinearAlgebra.Solvers.Status;
using MathNet.Numerics.LinearAlgebra.Solvers;
using NUnit.Framework;
using System;
namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.StopCriterium
{
@ -115,54 +115,6 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.StopCrite
DenseVector.Create(3, i => 6)));
}
/// <summary>
/// Determine status with <c>null</c> solution vector throws <c>ArgumentNullException</c>.
/// </summary>
[Test]
public void DetermineStatusWithNullSolutionVectorThrowsArgumentNullException()
{
var criterium = new ResidualStopCriterium(1e-8, 50);
Assert.IsNotNull(criterium, "There should be a criterium");
Assert.Throws<ArgumentNullException>(() => criterium.DetermineStatus(
1,
null,
DenseVector.Create(3, i => 5),
DenseVector.Create(3, i => 6)));
}
/// <summary>
/// Determine status with <c>null</c> source vector throws <c>ArgumentNullException</c>.
/// </summary>
[Test]
public void DetermineStatusWithNullSourceVectorThrowsArgumentNullException()
{
var criterium = new ResidualStopCriterium(1e-8, 50);
Assert.IsNotNull(criterium, "There should be a criterium");
Assert.Throws<ArgumentNullException>(() => criterium.DetermineStatus(
1,
DenseVector.Create(3, i => 4),
null,
DenseVector.Create(3, i => 6)));
}
/// <summary>
/// Determine status with <c>null</c> residual vector throws <c>ArgumentNullException</c>.
/// </summary>
[Test]
public void DetermineStatusWithNullResidualVectorThrowsArgumentNullException()
{
var criterium = new ResidualStopCriterium(1e-8, 50);
Assert.IsNotNull(criterium, "There should be a criterium");
Assert.Throws<ArgumentNullException>(() => criterium.DetermineStatus(
1,
DenseVector.Create(3, i => 4),
DenseVector.Create(3, i => 5),
null));
}
/// <summary>
/// Determine status with non-matching solution vector throws <c>ArgumentException</c>.
/// </summary>
@ -225,7 +177,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.StopCrite
var residual = new DenseVector(new[] {1000.0, 1000.0, 2001.0});
var status = criterium.DetermineStatus(5, solution, source, residual);
Assert.IsInstanceOf(typeof (CalculationDiverged), status, "Should be diverged");
Assert.AreEqual(IterationStatus.Diverged, status, "Should be diverged");
}
/// <summary>
@ -242,7 +194,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.StopCrite
var residual = new DenseVector(new[] {1000.0, double.NaN, 2001.0});
var status = criterium.DetermineStatus(5, solution, source, residual);
Assert.IsInstanceOf(typeof (CalculationDiverged), status, "Should be diverged");
Assert.AreEqual(IterationStatus.Diverged, status, "Should be diverged");
}
/// <summary>
@ -259,7 +211,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.StopCrite
var residual = new DenseVector(new[] {0.0, 0.0, 0.0});
var status = criterium.DetermineStatus(0, solution, source, residual);
Assert.IsInstanceOf(typeof (CalculationConverged), status, "Should be done");
Assert.AreEqual(IterationStatus.Converged, status, "Should be done");
}
/// <summary>
@ -281,10 +233,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.StopCrite
var residual = new DenseVector(new[] {0.001, 0.001, 0.002});
var status = criterium.DetermineStatus(5, solution, source, residual);
Assert.IsInstanceOf(typeof (CalculationRunning), status, "Should still be running");
Assert.AreEqual(IterationStatus.Running, status, "Should still be running");
var status2 = criterium.DetermineStatus(16, solution, source, residual);
Assert.IsInstanceOf(typeof (CalculationConverged), status2, "Should be done");
Assert.AreEqual(IterationStatus.Converged, status2, "Should be done");
}
/// <summary>
@ -301,10 +253,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.StopCrite
var residual = new DenseVector(new[] {1.000, 1.000, 2.001});
var status = criterium.DetermineStatus(5, solution, source, residual);
Assert.IsInstanceOf(typeof (CalculationRunning), status, "Should be running");
Assert.AreEqual(IterationStatus.Running, status, "Should be running");
criterium.ResetToPrecalculationState();
Assert.IsInstanceOf(typeof (CalculationIndetermined), criterium.Status, "Should not have started");
Assert.AreEqual(IterationStatus.Indetermined, criterium.Status, "Should not have started");
}
/// <summary>

81
src/UnitTests/LinearAlgebraTests/Single/Solvers/IteratorTest.cs

@ -33,7 +33,6 @@ using System.Collections.Generic;
using MathNet.Numerics.LinearAlgebra.Single;
using MathNet.Numerics.LinearAlgebra.Single.Solvers.StopCriterium;
using MathNet.Numerics.LinearAlgebra.Solvers;
using MathNet.Numerics.LinearAlgebra.Solvers.Status;
using NUnit.Framework;
namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers
@ -80,72 +79,6 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers
DenseVector.Create(3, i => 6)));
}
/// <summary>
/// Determine status with <c>null</c> solution vector throws <c>ArgumentNullException</c>.
/// </summary>
[Test]
public void DetermineStatusWithNullSolutionVectorThrowsArgumentNullException()
{
var criteria = new List<IIterationStopCriterium<float>>
{
new FailureStopCriterium(),
new DivergenceStopCriterium(),
new IterationCountStopCriterium<float>(),
new ResidualStopCriterium()
};
var iterator = new Iterator<float>(criteria);
Assert.Throws<ArgumentNullException>(() => iterator.DetermineStatus(
1,
null,
DenseVector.Create(3, i => 5),
DenseVector.Create(3, i => 6)));
}
/// <summary>
/// Determine status with <c>null</c> source vector throws <c>ArgumentNullException</c>.
/// </summary>
[Test]
public void DetermineStatusWithNullSourceVectorThrowsArgumentNullException()
{
var criteria = new List<IIterationStopCriterium<float>>
{
new FailureStopCriterium(),
new DivergenceStopCriterium(),
new IterationCountStopCriterium<float>(),
new ResidualStopCriterium()
};
var iterator = new Iterator<float>(criteria);
Assert.Throws<ArgumentNullException>(() => iterator.DetermineStatus(
1,
DenseVector.Create(3, i => 5),
null,
DenseVector.Create(3, i => 6)));
}
/// <summary>
/// Determine status with <c>null</c> residual vector throws <c>ArgumentNullException</c>.
/// </summary>
[Test]
public void DetermineStatusWithNullResidualVectorThrowsArgumentNullException()
{
var criteria = new List<IIterationStopCriterium<float>>
{
new FailureStopCriterium(),
new DivergenceStopCriterium(),
new IterationCountStopCriterium<float>(),
new ResidualStopCriterium()
};
var iterator = new Iterator<float>(criteria);
Assert.Throws<ArgumentNullException>(() => iterator.DetermineStatus(
1,
DenseVector.Create(3, i => 4),
DenseVector.Create(3, i => 5),
null));
}
/// <summary>
/// Can determine status.
/// </summary>
@ -167,7 +100,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers
DenseVector.Create(3, i => 4),
DenseVector.Create(3, i => 4),
DenseVector.Create(3, i => 4));
Assert.IsInstanceOf(typeof (CalculationRunning), iterator.Status, "Incorrect status");
Assert.AreEqual(IterationStatus.Running, iterator.Status, "Incorrect status");
// Second step, should run out of iterations.
iterator.DetermineStatus(
@ -175,7 +108,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers
DenseVector.Create(3, i => 4),
DenseVector.Create(3, i => 4),
DenseVector.Create(3, i => 4));
Assert.IsInstanceOf(typeof (CalculationStoppedWithoutConvergence), iterator.Status, "Incorrect status");
Assert.AreEqual(IterationStatus.StoppedWithoutConvergence, iterator.Status, "Incorrect status");
}
/// <summary>
@ -199,13 +132,13 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers
DenseVector.Create(3, i => 4),
DenseVector.Create(3, i => 4),
DenseVector.Create(3, i => 4));
Assert.IsInstanceOf(typeof (CalculationRunning), iterator.Status, "Incorrect status");
Assert.AreEqual(IterationStatus.Running, iterator.Status, "Incorrect status");
iterator.Reset();
Assert.IsInstanceOf(typeof (CalculationIndetermined), iterator.Status, "Incorrect status");
Assert.IsInstanceOf(typeof (CalculationIndetermined), criteria[0].Status, "Incorrect status");
Assert.IsInstanceOf(typeof (CalculationIndetermined), criteria[1].Status, "Incorrect status");
Assert.IsInstanceOf(typeof (CalculationIndetermined), criteria[2].Status, "Incorrect status");
Assert.AreEqual(IterationStatus.Indetermined, iterator.Status, "Incorrect status");
Assert.AreEqual(IterationStatus.Indetermined, criteria[0].Status, "Incorrect status");
Assert.AreEqual(IterationStatus.Indetermined, criteria[1].Status, "Incorrect status");
Assert.AreEqual(IterationStatus.Indetermined, criteria[2].Status, "Incorrect status");
}
}
}

34
src/UnitTests/LinearAlgebraTests/Single/Solvers/StopCriterium/DivergenceStopCriteriumTest.cs

@ -28,11 +28,11 @@
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
using System;
using MathNet.Numerics.LinearAlgebra.Single;
using MathNet.Numerics.LinearAlgebra.Single.Solvers.StopCriterium;
using MathNet.Numerics.LinearAlgebra.Solvers.Status;
using MathNet.Numerics.LinearAlgebra.Solvers;
using NUnit.Framework;
using System;
namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.StopCriterium
{
@ -117,20 +117,6 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.StopCrite
DenseVector.Create(3, i => 6)));
}
/// <summary>
/// Determine status with <c>null</c> residual vector throws <c>ArgumentNullException</c>.
/// </summary>
[Test]
public void DetermineStatusWithNullResidualVectorThrowsArgumentNullException()
{
var criterium = new DivergenceStopCriterium(0.5, 15);
Assert.Throws<ArgumentNullException>(() => criterium.DetermineStatus(
1,
DenseVector.Create(3, i => 4),
DenseVector.Create(3, i => 5),
null));
}
/// <summary>
/// Can determine status with too few iterations.
/// </summary>
@ -151,7 +137,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.StopCrite
new DenseVector(new[] {1.0f}),
new DenseVector(new[] {(i + 1)*(Increase + 0.1f)}));
Assert.IsInstanceOf(typeof (CalculationRunning), status, "Status check fail.");
Assert.AreEqual(IterationStatus.Running, status, "Status check fail.");
}
}
@ -175,7 +161,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.StopCrite
new DenseVector(new[] {1.0f}),
new DenseVector(new[] {(i + 1)*(Increase - 0.01f)}));
Assert.IsInstanceOf(typeof (CalculationRunning), status, "Status check fail.");
Assert.AreEqual(IterationStatus.Running, status, "Status check fail.");
}
}
@ -199,7 +185,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.StopCrite
new DenseVector(new[] {1.0f}),
new DenseVector(new[] {(i + 1)*(Increase - 0.01f)}));
Assert.IsInstanceOf(typeof (CalculationRunning), status, "Status check fail.");
Assert.AreEqual(IterationStatus.Running, status, "Status check fail.");
}
// Now make it fail by throwing in a NaN
@ -209,7 +195,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.StopCrite
new DenseVector(new[] {1.0f}),
new DenseVector(new[] {float.NaN}));
Assert.IsInstanceOf(typeof (CalculationDiverged), status2, "Status check fail.");
Assert.AreEqual(IterationStatus.Diverged, status2, "Status check fail.");
}
/// <summary>
@ -234,7 +220,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.StopCrite
new DenseVector(new[] {1.0f}),
new DenseVector(new[] {previous}));
Assert.IsInstanceOf(typeof (CalculationRunning), status, "Status check fail.");
Assert.AreEqual(IterationStatus.Running, status, "Status check fail.");
}
// Add the final residual. Now we should have divergence
@ -245,7 +231,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.StopCrite
new DenseVector(new[] {1.0f}),
new DenseVector(new[] {previous}));
Assert.IsInstanceOf(typeof (CalculationDiverged), status2, "Status check fail.");
Assert.AreEqual(IterationStatus.Diverged, status2, "Status check fail.");
}
/// <summary>
@ -266,14 +252,14 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.StopCrite
new DenseVector(new[] {1.0f}),
new DenseVector(new[] {float.NaN}));
Assert.IsInstanceOf(typeof (CalculationDiverged), status, "Status check fail.");
Assert.AreEqual(IterationStatus.Diverged, status, "Status check fail.");
// Reset the state
criterium.ResetToPrecalculationState();
Assert.AreEqual(Increase, criterium.MaximumRelativeIncrease, "Incorrect maximum");
Assert.AreEqual(Iterations, criterium.MinimumNumberOfIterations, "Incorrect iteration count");
Assert.IsInstanceOf(typeof (CalculationIndetermined), criterium.Status, "Status check fail.");
Assert.AreEqual(IterationStatus.Indetermined, criterium.Status, "Status check fail.");
}
/// <summary>

36
src/UnitTests/LinearAlgebraTests/Single/Solvers/StopCriterium/FailureStopCriteriumTest.cs

@ -30,7 +30,7 @@
using MathNet.Numerics.LinearAlgebra.Single;
using MathNet.Numerics.LinearAlgebra.Single.Solvers.StopCriterium;
using MathNet.Numerics.LinearAlgebra.Solvers.Status;
using MathNet.Numerics.LinearAlgebra.Solvers;
using NUnit.Framework;
using System;
@ -64,30 +64,6 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.StopCrite
Assert.Throws<ArgumentOutOfRangeException>(() => criterium.DetermineStatus(-1, DenseVector.Create(3, i => 4), DenseVector.Create(3, i => 5), DenseVector.Create(3, i => 6)));
}
/// <summary>
/// Determine status with <c>null</c> solution vector throws <c>ArgumentNullException</c>.
/// </summary>
[Test]
public void DetermineStatusWithNullSolutionVectorThrowsArgumentNullException()
{
var criterium = new FailureStopCriterium();
Assert.IsNotNull(criterium, "There should be a criterium");
Assert.Throws<ArgumentNullException>(() => criterium.DetermineStatus(1, null, DenseVector.Create(3, i => 6), DenseVector.Create(4, i => 4)));
}
/// <summary>
/// Determine status with <c>null</c> residual vector throws <c>ArgumentNullException</c>.
/// </summary>
[Test]
public void DetermineStatusWithNullResidualVectorThrowsArgumentNullException()
{
var criterium = new FailureStopCriterium();
Assert.IsNotNull(criterium, "There should be a criterium");
Assert.Throws<ArgumentNullException>(() => criterium.DetermineStatus(1, DenseVector.Create(3, i => 4), DenseVector.Create(3, i => 6), null));
}
/// <summary>
/// Determine status with non-matching vectors throws <c>ArgumentException</c>.
/// </summary>
@ -114,7 +90,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.StopCrite
var residual = new DenseVector(new[] {1000, float.NaN, 2001});
var status = criterium.DetermineStatus(5, solution, source, residual);
Assert.IsInstanceOf(typeof (CalculationFailure), status, "Should be failed");
Assert.AreEqual(IterationStatus.Failure, status, "Should be failed");
}
/// <summary>
@ -131,7 +107,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.StopCrite
var residual = new DenseVector(new[] {1000.0f, 1000.0f, 2001.0f});
var status = criterium.DetermineStatus(5, solution, source, residual);
Assert.IsInstanceOf(typeof (CalculationFailure), status, "Should be failed");
Assert.AreEqual(IterationStatus.Failure, status, "Should be failed");
}
/// <summary>
@ -148,7 +124,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.StopCrite
var residual = new DenseVector(new[] {1.0f, 2.0f, 3.0f});
var status = criterium.DetermineStatus(5, solution, source, residual);
Assert.IsInstanceOf(typeof (CalculationRunning), status, "Should be running");
Assert.AreEqual(IterationStatus.Running, status, "Should be running");
}
/// <summary>
@ -165,10 +141,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.StopCrite
var residual = new DenseVector(new[] {1000.0f, 1000.0f, 2001.0f});
var status = criterium.DetermineStatus(5, solution, source, residual);
Assert.IsInstanceOf(typeof (CalculationRunning), status, "Should be running");
Assert.AreEqual(IterationStatus.Running, status, "Should be running");
criterium.ResetToPrecalculationState();
Assert.IsInstanceOf(typeof (CalculationIndetermined), criterium.Status, "Should not have started");
Assert.AreEqual(IterationStatus.Indetermined, criterium.Status, "Should not have started");
}
/// <summary>

9
src/UnitTests/LinearAlgebraTests/Single/Solvers/StopCriterium/IterationCountStopCriteriumTest.cs

@ -31,7 +31,6 @@
using System;
using MathNet.Numerics.LinearAlgebra.Single;
using MathNet.Numerics.LinearAlgebra.Solvers;
using MathNet.Numerics.LinearAlgebra.Solvers.Status;
using NUnit.Framework;
namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.StopCriterium
@ -98,10 +97,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.StopCrite
Assert.IsNotNull(criterium, "A criterium should have been created");
var status = criterium.DetermineStatus(5, DenseVector.Create(3, i => 1), DenseVector.Create(3, i => 2), DenseVector.Create(3, i => 3));
Assert.IsInstanceOf(typeof (CalculationRunning), status, "Should be running");
Assert.AreEqual(IterationStatus.Running, status, "Should be running");
var status2 = criterium.DetermineStatus(10, DenseVector.Create(3, i => 1), DenseVector.Create(3, i => 2), DenseVector.Create(3, i => 3));
Assert.IsInstanceOf(typeof (CalculationStoppedWithoutConvergence), status2, "Should be finished");
Assert.AreEqual(IterationStatus.StoppedWithoutConvergence, status2, "Should be finished");
}
/// <summary>
@ -114,10 +113,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.StopCrite
Assert.IsNotNull(criterium, "A criterium should have been created");
var status = criterium.DetermineStatus(5, DenseVector.Create(3, i => 1), DenseVector.Create(3, i => 2), DenseVector.Create(3, i => 3));
Assert.IsInstanceOf(typeof (CalculationRunning), status, "Should be running");
Assert.AreEqual(IterationStatus.Running, status, "Should be running");
criterium.ResetToPrecalculationState();
Assert.IsInstanceOf(typeof (CalculationIndetermined), criterium.Status, "Should not have started");
Assert.AreEqual(IterationStatus.Indetermined, criterium.Status, "Should not have started");
}
/// <summary>

66
src/UnitTests/LinearAlgebraTests/Single/Solvers/StopCriterium/ResidualStopCriteriumTest.cs

@ -28,11 +28,11 @@
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
using System;
using MathNet.Numerics.LinearAlgebra.Single;
using MathNet.Numerics.LinearAlgebra.Single.Solvers.StopCriterium;
using MathNet.Numerics.LinearAlgebra.Solvers.Status;
using MathNet.Numerics.LinearAlgebra.Solvers;
using NUnit.Framework;
using System;
namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.StopCriterium
{
@ -115,54 +115,6 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.StopCrite
DenseVector.Create(3, i => 6)));
}
/// <summary>
/// Determine status with <c>null</c> solution vector throws <c>ArgumentNullException</c>.
/// </summary>
[Test]
public void DetermineStatusWithNullSolutionVectorThrowsArgumentNullException()
{
var criterium = new ResidualStopCriterium(1e-6f, 50);
Assert.IsNotNull(criterium, "There should be a criterium");
Assert.Throws<ArgumentNullException>(() => criterium.DetermineStatus(
1,
null,
DenseVector.Create(3, i => 5),
DenseVector.Create(3, i => 6)));
}
/// <summary>
/// Determine status with <c>null</c> source vector throws <c>ArgumentNullException</c>.
/// </summary>
[Test]
public void DetermineStatusWithNullSourceVectorThrowsArgumentNullException()
{
var criterium = new ResidualStopCriterium(1e-6f, 50);
Assert.IsNotNull(criterium, "There should be a criterium");
Assert.Throws<ArgumentNullException>(() => criterium.DetermineStatus(
1,
DenseVector.Create(3, i => 4),
null,
DenseVector.Create(3, i => 6)));
}
/// <summary>
/// Determine status with <c>null</c> residual vector throws <c>ArgumentNullException</c>.
/// </summary>
[Test]
public void DetermineStatusWithNullResidualVectorThrowsArgumentNullException()
{
var criterium = new ResidualStopCriterium(1e-6f, 50);
Assert.IsNotNull(criterium, "There should be a criterium");
Assert.Throws<ArgumentNullException>(() => criterium.DetermineStatus(
1,
DenseVector.Create(3, i => 4),
DenseVector.Create(3, i => 5),
null));
}
/// <summary>
/// Determine status with non-matching solution vector throws <c>ArgumentException</c>.
/// </summary>
@ -225,7 +177,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.StopCrite
var residual = new DenseVector(new[] {1000.0f, 1000.0f, 2001.0f});
var status = criterium.DetermineStatus(5, solution, source, residual);
Assert.IsInstanceOf(typeof (CalculationDiverged), status, "Should be diverged");
Assert.AreEqual(IterationStatus.Diverged, status, "Should be diverged");
}
/// <summary>
@ -242,7 +194,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.StopCrite
var residual = new DenseVector(new[] {1000.0f, float.NaN, 2001.0f});
var status = criterium.DetermineStatus(5, solution, source, residual);
Assert.IsInstanceOf(typeof (CalculationDiverged), status, "Should be diverged");
Assert.AreEqual(IterationStatus.Diverged, status, "Should be diverged");
}
/// <summary>
@ -259,7 +211,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.StopCrite
var residual = new DenseVector(new[] {0.0f, 0.0f, 0.0f});
var status = criterium.DetermineStatus(0, solution, source, residual);
Assert.IsInstanceOf(typeof (CalculationConverged), status, "Should be done");
Assert.AreEqual(IterationStatus.Converged, status, "Should be done");
}
/// <summary>
@ -281,10 +233,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.StopCrite
var residual = new DenseVector(new[] {0.001f, 0.001f, 0.002f});
var status = criterium.DetermineStatus(5, solution, source, residual);
Assert.IsInstanceOf(typeof (CalculationRunning), status, "Should still be running");
Assert.AreEqual(IterationStatus.Running, status, "Should still be running");
var status2 = criterium.DetermineStatus(16, solution, source, residual);
Assert.IsInstanceOf(typeof (CalculationConverged), status2, "Should be done");
Assert.AreEqual(IterationStatus.Converged, status2, "Should be done");
}
/// <summary>
@ -301,10 +253,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.StopCrite
var residual = new DenseVector(new[] {1.000f, 1.000f, 2.001f});
var status = criterium.DetermineStatus(5, solution, source, residual);
Assert.IsInstanceOf(typeof (CalculationRunning), status, "Should be running");
Assert.AreEqual(IterationStatus.Running, status, "Should be running");
criterium.ResetToPrecalculationState();
Assert.IsInstanceOf(typeof (CalculationIndetermined), criterium.Status, "Should not have started");
Assert.AreEqual(IterationStatus.Indetermined, criterium.Status, "Should not have started");
}
/// <summary>

Loading…
Cancel
Save