Browse Source

LA: iterative solver no longer stateful on iterator

pull/163/head
Christoph Ruegg 13 years ago
parent
commit
c095cdb536
  1. 6
      src/Examples/LinearAlgebra/IterativeSolvers/BiCgStabSolver.cs
  2. 6
      src/Examples/LinearAlgebra/IterativeSolvers/CompositeSolverExample.cs
  3. 6
      src/Examples/LinearAlgebra/IterativeSolvers/GpBiCgSolver.cs
  4. 6
      src/Examples/LinearAlgebra/IterativeSolvers/MlkBiCgStabSolver.cs
  5. 6
      src/Examples/LinearAlgebra/IterativeSolvers/TFQMRSolver.cs
  6. 129
      src/Numerics/LinearAlgebra/Complex/Solvers/BiCgStab.cs
  7. 72
      src/Numerics/LinearAlgebra/Complex/Solvers/CompositeSolver.cs
  8. 123
      src/Numerics/LinearAlgebra/Complex/Solvers/GpBiCg.cs
  9. 19
      src/Numerics/LinearAlgebra/Complex/Solvers/Iterator.cs
  10. 128
      src/Numerics/LinearAlgebra/Complex/Solvers/MlkBiCgStab.cs
  11. 129
      src/Numerics/LinearAlgebra/Complex/Solvers/TFQMR.cs
  12. 129
      src/Numerics/LinearAlgebra/Complex32/Solvers/BiCgStab.cs
  13. 74
      src/Numerics/LinearAlgebra/Complex32/Solvers/CompositeSolver.cs
  14. 120
      src/Numerics/LinearAlgebra/Complex32/Solvers/GpBiCg.cs
  15. 19
      src/Numerics/LinearAlgebra/Complex32/Solvers/Iterator.cs
  16. 128
      src/Numerics/LinearAlgebra/Complex32/Solvers/MlkBiCgStab.cs
  17. 129
      src/Numerics/LinearAlgebra/Complex32/Solvers/TFQMR.cs
  18. 133
      src/Numerics/LinearAlgebra/Double/Solvers/BiCgStab.cs
  19. 61
      src/Numerics/LinearAlgebra/Double/Solvers/CompositeSolver.cs
  20. 127
      src/Numerics/LinearAlgebra/Double/Solvers/GpBiCg.cs
  21. 19
      src/Numerics/LinearAlgebra/Double/Solvers/Iterator.cs
  22. 132
      src/Numerics/LinearAlgebra/Double/Solvers/MlkBiCgStab.cs
  23. 133
      src/Numerics/LinearAlgebra/Double/Solvers/TFQMR.cs
  24. 133
      src/Numerics/LinearAlgebra/Single/Solvers/BiCgStab.cs
  25. 72
      src/Numerics/LinearAlgebra/Single/Solvers/CompositeSolver.cs
  26. 123
      src/Numerics/LinearAlgebra/Single/Solvers/GpBiCg.cs
  27. 19
      src/Numerics/LinearAlgebra/Single/Solvers/Iterator.cs
  28. 132
      src/Numerics/LinearAlgebra/Single/Solvers/MlkBiCgStab.cs
  29. 129
      src/Numerics/LinearAlgebra/Single/Solvers/TFQMR.cs
  30. 19
      src/Numerics/LinearAlgebra/Solvers/IIterativeSolver.cs
  31. 20
      src/UnitTests/LinearAlgebraTests/Complex/Solvers/Iterative/BiCgStabTest.cs
  32. 20
      src/UnitTests/LinearAlgebraTests/Complex/Solvers/Iterative/GpBiCgTest.cs
  33. 20
      src/UnitTests/LinearAlgebraTests/Complex/Solvers/Iterative/MlkBiCgStabTest.cs
  34. 20
      src/UnitTests/LinearAlgebraTests/Complex/Solvers/Iterative/TFQMRTest.cs
  35. 20
      src/UnitTests/LinearAlgebraTests/Complex32/Solvers/Iterative/BiCgStabTest.cs
  36. 16
      src/UnitTests/LinearAlgebraTests/Complex32/Solvers/Iterative/GpBiCgTest.cs
  37. 20
      src/UnitTests/LinearAlgebraTests/Complex32/Solvers/Iterative/MlkBiCgStabTest.cs
  38. 20
      src/UnitTests/LinearAlgebraTests/Complex32/Solvers/Iterative/TFQMRTest.cs
  39. 20
      src/UnitTests/LinearAlgebraTests/Double/Solvers/Iterative/BiCgStabTest.cs
  40. 20
      src/UnitTests/LinearAlgebraTests/Double/Solvers/Iterative/GpBiCgTest.cs
  41. 20
      src/UnitTests/LinearAlgebraTests/Double/Solvers/Iterative/MlkBiCgStabTest.cs
  42. 20
      src/UnitTests/LinearAlgebraTests/Double/Solvers/Iterative/TFQMRTest.cs
  43. 20
      src/UnitTests/LinearAlgebraTests/Single/Solvers/Iterative/BiCgStabTest.cs
  44. 20
      src/UnitTests/LinearAlgebraTests/Single/Solvers/Iterative/GpBiCgTest.cs
  45. 20
      src/UnitTests/LinearAlgebraTests/Single/Solvers/Iterative/MlkBiCgStabTest.cs
  46. 20
      src/UnitTests/LinearAlgebraTests/Single/Solvers/Iterative/TFQMRTest.cs

6
src/Examples/LinearAlgebra/IterativeSolvers/BiCgStabSolver.cs

@ -108,10 +108,10 @@ namespace Examples.LinearAlgebra.IterativeSolversExamples
var monitor = new Iterator<double>(new IIterationStopCriterium<double>[] { iterationCountStopCriterium, residualStopCriterium });
// Create Bi-Conjugate Gradient Stabilized solver
var solver = new BiCgStab(monitor);
var solver = new BiCgStab();
// 1. Solve the matrix equation
var resultX = solver.Solve(matrixA, vectorB);
var resultX = solver.Solve(matrixA, vectorB, monitor);
Console.WriteLine(@"1. Solve the matrix equation");
Console.WriteLine();
@ -126,7 +126,7 @@ namespace Examples.LinearAlgebra.IterativeSolversExamples
// - CalculationRunning: calculation is running and no results are yet known;
// - CalculationStoppedWithoutConvergence: calculation has been stopped due to reaching the stopping limits, but that convergence was not achieved;
Console.WriteLine(@"2. Solver status of the iterations");
Console.WriteLine(solver.IterationResult);
Console.WriteLine(monitor.Status);
Console.WriteLine();
// 3. Solution result vector of the matrix equation

6
src/Examples/LinearAlgebra/IterativeSolvers/CompositeSolverExample.cs

@ -112,10 +112,10 @@ namespace Examples.LinearAlgebra.IterativeSolversExamples
CompositeSolver.LoadSolverInformationFromAssembly(Assembly.GetExecutingAssembly());
// Create composite solver
var solver = new CompositeSolver(monitor);
var solver = new CompositeSolver();
// 1. Solve the matrix equation
var resultX = solver.Solve(matrixA, vectorB);
var resultX = solver.Solve(matrixA, vectorB, monitor);
Console.WriteLine(@"1. Solve the matrix equation");
Console.WriteLine();
@ -130,7 +130,7 @@ namespace Examples.LinearAlgebra.IterativeSolversExamples
// - CalculationRunning: calculation is running and no results are yet known;
// - CalculationStoppedWithoutConvergence: calculation has been stopped due to reaching the stopping limits, but that convergence was not achieved;
Console.WriteLine(@"2. Solver status of the iterations");
Console.WriteLine(solver.IterationResult);
Console.WriteLine(monitor.Status);
Console.WriteLine();
// 3. Solution result vector of the matrix equation

6
src/Examples/LinearAlgebra/IterativeSolvers/GpBiCgSolver.cs

@ -106,10 +106,10 @@ namespace Examples.LinearAlgebra.IterativeSolversExamples
var monitor = new Iterator<double>(new IIterationStopCriterium<double>[] { iterationCountStopCriterium, residualStopCriterium });
// Create Generalized Product Bi-Conjugate Gradient solver
var solver = new GpBiCg(monitor);
var solver = new GpBiCg();
// 1. Solve the matrix equation
var resultX = solver.Solve(matrixA, vectorB);
var resultX = solver.Solve(matrixA, vectorB, monitor);
Console.WriteLine(@"1. Solve the matrix equation");
Console.WriteLine();
@ -124,7 +124,7 @@ namespace Examples.LinearAlgebra.IterativeSolversExamples
// - CalculationRunning: calculation is running and no results are yet known;
// - CalculationStoppedWithoutConvergence: calculation has been stopped due to reaching the stopping limits, but that convergence was not achieved;
Console.WriteLine(@"2. Solver status of the iterations");
Console.WriteLine(solver.IterationResult);
Console.WriteLine(monitor.Status);
Console.WriteLine();
// 3. Solution result vector of the matrix equation

6
src/Examples/LinearAlgebra/IterativeSolvers/MlkBiCgStabSolver.cs

@ -107,10 +107,10 @@ namespace Examples.LinearAlgebra.IterativeSolversExamples
var monitor = new Iterator<double>(new IIterationStopCriterium<double>[] { iterationCountStopCriterium, residualStopCriterium });
// Create Multiple-Lanczos Bi-Conjugate Gradient Stabilized solver
var solver = new MlkBiCgStab(monitor);
var solver = new MlkBiCgStab();
// 1. Solve the matrix equation
var resultX = solver.Solve(matrixA, vectorB);
var resultX = solver.Solve(matrixA, vectorB, monitor);
Console.WriteLine(@"1. Solve the matrix equation");
Console.WriteLine();
@ -125,7 +125,7 @@ namespace Examples.LinearAlgebra.IterativeSolversExamples
// - CalculationRunning: calculation is running and no results are yet known;
// - CalculationStoppedWithoutConvergence: calculation has been stopped due to reaching the stopping limits, but that convergence was not achieved;
Console.WriteLine(@"2. Solver status of the iterations");
Console.WriteLine(solver.IterationResult);
Console.WriteLine(monitor.Status);
Console.WriteLine();
// 3. Solution result vector of the matrix equation

6
src/Examples/LinearAlgebra/IterativeSolvers/TFQMRSolver.cs

@ -107,10 +107,10 @@ namespace Examples.LinearAlgebra.IterativeSolversExamples
var monitor = new Iterator<double>(new IIterationStopCriterium<double>[] { iterationCountStopCriterium, residualStopCriterium });
// Create Transpose Free Quasi-Minimal Residual solver
var solver = new TFQMR(monitor);
var solver = new TFQMR();
// 1. Solve the matrix equation
var resultX = solver.Solve(matrixA, vectorB);
var resultX = solver.Solve(matrixA, vectorB, monitor);
Console.WriteLine(@"1. Solve the matrix equation");
Console.WriteLine();
@ -125,7 +125,7 @@ namespace Examples.LinearAlgebra.IterativeSolversExamples
// - CalculationRunning: calculation is running and no results are yet known;
// - CalculationStoppedWithoutConvergence: calculation has been stopped due to reaching the stopping limits, but that convergence was not achieved;
Console.WriteLine(@"2. Solver status of the iterations");
Console.WriteLine(solver.IterationResult);
Console.WriteLine(monitor.Status);
Console.WriteLine();
// 3. Solution result vector of the matrix equation

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

@ -78,11 +78,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
/// </summary>
IPreConditioner<Complex> _preconditioner;
/// <summary>
/// The iterative process controller.
/// </summary>
Iterator<Complex> _iterator;
/// <summary>
/// Indicates if the user has stopped the solver.
/// </summary>
@ -96,44 +91,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
/// the standard settings and a default preconditioner.
/// </remarks>
public BiCgStab()
: this(null, null)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="BiCgStab"/> class.
/// </summary>
/// <remarks>
/// <para>
/// When using this constructor the solver will use a default preconditioner.
/// </para>
/// <para>
/// The main advantages of using a user defined <see cref="Iterator{T}"/> are:
/// <list type="number">
/// <item>It is possible to set the desired convergence limits.</item>
/// <item>
/// It is possible to check the reason for which the solver finished
/// the iterative procedure by calling the <see cref="Iterator{T}.Status"/> property.
/// </item>
/// </list>
/// </para>
/// </remarks>
/// <param name="iterator">The <see cref="Iterator{T}"/> that will be used to monitor the iterative process. </param>
public BiCgStab(Iterator<Complex> iterator)
: this(null, iterator)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="BiCgStab"/> class.
/// </summary>
/// <remarks>
/// When using this constructor the solver will use the <see cref="Iterator{T}"/> with
/// the standard settings.
/// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation.</param>
public BiCgStab(IPreConditioner<Complex> preconditioner)
: this(preconditioner, null)
{
}
@ -153,10 +110,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
/// </para>
/// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation. </param>
/// <param name="iterator">The <see cref="Iterator{T}"/> that will be used to monitor the iterative process. </param>
public BiCgStab(IPreConditioner<Complex> preconditioner, Iterator<Complex> iterator)
public BiCgStab(IPreConditioner<Complex> preconditioner)
{
_iterator = iterator;
_preconditioner = preconditioner;
}
@ -169,23 +124,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
_preconditioner = preconditioner;
}
/// <summary>
/// Sets the <see cref="Iterator{T}"/> that will be used to track the iterative process.
/// </summary>
/// <param name="iterator">The iterator.</param>
public void SetIterator(Iterator<Complex> iterator)
{
_iterator = iterator;
}
/// <summary>
/// Gets the status of the iteration once the calculation is finished.
/// </summary>
public IterationStatus IterationResult
{
get { return (_iterator != null) ? _iterator.Status : IterationStatus.Indetermined; }
}
/// <summary>
/// Stops the solve process.
/// </summary>
@ -204,15 +142,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
/// <param name="matrix">The coefficient <see cref="Matrix"/>, <c>A</c>.</param>
/// <param name="vector">The solution <see cref="Vector"/>, <c>b</c>.</param>
/// <returns>The result <see cref="Vector"/>, <c>x</c>.</returns>
public Vector<Complex> Solve(Matrix<Complex> matrix, Vector<Complex> vector)
public Vector<Complex> Solve(Matrix<Complex> matrix, Vector<Complex> vector, Iterator<Complex> iterator = null)
{
if (vector == null)
{
throw new ArgumentNullException();
}
var result = new DenseVector(matrix.RowCount);
Solve(matrix, vector, result);
Solve(matrix, vector, result, iterator);
return result;
}
@ -223,7 +156,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
/// <param name="matrix">The coefficient <see cref="Matrix"/>, <c>A</c>.</param>
/// <param name="input">The solution <see cref="Vector"/>, <c>b</c>.</param>
/// <param name="result">The result <see cref="Vector"/>, <c>x</c>.</param>
public void Solve(Matrix<Complex> matrix, Vector<Complex> input, Vector<Complex> result)
public void Solve(Matrix<Complex> matrix, Vector<Complex> input, Vector<Complex> result, Iterator<Complex> iterator = null)
{
// If we were stopped before, we are no longer
// We're doing this at the start of the method to ensure
@ -263,9 +196,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
// Initialize the solver fields
// Set the convergence monitor
if (_iterator == null)
if (iterator == null)
{
_iterator = Iterator.CreateDefault();
iterator = new Iterator<Complex>(Iterator.CreateDefaultStopCriteria());
}
if (_preconditioner == null)
@ -302,7 +235,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
Complex omega = 0;
var iterationNumber = 0;
while (ShouldContinue(iterationNumber, result, input, residuals))
while (ShouldContinue(iterator, iterationNumber, result, input, residuals))
{
// rho_(i-1) = r~^T r_(i-1) // dotproduct r~ and r_(i-1)
var oldRho = currentRho;
@ -361,7 +294,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
temp2.CopyTo(temp);
// Check convergence and stop if we are converged.
if (!ShouldContinue(iterationNumber, temp, input, vecS))
if (!ShouldContinue(iterator, iterationNumber, temp, input, vecS))
{
temp.CopyTo(result);
@ -369,7 +302,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
CalculateTrueResidual(matrix, residuals, result, input);
// Now recheck the convergence
if (!ShouldContinue(iterationNumber, result, input, residuals))
if (!ShouldContinue(iterator, iterationNumber, result, input, residuals))
{
// We're all good now.
return;
@ -410,7 +343,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
throw new Exception("Iterative solver experience a numerical break down");
}
if (!ShouldContinue(iterationNumber, result, input, residuals))
if (!ShouldContinue(iterator, iterationNumber, result, input, residuals))
{
// Recalculate the residuals and go round again. This is done to ensure that
// we have the proper residuals.
@ -451,7 +384,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
/// <param name="source">Source <see cref="Vector"/>.</param>
/// <param name="residuals">Residual <see cref="Vector"/>.</param>
/// <returns><c>true</c> if continue, otherwise <c>false</c></returns>
bool ShouldContinue(int iterationNumber, Vector<Complex> result, Vector<Complex> source, Vector<Complex> residuals)
bool ShouldContinue(Iterator<Complex> iterator, int iterationNumber, Vector<Complex> result, Vector<Complex> source, Vector<Complex> residuals)
{
// We stop if either:
// - the user has stopped the calculation
@ -459,11 +392,11 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
if (_hasBeenStopped)
{
_iterator.Cancel();
iterator.Cancel();
return true;
}
var status = _iterator.DetermineStatus(iterationNumber, result, source, residuals);
var status = iterator.DetermineStatus(iterationNumber, result, source, residuals);
return status == IterationStatus.Running || status == IterationStatus.Indetermined;
}
@ -474,20 +407,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
/// <param name="matrix">The coefficient <see cref="Matrix"/>, <c>A</c>.</param>
/// <param name="input">The solution <see cref="Matrix"/>, <c>B</c>.</param>
/// <returns>The result <see cref="Matrix"/>, <c>X</c>.</returns>
public Matrix<Complex> Solve(Matrix<Complex> matrix, Matrix<Complex> input)
public Matrix<Complex> Solve(Matrix<Complex> matrix, Matrix<Complex> input, Iterator<Complex> iterator = null)
{
if (matrix == null)
{
throw new ArgumentNullException("matrix");
}
if (input == null)
{
throw new ArgumentNullException("input");
}
var result = matrix.CreateMatrix(input.RowCount, input.ColumnCount);
Solve(matrix, input, result);
Solve(matrix, input, result, iterator);
return result;
}
@ -498,31 +421,21 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
/// <param name="matrix">The coefficient <see cref="Matrix"/>, <c>A</c>.</param>
/// <param name="input">The solution <see cref="Matrix"/>, <c>B</c>.</param>
/// <param name="result">The result <see cref="Matrix"/>, <c>X</c></param>
public void Solve(Matrix<Complex> matrix, Matrix<Complex> input, Matrix<Complex> result)
public void Solve(Matrix<Complex> matrix, Matrix<Complex> input, Matrix<Complex> result, Iterator<Complex> iterator = null)
{
if (matrix == null)
{
throw new ArgumentNullException("matrix");
}
if (input == null)
{
throw new ArgumentNullException("input");
}
if (result == null)
if (matrix.RowCount != input.RowCount || input.RowCount != result.RowCount || input.ColumnCount != result.ColumnCount)
{
throw new ArgumentNullException("result");
throw Matrix.DimensionsDontMatch<ArgumentException>(matrix, input, result);
}
if (matrix.RowCount != input.RowCount || input.RowCount != result.RowCount || input.ColumnCount != result.ColumnCount)
if (iterator == null)
{
throw Matrix.DimensionsDontMatch<ArgumentException>(matrix, input, result);
iterator = new Iterator<Complex>(Iterator.CreateDefaultStopCriteria());
}
for (var column = 0; column < input.ColumnCount; column++)
{
var solution = Solve(matrix, input.Column(column));
var solution = Solve(matrix, input.Column(column), iterator);
foreach (var element in solution.EnumerateNonZeroIndexed())
{
result.At(element.Item1, column, element.Item2);

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

@ -339,11 +339,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
/// </summary>
IterationStatus _status = IterationStatus.Indetermined;
/// <summary>
/// The iterator that is used to control the iteration process.
/// </summary>
Iterator<Complex> _iterator;
/// <summary>
/// A flag indicating if the solver has been stopped or not.
/// </summary>
@ -358,37 +353,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
/// <summary>
/// Initializes a new instance of the <see cref="CompositeSolver"/> class with the default iterator.
/// </summary>
public CompositeSolver() : this(null)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="CompositeSolver"/> class with the specified iterator.
/// </summary>
/// <param name="iterator">The iterator that will be used to control the iteration process. </param>
public CompositeSolver(Iterator<Complex> iterator)
{
_iterator = iterator;
}
/// <summary>
/// Sets the <c>IIterator</c> that will be used to track the iterative process.
/// </summary>
/// <param name="iterator">The iterator.</param>
public void SetIterator(Iterator<Complex> iterator)
{
_iterator = iterator;
}
/// <summary>
/// Gets the status of the iteration once the calculation is finished.
/// </summary>
public IterationStatus IterationResult
public CompositeSolver()
{
get
{
return _status;
}
}
/// <summary>
@ -414,10 +380,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="vector">The solution vector, <c>b</c>.</param>
/// <returns>The result vector, <c>x</c>.</returns>
public Vector<Complex> Solve(Matrix<Complex> matrix, Vector<Complex> vector)
public Vector<Complex> Solve(Matrix<Complex> matrix, Vector<Complex> vector, Iterator<Complex> iterator = null)
{
var result = new DenseVector(matrix.RowCount);
Solve(matrix, vector, result);
Solve(matrix, vector, result, iterator);
return result;
}
@ -428,7 +394,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution vector, <c>b</c></param>
/// <param name="result">The result vector, <c>x</c></param>
public void Solve(Matrix<Complex> matrix, Vector<Complex> input, Vector<Complex> result)
public void Solve(Matrix<Complex> matrix, Vector<Complex> input, Vector<Complex> result, Iterator<Complex> iterator = null)
{
// If we were stopped before, we are no longer
// We're doing this at the start of the method to ensure
@ -448,9 +414,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
// Initialize the solver fields
// Set the convergence monitor
if (_iterator == null)
if (iterator == null)
{
_iterator = Iterator.CreateDefault();
iterator = new Iterator<Complex>(Iterator.CreateDefaultStopCriteria());
}
// Load the solvers into our own internal data structure
@ -473,11 +439,11 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
try
{
// Reset the iterator and pass it to the solver
_iterator.Reset();
solver.SetIterator(_iterator);
iterator.Reset();
// Start the solver
solver.Solve(matrix, internalInput, internalResult);
solver.Solve(matrix, internalInput, internalResult, iterator);
_status = iterator.Status;
}
catch (Exception)
{
@ -491,7 +457,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
}
// There was no fatal breakdown so check the status
if (_iterator.HasConverged)
if (_status == IterationStatus.Converged)
{
// We're done
internalResult.CopyTo(result);
@ -501,7 +467,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
// We're not done
// Either:
// - calculation finished without convergence
if (_iterator.HasStoppedWithoutConvergence)
if (_status == IterationStatus.StoppedWithoutConvergence)
{
// Copy the internal result to the result vector and
// continue with the calculation.
@ -522,9 +488,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
// Clean up
// No longer need the current solver
_currentSolver = null;
// Set the final status
_status = _iterator.Status;
}
/// <summary>
@ -554,10 +517,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution matrix, <c>B</c>.</param>
/// <returns>The result matrix, <c>X</c>.</returns>
public Matrix<Complex> Solve(Matrix<Complex> matrix, Matrix<Complex> input)
public Matrix<Complex> Solve(Matrix<Complex> matrix, Matrix<Complex> input, Iterator<Complex> iterator = null)
{
var result = matrix.CreateMatrix(input.RowCount, input.ColumnCount);
Solve(matrix, input, result);
Solve(matrix, input, result, iterator);
return result;
}
@ -568,16 +531,21 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution matrix, <c>B</c>.</param>
/// <param name="result">The result matrix, <c>X</c></param>
public void Solve(Matrix<Complex> matrix, Matrix<Complex> input, Matrix<Complex> result)
public void Solve(Matrix<Complex> matrix, Matrix<Complex> input, Matrix<Complex> result, Iterator<Complex> iterator = null)
{
if (matrix.RowCount != input.RowCount || input.RowCount != result.RowCount || input.ColumnCount != result.ColumnCount)
{
throw Matrix.DimensionsDontMatch<ArgumentException>(matrix, input, result);
}
if (iterator == null)
{
iterator = new Iterator<Complex>(Iterator.CreateDefaultStopCriteria());
}
for (var column = 0; column < input.ColumnCount; column++)
{
var solution = Solve(matrix, input.Column(column));
var solution = Solve(matrix, input.Column(column), iterator);
foreach (var element in solution.EnumerateNonZeroIndexed())
{
result.At(element.Item1, column, element.Item2);

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

@ -76,11 +76,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
/// </summary>
IPreConditioner<Complex> _preconditioner;
/// <summary>
/// The iterative process controller.
/// </summary>
Iterator<Complex> _iterator;
/// <summary>
/// Indicates the number of <c>BiCGStab</c> steps should be taken
/// before switching.
@ -106,7 +101,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
/// the standard settings and a default preconditioner.
/// </remarks>
public GpBiCg()
: this(null, null)
{
}
@ -115,9 +109,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
/// </summary>
/// <remarks>
/// <para>
/// When using this constructor the solver will use a default preconditioner.
/// </para>
/// <para>
/// The main advantages of using a user defined <see cref="Iterator{T}"/> are:
/// <list type="number">
/// <item>It is possible to set the desired convergence limits.</item>
@ -128,45 +119,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
/// </list>
/// </para>
/// </remarks>
/// <param name="iterator">The <see cref="Iterator{T}"/> that will be used to monitor the iterative process.</param>
public GpBiCg(Iterator<Complex> iterator)
: this(null, iterator)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="GpBiCg"/> class.
/// </summary>
/// <remarks>
/// When using this constructor the solver will use the <see cref="Iterator{T}"/> with
/// the standard settings.
/// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation.</param>
public GpBiCg(IPreConditioner<Complex> preconditioner)
: this(preconditioner, null)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="GpBiCg"/> class.
/// </summary>
/// <remarks>
/// <para>
/// The main advantages of using a user defined <see cref="Iterator{T}"/> are:
/// <list type="number">
/// <item>It is possible to set the desired convergence limits.</item>
/// <item>
/// It is possible to check the reason for which the solver finished
/// the iterative procedure by calling the <see cref="Iterator{T}.Status"/> property.
/// </item>
/// </list>
/// </para>
/// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation.</param>
/// <param name="iterator">The <see cref="Iterator{T}"/> that will be used to monitor the iterative process.</param>
public GpBiCg(IPreConditioner<Complex> preconditioner, Iterator<Complex> iterator)
{
_iterator = iterator;
_preconditioner = preconditioner;
}
@ -217,23 +172,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
_preconditioner = preconditioner;
}
/// <summary>
/// Sets the <see cref="Iterator{T}"/> that will be used to track the iterative process.
/// </summary>
/// <param name="iterator">The iterator.</param>
public void SetIterator(Iterator<Complex> iterator)
{
_iterator = iterator;
}
/// <summary>
/// Gets the status of the iteration once the calculation is finished.
/// </summary>
public IterationStatus IterationResult
{
get { return (_iterator != null) ? _iterator.Status : IterationStatus.Indetermined; }
}
/// <summary>
/// Stops the solve process.
/// </summary>
@ -253,15 +191,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="vector">The solution vector, <c>b</c>.</param>
/// <returns>The result vector, <c>x</c>.</returns>
public Vector<Complex> Solve(Matrix<Complex> matrix, Vector<Complex> vector)
public Vector<Complex> Solve(Matrix<Complex> matrix, Vector<Complex> vector, Iterator<Complex> iterator = null)
{
if (vector == null)
{
throw new ArgumentNullException();
}
var result = new DenseVector(matrix.RowCount);
Solve(matrix, vector, result);
Solve(matrix, vector, result, iterator);
return result;
}
@ -272,7 +205,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution vector, <c>b</c></param>
/// <param name="result">The result vector, <c>x</c></param>
public void Solve(Matrix<Complex> matrix, Vector<Complex> input, Vector<Complex> result)
public void Solve(Matrix<Complex> matrix, Vector<Complex> input, Vector<Complex> result, Iterator<Complex> iterator = null)
{
// If we were stopped before, we are no longer
// We're doing this at the start of the method to ensure
@ -307,9 +240,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
// Initialize the solver fields
// Set the convergence monitor
if (_iterator == null)
if (iterator == null)
{
_iterator = Iterator.CreateDefault();
iterator = new Iterator<Complex>(Iterator.CreateDefaultStopCriteria());
}
if (_preconditioner == null)
@ -356,7 +289,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
// for (k = 0, 1, .... )
var iterationNumber = 0;
while (ShouldContinue(iterationNumber, xtemp, input, residuals))
while (ShouldContinue(iterator, iterationNumber, xtemp, input, residuals))
{
// p_k = r_k + beta_(k-1) * (p_(k-1) - u_(k-1))
p.Subtract(u, temp);
@ -497,7 +430,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
_preconditioner.Approximate(xtemp, result);
// Now check for convergence
if (!ShouldContinue(iterationNumber, result, input, residuals))
if (!ShouldContinue(iterator, iterationNumber, result, input, residuals))
{
// Recalculate the residuals and go round again. This is done to ensure that
// we have the proper residuals.
@ -534,7 +467,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
/// <param name="source">Source <see cref="Vector"/>.</param>
/// <param name="residuals">Residual <see cref="Vector"/>.</param>
/// <returns><c>true</c> if continue, otherwise <c>false</c></returns>
bool ShouldContinue(int iterationNumber, Vector<Complex> result, Vector<Complex> source, Vector<Complex> residuals)
bool ShouldContinue(Iterator<Complex> iterator, int iterationNumber, Vector<Complex> result, Vector<Complex> source, Vector<Complex> residuals)
{
// We stop if either:
// - the user has stopped the calculation
@ -542,11 +475,11 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
if (_hasBeenStopped)
{
_iterator.Cancel();
iterator.Cancel();
return true;
}
var status = _iterator.DetermineStatus(iterationNumber, result, source, residuals);
var status = iterator.DetermineStatus(iterationNumber, result, source, residuals);
return status == IterationStatus.Running || status == IterationStatus.Indetermined;
}
@ -574,20 +507,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution matrix, <c>B</c>.</param>
/// <returns>The result matrix, <c>X</c>.</returns>
public Matrix<Complex> Solve(Matrix<Complex> matrix, Matrix<Complex> input)
public Matrix<Complex> Solve(Matrix<Complex> matrix, Matrix<Complex> input, Iterator<Complex> iterator = null)
{
if (matrix == null)
{
throw new ArgumentNullException("matrix");
}
if (input == null)
{
throw new ArgumentNullException("input");
}
var result = matrix.CreateMatrix(input.RowCount, input.ColumnCount);
Solve(matrix, input, result);
Solve(matrix, input, result, iterator);
return result;
}
@ -598,31 +521,21 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution matrix, <c>B</c>.</param>
/// <param name="result">The result matrix, <c>X</c></param>
public void Solve(Matrix<Complex> matrix, Matrix<Complex> input, Matrix<Complex> result)
public void Solve(Matrix<Complex> matrix, Matrix<Complex> input, Matrix<Complex> result, Iterator<Complex> iterator = null)
{
if (matrix == null)
{
throw new ArgumentNullException("matrix");
}
if (input == null)
{
throw new ArgumentNullException("input");
}
if (result == null)
if (matrix.RowCount != input.RowCount || input.RowCount != result.RowCount || input.ColumnCount != result.ColumnCount)
{
throw new ArgumentNullException("result");
throw Matrix.DimensionsDontMatch<ArgumentException>(matrix, input, result);
}
if (matrix.RowCount != input.RowCount || input.RowCount != result.RowCount || input.ColumnCount != result.ColumnCount)
if (iterator == null)
{
throw Matrix.DimensionsDontMatch<ArgumentException>(matrix, input, result);
iterator = new Iterator<Complex>(Iterator.CreateDefaultStopCriteria());
}
for (var column = 0; column < input.ColumnCount; column++)
{
var solution = Solve(matrix, input.Column(column));
var solution = Solve(matrix, input.Column(column), iterator);
foreach (var element in solution.EnumerateNonZeroIndexed())
{
result.At(element.Item1, column, element.Item2);

19
src/Numerics/LinearAlgebra/Complex/Solvers/Iterator.cs

@ -49,16 +49,25 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
// TODO: Refactor
/// <summary>
/// Creates a default iterator with all the <see cref="IIterationStopCriterium{T}"/> objects.
/// Creates the default stop criteria.
/// </summary>
/// <returns>A new <see cref="Iterator{T}"/> object.</returns>
public static Iterator<Complex> CreateDefault()
public static IIterationStopCriterium<Complex>[] CreateDefaultStopCriteria()
{
return new Iterator<Complex>(
return new IIterationStopCriterium<Complex>[]
{
new FailureStopCriterium(),
new DivergenceStopCriterium(),
new IterationCountStopCriterium<Complex>(),
new ResidualStopCriterium());
new ResidualStopCriterium()
};
}
/// <summary>
/// Creates a default iterator with all the default stop criteria.
/// </summary>
public static Iterator<Complex> CreateDefault()
{
return new Iterator<Complex>(CreateDefaultStopCriteria());
}
}
}

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

@ -82,11 +82,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
/// </summary>
IPreConditioner<Complex> _preconditioner;
/// <summary>
/// The iterative process controller.
/// </summary>
Iterator<Complex> _iterator;
/// <summary>
/// The collection of starting vectors which are used as the basis for the Krylov sub-space.
/// </summary>
@ -110,7 +105,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
/// the standard settings and a default preconditioner.
/// </remarks>
public MlkBiCgStab()
: this(null, null)
{
}
@ -119,9 +113,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
/// </summary>
/// <remarks>
/// <para>
/// When using this constructor the solver will use a default preconditioner.
/// </para>
/// <para>
/// The main advantages of using a user defined <see cref="Iterator{T}"/> are:
/// <list type="number">
/// <item>It is possible to set the desired convergence limits.</item>
@ -132,45 +123,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
/// </list>
/// </para>
/// </remarks>
/// <param name="iterator">The <see cref="Iterator{T}"/> that will be used to monitor the iterative process.</param>
public MlkBiCgStab(Iterator<Complex> iterator)
: this(null, iterator)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="MlkBiCgStab"/> class.
/// </summary>
/// <remarks>
/// When using this constructor the solver will use the <see cref="Iterator{T}"/> with
/// the standard settings.
/// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation.</param>
public MlkBiCgStab(IPreConditioner<Complex> preconditioner)
: this(preconditioner, null)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="MlkBiCgStab"/> class.
/// </summary>
/// <remarks>
/// <para>
/// The main advantages of using a user defined <see cref="Iterator{T}"/> are:
/// <list type="number">
/// <item>It is possible to set the desired convergence limits.</item>
/// <item>
/// It is possible to check the reason for which the solver finished
/// the iterative procedure by calling the <see cref="Iterator{T}.Status"/> property.
/// </item>
/// </list>
/// </para>
/// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation.</param>
/// <param name="iterator">The <see cref="Iterator{T}"/> that will be used to monitor the iterative process.</param>
public MlkBiCgStab(IPreConditioner<Complex> preconditioner, Iterator<Complex> iterator)
{
_iterator = iterator;
_preconditioner = preconditioner;
}
@ -215,15 +170,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
_preconditioner = preconditioner;
}
/// <summary>
/// Sets the <see cref="Iterator{T}"/> that will be used to track the iterative process.
/// </summary>
/// <param name="iterator">The iterator.</param>
public void SetIterator(Iterator<Complex> iterator)
{
_iterator = iterator;
}
/// <summary>
/// Gets or sets a series of orthonormal vectors which will be used as basis for the
/// Krylov sub-space.
@ -247,15 +193,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
}
}
/// <summary>
/// Gets the status of the iteration once the calculation is finished.
/// </summary>
public IterationStatus IterationResult
{
[DebuggerStepThrough]
get { return (_iterator != null) ? _iterator.Status : IterationStatus.Indetermined; }
}
/// <summary>
/// Stops the solve process.
/// </summary>
@ -274,15 +211,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="vector">The solution vector, <c>b</c>.</param>
/// <returns>The result vector, <c>x</c>.</returns>
public Vector<Complex> Solve(Matrix<Complex> matrix, Vector<Complex> vector)
public Vector<Complex> Solve(Matrix<Complex> matrix, Vector<Complex> vector, Iterator<Complex> iterator = null)
{
if (vector == null)
{
throw new ArgumentNullException();
}
var result = new DenseVector(matrix.RowCount);
Solve(matrix, vector, result);
Solve(matrix, vector, result, iterator);
return result;
}
@ -293,7 +225,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution vector, <c>b</c></param>
/// <param name="result">The result vector, <c>x</c></param>
public void Solve(Matrix<Complex> matrix, Vector<Complex> input, Vector<Complex> result)
public void Solve(Matrix<Complex> matrix, Vector<Complex> input, Vector<Complex> result, Iterator<Complex> iterator = null)
{
// If we were stopped before, we are no longer
// We're doing this at the start of the method to ensure
@ -328,9 +260,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
// Initialize the solver fields
// Set the convergence monitor
if (_iterator == null)
if (iterator == null)
{
_iterator = Iterator.CreateDefault();
iterator = new Iterator<Complex>(Iterator.CreateDefaultStopCriteria());
}
if (_preconditioner == null)
@ -400,7 +332,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
// FOR (j = 0, 1, 2 ....)
var iterationNumber = 0;
while (ShouldContinue(iterationNumber, xtemp, input, residuals))
while (ShouldContinue(iterator, iterationNumber, xtemp, input, residuals))
{
// SOLVE M g~_((j-1)k+k) = g_((j-1)k+k)
_preconditioner.Approximate(g[k - 1], gtemp);
@ -458,13 +390,13 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
temp2.CopyTo(xtemp);
// Check convergence and stop if we are converged.
if (!ShouldContinue(iterationNumber, xtemp, input, residuals))
if (!ShouldContinue(iterator, iterationNumber, xtemp, input, residuals))
{
// Calculate the true residual
CalculateTrueResidual(matrix, residuals, xtemp, input);
// Now recheck the convergence
if (!ShouldContinue(iterationNumber, xtemp, input, residuals))
if (!ShouldContinue(iterator, iterationNumber, xtemp, input, residuals))
{
// We're all good now.
// Exit from the while loop.
@ -593,7 +525,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
temp2.CopyTo(residuals);
// We can check the residuals here if they're close
if (!ShouldContinue(iterationNumber, xtemp, input, residuals))
if (!ShouldContinue(iterator, iterationNumber, xtemp, input, residuals))
{
// Recalculate the residuals and go round again. This is done to ensure that
// we have the proper residuals.
@ -717,7 +649,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
/// <param name="source">Source <see cref="Vector"/>.</param>
/// <param name="residuals">Residual <see cref="Vector"/>.</param>
/// <returns><c>true</c> if continue, otherwise <c>false</c></returns>
bool ShouldContinue(int iterationNumber, Vector<Complex> result, Vector<Complex> source, Vector<Complex> residuals)
bool ShouldContinue(Iterator<Complex> iterator, int iterationNumber, Vector<Complex> result, Vector<Complex> source, Vector<Complex> residuals)
{
// We stop if either:
// - the user has stopped the calculation
@ -725,11 +657,11 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
if (_hasBeenStopped)
{
_iterator.Cancel();
iterator.Cancel();
return true;
}
var status = _iterator.DetermineStatus(iterationNumber, result, source, residuals);
var status = iterator.DetermineStatus(iterationNumber, result, source, residuals);
return status == IterationStatus.Running || status == IterationStatus.Indetermined;
}
@ -740,20 +672,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution matrix, <c>B</c>.</param>
/// <returns>The result matrix, <c>X</c>.</returns>
public Matrix<Complex> Solve(Matrix<Complex> matrix, Matrix<Complex> input)
public Matrix<Complex> Solve(Matrix<Complex> matrix, Matrix<Complex> input, Iterator<Complex> iterator = null)
{
if (matrix == null)
{
throw new ArgumentNullException("matrix");
}
if (input == null)
{
throw new ArgumentNullException("input");
}
var result = matrix.CreateMatrix(input.RowCount, input.ColumnCount);
Solve(matrix, input, result);
Solve(matrix, input, result, iterator);
return result;
}
@ -764,31 +686,21 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution matrix, <c>B</c>.</param>
/// <param name="result">The result matrix, <c>X</c></param>
public void Solve(Matrix<Complex> matrix, Matrix<Complex> input, Matrix<Complex> result)
public void Solve(Matrix<Complex> matrix, Matrix<Complex> input, Matrix<Complex> result, Iterator<Complex> iterator = null)
{
if (matrix == null)
{
throw new ArgumentNullException("matrix");
}
if (input == null)
{
throw new ArgumentNullException("input");
}
if (result == null)
if (matrix.RowCount != input.RowCount || input.RowCount != result.RowCount || input.ColumnCount != result.ColumnCount)
{
throw new ArgumentNullException("result");
throw Matrix.DimensionsDontMatch<ArgumentException>(matrix, input, result);
}
if (matrix.RowCount != input.RowCount || input.RowCount != result.RowCount || input.ColumnCount != result.ColumnCount)
if (iterator == null)
{
throw Matrix.DimensionsDontMatch<ArgumentException>(matrix, input, result);
iterator = new Iterator<Complex>(Iterator.CreateDefaultStopCriteria());
}
for (var column = 0; column < input.ColumnCount; column++)
{
var solution = Solve(matrix, input.Column(column));
var solution = Solve(matrix, input.Column(column), iterator);
foreach (var element in solution.EnumerateNonZeroIndexed())
{
result.At(element.Item1, column, element.Item2);

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

@ -67,11 +67,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
/// </summary>
IPreConditioner<Complex> _preconditioner;
/// <summary>
/// The iterative process controller.
/// </summary>
Iterator<Complex> _iterator;
/// <summary>
/// Indicates if the user has stopped the solver.
/// </summary>
@ -85,7 +80,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
/// the standard settings and a default preconditioner.
/// </remarks>
public TFQMR()
: this(null, null)
{
}
@ -94,9 +88,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
/// </summary>
/// <remarks>
/// <para>
/// When using this constructor the solver will use a default preconditioner.
/// </para>
/// <para>
/// The main advantages of using a user defined <see cref="Iterator{T}"/> are:
/// <list type="number">
/// <item>It is possible to set the desired convergence limits.</item>
@ -107,45 +98,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
/// </list>
/// </para>
/// </remarks>
/// <param name="iterator">The <see cref="Iterator{T}"/> that will be used to monitor the iterative process.</param>
public TFQMR(Iterator<Complex> iterator)
: this(null, iterator)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="TFQMR"/> class.
/// </summary>
/// <remarks>
/// When using this constructor the solver will use the <see cref="Iterator{T}"/> with
/// the standard settings.
/// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation.</param>
public TFQMR(IPreConditioner<Complex> preconditioner)
: this(preconditioner, null)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="TFQMR"/> class.
/// </summary>
/// <remarks>
/// <para>
/// The main advantages of using a user defined <see cref="Iterator{T}"/> are:
/// <list type="number">
/// <item>It is possible to set the desired convergence limits.</item>
/// <item>
/// It is possible to check the reason for which the solver finished
/// the iterative procedure by calling the <see cref="Iterator{T}.Status"/> property.
/// </item>
/// </list>
/// </para>
/// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation.</param>
/// <param name="iterator">The <see cref="Iterator{T}"/> that will be used to monitor the iterative process.</param>
public TFQMR(IPreConditioner<Complex> preconditioner, Iterator<Complex> iterator)
{
_iterator = iterator;
_preconditioner = preconditioner;
}
@ -158,23 +113,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
_preconditioner = preconditioner;
}
/// <summary>
/// Sets the <see cref="Iterator{T}"/> that will be used to track the iterative process.
/// </summary>
/// <param name="iterator">The iterator.</param>
public void SetIterator(Iterator<Complex> iterator)
{
_iterator = iterator;
}
/// <summary>
/// Gets the status of the iteration once the calculation is finished.
/// </summary>
public IterationStatus IterationResult
{
get { return (_iterator != null) ? _iterator.Status : IterationStatus.Indetermined; }
}
/// <summary>
/// Stops the solve process.
/// </summary>
@ -193,15 +131,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="vector">The solution vector, <c>b</c>.</param>
/// <returns>The result vector, <c>x</c>.</returns>
public Vector<Complex> Solve(Matrix<Complex> matrix, Vector<Complex> vector)
public Vector<Complex> Solve(Matrix<Complex> matrix, Vector<Complex> vector, Iterator<Complex> iterator = null)
{
if (vector == null)
{
throw new ArgumentNullException();
}
var result = new DenseVector(matrix.RowCount);
Solve(matrix, vector, result);
Solve(matrix, vector, result, iterator);
return result;
}
@ -212,7 +145,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution vector, <c>b</c></param>
/// <param name="result">The result vector, <c>x</c></param>
public void Solve(Matrix<Complex> matrix, Vector<Complex> input, Vector<Complex> result)
public void Solve(Matrix<Complex> matrix, Vector<Complex> input, Vector<Complex> result, Iterator<Complex> iterator = null)
{
// If we were stopped before, we are no longer
// We're doing this at the start of the method to ensure
@ -247,9 +180,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
// Initialize the solver fields
// Set the convergence monitor
if (_iterator == null)
if (iterator == null)
{
_iterator = Iterator.CreateDefault();
iterator = new Iterator<Complex>(Iterator.CreateDefaultStopCriteria());
}
if (_preconditioner == null)
@ -298,7 +231,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
// Start the iteration
var iterationNumber = 0;
while (ShouldContinue(iterationNumber, result, input, pseudoResiduals))
while (ShouldContinue(iterator, iterationNumber, result, input, pseudoResiduals))
{
// First part of the step, the even bit
if (IsEven(iterationNumber))
@ -308,7 +241,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
if (sigma.Real.AlmostEqual(0, 1) && sigma.Imaginary.AlmostEqual(0, 1))
{
// FAIL HERE
_iterator.Cancel();
iterator.Cancel();
break;
}
@ -357,7 +290,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
temp2.CopyTo(x);
// Check convergence and see if we can bail
if (!ShouldContinue(iterationNumber, result, input, pseudoResiduals))
if (!ShouldContinue(iterator, iterationNumber, result, input, pseudoResiduals))
{
// Calculate the real values
_preconditioner.Approximate(x, result);
@ -368,7 +301,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
CalculateTrueResidual(matrix, temp, result, input);
// Now recheck the convergence
if (!ShouldContinue(iterationNumber, result, input, temp))
if (!ShouldContinue(iterator, iterationNumber, result, input, temp))
{
// We're all good now.
return;
@ -381,7 +314,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
if (rho.Real.AlmostEqual(0, 1) && rho.Imaginary.AlmostEqual(0, 1))
{
// FAIL HERE
_iterator.Cancel();
iterator.Cancel();
break;
}
@ -441,7 +374,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
/// <param name="source">Source <see cref="Vector"/>.</param>
/// <param name="residuals">Residual <see cref="Vector"/>.</param>
/// <returns><c>true</c> if continue, otherwise <c>false</c></returns>
bool ShouldContinue(int iterationNumber, Vector<Complex> result, Vector<Complex> source, Vector<Complex> residuals)
bool ShouldContinue(Iterator<Complex> iterator, int iterationNumber, Vector<Complex> result, Vector<Complex> source, Vector<Complex> residuals)
{
// We stop if either:
// - the user has stopped the calculation
@ -449,11 +382,11 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
if (_hasBeenStopped)
{
_iterator.Cancel();
iterator.Cancel();
return true;
}
var status = _iterator.DetermineStatus(iterationNumber, result, source, residuals);
var status = iterator.DetermineStatus(iterationNumber, result, source, residuals);
return status == IterationStatus.Running || status == IterationStatus.Indetermined;
}
@ -474,20 +407,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution matrix, <c>B</c>.</param>
/// <returns>The result matrix, <c>X</c>.</returns>
public Matrix<Complex> Solve(Matrix<Complex> matrix, Matrix<Complex> input)
public Matrix<Complex> Solve(Matrix<Complex> matrix, Matrix<Complex> input, Iterator<Complex> iterator = null)
{
if (matrix == null)
{
throw new ArgumentNullException("matrix");
}
if (input == null)
{
throw new ArgumentNullException("input");
}
var result = matrix.CreateMatrix(input.RowCount, input.ColumnCount);
Solve(matrix, input, result);
Solve(matrix, input, result, iterator);
return result;
}
@ -498,31 +421,21 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution matrix, <c>B</c>.</param>
/// <param name="result">The result matrix, <c>X</c></param>
public void Solve(Matrix<Complex> matrix, Matrix<Complex> input, Matrix<Complex> result)
public void Solve(Matrix<Complex> matrix, Matrix<Complex> input, Matrix<Complex> result, Iterator<Complex> iterator = null)
{
if (matrix == null)
{
throw new ArgumentNullException("matrix");
}
if (input == null)
{
throw new ArgumentNullException("input");
}
if (result == null)
if (matrix.RowCount != input.RowCount || input.RowCount != result.RowCount || input.ColumnCount != result.ColumnCount)
{
throw new ArgumentNullException("result");
throw Matrix.DimensionsDontMatch<ArgumentException>(matrix, input, result);
}
if (matrix.RowCount != input.RowCount || input.RowCount != result.RowCount || input.ColumnCount != result.ColumnCount)
if (iterator == null)
{
throw Matrix.DimensionsDontMatch<ArgumentException>(matrix, input, result);
iterator = new Iterator<Complex>(Iterator.CreateDefaultStopCriteria());
}
for (var column = 0; column < input.ColumnCount; column++)
{
var solution = Solve(matrix, input.Column(column));
var solution = Solve(matrix, input.Column(column), iterator);
foreach (var element in solution.EnumerateNonZeroIndexed())
{
result.At(element.Item1, column, element.Item2);

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

@ -71,11 +71,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
/// </summary>
IPreConditioner<Numerics.Complex32> _preconditioner;
/// <summary>
/// The iterative process controller.
/// </summary>
Iterator<Numerics.Complex32> _iterator;
/// <summary>
/// Indicates if the user has stopped the solver.
/// </summary>
@ -89,44 +84,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
/// the standard settings and a default preconditioner.
/// </remarks>
public BiCgStab()
: this(null, null)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="BiCgStab"/> class.
/// </summary>
/// <remarks>
/// <para>
/// When using this constructor the solver will use a default preconditioner.
/// </para>
/// <para>
/// The main advantages of using a user defined <see cref="Iterator{T}"/> are:
/// <list type="number">
/// <item>It is possible to set the desired convergence limits.</item>
/// <item>
/// It is possible to check the reason for which the solver finished
/// the iterative procedure by calling the <see cref="Iterator{T}.Status"/> property.
/// </item>
/// </list>
/// </para>
/// </remarks>
/// <param name="iterator">The <see cref="Iterator{T}"/> that will be used to monitor the iterative process. </param>
public BiCgStab(Iterator<Numerics.Complex32> iterator)
: this(null, iterator)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="BiCgStab"/> class.
/// </summary>
/// <remarks>
/// When using this constructor the solver will use the <see cref="Iterator{T}"/> with
/// the standard settings.
/// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation.</param>
public BiCgStab(IPreConditioner<Numerics.Complex32> preconditioner)
: this(preconditioner, null)
{
}
@ -146,10 +103,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
/// </para>
/// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation. </param>
/// <param name="iterator">The <see cref="Iterator{T}"/> that will be used to monitor the iterative process. </param>
public BiCgStab(IPreConditioner<Numerics.Complex32> preconditioner, Iterator<Numerics.Complex32> iterator)
public BiCgStab(IPreConditioner<Numerics.Complex32> preconditioner)
{
_iterator = iterator;
_preconditioner = preconditioner;
}
@ -162,23 +117,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
_preconditioner = preconditioner;
}
/// <summary>
/// Sets the <see cref="Iterator{T}"/> that will be used to track the iterative process.
/// </summary>
/// <param name="iterator">The iterator.</param>
public void SetIterator(Iterator<Numerics.Complex32> iterator)
{
_iterator = iterator;
}
/// <summary>
/// Gets the status of the iteration once the calculation is finished.
/// </summary>
public IterationStatus IterationResult
{
get { return (_iterator != null) ? _iterator.Status : IterationStatus.Indetermined; }
}
/// <summary>
/// Stops the solve process.
/// </summary>
@ -197,15 +135,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
/// <param name="matrix">The coefficient <see cref="Matrix"/>, <c>A</c>.</param>
/// <param name="vector">The solution <see cref="Vector"/>, <c>b</c>.</param>
/// <returns>The result <see cref="Vector"/>, <c>x</c>.</returns>
public Vector<Numerics.Complex32> Solve(Matrix<Numerics.Complex32> matrix, Vector<Numerics.Complex32> vector)
public Vector<Numerics.Complex32> Solve(Matrix<Numerics.Complex32> matrix, Vector<Numerics.Complex32> vector, Iterator<Numerics.Complex32> iterator = null)
{
if (vector == null)
{
throw new ArgumentNullException();
}
var result = new DenseVector(matrix.RowCount);
Solve(matrix, vector, result);
Solve(matrix, vector, result, iterator);
return result;
}
@ -216,7 +149,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
/// <param name="matrix">The coefficient <see cref="Matrix"/>, <c>A</c>.</param>
/// <param name="input">The solution <see cref="Vector"/>, <c>b</c>.</param>
/// <param name="result">The result <see cref="Vector"/>, <c>x</c>.</param>
public void Solve(Matrix<Numerics.Complex32> matrix, Vector<Numerics.Complex32> input, Vector<Numerics.Complex32> result)
public void Solve(Matrix<Numerics.Complex32> matrix, Vector<Numerics.Complex32> input, Vector<Numerics.Complex32> result, Iterator<Numerics.Complex32> iterator = null)
{
// If we were stopped before, we are no longer
// We're doing this at the start of the method to ensure
@ -256,9 +189,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
// Initialize the solver fields
// Set the convergence monitor
if (_iterator == null)
if (iterator == null)
{
_iterator = Iterator.CreateDefault();
iterator = new Iterator<Numerics.Complex32>(Iterator.CreateDefaultStopCriteria());
}
if (_preconditioner == null)
@ -295,7 +228,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
Numerics.Complex32 omega = 0;
var iterationNumber = 0;
while (ShouldContinue(iterationNumber, result, input, residuals))
while (ShouldContinue(iterator, iterationNumber, result, input, residuals))
{
// rho_(i-1) = r~^T r_(i-1) // dotproduct r~ and r_(i-1)
var oldRho = currentRho;
@ -354,7 +287,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
temp2.CopyTo(temp);
// Check convergence and stop if we are converged.
if (!ShouldContinue(iterationNumber, temp, input, vecS))
if (!ShouldContinue(iterator, iterationNumber, temp, input, vecS))
{
temp.CopyTo(result);
@ -362,7 +295,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
CalculateTrueResidual(matrix, residuals, result, input);
// Now recheck the convergence
if (!ShouldContinue(iterationNumber, result, input, residuals))
if (!ShouldContinue(iterator, iterationNumber, result, input, residuals))
{
// We're all good now.
return;
@ -403,7 +336,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
throw new Exception("Iterative solver experience a numerical break down");
}
if (!ShouldContinue(iterationNumber, result, input, residuals))
if (!ShouldContinue(iterator, iterationNumber, result, input, residuals))
{
// Recalculate the residuals and go round again. This is done to ensure that
// we have the proper residuals.
@ -444,7 +377,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
/// <param name="source">Source <see cref="Vector"/>.</param>
/// <param name="residuals">Residual <see cref="Vector"/>.</param>
/// <returns><c>true</c> if continue, otherwise <c>false</c></returns>
bool ShouldContinue(int iterationNumber, Vector<Numerics.Complex32> result, Vector<Numerics.Complex32> source, Vector<Numerics.Complex32> residuals)
bool ShouldContinue(Iterator<Numerics.Complex32> iterator, int iterationNumber, Vector<Numerics.Complex32> result, Vector<Numerics.Complex32> source, Vector<Numerics.Complex32> residuals)
{
// We stop if either:
// - the user has stopped the calculation
@ -452,11 +385,11 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
if (_hasBeenStopped)
{
_iterator.Cancel();
iterator.Cancel();
return true;
}
var status = _iterator.DetermineStatus(iterationNumber, result, source, residuals);
var status = iterator.DetermineStatus(iterationNumber, result, source, residuals);
return status == IterationStatus.Running || status == IterationStatus.Indetermined;
}
@ -467,20 +400,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
/// <param name="matrix">The coefficient <see cref="Matrix"/>, <c>A</c>.</param>
/// <param name="input">The solution <see cref="Matrix"/>, <c>B</c>.</param>
/// <returns>The result <see cref="Matrix"/>, <c>X</c>.</returns>
public Matrix<Numerics.Complex32> Solve(Matrix<Numerics.Complex32> matrix, Matrix<Numerics.Complex32> input)
public Matrix<Numerics.Complex32> Solve(Matrix<Numerics.Complex32> matrix, Matrix<Numerics.Complex32> input, Iterator<Numerics.Complex32> iterator = null)
{
if (matrix == null)
{
throw new ArgumentNullException("matrix");
}
if (input == null)
{
throw new ArgumentNullException("input");
}
var result = matrix.CreateMatrix(input.RowCount, input.ColumnCount);
Solve(matrix, input, result);
Solve(matrix, input, result, iterator);
return result;
}
@ -491,31 +414,21 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
/// <param name="matrix">The coefficient <see cref="Matrix"/>, <c>A</c>.</param>
/// <param name="input">The solution <see cref="Matrix"/>, <c>B</c>.</param>
/// <param name="result">The result <see cref="Matrix"/>, <c>X</c></param>
public void Solve(Matrix<Numerics.Complex32> matrix, Matrix<Numerics.Complex32> input, Matrix<Numerics.Complex32> result)
public void Solve(Matrix<Numerics.Complex32> matrix, Matrix<Numerics.Complex32> input, Matrix<Numerics.Complex32> result, Iterator<Numerics.Complex32> iterator = null)
{
if (matrix == null)
{
throw new ArgumentNullException("matrix");
}
if (input == null)
{
throw new ArgumentNullException("input");
}
if (result == null)
if (matrix.RowCount != input.RowCount || input.RowCount != result.RowCount || input.ColumnCount != result.ColumnCount)
{
throw new ArgumentNullException("result");
throw Matrix.DimensionsDontMatch<ArgumentException>(matrix, input, result);
}
if (matrix.RowCount != input.RowCount || input.RowCount != result.RowCount || input.ColumnCount != result.ColumnCount)
if (iterator == null)
{
throw Matrix.DimensionsDontMatch<ArgumentException>(matrix, input, result);
iterator = new Iterator<Numerics.Complex32>(Iterator.CreateDefaultStopCriteria());
}
for (var column = 0; column < input.ColumnCount; column++)
{
var solution = Solve(matrix, input.Column(column));
var solution = Solve(matrix, input.Column(column), iterator);
foreach (var element in solution.EnumerateNonZeroIndexed())
{
result.At(element.Item1, column, element.Item2);

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

@ -86,7 +86,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
#endregion
#if PORTABLE
private static readonly Dictionary<double, List<IIterativeSolverSetup<Complex32>>> SolverSetups = new Dictionary<double, List<IIterativeSolverSetup<Complex32>>>();
private static readonly Dictionary<double, List<IIterativeSolverSetup<Numerics.Complex32>>> SolverSetups = new Dictionary<double, List<IIterativeSolverSetup<Numerics.Complex32>>>();
#else
/// <summary>
/// The collection of iterative solver setups. Stored based on the
@ -331,11 +331,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
/// </summary>
IterationStatus _status = IterationStatus.Indetermined;
/// <summary>
/// The iterator that is used to control the iteration process.
/// </summary>
Iterator<Numerics.Complex32> _iterator;
/// <summary>
/// A flag indicating if the solver has been stopped or not.
/// </summary>
@ -350,37 +345,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
/// <summary>
/// Initializes a new instance of the <see cref="CompositeSolver"/> class with the default iterator.
/// </summary>
public CompositeSolver() : this(null)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="CompositeSolver"/> class with the specified iterator.
/// </summary>
/// <param name="iterator">The iterator that will be used to control the iteration process. </param>
public CompositeSolver(Iterator<Numerics.Complex32> iterator)
{
_iterator = iterator;
}
/// <summary>
/// Sets the <c>IIterator</c> that will be used to track the iterative process.
/// </summary>
/// <param name="iterator">The iterator.</param>
public void SetIterator(Iterator<Numerics.Complex32> iterator)
{
_iterator = iterator;
}
/// <summary>
/// Gets the status of the iteration once the calculation is finished.
/// </summary>
public IterationStatus IterationResult
public CompositeSolver()
{
get
{
return _status;
}
}
/// <summary>
@ -406,10 +372,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="vector">The solution vector, <c>b</c>.</param>
/// <returns>The result vector, <c>x</c>.</returns>
public Vector<Numerics.Complex32> Solve(Matrix<Numerics.Complex32> matrix, Vector<Numerics.Complex32> vector)
public Vector<Numerics.Complex32> Solve(Matrix<Numerics.Complex32> matrix, Vector<Numerics.Complex32> vector, Iterator<Numerics.Complex32> iterator = null)
{
var result = new DenseVector(matrix.RowCount);
Solve(matrix, vector, result);
Solve(matrix, vector, result, iterator);
return result;
}
@ -420,7 +386,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution vector, <c>b</c></param>
/// <param name="result">The result vector, <c>x</c></param>
public void Solve(Matrix<Numerics.Complex32> matrix, Vector<Numerics.Complex32> input, Vector<Numerics.Complex32> result)
public void Solve(Matrix<Numerics.Complex32> matrix, Vector<Numerics.Complex32> input, Vector<Numerics.Complex32> result, Iterator<Numerics.Complex32> iterator = null)
{
// If we were stopped before, we are no longer
// We're doing this at the start of the method to ensure
@ -440,9 +406,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
// Initialize the solver fields
// Set the convergence monitor
if (_iterator == null)
if (iterator == null)
{
_iterator = Iterator.CreateDefault();
iterator = new Iterator<Numerics.Complex32>(Iterator.CreateDefaultStopCriteria());
}
// Load the solvers into our own internal data structure
@ -465,11 +431,11 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
try
{
// Reset the iterator and pass it to the solver
_iterator.Reset();
solver.SetIterator(_iterator);
iterator.Reset();
// Start the solver
solver.Solve(matrix, internalInput, internalResult);
solver.Solve(matrix, internalInput, internalResult, iterator);
_status = iterator.Status;
}
catch (Exception)
{
@ -483,7 +449,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
}
// There was no fatal breakdown so check the status
if (_iterator.HasConverged)
if (_status == IterationStatus.Converged)
{
// We're done
internalResult.CopyTo(result);
@ -493,7 +459,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
// We're not done
// Either:
// - calculation finished without convergence
if (_iterator.HasStoppedWithoutConvergence)
if (_status == IterationStatus.StoppedWithoutConvergence)
{
// Copy the internal result to the result vector and
// continue with the calculation.
@ -514,9 +480,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
// Clean up
// No longer need the current solver
_currentSolver = null;
// Set the final status
_status = _iterator.Status;
}
/// <summary>
@ -546,10 +509,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution matrix, <c>B</c>.</param>
/// <returns>The result matrix, <c>X</c>.</returns>
public Matrix<Numerics.Complex32> Solve(Matrix<Numerics.Complex32> matrix, Matrix<Numerics.Complex32> input)
public Matrix<Numerics.Complex32> Solve(Matrix<Numerics.Complex32> matrix, Matrix<Numerics.Complex32> input, Iterator<Numerics.Complex32> iterator = null)
{
var result = matrix.CreateMatrix(input.RowCount, input.ColumnCount);
Solve(matrix, input, result);
Solve(matrix, input, result, iterator);
return result;
}
@ -560,16 +523,21 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution matrix, <c>B</c>.</param>
/// <param name="result">The result matrix, <c>X</c></param>
public void Solve(Matrix<Numerics.Complex32> matrix, Matrix<Numerics.Complex32> input, Matrix<Numerics.Complex32> result)
public void Solve(Matrix<Numerics.Complex32> matrix, Matrix<Numerics.Complex32> input, Matrix<Numerics.Complex32> result, Iterator<Numerics.Complex32> iterator = null)
{
if (matrix.RowCount != input.RowCount || input.RowCount != result.RowCount || input.ColumnCount != result.ColumnCount)
{
throw Matrix.DimensionsDontMatch<ArgumentException>(matrix, input, result);
}
if (iterator == null)
{
iterator = new Iterator<Numerics.Complex32>(Iterator.CreateDefaultStopCriteria());
}
for (var column = 0; column < input.ColumnCount; column++)
{
var solution = Solve(matrix, input.Column(column));
var solution = Solve(matrix, input.Column(column), iterator);
foreach (var element in solution.EnumerateNonZeroIndexed())
{
result.At(element.Item1, column, element.Item2);

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

@ -69,11 +69,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
/// </summary>
IPreConditioner<Numerics.Complex32> _preconditioner;
/// <summary>
/// The iterative process controller.
/// </summary>
Iterator<Numerics.Complex32> _iterator;
/// <summary>
/// Indicates the number of <c>BiCGStab</c> steps should be taken
/// before switching.
@ -99,7 +94,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
/// the standard settings and a default preconditioner.
/// </remarks>
public GpBiCg()
: this(null, null)
{
}
@ -108,9 +102,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
/// </summary>
/// <remarks>
/// <para>
/// When using this constructor the solver will use a default preconditioner.
/// </para>
/// <para>
/// The main advantages of using a user defined <see cref="Iterator{T}"/> are:
/// <list type="number">
/// <item>It is possible to set the desired convergence limits.</item>
@ -121,45 +112,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
/// </list>
/// </para>
/// </remarks>
/// <param name="iterator">The <see cref="Iterator{T}"/> that will be used to monitor the iterative process.</param>
public GpBiCg(Iterator<Numerics.Complex32> iterator)
: this(null, iterator)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="GpBiCg"/> class.
/// </summary>
/// <remarks>
/// When using this constructor the solver will use the <see cref="Iterator{T}"/> with
/// the standard settings.
/// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation.</param>
public GpBiCg(IPreConditioner<Numerics.Complex32> preconditioner)
: this(preconditioner, null)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="GpBiCg"/> class.
/// </summary>
/// <remarks>
/// <para>
/// The main advantages of using a user defined <see cref="Iterator{T}"/> are:
/// <list type="number">
/// <item>It is possible to set the desired convergence limits.</item>
/// <item>
/// It is possible to check the reason for which the solver finished
/// the iterative procedure by calling the <see cref="Iterator{T}.Status"/> property.
/// </item>
/// </list>
/// </para>
/// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation.</param>
/// <param name="iterator">The <see cref="Iterator{T}"/> that will be used to monitor the iterative process.</param>
public GpBiCg(IPreConditioner<Numerics.Complex32> preconditioner, Iterator<Numerics.Complex32> iterator)
{
_iterator = iterator;
_preconditioner = preconditioner;
}
@ -210,23 +165,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
_preconditioner = preconditioner;
}
/// <summary>
/// Sets the <see cref="Iterator{T}"/> that will be used to track the iterative process.
/// </summary>
/// <param name="iterator">The iterator.</param>
public void SetIterator(Iterator<Numerics.Complex32> iterator)
{
_iterator = iterator;
}
/// <summary>
/// Gets the status of the iteration once the calculation is finished.
/// </summary>
public IterationStatus IterationResult
{
get { return (_iterator != null) ? _iterator.Status : IterationStatus.Indetermined; }
}
/// <summary>
/// Stops the solve process.
/// </summary>
@ -246,15 +184,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="vector">The solution vector, <c>b</c>.</param>
/// <returns>The result vector, <c>x</c>.</returns>
public Vector<Numerics.Complex32> Solve(Matrix<Numerics.Complex32> matrix, Vector<Numerics.Complex32> vector)
public Vector<Numerics.Complex32> Solve(Matrix<Numerics.Complex32> matrix, Vector<Numerics.Complex32> vector, Iterator<Numerics.Complex32> iterator = null)
{
if (vector == null)
{
throw new ArgumentNullException();
}
var result = new DenseVector(matrix.RowCount);
Solve(matrix, vector, result);
Solve(matrix, vector, result, iterator);
return result;
}
@ -265,7 +198,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution vector, <c>b</c></param>
/// <param name="result">The result vector, <c>x</c></param>
public void Solve(Matrix<Numerics.Complex32> matrix, Vector<Numerics.Complex32> input, Vector<Numerics.Complex32> result)
public void Solve(Matrix<Numerics.Complex32> matrix, Vector<Numerics.Complex32> input, Vector<Numerics.Complex32> result, Iterator<Numerics.Complex32> iterator = null)
{
// If we were stopped before, we are no longer
// We're doing this at the start of the method to ensure
@ -305,9 +238,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
// Initialize the solver fields
// Set the convergence monitor
if (_iterator == null)
if (iterator == null)
{
_iterator = Iterator.CreateDefault();
iterator = new Iterator<Numerics.Complex32>(Iterator.CreateDefaultStopCriteria());
}
if (_preconditioner == null)
@ -354,7 +287,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
// for (k = 0, 1, .... )
var iterationNumber = 0;
while (ShouldContinue(iterationNumber, xtemp, input, residuals))
while (ShouldContinue(iterator, iterationNumber, xtemp, input, residuals))
{
// p_k = r_k + beta_(k-1) * (p_(k-1) - u_(k-1))
p.Subtract(u, temp);
@ -495,7 +428,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
_preconditioner.Approximate(xtemp, result);
// Now check for convergence
if (!ShouldContinue(iterationNumber, result, input, residuals))
if (!ShouldContinue(iterator, iterationNumber, result, input, residuals))
{
// Recalculate the residuals and go round again. This is done to ensure that
// we have the proper residuals.
@ -532,7 +465,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
/// <param name="source">Source <see cref="Vector"/>.</param>
/// <param name="residuals">Residual <see cref="Vector"/>.</param>
/// <returns><c>true</c> if continue, otherwise <c>false</c></returns>
bool ShouldContinue(int iterationNumber, Vector<Numerics.Complex32> result, Vector<Numerics.Complex32> source, Vector<Numerics.Complex32> residuals)
bool ShouldContinue(Iterator<Numerics.Complex32> iterator, int iterationNumber, Vector<Numerics.Complex32> result, Vector<Numerics.Complex32> source, Vector<Numerics.Complex32> residuals)
{
// We stop if either:
// - the user has stopped the calculation
@ -540,11 +473,11 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
if (_hasBeenStopped)
{
_iterator.Cancel();
iterator.Cancel();
return true;
}
var status = _iterator.DetermineStatus(iterationNumber, result, source, residuals);
var status = iterator.DetermineStatus(iterationNumber, result, source, residuals);
return status == IterationStatus.Running || status == IterationStatus.Indetermined;
}
@ -572,20 +505,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution matrix, <c>B</c>.</param>
/// <returns>The result matrix, <c>X</c>.</returns>
public Matrix<Numerics.Complex32> Solve(Matrix<Numerics.Complex32> matrix, Matrix<Numerics.Complex32> input)
public Matrix<Numerics.Complex32> Solve(Matrix<Numerics.Complex32> matrix, Matrix<Numerics.Complex32> input, Iterator<Numerics.Complex32> iterator = null)
{
if (matrix == null)
{
throw new ArgumentNullException("matrix");
}
if (input == null)
{
throw new ArgumentNullException("input");
}
var result = matrix.CreateMatrix(input.RowCount, input.ColumnCount);
Solve(matrix, input, result);
Solve(matrix, input, result, iterator);
return result;
}
@ -596,23 +519,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution matrix, <c>B</c>.</param>
/// <param name="result">The result matrix, <c>X</c></param>
public void Solve(Matrix<Numerics.Complex32> matrix, Matrix<Numerics.Complex32> input, Matrix<Numerics.Complex32> result)
public void Solve(Matrix<Numerics.Complex32> matrix, Matrix<Numerics.Complex32> input, Matrix<Numerics.Complex32> result, Iterator<Numerics.Complex32> iterator = null)
{
if (matrix == null)
{
throw new ArgumentNullException("matrix");
}
if (input == null)
{
throw new ArgumentNullException("input");
}
if (result == null)
{
throw new ArgumentNullException("result");
}
if (matrix.RowCount != input.RowCount || input.RowCount != result.RowCount || input.ColumnCount != result.ColumnCount)
{
throw Matrix.DimensionsDontMatch<ArgumentException>(matrix, input, result);
@ -620,7 +528,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
for (var column = 0; column < input.ColumnCount; column++)
{
var solution = Solve(matrix, input.Column(column));
var solution = Solve(matrix, input.Column(column), iterator);
foreach (var element in solution.EnumerateNonZeroIndexed())
{
result.At(element.Item1, column, element.Item2);

19
src/Numerics/LinearAlgebra/Complex32/Solvers/Iterator.cs

@ -44,16 +44,25 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
// TODO: Refactor
/// <summary>
/// Creates a default iterator with all the <see cref="IIterationStopCriterium{T}"/> objects.
/// Creates the default stop criteria.
/// </summary>
/// <returns>A new <see cref="Iterator{T}"/> object.</returns>
public static Iterator<Complex32> CreateDefault()
public static IIterationStopCriterium<Complex32>[] CreateDefaultStopCriteria()
{
return new Iterator<Complex32>(
return new IIterationStopCriterium<Complex32>[]
{
new FailureStopCriterium(),
new DivergenceStopCriterium(),
new IterationCountStopCriterium<Complex32>(),
new ResidualStopCriterium());
new ResidualStopCriterium()
};
}
/// <summary>
/// Creates a default iterator with all the default stop criteria.
/// </summary>
public static Iterator<Complex32> CreateDefault()
{
return new Iterator<Complex32>(CreateDefaultStopCriteria());
}
}
}

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

@ -74,11 +74,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
/// </summary>
IPreConditioner<Numerics.Complex32> _preconditioner;
/// <summary>
/// The iterative process controller.
/// </summary>
Iterator<Numerics.Complex32> _iterator;
/// <summary>
/// The collection of starting vectors which are used as the basis for the Krylov sub-space.
/// </summary>
@ -102,7 +97,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
/// the standard settings and a default preconditioner.
/// </remarks>
public MlkBiCgStab()
: this(null, null)
{
}
@ -111,9 +105,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
/// </summary>
/// <remarks>
/// <para>
/// When using this constructor the solver will use a default preconditioner.
/// </para>
/// <para>
/// The main advantages of using a user defined <see cref="Iterator{T}"/> are:
/// <list type="number">
/// <item>It is possible to set the desired convergence limits.</item>
@ -124,45 +115,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
/// </list>
/// </para>
/// </remarks>
/// <param name="iterator">The <see cref="Iterator{T}"/> that will be used to monitor the iterative process.</param>
public MlkBiCgStab(Iterator<Numerics.Complex32> iterator)
: this(null, iterator)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="MlkBiCgStab"/> class.
/// </summary>
/// <remarks>
/// When using this constructor the solver will use the <see cref="Iterator{T}"/> with
/// the standard settings.
/// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation.</param>
public MlkBiCgStab(IPreConditioner<Numerics.Complex32> preconditioner)
: this(preconditioner, null)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="MlkBiCgStab"/> class.
/// </summary>
/// <remarks>
/// <para>
/// The main advantages of using a user defined <see cref="Iterator{T}"/> are:
/// <list type="number">
/// <item>It is possible to set the desired convergence limits.</item>
/// <item>
/// It is possible to check the reason for which the solver finished
/// the iterative procedure by calling the <see cref="Iterator{T}.Status"/> property.
/// </item>
/// </list>
/// </para>
/// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation.</param>
/// <param name="iterator">The <see cref="Iterator{T}"/> that will be used to monitor the iterative process.</param>
public MlkBiCgStab(IPreConditioner<Numerics.Complex32> preconditioner, Iterator<Numerics.Complex32> iterator)
{
_iterator = iterator;
_preconditioner = preconditioner;
}
@ -207,15 +162,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
_preconditioner = preconditioner;
}
/// <summary>
/// Sets the <see cref="Iterator{T}"/> that will be used to track the iterative process.
/// </summary>
/// <param name="iterator">The iterator.</param>
public void SetIterator(Iterator<Numerics.Complex32> iterator)
{
_iterator = iterator;
}
/// <summary>
/// Gets or sets a series of orthonormal vectors which will be used as basis for the
/// Krylov sub-space.
@ -239,15 +185,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
}
}
/// <summary>
/// Gets the status of the iteration once the calculation is finished.
/// </summary>
public IterationStatus IterationResult
{
[DebuggerStepThrough]
get { return (_iterator != null) ? _iterator.Status : IterationStatus.Indetermined; }
}
/// <summary>
/// Stops the solve process.
/// </summary>
@ -266,15 +203,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="vector">The solution vector, <c>b</c>.</param>
/// <returns>The result vector, <c>x</c>.</returns>
public Vector<Numerics.Complex32> Solve(Matrix<Numerics.Complex32> matrix, Vector<Numerics.Complex32> vector)
public Vector<Numerics.Complex32> Solve(Matrix<Numerics.Complex32> matrix, Vector<Numerics.Complex32> vector, Iterator<Numerics.Complex32> iterator = null)
{
if (vector == null)
{
throw new ArgumentNullException();
}
var result = new DenseVector(matrix.RowCount);
Solve(matrix, vector, result);
Solve(matrix, vector, result, iterator);
return result;
}
@ -285,7 +217,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution vector, <c>b</c></param>
/// <param name="result">The result vector, <c>x</c></param>
public void Solve(Matrix<Numerics.Complex32> matrix, Vector<Numerics.Complex32> input, Vector<Numerics.Complex32> result)
public void Solve(Matrix<Numerics.Complex32> matrix, Vector<Numerics.Complex32> input, Vector<Numerics.Complex32> result, Iterator<Numerics.Complex32> iterator = null)
{
// If we were stopped before, we are no longer
// We're doing this at the start of the method to ensure
@ -325,9 +257,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
// Initialize the solver fields
// Set the convergence monitor
if (_iterator == null)
if (iterator == null)
{
_iterator = Iterator.CreateDefault();
iterator = new Iterator<Numerics.Complex32>(Iterator.CreateDefaultStopCriteria());
}
if (_preconditioner == null)
@ -397,7 +329,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
// FOR (j = 0, 1, 2 ....)
var iterationNumber = 0;
while (ShouldContinue(iterationNumber, xtemp, input, residuals))
while (ShouldContinue(iterator, iterationNumber, xtemp, input, residuals))
{
// SOLVE M g~_((j-1)k+k) = g_((j-1)k+k)
_preconditioner.Approximate(g[k - 1], gtemp);
@ -455,13 +387,13 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
temp2.CopyTo(xtemp);
// Check convergence and stop if we are converged.
if (!ShouldContinue(iterationNumber, xtemp, input, residuals))
if (!ShouldContinue(iterator, iterationNumber, xtemp, input, residuals))
{
// Calculate the true residual
CalculateTrueResidual(matrix, residuals, xtemp, input);
// Now recheck the convergence
if (!ShouldContinue(iterationNumber, xtemp, input, residuals))
if (!ShouldContinue(iterator, iterationNumber, xtemp, input, residuals))
{
// We're all good now.
// Exit from the while loop.
@ -590,7 +522,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
temp2.CopyTo(residuals);
// We can check the residuals here if they're close
if (!ShouldContinue(iterationNumber, xtemp, input, residuals))
if (!ShouldContinue(iterator, iterationNumber, xtemp, input, residuals))
{
// Recalculate the residuals and go round again. This is done to ensure that
// we have the proper residuals.
@ -714,7 +646,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
/// <param name="source">Source <see cref="Vector"/>.</param>
/// <param name="residuals">Residual <see cref="Vector"/>.</param>
/// <returns><c>true</c> if continue, otherwise <c>false</c></returns>
bool ShouldContinue(int iterationNumber, Vector<Numerics.Complex32> result, Vector<Numerics.Complex32> source, Vector<Numerics.Complex32> residuals)
bool ShouldContinue(Iterator<Numerics.Complex32> iterator, int iterationNumber, Vector<Numerics.Complex32> result, Vector<Numerics.Complex32> source, Vector<Numerics.Complex32> residuals)
{
// We stop if either:
// - the user has stopped the calculation
@ -722,11 +654,11 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
if (_hasBeenStopped)
{
_iterator.Cancel();
iterator.Cancel();
return true;
}
var status = _iterator.DetermineStatus(iterationNumber, result, source, residuals);
var status = iterator.DetermineStatus(iterationNumber, result, source, residuals);
return status == IterationStatus.Running || status == IterationStatus.Indetermined;
}
@ -737,20 +669,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution matrix, <c>B</c>.</param>
/// <returns>The result matrix, <c>X</c>.</returns>
public Matrix<Numerics.Complex32> Solve(Matrix<Numerics.Complex32> matrix, Matrix<Numerics.Complex32> input)
public Matrix<Numerics.Complex32> Solve(Matrix<Numerics.Complex32> matrix, Matrix<Numerics.Complex32> input, Iterator<Numerics.Complex32> iterator = null)
{
if (matrix == null)
{
throw new ArgumentNullException("matrix");
}
if (input == null)
{
throw new ArgumentNullException("input");
}
var result = matrix.CreateMatrix(input.RowCount, input.ColumnCount);
Solve(matrix, input, result);
Solve(matrix, input, result, iterator);
return result;
}
@ -761,31 +683,21 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution matrix, <c>B</c>.</param>
/// <param name="result">The result matrix, <c>X</c></param>
public void Solve(Matrix<Numerics.Complex32> matrix, Matrix<Numerics.Complex32> input, Matrix<Numerics.Complex32> result)
public void Solve(Matrix<Numerics.Complex32> matrix, Matrix<Numerics.Complex32> input, Matrix<Numerics.Complex32> result, Iterator<Numerics.Complex32> iterator = null)
{
if (matrix == null)
{
throw new ArgumentNullException("matrix");
}
if (input == null)
{
throw new ArgumentNullException("input");
}
if (result == null)
if (matrix.RowCount != input.RowCount || input.RowCount != result.RowCount || input.ColumnCount != result.ColumnCount)
{
throw new ArgumentNullException("result");
throw Matrix.DimensionsDontMatch<ArgumentException>(matrix, input, result);
}
if (matrix.RowCount != input.RowCount || input.RowCount != result.RowCount || input.ColumnCount != result.ColumnCount)
if (iterator == null)
{
throw Matrix.DimensionsDontMatch<ArgumentException>(matrix, input, result);
iterator = new Iterator<Numerics.Complex32>(Iterator.CreateDefaultStopCriteria());
}
for (var column = 0; column < input.ColumnCount; column++)
{
var solution = Solve(matrix, input.Column(column));
var solution = Solve(matrix, input.Column(column), iterator);
foreach (var element in solution.EnumerateNonZeroIndexed())
{
result.At(element.Item1, column, element.Item2);

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

@ -59,11 +59,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
/// </summary>
IPreConditioner<Numerics.Complex32> _preconditioner;
/// <summary>
/// The iterative process controller.
/// </summary>
Iterator<Numerics.Complex32> _iterator;
/// <summary>
/// Indicates if the user has stopped the solver.
/// </summary>
@ -77,7 +72,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
/// the standard settings and a default preconditioner.
/// </remarks>
public TFQMR()
: this(null, null)
{
}
@ -86,9 +80,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
/// </summary>
/// <remarks>
/// <para>
/// When using this constructor the solver will use a default preconditioner.
/// </para>
/// <para>
/// The main advantages of using a user defined <see cref="Iterator{T}"/> are:
/// <list type="number">
/// <item>It is possible to set the desired convergence limits.</item>
@ -99,45 +90,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
/// </list>
/// </para>
/// </remarks>
/// <param name="iterator">The <see cref="Iterator{T}"/> that will be used to monitor the iterative process.</param>
public TFQMR(Iterator<Numerics.Complex32> iterator)
: this(null, iterator)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="TFQMR"/> class.
/// </summary>
/// <remarks>
/// When using this constructor the solver will use the <see cref="Iterator{T}"/> with
/// the standard settings.
/// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation.</param>
public TFQMR(IPreConditioner<Numerics.Complex32> preconditioner)
: this(preconditioner, null)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="TFQMR"/> class.
/// </summary>
/// <remarks>
/// <para>
/// The main advantages of using a user defined <see cref="Iterator{T}"/> are:
/// <list type="number">
/// <item>It is possible to set the desired convergence limits.</item>
/// <item>
/// It is possible to check the reason for which the solver finished
/// the iterative procedure by calling the <see cref="Iterator{T}.Status"/> property.
/// </item>
/// </list>
/// </para>
/// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation.</param>
/// <param name="iterator">The <see cref="Iterator{T}"/> that will be used to monitor the iterative process.</param>
public TFQMR(IPreConditioner<Numerics.Complex32> preconditioner, Iterator<Numerics.Complex32> iterator)
{
_iterator = iterator;
_preconditioner = preconditioner;
}
@ -150,23 +105,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
_preconditioner = preconditioner;
}
/// <summary>
/// Sets the <see cref="Iterator{T}"/> that will be used to track the iterative process.
/// </summary>
/// <param name="iterator">The iterator.</param>
public void SetIterator(Iterator<Numerics.Complex32> iterator)
{
_iterator = iterator;
}
/// <summary>
/// Gets the status of the iteration once the calculation is finished.
/// </summary>
public IterationStatus IterationResult
{
get { return (_iterator != null) ? _iterator.Status : IterationStatus.Indetermined; }
}
/// <summary>
/// Stops the solve process.
/// </summary>
@ -185,15 +123,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="vector">The solution vector, <c>b</c>.</param>
/// <returns>The result vector, <c>x</c>.</returns>
public Vector<Numerics.Complex32> Solve(Matrix<Numerics.Complex32> matrix, Vector<Numerics.Complex32> vector)
public Vector<Numerics.Complex32> Solve(Matrix<Numerics.Complex32> matrix, Vector<Numerics.Complex32> vector, Iterator<Numerics.Complex32> iterator = null)
{
if (vector == null)
{
throw new ArgumentNullException();
}
var result = new DenseVector(matrix.RowCount);
Solve(matrix, vector, result);
Solve(matrix, vector, result, iterator);
return result;
}
@ -204,7 +137,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution vector, <c>b</c></param>
/// <param name="result">The result vector, <c>x</c></param>
public void Solve(Matrix<Numerics.Complex32> matrix, Vector<Numerics.Complex32> input, Vector<Numerics.Complex32> result)
public void Solve(Matrix<Numerics.Complex32> matrix, Vector<Numerics.Complex32> input, Vector<Numerics.Complex32> result, Iterator<Numerics.Complex32> iterator = null)
{
// If we were stopped before, we are no longer
// We're doing this at the start of the method to ensure
@ -244,9 +177,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
// Initialize the solver fields
// Set the convergence monitor
if (_iterator == null)
if (iterator == null)
{
_iterator = Iterator.CreateDefault();
iterator = new Iterator<Numerics.Complex32>(Iterator.CreateDefaultStopCriteria());
}
if (_preconditioner == null)
@ -295,7 +228,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
// Start the iteration
var iterationNumber = 0;
while (ShouldContinue(iterationNumber, result, input, pseudoResiduals))
while (ShouldContinue(iterator, iterationNumber, result, input, pseudoResiduals))
{
// First part of the step, the even bit
if (IsEven(iterationNumber))
@ -305,7 +238,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
if (sigma.Real.AlmostEqual(0, 1) && sigma.Imaginary.AlmostEqual(0, 1))
{
// FAIL HERE
_iterator.Cancel();
iterator.Cancel();
break;
}
@ -354,7 +287,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
temp2.CopyTo(x);
// Check convergence and see if we can bail
if (!ShouldContinue(iterationNumber, result, input, pseudoResiduals))
if (!ShouldContinue(iterator, iterationNumber, result, input, pseudoResiduals))
{
// Calculate the real values
_preconditioner.Approximate(x, result);
@ -365,7 +298,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
CalculateTrueResidual(matrix, temp, result, input);
// Now recheck the convergence
if (!ShouldContinue(iterationNumber, result, input, temp))
if (!ShouldContinue(iterator, iterationNumber, result, input, temp))
{
// We're all good now.
return;
@ -378,7 +311,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
if (rho.Real.AlmostEqual(0, 1) && rho.Imaginary.AlmostEqual(0, 1))
{
// FAIL HERE
_iterator.Cancel();
iterator.Cancel();
break;
}
@ -438,7 +371,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
/// <param name="source">Source <see cref="Vector"/>.</param>
/// <param name="residuals">Residual <see cref="Vector"/>.</param>
/// <returns><c>true</c> if continue, otherwise <c>false</c></returns>
bool ShouldContinue(int iterationNumber, Vector<Numerics.Complex32> result, Vector<Numerics.Complex32> source, Vector<Numerics.Complex32> residuals)
bool ShouldContinue(Iterator<Numerics.Complex32> iterator, int iterationNumber, Vector<Numerics.Complex32> result, Vector<Numerics.Complex32> source, Vector<Numerics.Complex32> residuals)
{
// We stop if either:
// - the user has stopped the calculation
@ -446,11 +379,11 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
if (_hasBeenStopped)
{
_iterator.Cancel();
iterator.Cancel();
return true;
}
var status = _iterator.DetermineStatus(iterationNumber, result, source, residuals);
var status = iterator.DetermineStatus(iterationNumber, result, source, residuals);
return status == IterationStatus.Running || status == IterationStatus.Indetermined;
}
@ -471,20 +404,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution matrix, <c>B</c>.</param>
/// <returns>The result matrix, <c>X</c>.</returns>
public Matrix<Numerics.Complex32> Solve(Matrix<Numerics.Complex32> matrix, Matrix<Numerics.Complex32> input)
public Matrix<Numerics.Complex32> Solve(Matrix<Numerics.Complex32> matrix, Matrix<Numerics.Complex32> input, Iterator<Numerics.Complex32> iterator = null)
{
if (matrix == null)
{
throw new ArgumentNullException("matrix");
}
if (input == null)
{
throw new ArgumentNullException("input");
}
var result = matrix.CreateMatrix(input.RowCount, input.ColumnCount);
Solve(matrix, input, result);
Solve(matrix, input, result, iterator);
return result;
}
@ -495,31 +418,21 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution matrix, <c>B</c>.</param>
/// <param name="result">The result matrix, <c>X</c></param>
public void Solve(Matrix<Numerics.Complex32> matrix, Matrix<Numerics.Complex32> input, Matrix<Numerics.Complex32> result)
public void Solve(Matrix<Numerics.Complex32> matrix, Matrix<Numerics.Complex32> input, Matrix<Numerics.Complex32> result, Iterator<Numerics.Complex32> iterator = null)
{
if (matrix == null)
{
throw new ArgumentNullException("matrix");
}
if (input == null)
{
throw new ArgumentNullException("input");
}
if (result == null)
if (matrix.RowCount != input.RowCount || input.RowCount != result.RowCount || input.ColumnCount != result.ColumnCount)
{
throw new ArgumentNullException("result");
throw Matrix.DimensionsDontMatch<ArgumentException>(input, matrix, result);
}
if (matrix.RowCount != input.RowCount || input.RowCount != result.RowCount || input.ColumnCount != result.ColumnCount)
if (iterator == null)
{
throw Matrix.DimensionsDontMatch<ArgumentException>(input, matrix, result);
iterator = new Iterator<Numerics.Complex32>(Iterator.CreateDefaultStopCriteria());
}
for (var column = 0; column < input.ColumnCount; column++)
{
var solution = Solve(matrix, input.Column(column));
var solution = Solve(matrix, input.Column(column), iterator);
foreach (var element in solution.EnumerateNonZeroIndexed())
{
result.At(element.Item1, column, element.Item2);

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

@ -71,11 +71,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
/// </summary>
IPreConditioner<double> _preconditioner;
/// <summary>
/// The iterative process controller.
/// </summary>
Iterator<double> _iterator;
/// <summary>
/// Indicates if the user has stopped the solver.
/// </summary>
@ -88,44 +83,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
/// When using this constructor the solver will use the <see cref="Iterator{T}"/> with
/// the standard settings and a default preconditioner.
/// </remarks>
public BiCgStab() : this(null, null)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="BiCgStab"/> class.
/// </summary>
/// <remarks>
/// <para>
/// When using this constructor the solver will use a default preconditioner.
/// </para>
/// <para>
/// The main advantages of using a user defined <see cref="Iterator{T}"/> are:
/// <list type="number">
/// <item>It is possible to set the desired convergence limits.</item>
/// <item>
/// It is possible to check the reason for which the solver finished
/// the iterative procedure by calling the <see cref="Iterator{T}.Status"/> property.
/// </item>
/// </list>
/// </para>
/// </remarks>
/// <param name="iterator">The <see cref="Iterator{T}"/> that will be used to monitor the iterative process. </param>
public BiCgStab(Iterator<double> iterator)
: this(null, iterator)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="BiCgStab"/> class.
/// </summary>
/// <remarks>
/// When using this constructor the solver will use the <see cref="Iterator{T}"/> with
/// the standard settings.
/// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation.</param>
public BiCgStab(IPreConditioner<double> preconditioner)
: this(preconditioner, null)
public BiCgStab()
{
}
@ -145,10 +103,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
/// </para>
/// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation. </param>
/// <param name="iterator">The <see cref="Iterator{T}"/> that will be used to monitor the iterative process. </param>
public BiCgStab(IPreConditioner<double> preconditioner, Iterator<double> iterator)
public BiCgStab(IPreConditioner<double> preconditioner)
{
_iterator = iterator;
_preconditioner = preconditioner;
}
@ -161,26 +117,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
_preconditioner = preconditioner;
}
/// <summary>
/// Sets the <see cref="Iterator{T}"/> that will be used to track the iterative process.
/// </summary>
/// <param name="iterator">The iterator.</param>
public void SetIterator(Iterator<double> iterator)
{
_iterator = iterator;
}
/// <summary>
/// Gets the status of the iteration once the calculation is finished.
/// </summary>
public IterationStatus IterationResult
{
get
{
return (_iterator != null) ? _iterator.Status : IterationStatus.Indetermined;
}
}
/// <summary>
/// Stops the solve process.
/// </summary>
@ -199,15 +135,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
/// <param name="matrix">The coefficient <see cref="Matrix"/>, <c>A</c>.</param>
/// <param name="vector">The solution <see cref="Vector"/>, <c>b</c>.</param>
/// <returns>The result <see cref="Vector"/>, <c>x</c>.</returns>
public Vector<double> Solve(Matrix<double> matrix, Vector<double> vector)
public Vector<double> Solve(Matrix<double> matrix, Vector<double> vector, Iterator<double> iterator = null)
{
if (vector == null)
{
throw new ArgumentNullException();
}
var result = new DenseVector(matrix.RowCount);
Solve(matrix, vector, result);
Solve(matrix, vector, result, iterator);
return result;
}
@ -218,7 +149,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
/// <param name="matrix">The coefficient <see cref="Matrix"/>, <c>A</c>.</param>
/// <param name="input">The solution <see cref="Vector"/>, <c>b</c>.</param>
/// <param name="result">The result <see cref="Vector"/>, <c>x</c>.</param>
public void Solve(Matrix<double> matrix, Vector<double> input, Vector<double> result)
public void Solve(Matrix<double> matrix, Vector<double> input, Vector<double> result, Iterator<double> iterator = null)
{
// If we were stopped before, we are no longer
// We're doing this at the start of the method to ensure
@ -258,9 +189,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
// Initialize the solver fields
// Set the convergence monitor
if (_iterator == null)
if (iterator == null)
{
_iterator = Iterator.CreateDefault();
iterator = new Iterator<double>(Iterator.CreateDefaultStopCriteria());
}
if (_preconditioner == null)
@ -297,7 +228,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
double omega = 0;
var iterationNumber = 0;
while (ShouldContinue(iterationNumber, result, input, residuals))
while (ShouldContinue(iterator, iterationNumber, result, input, residuals))
{
// rho_(i-1) = r~^T r_(i-1) // dotproduct r~ and r_(i-1)
var oldRho = currentRho;
@ -356,7 +287,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
temp2.CopyTo(temp);
// Check convergence and stop if we are converged.
if (!ShouldContinue(iterationNumber, temp, input, vecS))
if (!ShouldContinue(iterator, iterationNumber, temp, input, vecS))
{
temp.CopyTo(result);
@ -364,7 +295,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
CalculateTrueResidual(matrix, residuals, result, input);
// Now recheck the convergence
if (!ShouldContinue(iterationNumber, result, input, residuals))
if (!ShouldContinue(iterator, iterationNumber, result, input, residuals))
{
// We're all good now.
return;
@ -405,7 +336,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
throw new Exception("Iterative solver experience a numerical break down");
}
if (!ShouldContinue(iterationNumber, result, input, residuals))
if (!ShouldContinue(iterator, iterationNumber, result, input, residuals))
{
// Recalculate the residuals and go round again. This is done to ensure that
// we have the proper residuals.
@ -446,7 +377,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
/// <param name="source">Source <see cref="Vector"/>.</param>
/// <param name="residuals">Residual <see cref="Vector"/>.</param>
/// <returns><c>true</c> if continue, otherwise <c>false</c></returns>
bool ShouldContinue(int iterationNumber, Vector<double> result, Vector<double> source, Vector<double> residuals)
bool ShouldContinue(Iterator<double> iterator, int iterationNumber, Vector<double> result, Vector<double> source, Vector<double> residuals)
{
// We stop if either:
// - the user has stopped the calculation
@ -454,11 +385,11 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
if (_hasBeenStopped)
{
_iterator.Cancel();
iterator.Cancel();
return true;
}
var status = _iterator.DetermineStatus(iterationNumber, result, source, residuals);
var status = iterator.DetermineStatus(iterationNumber, result, source, residuals);
return status == IterationStatus.Running || status == IterationStatus.Indetermined;
}
@ -469,20 +400,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
/// <param name="matrix">The coefficient <see cref="Matrix"/>, <c>A</c>.</param>
/// <param name="input">The solution <see cref="Matrix"/>, <c>B</c>.</param>
/// <returns>The result <see cref="Matrix"/>, <c>X</c>.</returns>
public Matrix<double> Solve(Matrix<double> matrix, Matrix<double> input)
public Matrix<double> Solve(Matrix<double> matrix, Matrix<double> input, Iterator<double> iterator = null)
{
if (matrix == null)
{
throw new ArgumentNullException("matrix");
}
if (input == null)
{
throw new ArgumentNullException("input");
}
var result = matrix.CreateMatrix(input.RowCount, input.ColumnCount);
Solve(matrix, input, result);
Solve(matrix, input, result, iterator);
return result;
}
@ -493,31 +414,21 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
/// <param name="matrix">The coefficient <see cref="Matrix"/>, <c>A</c>.</param>
/// <param name="input">The solution <see cref="Matrix"/>, <c>B</c>.</param>
/// <param name="result">The result <see cref="Matrix"/>, <c>X</c></param>
public void Solve(Matrix<double> matrix, Matrix<double> input, Matrix<double> result)
public void Solve(Matrix<double> matrix, Matrix<double> input, Matrix<double> result, Iterator<double> iterator = null)
{
if (matrix == null)
{
throw new ArgumentNullException("matrix");
}
if (input == null)
{
throw new ArgumentNullException("input");
}
if (result == null)
if (matrix.RowCount != input.RowCount || input.RowCount != result.RowCount || input.ColumnCount != result.ColumnCount)
{
throw new ArgumentNullException("result");
throw Matrix.DimensionsDontMatch<ArgumentException>(matrix, input, result);
}
if (matrix.RowCount != input.RowCount || input.RowCount != result.RowCount || input.ColumnCount != result.ColumnCount)
if (iterator == null)
{
throw Matrix.DimensionsDontMatch<ArgumentException>(matrix, input, result);
iterator = new Iterator<double>(Iterator.CreateDefaultStopCriteria());
}
for (var column = 0; column < input.ColumnCount; column++)
{
var solution = Solve(matrix, input.Column(column));
var solution = Solve(matrix, input.Column(column), iterator);
foreach (var element in solution.EnumerateNonZeroIndexed())
{
result.At(element.Item1, column, element.Item2);

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

@ -328,11 +328,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
/// </summary>
IterationStatus _status = IterationStatus.Indetermined;
/// <summary>
/// The iterator that is used to control the iteration process.
/// </summary>
Iterator<double> _iterator;
/// <summary>
/// A flag indicating if the solver has been stopped or not.
/// </summary>
@ -347,28 +342,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
/// <summary>
/// Initializes a new instance of the <see cref="CompositeSolver"/> class with the default iterator.
/// </summary>
public CompositeSolver() : this(null)
public CompositeSolver()
{
}
/// <summary>
/// Initializes a new instance of the <see cref="CompositeSolver"/> class with the specified iterator.
/// </summary>
/// <param name="iterator">The iterator that will be used to control the iteration process. </param>
public CompositeSolver(Iterator<double> iterator)
{
_iterator = iterator;
}
/// <summary>
/// Sets the <see cref="Iterator{T}"/> that will be used to track the iterative process.
/// </summary>
/// <param name="iterator">The iterator.</param>
public void SetIterator(Iterator<double> iterator)
{
_iterator = iterator;
}
/// <summary>
/// Gets the status of the iteration once the calculation is finished.
/// </summary>
@ -403,10 +380,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="vector">The solution vector, <c>b</c>.</param>
/// <returns>The result vector, <c>x</c>.</returns>
public Vector<double> Solve(Matrix<double> matrix, Vector<double> vector)
public Vector<double> Solve(Matrix<double> matrix, Vector<double> vector, Iterator<double> iterator = null)
{
var result = new DenseVector(matrix.RowCount);
Solve(matrix, vector, result);
Solve(matrix, vector, result, iterator);
return result;
}
@ -417,7 +394,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution vector, <c>b</c></param>
/// <param name="result">The result vector, <c>x</c></param>
public void Solve(Matrix<double> matrix, Vector<double> input, Vector<double> result)
public void Solve(Matrix<double> matrix, Vector<double> input, Vector<double> result, Iterator<double> iterator = null)
{
// If we were stopped before, we are no longer
// We're doing this at the start of the method to ensure
@ -437,9 +414,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
// Initialize the solver fields
// Set the convergence monitor
if (_iterator == null)
if (iterator == null)
{
_iterator = Iterator.CreateDefault();
iterator = new Iterator<double>(Iterator.CreateDefaultStopCriteria());
}
// Load the solvers into our own internal data structure
@ -462,11 +439,11 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
try
{
// Reset the iterator and pass it to the solver
_iterator.Reset();
solver.SetIterator(_iterator);
iterator.Reset();
// Start the solver
solver.Solve(matrix, internalInput, internalResult);
solver.Solve(matrix, internalInput, internalResult, iterator);
_status = iterator.Status;
}
catch (Exception)
{
@ -480,7 +457,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
}
// There was no fatal breakdown so check the status
if (_iterator.HasConverged)
if (_status == IterationStatus.Converged)
{
// We're done
internalResult.CopyTo(result);
@ -490,7 +467,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
// We're not done
// Either:
// - calculation finished without convergence
if (_iterator.HasStoppedWithoutConvergence)
if (_status == IterationStatus.StoppedWithoutConvergence)
{
// Copy the internal result to the result vector and
// continue with the calculation.
@ -511,9 +488,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
// Clean up
// No longer need the current solver
_currentSolver = null;
// Set the final status
_status = _iterator.Status;
}
/// <summary>
@ -543,10 +517,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution matrix, <c>B</c>.</param>
/// <returns>The result matrix, <c>X</c>.</returns>
public Matrix<double> Solve(Matrix<double> matrix, Matrix<double> input)
public Matrix<double> Solve(Matrix<double> matrix, Matrix<double> input, Iterator<double> iterator = null)
{
var result = matrix.CreateMatrix(input.RowCount, input.ColumnCount);
Solve(matrix, input, result);
Solve(matrix, input, result, iterator);
return result;
}
@ -557,16 +531,21 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution matrix, <c>B</c>.</param>
/// <param name="result">The result matrix, <c>X</c></param>
public void Solve(Matrix<double> matrix, Matrix<double> input, Matrix<double> result)
public void Solve(Matrix<double> matrix, Matrix<double> input, Matrix<double> result, Iterator<double> iterator = null)
{
if (matrix.RowCount != input.RowCount || input.RowCount != result.RowCount || input.ColumnCount != result.ColumnCount)
{
throw Matrix.DimensionsDontMatch<ArgumentException>(matrix, input, result);
}
if (iterator == null)
{
iterator = new Iterator<double>(Iterator.CreateDefaultStopCriteria());
}
for (var column = 0; column < input.ColumnCount; column++)
{
var solution = Solve(matrix, input.Column(column));
var solution = Solve(matrix, input.Column(column), iterator);
foreach (var element in solution.EnumerateNonZeroIndexed())
{
result.At(element.Item1, column, element.Item2);

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

@ -69,11 +69,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
/// </summary>
IPreConditioner<double> _preconditioner;
/// <summary>
/// The iterative process controller.
/// </summary>
Iterator<double> _iterator;
/// <summary>
/// Indicates the number of <c>BiCGStab</c> steps should be taken
/// before switching.
@ -98,7 +93,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
/// When using this constructor the solver will use the <see cref="Iterator{T}"/> with
/// the standard settings and a default preconditioner.
/// </remarks>
public GpBiCg() : this(null, null)
public GpBiCg()
{
}
@ -107,9 +102,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
/// </summary>
/// <remarks>
/// <para>
/// When using this constructor the solver will use a default preconditioner.
/// </para>
/// <para>
/// The main advantages of using a user defined <see cref="Iterator{T}"/> are:
/// <list type="number">
/// <item>It is possible to set the desired convergence limits.</item>
@ -120,45 +112,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
/// </list>
/// </para>
/// </remarks>
/// <param name="iterator">The <see cref="Iterator{T}"/> that will be used to monitor the iterative process.</param>
public GpBiCg(Iterator<double> iterator)
: this(null, iterator)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="GpBiCg"/> class.
/// </summary>
/// <remarks>
/// When using this constructor the solver will use the <see cref="Iterator{T}"/> with
/// the standard settings.
/// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation.</param>
public GpBiCg(IPreConditioner<double> preconditioner)
: this(preconditioner, null)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="GpBiCg"/> class.
/// </summary>
/// <remarks>
/// <para>
/// The main advantages of using a user defined <see cref="Iterator{T}"/> are:
/// <list type="number">
/// <item>It is possible to set the desired convergence limits.</item>
/// <item>
/// It is possible to check the reason for which the solver finished
/// the iterative procedure by calling the <see cref="Iterator{T}.Status"/> property.
/// </item>
/// </list>
/// </para>
/// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation.</param>
/// <param name="iterator">The <see cref="Iterator{T}"/> that will be used to monitor the iterative process.</param>
public GpBiCg(IPreConditioner<double> preconditioner, Iterator<double> iterator)
{
_iterator = iterator;
_preconditioner = preconditioner;
}
@ -215,26 +171,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
_preconditioner = preconditioner;
}
/// <summary>
/// Sets the <see cref="Iterator{T}"/> that will be used to track the iterative process.
/// </summary>
/// <param name="iterator">The iterator.</param>
public void SetIterator(Iterator<double> iterator)
{
_iterator = iterator;
}
/// <summary>
/// Gets the status of the iteration once the calculation is finished.
/// </summary>
public IterationStatus IterationResult
{
get
{
return (_iterator != null) ? _iterator.Status : IterationStatus.Indetermined;
}
}
/// <summary>
/// Stops the solve process.
/// </summary>
@ -254,15 +190,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="vector">The solution vector, <c>b</c>.</param>
/// <returns>The result vector, <c>x</c>.</returns>
public Vector<double> Solve(Matrix<double> matrix, Vector<double> vector)
public Vector<double> Solve(Matrix<double> matrix, Vector<double> vector, Iterator<double> iterator = null)
{
if (vector == null)
{
throw new ArgumentNullException();
}
var result = new DenseVector(matrix.RowCount);
Solve(matrix, vector, result);
Solve(matrix, vector, result, iterator);
return result;
}
@ -273,7 +204,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution vector, <c>b</c></param>
/// <param name="result">The result vector, <c>x</c></param>
public void Solve(Matrix<double> matrix, Vector<double> input, Vector<double> result)
public void Solve(Matrix<double> matrix, Vector<double> input, Vector<double> result, Iterator<double> iterator = null)
{
// If we were stopped before, we are no longer
// We're doing this at the start of the method to ensure
@ -313,9 +244,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
// Initialize the solver fields
// Set the convergence monitor
if (_iterator == null)
if (iterator == null)
{
_iterator = Iterator.CreateDefault();
iterator = new Iterator<double>(Iterator.CreateDefaultStopCriteria());
}
if (_preconditioner == null)
@ -362,7 +293,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
// for (k = 0, 1, .... )
var iterationNumber = 0;
while (ShouldContinue(iterationNumber, xtemp, input, residuals))
while (ShouldContinue(iterator, iterationNumber, xtemp, input, residuals))
{
// p_k = r_k + beta_(k-1) * (p_(k-1) - u_(k-1))
p.Subtract(u, temp);
@ -503,7 +434,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
_preconditioner.Approximate(xtemp, result);
// Now check for convergence
if (!ShouldContinue(iterationNumber, result, input, residuals))
if (!ShouldContinue(iterator, iterationNumber, result, input, residuals))
{
// Recalculate the residuals and go round again. This is done to ensure that
// we have the proper residuals.
@ -540,7 +471,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
/// <param name="source">Source <see cref="Vector"/>.</param>
/// <param name="residuals">Residual <see cref="Vector"/>.</param>
/// <returns><c>true</c> if continue, otherwise <c>false</c></returns>
bool ShouldContinue(int iterationNumber, Vector<double> result, Vector<double> source, Vector<double> residuals)
bool ShouldContinue(Iterator<double> iterator, int iterationNumber, Vector<double> result, Vector<double> source, Vector<double> residuals)
{
// We stop if either:
// - the user has stopped the calculation
@ -548,11 +479,11 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
if (_hasBeenStopped)
{
_iterator.Cancel();
iterator.Cancel();
return true;
}
var status = _iterator.DetermineStatus(iterationNumber, result, source, residuals);
var status = iterator.DetermineStatus(iterationNumber, result, source, residuals);
return status == IterationStatus.Running || status == IterationStatus.Indetermined;
}
@ -580,20 +511,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution matrix, <c>B</c>.</param>
/// <returns>The result matrix, <c>X</c>.</returns>
public Matrix<double> Solve(Matrix<double> matrix, Matrix<double> input)
public Matrix<double> Solve(Matrix<double> matrix, Matrix<double> input, Iterator<double> iterator = null)
{
if (matrix == null)
{
throw new ArgumentNullException("matrix");
}
if (input == null)
{
throw new ArgumentNullException("input");
}
var result = matrix.CreateMatrix(input.RowCount, input.ColumnCount);
Solve(matrix, input, result);
Solve(matrix, input, result, iterator);
return result;
}
@ -604,31 +525,21 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution matrix, <c>B</c>.</param>
/// <param name="result">The result matrix, <c>X</c></param>
public void Solve(Matrix<double> matrix, Matrix<double> input, Matrix<double> result)
public void Solve(Matrix<double> matrix, Matrix<double> input, Matrix<double> result, Iterator<double> iterator = null)
{
if (matrix == null)
{
throw new ArgumentNullException("matrix");
}
if (input == null)
{
throw new ArgumentNullException("input");
}
if (result == null)
if (matrix.RowCount != input.RowCount || input.RowCount != result.RowCount || input.ColumnCount != result.ColumnCount)
{
throw new ArgumentNullException("result");
throw Matrix.DimensionsDontMatch<ArgumentException>(matrix, input, result);
}
if (matrix.RowCount != input.RowCount || input.RowCount != result.RowCount || input.ColumnCount != result.ColumnCount)
if (iterator == null)
{
throw Matrix.DimensionsDontMatch<ArgumentException>(matrix, input, result);
iterator = new Iterator<double>(Iterator.CreateDefaultStopCriteria());
}
for (var column = 0; column < input.ColumnCount; column++)
{
var solution = Solve(matrix, input.Column(column));
var solution = Solve(matrix, input.Column(column), iterator);
foreach (var element in solution.EnumerateNonZeroIndexed())
{
result.At(element.Item1, column, element.Item2);

19
src/Numerics/LinearAlgebra/Double/Solvers/Iterator.cs

@ -42,16 +42,25 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
// TODO: Refactor
/// <summary>
/// Creates a default iterator with all the <see cref="IIterationStopCriterium{T}"/> objects.
/// Creates the default stop criteria.
/// </summary>
/// <returns>A new <see cref="Iterator{T}"/> object.</returns>
public static Iterator<double> CreateDefault()
public static IIterationStopCriterium<double>[] CreateDefaultStopCriteria()
{
return new Iterator<double>(
return new IIterationStopCriterium<double>[]
{
new FailureStopCriterium(),
new DivergenceStopCriterium(),
new IterationCountStopCriterium<double>(),
new ResidualStopCriterium());
new ResidualStopCriterium()
};
}
/// <summary>
/// Creates a default iterator with all the default stop criteria.
/// </summary>
public static Iterator<double> CreateDefault()
{
return new Iterator<double>(CreateDefaultStopCriteria());
}
}
}

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

@ -74,11 +74,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
/// </summary>
IPreConditioner<double> _preconditioner;
/// <summary>
/// The iterative process controller.
/// </summary>
Iterator<double> _iterator;
/// <summary>
/// The collection of starting vectors which are used as the basis for the Krylov sub-space.
/// </summary>
@ -101,7 +96,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
/// When using this constructor the solver will use the <see cref="Iterator{T}"/> with
/// the standard settings and a default preconditioner.
/// </remarks>
public MlkBiCgStab() : this(null, null)
public MlkBiCgStab()
{
}
@ -110,9 +105,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
/// </summary>
/// <remarks>
/// <para>
/// When using this constructor the solver will use a default preconditioner.
/// </para>
/// <para>
/// The main advantages of using a user defined <see cref="Iterator{T}"/> are:
/// <list type="number">
/// <item>It is possible to set the desired convergence limits.</item>
@ -123,45 +115,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
/// </list>
/// </para>
/// </remarks>
/// <param name="iterator">The <see cref="Iterator{T}"/> that will be used to monitor the iterative process.</param>
public MlkBiCgStab(Iterator<double> iterator)
: this(null, iterator)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="MlkBiCgStab"/> class.
/// </summary>
/// <remarks>
/// When using this constructor the solver will use the <see cref="Iterator{T}"/> with
/// the standard settings.
/// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation.</param>
public MlkBiCgStab(IPreConditioner<double> preconditioner)
: this(preconditioner, null)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="MlkBiCgStab"/> class.
/// </summary>
/// <remarks>
/// <para>
/// The main advantages of using a user defined <see cref="Iterator{T}"/> are:
/// <list type="number">
/// <item>It is possible to set the desired convergence limits.</item>
/// <item>
/// It is possible to check the reason for which the solver finished
/// the iterative procedure by calling the <see cref="Iterator{T}.Status"/> property.
/// </item>
/// </list>
/// </para>
/// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation.</param>
/// <param name="iterator">The <see cref="Iterator{T}"/> that will be used to monitor the iterative process.</param>
public MlkBiCgStab(IPreConditioner<double> preconditioner, Iterator<double> iterator)
{
_iterator = iterator;
_preconditioner = preconditioner;
}
@ -209,15 +165,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
_preconditioner = preconditioner;
}
/// <summary>
/// Sets the <see cref="Iterator{T}"/> that will be used to track the iterative process.
/// </summary>
/// <param name="iterator">The iterator.</param>
public void SetIterator(Iterator<double> iterator)
{
_iterator = iterator;
}
/// <summary>
/// Gets or sets a series of orthonormal vectors which will be used as basis for the
/// Krylov sub-space.
@ -244,18 +191,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
}
}
/// <summary>
/// Gets the status of the iteration once the calculation is finished.
/// </summary>
public IterationStatus IterationResult
{
[DebuggerStepThrough]
get
{
return (_iterator != null) ? _iterator.Status : IterationStatus.Indetermined;
}
}
/// <summary>
/// Stops the solve process.
/// </summary>
@ -274,15 +209,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="vector">The solution vector, <c>b</c>.</param>
/// <returns>The result vector, <c>x</c>.</returns>
public Vector<double> Solve(Matrix<double> matrix, Vector<double> vector)
public Vector<double> Solve(Matrix<double> matrix, Vector<double> vector, Iterator<double> iterator = null)
{
if (vector == null)
{
throw new ArgumentNullException();
}
var result = new DenseVector(matrix.RowCount);
Solve(matrix, vector, result);
Solve(matrix, vector, result, iterator);
return result;
}
@ -293,7 +223,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution vector, <c>b</c></param>
/// <param name="result">The result vector, <c>x</c></param>
public void Solve(Matrix<double> matrix, Vector<double> input, Vector<double> result)
public void Solve(Matrix<double> matrix, Vector<double> input, Vector<double> result, Iterator<double> iterator = null)
{
// If we were stopped before, we are no longer
// We're doing this at the start of the method to ensure
@ -333,9 +263,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
// Initialize the solver fields
// Set the convergence monitor
if (_iterator == null)
if (iterator == null)
{
_iterator = Iterator.CreateDefault();
iterator = new Iterator<double>(Iterator.CreateDefaultStopCriteria());
}
if (_preconditioner == null)
@ -405,7 +335,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
// FOR (j = 0, 1, 2 ....)
var iterationNumber = 0;
while (ShouldContinue(iterationNumber, xtemp, input, residuals))
while (ShouldContinue(iterator, iterationNumber, xtemp, input, residuals))
{
// SOLVE M g~_((j-1)k+k) = g_((j-1)k+k)
_preconditioner.Approximate(g[k - 1], gtemp);
@ -463,13 +393,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
temp2.CopyTo(xtemp);
// Check convergence and stop if we are converged.
if (!ShouldContinue(iterationNumber, xtemp, input, residuals))
if (!ShouldContinue(iterator, iterationNumber, xtemp, input, residuals))
{
// Calculate the true residual
CalculateTrueResidual(matrix, residuals, xtemp, input);
// Now recheck the convergence
if (!ShouldContinue(iterationNumber, xtemp, input, residuals))
if (!ShouldContinue(iterator, iterationNumber, xtemp, input, residuals))
{
// We're all good now.
// Exit from the while loop.
@ -598,7 +528,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
temp2.CopyTo(residuals);
// We can check the residuals here if they're close
if (!ShouldContinue(iterationNumber, xtemp, input, residuals))
if (!ShouldContinue(iterator, iterationNumber, xtemp, input, residuals))
{
// Recalculate the residuals and go round again. This is done to ensure that
// we have the proper residuals.
@ -716,7 +646,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
/// <param name="source">Source <see cref="Vector"/>.</param>
/// <param name="residuals">Residual <see cref="Vector"/>.</param>
/// <returns><c>true</c> if continue, otherwise <c>false</c></returns>
bool ShouldContinue(int iterationNumber, Vector<double> result, Vector<double> source, Vector<double> residuals)
bool ShouldContinue(Iterator<double> iterator, int iterationNumber, Vector<double> result, Vector<double> source, Vector<double> residuals)
{
// We stop if either:
// - the user has stopped the calculation
@ -724,11 +654,11 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
if (_hasBeenStopped)
{
_iterator.Cancel();
iterator.Cancel();
return true;
}
var status = _iterator.DetermineStatus(iterationNumber, result, source, residuals);
var status = iterator.DetermineStatus(iterationNumber, result, source, residuals);
return status == IterationStatus.Running || status == IterationStatus.Indetermined;
}
@ -739,20 +669,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution matrix, <c>B</c>.</param>
/// <returns>The result matrix, <c>X</c>.</returns>
public Matrix<double> Solve(Matrix<double> matrix, Matrix<double> input)
public Matrix<double> Solve(Matrix<double> matrix, Matrix<double> input, Iterator<double> iterator = null)
{
if (matrix == null)
{
throw new ArgumentNullException("matrix");
}
if (input == null)
{
throw new ArgumentNullException("input");
}
var result = matrix.CreateMatrix(input.RowCount, input.ColumnCount);
Solve(matrix, input, result);
Solve(matrix, input, result, iterator);
return result;
}
@ -763,31 +683,21 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution matrix, <c>B</c>.</param>
/// <param name="result">The result matrix, <c>X</c></param>
public void Solve(Matrix<double> matrix, Matrix<double> input, Matrix<double> result)
public void Solve(Matrix<double> matrix, Matrix<double> input, Matrix<double> result, Iterator<double> iterator = null)
{
if (matrix == null)
{
throw new ArgumentNullException("matrix");
}
if (input == null)
{
throw new ArgumentNullException("input");
}
if (result == null)
if (matrix.RowCount != input.RowCount || input.RowCount != result.RowCount || input.ColumnCount != result.ColumnCount)
{
throw new ArgumentNullException("result");
throw Matrix.DimensionsDontMatch<ArgumentException>(matrix, input, result);
}
if (matrix.RowCount != input.RowCount || input.RowCount != result.RowCount || input.ColumnCount != result.ColumnCount)
if (iterator == null)
{
throw Matrix.DimensionsDontMatch<ArgumentException>(matrix, input, result);
iterator = new Iterator<double>(Iterator.CreateDefaultStopCriteria());
}
for (var column = 0; column < input.ColumnCount; column++)
{
var solution = Solve(matrix, input.Column(column));
var solution = Solve(matrix, input.Column(column), iterator);
foreach (var element in solution.EnumerateNonZeroIndexed())
{
result.At(element.Item1, column, element.Item2);

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

@ -59,11 +59,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
/// </summary>
IPreConditioner<double> _preconditioner;
/// <summary>
/// The iterative process controller.
/// </summary>
Iterator<double> _iterator;
/// <summary>
/// Indicates if the user has stopped the solver.
/// </summary>
@ -76,7 +71,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
/// When using this constructor the solver will use the <see cref="Iterator{T}"/> with
/// the standard settings and a default preconditioner.
/// </remarks>
public TFQMR() : this(null, null)
public TFQMR()
{
}
@ -85,9 +80,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
/// </summary>
/// <remarks>
/// <para>
/// When using this constructor the solver will use a default preconditioner.
/// </para>
/// <para>
/// The main advantages of using a user defined <see cref="Iterator{T}"/> are:
/// <list type="number">
/// <item>It is possible to set the desired convergence limits.</item>
@ -98,45 +90,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
/// </list>
/// </para>
/// </remarks>
/// <param name="iterator">The <see cref="Iterator{T}"/> that will be used to monitor the iterative process.</param>
public TFQMR(Iterator<double> iterator)
: this(null, iterator)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="TFQMR"/> class.
/// </summary>
/// <remarks>
/// When using this constructor the solver will use the <see cref="Iterator{T}"/> with
/// the standard settings.
/// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation.</param>
public TFQMR(IPreConditioner<double> preconditioner)
: this(preconditioner, null)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="TFQMR"/> class.
/// </summary>
/// <remarks>
/// <para>
/// The main advantages of using a user defined <see cref="Iterator{T}"/> are:
/// <list type="number">
/// <item>It is possible to set the desired convergence limits.</item>
/// <item>
/// It is possible to check the reason for which the solver finished
/// the iterative procedure by calling the <see cref="Iterator{T}.Status"/> property.
/// </item>
/// </list>
/// </para>
/// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation.</param>
/// <param name="iterator">The <see cref="Iterator{T}"/> that will be used to monitor the iterative process.</param>
public TFQMR(IPreConditioner<double> preconditioner, Iterator<double> iterator)
{
_iterator = iterator;
_preconditioner = preconditioner;
}
@ -149,26 +105,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
_preconditioner = preconditioner;
}
/// <summary>
/// Sets the <see cref="Iterator{T}"/> that will be used to track the iterative process.
/// </summary>
/// <param name="iterator">The iterator.</param>
public void SetIterator(Iterator<double> iterator)
{
_iterator = iterator;
}
/// <summary>
/// Gets the status of the iteration once the calculation is finished.
/// </summary>
public IterationStatus IterationResult
{
get
{
return (_iterator != null) ? _iterator.Status : IterationStatus.Indetermined;
}
}
/// <summary>
/// Stops the solve process.
/// </summary>
@ -187,15 +123,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="vector">The solution vector, <c>b</c>.</param>
/// <returns>The result vector, <c>x</c>.</returns>
public Vector<double> Solve(Matrix<double> matrix, Vector<double> vector)
public Vector<double> Solve(Matrix<double> matrix, Vector<double> vector, Iterator<double> iterator = null)
{
if (vector == null)
{
throw new ArgumentNullException();
}
var result = new DenseVector(matrix.RowCount);
Solve(matrix, vector, result);
Solve(matrix, vector, result, iterator);
return result;
}
@ -206,7 +137,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution vector, <c>b</c></param>
/// <param name="result">The result vector, <c>x</c></param>
public void Solve(Matrix<double> matrix, Vector<double> input, Vector<double> result)
public void Solve(Matrix<double> matrix, Vector<double> input, Vector<double> result, Iterator<double> iterator = null)
{
// If we were stopped before, we are no longer
// We're doing this at the start of the method to ensure
@ -246,9 +177,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
// Initialize the solver fields
// Set the convergence monitor
if (_iterator == null)
if (iterator == null)
{
_iterator = Iterator.CreateDefault();
iterator = new Iterator<double>(Iterator.CreateDefaultStopCriteria());
}
if (_preconditioner == null)
@ -297,7 +228,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
// Start the iteration
var iterationNumber = 0;
while (ShouldContinue(iterationNumber, result, input, pseudoResiduals))
while (ShouldContinue(iterator, iterationNumber, result, input, pseudoResiduals))
{
// First part of the step, the even bit
if (IsEven(iterationNumber))
@ -307,7 +238,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
if (sigma.AlmostEqual(0, 1))
{
// FAIL HERE
_iterator.Cancel();
iterator.Cancel();
break;
}
@ -356,7 +287,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
temp2.CopyTo(x);
// Check convergence and see if we can bail
if (!ShouldContinue(iterationNumber, result, input, pseudoResiduals))
if (!ShouldContinue(iterator, iterationNumber, result, input, pseudoResiduals))
{
// Calculate the real values
_preconditioner.Approximate(x, result);
@ -367,7 +298,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
CalculateTrueResidual(matrix, temp, result, input);
// Now recheck the convergence
if (!ShouldContinue(iterationNumber, result, input, temp))
if (!ShouldContinue(iterator, iterationNumber, result, input, temp))
{
// We're all good now.
return;
@ -380,7 +311,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
if (rho.AlmostEqual(0, 1))
{
// FAIL HERE
_iterator.Cancel();
iterator.Cancel();
break;
}
@ -440,7 +371,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
/// <param name="source">Source <see cref="Vector"/>.</param>
/// <param name="residuals">Residual <see cref="Vector"/>.</param>
/// <returns><c>true</c> if continue, otherwise <c>false</c></returns>
bool ShouldContinue(int iterationNumber, Vector<double> result, Vector<double> source, Vector<double> residuals)
bool ShouldContinue(Iterator<double> iterator, int iterationNumber, Vector<double> result, Vector<double> source, Vector<double> residuals)
{
// We stop if either:
// - the user has stopped the calculation
@ -448,11 +379,11 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
if (_hasBeenStopped)
{
_iterator.Cancel();
iterator.Cancel();
return true;
}
var status = _iterator.DetermineStatus(iterationNumber, result, source, residuals);
var status = iterator.DetermineStatus(iterationNumber, result, source, residuals);
return status == IterationStatus.Running || status == IterationStatus.Indetermined;
}
@ -473,20 +404,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution matrix, <c>B</c>.</param>
/// <returns>The result matrix, <c>X</c>.</returns>
public Matrix<double> Solve(Matrix<double> matrix, Matrix<double> input)
public Matrix<double> Solve(Matrix<double> matrix, Matrix<double> input, Iterator<double> iterator = null)
{
if (matrix == null)
{
throw new ArgumentNullException("matrix");
}
if (input == null)
{
throw new ArgumentNullException("input");
}
var result = matrix.CreateMatrix(input.RowCount, input.ColumnCount);
Solve(matrix, input, result);
Solve(matrix, input, result, iterator);
return result;
}
@ -497,31 +418,21 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution matrix, <c>B</c>.</param>
/// <param name="result">The result matrix, <c>X</c></param>
public void Solve(Matrix<double> matrix, Matrix<double> input, Matrix<double> result)
public void Solve(Matrix<double> matrix, Matrix<double> input, Matrix<double> result, Iterator<double> iterator = null)
{
if (matrix == null)
{
throw new ArgumentNullException("matrix");
}
if (input == null)
{
throw new ArgumentNullException("input");
}
if (result == null)
if (matrix.RowCount != input.RowCount || input.RowCount != result.RowCount || input.ColumnCount != result.ColumnCount)
{
throw new ArgumentNullException("result");
throw Matrix.DimensionsDontMatch<ArgumentException>(matrix, input, result);
}
if (matrix.RowCount != input.RowCount || input.RowCount != result.RowCount || input.ColumnCount != result.ColumnCount)
if (iterator == null)
{
throw Matrix.DimensionsDontMatch<ArgumentException>(matrix, input, result);
iterator = new Iterator<double>(Iterator.CreateDefaultStopCriteria());
}
for (var column = 0; column < input.ColumnCount; column++)
{
var solution = Solve(matrix, input.Column(column));
var solution = Solve(matrix, input.Column(column), iterator);
foreach (var element in solution.EnumerateNonZeroIndexed())
{
result.At(element.Item1, column, element.Item2);

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

@ -71,11 +71,6 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
/// </summary>
IPreConditioner<float> _preconditioner;
/// <summary>
/// The iterative process controller.
/// </summary>
Iterator<float> _iterator;
/// <summary>
/// Indicates if the user has stopped the solver.
/// </summary>
@ -88,44 +83,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
/// When using this constructor the solver will use the <see cref="Iterator{T}"/> with
/// the standard settings and a default preconditioner.
/// </remarks>
public BiCgStab() : this(null, null)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="BiCgStab"/> class.
/// </summary>
/// <remarks>
/// <para>
/// When using this constructor the solver will use a default preconditioner.
/// </para>
/// <para>
/// The main advantages of using a user defined <see cref="Iterator{T}"/> are:
/// <list type="number">
/// <item>It is possible to set the desired convergence limits.</item>
/// <item>
/// It is possible to check the reason for which the solver finished
/// the iterative procedure by calling the <see cref="Iterator{T}.Status"/> property.
/// </item>
/// </list>
/// </para>
/// </remarks>
/// <param name="iterator">The <see cref="Iterator{T}"/> that will be used to monitor the iterative process. </param>
public BiCgStab(Iterator<float> iterator)
: this(null, iterator)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="BiCgStab"/> class.
/// </summary>
/// <remarks>
/// When using this constructor the solver will use the <see cref="Iterator{T}"/> with
/// the standard settings.
/// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation.</param>
public BiCgStab(IPreConditioner<float> preconditioner)
: this(preconditioner, null)
public BiCgStab()
{
}
@ -145,10 +103,8 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
/// </para>
/// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation. </param>
/// <param name="iterator">The <see cref="Iterator{T}"/> that will be used to monitor the iterative process. </param>
public BiCgStab(IPreConditioner<float> preconditioner, Iterator<float> iterator)
public BiCgStab(IPreConditioner<float> preconditioner)
{
_iterator = iterator;
_preconditioner = preconditioner;
}
@ -161,26 +117,6 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
_preconditioner = preconditioner;
}
/// <summary>
/// Sets the <see cref="Iterator{T}"/> that will be used to track the iterative process.
/// </summary>
/// <param name="iterator">The iterator.</param>
public void SetIterator(Iterator<float> iterator)
{
_iterator = iterator;
}
/// <summary>
/// Gets the status of the iteration once the calculation is finished.
/// </summary>
public IterationStatus IterationResult
{
get
{
return (_iterator != null) ? _iterator.Status : IterationStatus.Indetermined;
}
}
/// <summary>
/// Stops the solve process.
/// </summary>
@ -199,15 +135,10 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
/// <param name="matrix">The coefficient <see cref="Matrix"/>, <c>A</c>.</param>
/// <param name="vector">The solution <see cref="Vector"/>, <c>b</c>.</param>
/// <returns>The result <see cref="Vector"/>, <c>x</c>.</returns>
public Vector<float> Solve(Matrix<float> matrix, Vector<float> vector)
public Vector<float> Solve(Matrix<float> matrix, Vector<float> vector, Iterator<float> iterator = null)
{
if (vector == null)
{
throw new ArgumentNullException();
}
var result = new DenseVector(matrix.RowCount);
Solve(matrix, vector, result);
Solve(matrix, vector, result, iterator);
return result;
}
@ -218,7 +149,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
/// <param name="matrix">The coefficient <see cref="Matrix"/>, <c>A</c>.</param>
/// <param name="input">The solution <see cref="Vector"/>, <c>b</c>.</param>
/// <param name="result">The result <see cref="Vector"/>, <c>x</c>.</param>
public void Solve(Matrix<float> matrix, Vector<float> input, Vector<float> result)
public void Solve(Matrix<float> matrix, Vector<float> input, Vector<float> result, Iterator<float> iterator = null)
{
// If we were stopped before, we are no longer
// We're doing this at the start of the method to ensure
@ -258,9 +189,9 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
// Initialize the solver fields
// Set the convergence monitor
if (_iterator == null)
if (iterator == null)
{
_iterator = Iterator.CreateDefault();
iterator = new Iterator<float>(Iterator.CreateDefaultStopCriteria());
}
if (_preconditioner == null)
@ -297,7 +228,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
float omega = 0;
var iterationNumber = 0;
while (ShouldContinue(iterationNumber, result, input, residuals))
while (ShouldContinue(iterator, iterationNumber, result, input, residuals))
{
// rho_(i-1) = r~^T r_(i-1) // dotproduct r~ and r_(i-1)
var oldRho = currentRho;
@ -356,7 +287,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
temp2.CopyTo(temp);
// Check convergence and stop if we are converged.
if (!ShouldContinue(iterationNumber, temp, input, vecS))
if (!ShouldContinue(iterator, iterationNumber, temp, input, vecS))
{
temp.CopyTo(result);
@ -364,7 +295,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
CalculateTrueResidual(matrix, residuals, result, input);
// Now recheck the convergence
if (!ShouldContinue(iterationNumber, result, input, residuals))
if (!ShouldContinue(iterator, iterationNumber, result, input, residuals))
{
// We're all good now.
return;
@ -405,7 +336,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
throw new Exception("Iterative solver experience a numerical break down");
}
if (!ShouldContinue(iterationNumber, result, input, residuals))
if (!ShouldContinue(iterator, iterationNumber, result, input, residuals))
{
// Recalculate the residuals and go round again. This is done to ensure that
// we have the proper residuals.
@ -446,7 +377,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
/// <param name="source">Source <see cref="Vector"/>.</param>
/// <param name="residuals">Residual <see cref="Vector"/>.</param>
/// <returns><c>true</c> if continue, otherwise <c>false</c></returns>
bool ShouldContinue(int iterationNumber, Vector<float> result, Vector<float> source, Vector<float> residuals)
bool ShouldContinue(Iterator<float> iterator, int iterationNumber, Vector<float> result, Vector<float> source, Vector<float> residuals)
{
// We stop if either:
// - the user has stopped the calculation
@ -454,11 +385,11 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
if (_hasBeenStopped)
{
_iterator.Cancel();
iterator.Cancel();
return true;
}
var status = _iterator.DetermineStatus(iterationNumber, result, source, residuals);
var status = iterator.DetermineStatus(iterationNumber, result, source, residuals);
return status == IterationStatus.Running || status == IterationStatus.Indetermined;
}
@ -469,20 +400,10 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
/// <param name="matrix">The coefficient <see cref="Matrix"/>, <c>A</c>.</param>
/// <param name="input">The solution <see cref="Matrix"/>, <c>B</c>.</param>
/// <returns>The result <see cref="Matrix"/>, <c>X</c>.</returns>
public Matrix<float> Solve(Matrix<float> matrix, Matrix<float> input)
public Matrix<float> Solve(Matrix<float> matrix, Matrix<float> input, Iterator<float> iterator = null)
{
if (matrix == null)
{
throw new ArgumentNullException("matrix");
}
if (input == null)
{
throw new ArgumentNullException("input");
}
var result = matrix.CreateMatrix(input.RowCount, input.ColumnCount);
Solve(matrix, input, result);
Solve(matrix, input, result, iterator);
return result;
}
@ -493,31 +414,21 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
/// <param name="matrix">The coefficient <see cref="Matrix"/>, <c>A</c>.</param>
/// <param name="input">The solution <see cref="Matrix"/>, <c>B</c>.</param>
/// <param name="result">The result <see cref="Matrix"/>, <c>X</c></param>
public void Solve(Matrix<float> matrix, Matrix<float> input, Matrix<float> result)
public void Solve(Matrix<float> matrix, Matrix<float> input, Matrix<float> result, Iterator<float> iterator = null)
{
if (matrix == null)
{
throw new ArgumentNullException("matrix");
}
if (input == null)
{
throw new ArgumentNullException("input");
}
if (result == null)
if (matrix.RowCount != input.RowCount || input.RowCount != result.RowCount || input.ColumnCount != result.ColumnCount)
{
throw new ArgumentNullException("result");
throw Matrix.DimensionsDontMatch<ArgumentException>(matrix, input, result);
}
if (matrix.RowCount != input.RowCount || input.RowCount != result.RowCount || input.ColumnCount != result.ColumnCount)
if (iterator == null)
{
throw Matrix.DimensionsDontMatch<ArgumentException>(matrix, input, result);
iterator = new Iterator<float>(Iterator.CreateDefaultStopCriteria());
}
for (var column = 0; column < input.ColumnCount; column++)
{
var solution = Solve(matrix, input.Column(column));
var solution = Solve(matrix, input.Column(column), iterator);
foreach (var element in solution.EnumerateNonZeroIndexed())
{
result.At(element.Item1, column, element.Item2);

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

@ -331,11 +331,6 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
/// </summary>
IterationStatus _status = IterationStatus.Indetermined;
/// <summary>
/// The iterator that is used to control the iteration process.
/// </summary>
Iterator<float> _iterator;
/// <summary>
/// A flag indicating if the solver has been stopped or not.
/// </summary>
@ -350,37 +345,8 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
/// <summary>
/// Initializes a new instance of the <see cref="CompositeSolver"/> class with the default iterator.
/// </summary>
public CompositeSolver() : this(null)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="CompositeSolver"/> class with the specified iterator.
/// </summary>
/// <param name="iterator">The iterator that will be used to control the iteration process. </param>
public CompositeSolver(Iterator<float> iterator)
{
_iterator = iterator;
}
/// <summary>
/// Sets the <see cref="Iterator{T}"/> that will be used to track the iterative process.
/// </summary>
/// <param name="iterator">The iterator.</param>
public void SetIterator(Iterator<float> iterator)
{
_iterator = iterator;
}
/// <summary>
/// Gets the status of the iteration once the calculation is finished.
/// </summary>
public IterationStatus IterationResult
public CompositeSolver()
{
get
{
return _status;
}
}
/// <summary>
@ -406,10 +372,10 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="vector">The solution vector, <c>b</c>.</param>
/// <returns>The result vector, <c>x</c>.</returns>
public Vector<float> Solve(Matrix<float> matrix, Vector<float> vector)
public Vector<float> Solve(Matrix<float> matrix, Vector<float> vector, Iterator<float> iterator = null)
{
var result = new DenseVector(matrix.RowCount);
Solve(matrix, vector, result);
Solve(matrix, vector, result, iterator);
return result;
}
@ -420,7 +386,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution vector, <c>b</c></param>
/// <param name="result">The result vector, <c>x</c></param>
public void Solve(Matrix<float> matrix, Vector<float> input, Vector<float> result)
public void Solve(Matrix<float> matrix, Vector<float> input, Vector<float> result, Iterator<float> iterator = null)
{
// If we were stopped before, we are no longer
// We're doing this at the start of the method to ensure
@ -440,9 +406,9 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
// Initialize the solver fields
// Set the convergence monitor
if (_iterator == null)
if (iterator == null)
{
_iterator = Iterator.CreateDefault();
iterator = new Iterator<float>(Iterator.CreateDefaultStopCriteria());
}
// Load the solvers into our own internal data structure
@ -465,11 +431,11 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
try
{
// Reset the iterator and pass it to the solver
_iterator.Reset();
solver.SetIterator(_iterator);
iterator.Reset();
// Start the solver
solver.Solve(matrix, internalInput, internalResult);
solver.Solve(matrix, internalInput, internalResult, iterator);
_status = iterator.Status;
}
catch (Exception)
{
@ -483,7 +449,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
}
// There was no fatal breakdown so check the status
if (_iterator.HasConverged)
if (_status == IterationStatus.Converged)
{
// We're done
internalResult.CopyTo(result);
@ -493,7 +459,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
// We're not done
// Either:
// - calculation finished without convergence
if (_iterator.HasStoppedWithoutConvergence)
if (_status == IterationStatus.StoppedWithoutConvergence)
{
// Copy the internal result to the result vector and
// continue with the calculation.
@ -514,9 +480,6 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
// Clean up
// No longer need the current solver
_currentSolver = null;
// Set the final status
_status = _iterator.Status;
}
/// <summary>
@ -546,10 +509,10 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution matrix, <c>B</c>.</param>
/// <returns>The result matrix, <c>X</c>.</returns>
public Matrix<float> Solve(Matrix<float> matrix, Matrix<float> input)
public Matrix<float> Solve(Matrix<float> matrix, Matrix<float> input, Iterator<float> iterator = null)
{
var result = matrix.CreateMatrix(input.RowCount, input.ColumnCount);
Solve(matrix, input, result);
Solve(matrix, input, result, iterator);
return result;
}
@ -560,16 +523,21 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution matrix, <c>B</c>.</param>
/// <param name="result">The result matrix, <c>X</c></param>
public void Solve(Matrix<float> matrix, Matrix<float> input, Matrix<float> result)
public void Solve(Matrix<float> matrix, Matrix<float> input, Matrix<float> result, Iterator<float> iterator = null)
{
if (matrix.RowCount != input.RowCount || input.RowCount != result.RowCount || input.ColumnCount != result.ColumnCount)
{
throw Matrix.DimensionsDontMatch<ArgumentException>(matrix, input, result);
}
if (iterator == null)
{
iterator = new Iterator<float>(Iterator.CreateDefaultStopCriteria());
}
for (var column = 0; column < input.ColumnCount; column++)
{
var solution = Solve(matrix, input.Column(column));
var solution = Solve(matrix, input.Column(column), iterator);
foreach (var element in solution.EnumerateNonZeroIndexed())
{
result.At(element.Item1, column, element.Item2);

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

@ -69,11 +69,6 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
/// </summary>
IPreConditioner<float> _preconditioner;
/// <summary>
/// The iterative process controller.
/// </summary>
Iterator<float> _iterator;
/// <summary>
/// Indicates the number of <c>BiCGStab</c> steps should be taken
/// before switching.
@ -99,7 +94,6 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
/// the standard settings and a default preconditioner.
/// </remarks>
public GpBiCg()
: this(null, null)
{
}
@ -108,9 +102,6 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
/// </summary>
/// <remarks>
/// <para>
/// When using this constructor the solver will use a default preconditioner.
/// </para>
/// <para>
/// The main advantages of using a user defined <see cref="Iterator{T}"/> are:
/// <list type="number">
/// <item>It is possible to set the desired convergence limits.</item>
@ -121,45 +112,9 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
/// </list>
/// </para>
/// </remarks>
/// <param name="iterator">The <see cref="Iterator{T}"/> that will be used to monitor the iterative process.</param>
public GpBiCg(Iterator<float> iterator)
: this(null, iterator)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="GpBiCg"/> class.
/// </summary>
/// <remarks>
/// When using this constructor the solver will use the <see cref="Iterator{T}"/> with
/// the standard settings.
/// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation.</param>
public GpBiCg(IPreConditioner<float> preconditioner)
: this(preconditioner, null)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="GpBiCg"/> class.
/// </summary>
/// <remarks>
/// <para>
/// The main advantages of using a user defined <see cref="Iterator{T}"/> are:
/// <list type="number">
/// <item>It is possible to set the desired convergence limits.</item>
/// <item>
/// It is possible to check the reason for which the solver finished
/// the iterative procedure by calling the <see cref="Iterator{T}.Status"/> property.
/// </item>
/// </list>
/// </para>
/// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation.</param>
/// <param name="iterator">The <see cref="Iterator{T}"/> that will be used to monitor the iterative process.</param>
public GpBiCg(IPreConditioner<float> preconditioner, Iterator<float> iterator)
{
_iterator = iterator;
_preconditioner = preconditioner;
}
@ -210,23 +165,6 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
_preconditioner = preconditioner;
}
/// <summary>
/// Sets the <see cref="Iterator{T}"/> that will be used to track the iterative process.
/// </summary>
/// <param name="iterator">The iterator.</param>
public void SetIterator(Iterator<float> iterator)
{
_iterator = iterator;
}
/// <summary>
/// Gets the status of the iteration once the calculation is finished.
/// </summary>
public IterationStatus IterationResult
{
get { return (_iterator != null) ? _iterator.Status : IterationStatus.Indetermined; }
}
/// <summary>
/// Stops the solve process.
/// </summary>
@ -246,15 +184,10 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="vector">The solution vector, <c>b</c>.</param>
/// <returns>The result vector, <c>x</c>.</returns>
public Vector<float> Solve(Matrix<float> matrix, Vector<float> vector)
public Vector<float> Solve(Matrix<float> matrix, Vector<float> vector, Iterator<float> iterator = null)
{
if (vector == null)
{
throw new ArgumentNullException();
}
var result = new DenseVector(matrix.RowCount);
Solve(matrix, vector, result);
Solve(matrix, vector, result, iterator);
return result;
}
@ -265,7 +198,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution vector, <c>b</c></param>
/// <param name="result">The result vector, <c>x</c></param>
public void Solve(Matrix<float> matrix, Vector<float> input, Vector<float> result)
public void Solve(Matrix<float> matrix, Vector<float> input, Vector<float> result, Iterator<float> iterator = null)
{
// If we were stopped before, we are no longer
// We're doing this at the start of the method to ensure
@ -305,9 +238,9 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
// Initialize the solver fields
// Set the convergence monitor
if (_iterator == null)
if (iterator == null)
{
_iterator = Iterator.CreateDefault();
iterator = new Iterator<float>(Iterator.CreateDefaultStopCriteria());
}
if (_preconditioner == null)
@ -354,7 +287,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
// for (k = 0, 1, .... )
var iterationNumber = 0;
while (ShouldContinue(iterationNumber, xtemp, input, residuals))
while (ShouldContinue(iterator, iterationNumber, xtemp, input, residuals))
{
// p_k = r_k + beta_(k-1) * (p_(k-1) - u_(k-1))
p.Subtract(u, temp);
@ -495,7 +428,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
_preconditioner.Approximate(xtemp, result);
// Now check for convergence
if (!ShouldContinue(iterationNumber, result, input, residuals))
if (!ShouldContinue(iterator, iterationNumber, result, input, residuals))
{
// Recalculate the residuals and go round again. This is done to ensure that
// we have the proper residuals.
@ -532,7 +465,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
/// <param name="source">Source <see cref="Vector"/>.</param>
/// <param name="residuals">Residual <see cref="Vector"/>.</param>
/// <returns><c>true</c> if continue, otherwise <c>false</c></returns>
bool ShouldContinue(int iterationNumber, Vector<float> result, Vector<float> source, Vector<float> residuals)
bool ShouldContinue(Iterator<float> iterator, int iterationNumber, Vector<float> result, Vector<float> source, Vector<float> residuals)
{
// We stop if either:
// - the user has stopped the calculation
@ -540,11 +473,11 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
if (_hasBeenStopped)
{
_iterator.Cancel();
iterator.Cancel();
return true;
}
var status = _iterator.DetermineStatus(iterationNumber, result, source, residuals);
var status = iterator.DetermineStatus(iterationNumber, result, source, residuals);
return status == IterationStatus.Running || status == IterationStatus.Indetermined;
}
@ -572,20 +505,10 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution matrix, <c>B</c>.</param>
/// <returns>The result matrix, <c>X</c>.</returns>
public Matrix<float> Solve(Matrix<float> matrix, Matrix<float> input)
public Matrix<float> Solve(Matrix<float> matrix, Matrix<float> input, Iterator<float> iterator = null)
{
if (matrix == null)
{
throw new ArgumentNullException("matrix");
}
if (input == null)
{
throw new ArgumentNullException("input");
}
var result = matrix.CreateMatrix(input.RowCount, input.ColumnCount);
Solve(matrix, input, result);
Solve(matrix, input, result, iterator);
return result;
}
@ -596,31 +519,21 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution matrix, <c>B</c>.</param>
/// <param name="result">The result matrix, <c>X</c></param>
public void Solve(Matrix<float> matrix, Matrix<float> input, Matrix<float> result)
public void Solve(Matrix<float> matrix, Matrix<float> input, Matrix<float> result, Iterator<float> iterator = null)
{
if (matrix == null)
{
throw new ArgumentNullException("matrix");
}
if (input == null)
{
throw new ArgumentNullException("input");
}
if (result == null)
if (matrix.RowCount != input.RowCount || input.RowCount != result.RowCount || input.ColumnCount != result.ColumnCount)
{
throw new ArgumentNullException("result");
throw Matrix.DimensionsDontMatch<ArgumentException>(matrix, input, result);
}
if (matrix.RowCount != input.RowCount || input.RowCount != result.RowCount || input.ColumnCount != result.ColumnCount)
if (iterator == null)
{
throw Matrix.DimensionsDontMatch<ArgumentException>(matrix, input, result);
iterator = new Iterator<float>(Iterator.CreateDefaultStopCriteria());
}
for (var column = 0; column < input.ColumnCount; column++)
{
var solution = Solve(matrix, input.Column(column));
var solution = Solve(matrix, input.Column(column), iterator);
foreach (var element in solution.EnumerateNonZeroIndexed())
{
result.At(element.Item1, column, element.Item2);

19
src/Numerics/LinearAlgebra/Single/Solvers/Iterator.cs

@ -42,16 +42,25 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
// TODO: Refactor
/// <summary>
/// Creates a default iterator with all the <see cref="IIterationStopCriterium{T}"/> objects.
/// Creates the default stop criteria.
/// </summary>
/// <returns>A new <see cref="Iterator{T}"/> object.</returns>
public static Iterator<float> CreateDefault()
public static IIterationStopCriterium<float>[] CreateDefaultStopCriteria()
{
return new Iterator<float>(
return new IIterationStopCriterium<float>[]
{
new FailureStopCriterium(),
new DivergenceStopCriterium(),
new IterationCountStopCriterium<float>(),
new ResidualStopCriterium());
new ResidualStopCriterium()
};
}
/// <summary>
/// Creates a default iterator with all the default stop criteria.
/// </summary>
public static Iterator<float> CreateDefault()
{
return new Iterator<float>(CreateDefaultStopCriteria());
}
}
}

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

@ -73,11 +73,6 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
/// </summary>
IPreConditioner<float> _preconditioner;
/// <summary>
/// The iterative process controller.
/// </summary>
Iterator<float> _iterator;
/// <summary>
/// The collection of starting vectors which are used as the basis for the Krylov sub-space.
/// </summary>
@ -100,7 +95,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
/// When using this constructor the solver will use the <see cref="Iterator{T}"/> with
/// the standard settings and a default preconditioner.
/// </remarks>
public MlkBiCgStab() : this(null, null)
public MlkBiCgStab()
{
}
@ -109,9 +104,6 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
/// </summary>
/// <remarks>
/// <para>
/// When using this constructor the solver will use a default preconditioner.
/// </para>
/// <para>
/// The main advantages of using a user defined <see cref="Iterator{T}"/> are:
/// <list type="number">
/// <item>It is possible to set the desired convergence limits.</item>
@ -122,45 +114,9 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
/// </list>
/// </para>
/// </remarks>
/// <param name="iterator">The <see cref="Iterator{T}"/> that will be used to monitor the iterative process.</param>
public MlkBiCgStab(Iterator<float> iterator)
: this(null, iterator)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="MlkBiCgStab"/> class.
/// </summary>
/// <remarks>
/// When using this constructor the solver will use the <see cref="Iterator{T}"/> with
/// the standard settings.
/// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation.</param>
public MlkBiCgStab(IPreConditioner<float> preconditioner)
: this(preconditioner, null)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="MlkBiCgStab"/> class.
/// </summary>
/// <remarks>
/// <para>
/// The main advantages of using a user defined <see cref="Iterator{T}"/> are:
/// <list type="number">
/// <item>It is possible to set the desired convergence limits.</item>
/// <item>
/// It is possible to check the reason for which the solver finished
/// the iterative procedure by calling the <see cref="Iterator{T}.Status"/> property.
/// </item>
/// </list>
/// </para>
/// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation.</param>
/// <param name="iterator">The <see cref="Iterator{T}"/> that will be used to monitor the iterative process.</param>
public MlkBiCgStab(IPreConditioner<float> preconditioner, Iterator<float> iterator)
{
_iterator = iterator;
_preconditioner = preconditioner;
}
@ -208,15 +164,6 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
_preconditioner = preconditioner;
}
/// <summary>
/// Sets the <see cref="Iterator{T}"/> that will be used to track the iterative process.
/// </summary>
/// <param name="iterator">The iterator.</param>
public void SetIterator(Iterator<float> iterator)
{
_iterator = iterator;
}
/// <summary>
/// Gets or sets a series of orthonormal vectors which will be used as basis for the
/// Krylov sub-space.
@ -243,18 +190,6 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
}
}
/// <summary>
/// Gets the status of the iteration once the calculation is finished.
/// </summary>
public IterationStatus IterationResult
{
[DebuggerStepThrough]
get
{
return (_iterator != null) ? _iterator.Status : IterationStatus.Indetermined;
}
}
/// <summary>
/// Stops the solve process.
/// </summary>
@ -273,15 +208,10 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="vector">The solution vector, <c>b</c>.</param>
/// <returns>The result vector, <c>x</c>.</returns>
public Vector<float> Solve(Matrix<float> matrix, Vector<float> vector)
public Vector<float> Solve(Matrix<float> matrix, Vector<float> vector, Iterator<float> iterator = null)
{
if (vector == null)
{
throw new ArgumentNullException();
}
var result = new DenseVector(matrix.RowCount);
Solve(matrix, vector, result);
Solve(matrix, vector, result, iterator);
return result;
}
@ -292,7 +222,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution vector, <c>b</c></param>
/// <param name="result">The result vector, <c>x</c></param>
public void Solve(Matrix<float> matrix, Vector<float> input, Vector<float> result)
public void Solve(Matrix<float> matrix, Vector<float> input, Vector<float> result, Iterator<float> iterator = null)
{
// If we were stopped before, we are no longer
// We're doing this at the start of the method to ensure
@ -332,9 +262,9 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
// Initialize the solver fields
// Set the convergence monitor
if (_iterator == null)
if (iterator == null)
{
_iterator = Iterator.CreateDefault();
iterator = new Iterator<float>(Iterator.CreateDefaultStopCriteria());
}
if (_preconditioner == null)
@ -404,7 +334,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
// FOR (j = 0, 1, 2 ....)
var iterationNumber = 0;
while (ShouldContinue(iterationNumber, xtemp, input, residuals))
while (ShouldContinue(iterator, iterationNumber, xtemp, input, residuals))
{
// SOLVE M g~_((j-1)k+k) = g_((j-1)k+k)
_preconditioner.Approximate(g[k - 1], gtemp);
@ -462,13 +392,13 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
temp2.CopyTo(xtemp);
// Check convergence and stop if we are converged.
if (!ShouldContinue(iterationNumber, xtemp, input, residuals))
if (!ShouldContinue(iterator, iterationNumber, xtemp, input, residuals))
{
// Calculate the true residual
CalculateTrueResidual(matrix, residuals, xtemp, input);
// Now recheck the convergence
if (!ShouldContinue(iterationNumber, xtemp, input, residuals))
if (!ShouldContinue(iterator, iterationNumber, xtemp, input, residuals))
{
// We're all good now.
// Exit from the while loop.
@ -597,7 +527,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
temp2.CopyTo(residuals);
// We can check the residuals here if they're close
if (!ShouldContinue(iterationNumber, xtemp, input, residuals))
if (!ShouldContinue(iterator, iterationNumber, xtemp, input, residuals))
{
// Recalculate the residuals and go round again. This is done to ensure that
// we have the proper residuals.
@ -719,7 +649,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
/// <param name="source">Source <see cref="Vector"/>.</param>
/// <param name="residuals">Residual <see cref="Vector"/>.</param>
/// <returns><c>true</c> if continue, otherwise <c>false</c></returns>
bool ShouldContinue(int iterationNumber, Vector<float> result, Vector<float> source, Vector<float> residuals)
bool ShouldContinue(Iterator<float> iterator, int iterationNumber, Vector<float> result, Vector<float> source, Vector<float> residuals)
{
// We stop if either:
// - the user has stopped the calculation
@ -727,11 +657,11 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
if (_hasBeenStopped)
{
_iterator.Cancel();
iterator.Cancel();
return true;
}
var status = _iterator.DetermineStatus(iterationNumber, result, source, residuals);
var status = iterator.DetermineStatus(iterationNumber, result, source, residuals);
return status == IterationStatus.Running || status == IterationStatus.Indetermined;
}
@ -742,20 +672,10 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution matrix, <c>B</c>.</param>
/// <returns>The result matrix, <c>X</c>.</returns>
public Matrix<float> Solve(Matrix<float> matrix, Matrix<float> input)
public Matrix<float> Solve(Matrix<float> matrix, Matrix<float> input, Iterator<float> iterator = null)
{
if (matrix == null)
{
throw new ArgumentNullException("matrix");
}
if (input == null)
{
throw new ArgumentNullException("input");
}
var result = matrix.CreateMatrix(input.RowCount, input.ColumnCount);
Solve(matrix, input, result);
Solve(matrix, input, result, iterator);
return result;
}
@ -766,31 +686,21 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution matrix, <c>B</c>.</param>
/// <param name="result">The result matrix, <c>X</c></param>
public void Solve(Matrix<float> matrix, Matrix<float> input, Matrix<float> result)
public void Solve(Matrix<float> matrix, Matrix<float> input, Matrix<float> result, Iterator<float> iterator = null)
{
if (matrix == null)
{
throw new ArgumentNullException("matrix");
}
if (input == null)
{
throw new ArgumentNullException("input");
}
if (result == null)
if (matrix.RowCount != input.RowCount || input.RowCount != result.RowCount || input.ColumnCount != result.ColumnCount)
{
throw new ArgumentNullException("result");
throw Matrix.DimensionsDontMatch<ArgumentException>(matrix, input, result);
}
if (matrix.RowCount != input.RowCount || input.RowCount != result.RowCount || input.ColumnCount != result.ColumnCount)
if (iterator == null)
{
throw Matrix.DimensionsDontMatch<ArgumentException>(matrix, input, result);
iterator = new Iterator<float>(Iterator.CreateDefaultStopCriteria());
}
for (var column = 0; column < input.ColumnCount; column++)
{
var solution = Solve(matrix, input.Column(column));
var solution = Solve(matrix, input.Column(column), iterator);
foreach (var element in solution.EnumerateNonZeroIndexed())
{
result.At(element.Item1, column, element.Item2);

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

@ -59,11 +59,6 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
/// </summary>
IPreConditioner<float> _preconditioner;
/// <summary>
/// The iterative process controller.
/// </summary>
Iterator<float> _iterator;
/// <summary>
/// Indicates if the user has stopped the solver.
/// </summary>
@ -77,7 +72,6 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
/// the standard settings and a default preconditioner.
/// </remarks>
public TFQMR()
: this(null, null)
{
}
@ -86,9 +80,6 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
/// </summary>
/// <remarks>
/// <para>
/// When using this constructor the solver will use a default preconditioner.
/// </para>
/// <para>
/// The main advantages of using a user defined <see cref="Iterator{T}"/> are:
/// <list type="number">
/// <item>It is possible to set the desired convergence limits.</item>
@ -99,45 +90,9 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
/// </list>
/// </para>
/// </remarks>
/// <param name="iterator">The <see cref="Iterator{T}"/> that will be used to monitor the iterative process.</param>
public TFQMR(Iterator<float> iterator)
: this(null, iterator)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="TFQMR"/> class.
/// </summary>
/// <remarks>
/// When using this constructor the solver will use the <see cref="Iterator{T}"/> with
/// the standard settings.
/// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation.</param>
public TFQMR(IPreConditioner<float> preconditioner)
: this(preconditioner, null)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="TFQMR"/> class.
/// </summary>
/// <remarks>
/// <para>
/// The main advantages of using a user defined <see cref="Iterator{T}"/> are:
/// <list type="number">
/// <item>It is possible to set the desired convergence limits.</item>
/// <item>
/// It is possible to check the reason for which the solver finished
/// the iterative procedure by calling the <see cref="Iterator{T}.Status"/> property.
/// </item>
/// </list>
/// </para>
/// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation.</param>
/// <param name="iterator">The <see cref="Iterator{T}"/> that will be used to monitor the iterative process.</param>
public TFQMR(IPreConditioner<float> preconditioner, Iterator<float> iterator)
{
_iterator = iterator;
_preconditioner = preconditioner;
}
@ -150,23 +105,6 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
_preconditioner = preconditioner;
}
/// <summary>
/// Sets the <see cref="Iterator{T}"/> that will be used to track the iterative process.
/// </summary>
/// <param name="iterator">The iterator.</param>
public void SetIterator(Iterator<float> iterator)
{
_iterator = iterator;
}
/// <summary>
/// Gets the status of the iteration once the calculation is finished.
/// </summary>
public IterationStatus IterationResult
{
get { return (_iterator != null) ? _iterator.Status : IterationStatus.Indetermined; }
}
/// <summary>
/// Stops the solve process.
/// </summary>
@ -185,15 +123,10 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="vector">The solution vector, <c>b</c>.</param>
/// <returns>The result vector, <c>x</c>.</returns>
public Vector<float> Solve(Matrix<float> matrix, Vector<float> vector)
public Vector<float> Solve(Matrix<float> matrix, Vector<float> vector, Iterator<float> iterator = null)
{
if (vector == null)
{
throw new ArgumentNullException();
}
var result = new DenseVector(matrix.RowCount);
Solve(matrix, vector, result);
Solve(matrix, vector, result, iterator);
return result;
}
@ -204,7 +137,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution vector, <c>b</c></param>
/// <param name="result">The result vector, <c>x</c></param>
public void Solve(Matrix<float> matrix, Vector<float> input, Vector<float> result)
public void Solve(Matrix<float> matrix, Vector<float> input, Vector<float> result, Iterator<float> iterator = null)
{
// If we were stopped before, we are no longer
// We're doing this at the start of the method to ensure
@ -244,9 +177,9 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
// Initialize the solver fields
// Set the convergence monitor
if (_iterator == null)
if (iterator == null)
{
_iterator = Iterator.CreateDefault();
iterator = new Iterator<float>(Iterator.CreateDefaultStopCriteria());
}
if (_preconditioner == null)
@ -295,7 +228,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
// Start the iteration
var iterationNumber = 0;
while (ShouldContinue(iterationNumber, result, input, pseudoResiduals))
while (ShouldContinue(iterator, iterationNumber, result, input, pseudoResiduals))
{
// First part of the step, the even bit
if (IsEven(iterationNumber))
@ -305,7 +238,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
if (sigma.AlmostEqual(0, 1))
{
// FAIL HERE
_iterator.Cancel();
iterator.Cancel();
break;
}
@ -354,7 +287,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
temp2.CopyTo(x);
// Check convergence and see if we can bail
if (!ShouldContinue(iterationNumber, result, input, pseudoResiduals))
if (!ShouldContinue(iterator, iterationNumber, result, input, pseudoResiduals))
{
// Calculate the real values
_preconditioner.Approximate(x, result);
@ -365,7 +298,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
CalculateTrueResidual(matrix, temp, result, input);
// Now recheck the convergence
if (!ShouldContinue(iterationNumber, result, input, temp))
if (!ShouldContinue(iterator, iterationNumber, result, input, temp))
{
// We're all good now.
return;
@ -378,7 +311,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
if (rho.AlmostEqual(0, 1))
{
// FAIL HERE
_iterator.Cancel();
iterator.Cancel();
break;
}
@ -438,7 +371,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
/// <param name="source">Source <see cref="Vector"/>.</param>
/// <param name="residuals">Residual <see cref="Vector"/>.</param>
/// <returns><c>true</c> if continue, otherwise <c>false</c></returns>
bool ShouldContinue(int iterationNumber, Vector<float> result, Vector<float> source, Vector<float> residuals)
bool ShouldContinue(Iterator<float> iterator, int iterationNumber, Vector<float> result, Vector<float> source, Vector<float> residuals)
{
// We stop if either:
// - the user has stopped the calculation
@ -446,11 +379,11 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
if (_hasBeenStopped)
{
_iterator.Cancel();
iterator.Cancel();
return true;
}
var status = _iterator.DetermineStatus(iterationNumber, result, source, residuals);
var status = iterator.DetermineStatus(iterationNumber, result, source, residuals);
return status == IterationStatus.Running || status == IterationStatus.Indetermined;
}
@ -471,20 +404,10 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution matrix, <c>B</c>.</param>
/// <returns>The result matrix, <c>X</c>.</returns>
public Matrix<float> Solve(Matrix<float> matrix, Matrix<float> input)
public Matrix<float> Solve(Matrix<float> matrix, Matrix<float> input, Iterator<float> iterator = null)
{
if (matrix == null)
{
throw new ArgumentNullException("matrix");
}
if (input == null)
{
throw new ArgumentNullException("input");
}
var result = matrix.CreateMatrix(input.RowCount, input.ColumnCount);
Solve(matrix, input, result);
Solve(matrix, input, result, iterator);
return result;
}
@ -495,31 +418,21 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution matrix, <c>B</c>.</param>
/// <param name="result">The result matrix, <c>X</c></param>
public void Solve(Matrix<float> matrix, Matrix<float> input, Matrix<float> result)
public void Solve(Matrix<float> matrix, Matrix<float> input, Matrix<float> result, Iterator<float> iterator = null)
{
if (matrix == null)
{
throw new ArgumentNullException("matrix");
}
if (input == null)
{
throw new ArgumentNullException("input");
}
if (result == null)
if (matrix.RowCount != input.RowCount || input.RowCount != result.RowCount || input.ColumnCount != result.ColumnCount)
{
throw new ArgumentNullException("result");
throw Matrix.DimensionsDontMatch<ArgumentException>(matrix, input, result);
}
if (matrix.RowCount != input.RowCount || input.RowCount != result.RowCount || input.ColumnCount != result.ColumnCount)
if (iterator == null)
{
throw Matrix.DimensionsDontMatch<ArgumentException>(matrix, input, result);
iterator = new Iterator<float>(Iterator.CreateDefaultStopCriteria());
}
for (var column = 0; column < input.ColumnCount; column++)
{
var solution = Solve(matrix, input.Column(column));
var solution = Solve(matrix, input.Column(column), iterator);
foreach (var element in solution.EnumerateNonZeroIndexed())
{
result.At(element.Item1, column, element.Item2);

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

@ -46,17 +46,6 @@ namespace MathNet.Numerics.LinearAlgebra.Solvers
/// </remarks>
void StopSolve();
/// <summary>
/// Sets the <see cref="Iterator{T}"/> that will be used to track the iterative process.
/// </summary>
/// <param name="iterator">The iterator.</param>
void SetIterator(Iterator<T> iterator);
/// <summary>
/// Gets the status of the iteration once the calculation is finished.
/// </summary>
IterationStatus IterationResult { get; }
/// <summary>
/// Solves the matrix equation Ax = b, where A is the coefficient matrix, b is the
/// solution vector and x is the unknown vector.
@ -64,7 +53,7 @@ namespace MathNet.Numerics.LinearAlgebra.Solvers
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="vector">The solution vector, <c>b</c>.</param>
/// <returns>The result vector, <c>x</c>.</returns>
Vector<T> Solve(Matrix<T> matrix, Vector<T> vector);
Vector<T> Solve(Matrix<T> matrix, Vector<T> vector, Iterator<T> iterator = null);
/// <summary>
/// Solves the matrix equation Ax = b, where A is the coefficient matrix, b is the
@ -73,7 +62,7 @@ namespace MathNet.Numerics.LinearAlgebra.Solvers
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution vector, <c>b</c></param>
/// <param name="result">The result vector, <c>x</c></param>
void Solve(Matrix<T> matrix, Vector<T> input, Vector<T> result);
void Solve(Matrix<T> matrix, Vector<T> input, Vector<T> result, Iterator<T> iterator = null);
/// <summary>
/// Solves the matrix equation AX = B, where A is the coefficient matrix, B is the
@ -82,7 +71,7 @@ namespace MathNet.Numerics.LinearAlgebra.Solvers
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution matrix, <c>B</c>.</param>
/// <returns>The result matrix, <c>X</c>.</returns>
Matrix<T> Solve(Matrix<T> matrix, Matrix<T> input);
Matrix<T> Solve(Matrix<T> matrix, Matrix<T> input, Iterator<T> iterator = null);
/// <summary>
/// Solves the matrix equation AX = B, where A is the coefficient matrix, B is the
@ -91,6 +80,6 @@ namespace MathNet.Numerics.LinearAlgebra.Solvers
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution matrix, <c>B</c>.</param>
/// <param name="result">The result matrix, <c>X</c></param>
void Solve(Matrix<T> matrix, Matrix<T> input, Matrix<T> result);
void Solve(Matrix<T> matrix, Matrix<T> input, Matrix<T> result, Iterator<T> iterator = null);
}
}

20
src/UnitTests/LinearAlgebraTests/Complex/Solvers/Iterative/BiCgStabTest.cs

@ -101,10 +101,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Iterativ
new DivergenceStopCriterium(),
new FailureStopCriterium()
});
var solver = new BiCgStab(monitor);
var solver = new BiCgStab();
// Solve equation Ax = y
var x = solver.Solve(matrix, y);
var x = solver.Solve(matrix, y, monitor);
// Now compare the results
Assert.IsNotNull(x, "#02");
@ -146,10 +146,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Iterativ
new DivergenceStopCriterium(),
new FailureStopCriterium()
});
var solver = new BiCgStab(monitor);
var solver = new BiCgStab();
// Solve equation Ax = y
var x = solver.Solve(matrix, y);
var x = solver.Solve(matrix, y, monitor);
// Now compare the results
Assert.IsNotNull(x, "#02");
@ -224,10 +224,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Iterativ
new DivergenceStopCriterium(),
new FailureStopCriterium()
});
var solver = new BiCgStab(monitor);
var solver = new BiCgStab();
// Solve equation Ax = y
var x = solver.Solve(matrix, y);
var x = solver.Solve(matrix, y, monitor);
// Now compare the results
Assert.IsNotNull(x, "#02");
@ -263,9 +263,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Iterativ
new IterationCountStopCriterium<Complex>(1000),
new ResidualStopCriterium(1e-10),
});
var solver = new BiCgStab(monitor);
var solver = new BiCgStab();
var resultx = solver.Solve(matrixA, vectorb);
var resultx = solver.Solve(matrixA, vectorb, monitor);
Assert.AreEqual(matrixA.ColumnCount, resultx.Count);
var matrixBReconstruct = matrixA*resultx;
@ -295,8 +295,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Iterativ
new IterationCountStopCriterium<Complex>(1000),
new ResidualStopCriterium(1e-10),
});
var solver = new BiCgStab(monitor);
var matrixX = solver.Solve(matrixA, matrixB);
var solver = new BiCgStab();
var matrixX = solver.Solve(matrixA, matrixB, monitor);
// The solution X row dimension is equal to the column dimension of A
Assert.AreEqual(matrixA.ColumnCount, matrixX.RowCount);

20
src/UnitTests/LinearAlgebraTests/Complex/Solvers/Iterative/GpBiCgTest.cs

@ -101,10 +101,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Iterativ
new DivergenceStopCriterium(),
new FailureStopCriterium()
});
var solver = new GpBiCg(monitor);
var solver = new GpBiCg();
// Solve equation Ax = y
var x = solver.Solve(matrix, y);
var x = solver.Solve(matrix, y, monitor);
// Now compare the results
Assert.IsNotNull(x, "#02");
@ -147,10 +147,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Iterativ
new FailureStopCriterium()
});
var solver = new GpBiCg(monitor);
var solver = new GpBiCg();
// Solve equation Ax = y
var x = solver.Solve(matrix, y);
var x = solver.Solve(matrix, y, monitor);
// Now compare the results
Assert.IsNotNull(x, "#02");
@ -226,10 +226,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Iterativ
new FailureStopCriterium()
});
var solver = new GpBiCg(monitor);
var solver = new GpBiCg();
// Solve equation Ax = y
var x = solver.Solve(matrix, y);
var x = solver.Solve(matrix, y, monitor);
// Now compare the results
Assert.IsNotNull(x, "#02");
@ -265,9 +265,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Iterativ
new IterationCountStopCriterium<Complex>(1000),
new ResidualStopCriterium(1e-10),
});
var solver = new GpBiCg(monitor);
var solver = new GpBiCg();
var resultx = solver.Solve(matrixA, vectorb);
var resultx = solver.Solve(matrixA, vectorb, monitor);
Assert.AreEqual(matrixA.ColumnCount, resultx.Count);
var matrixBReconstruct = matrixA*resultx;
@ -297,8 +297,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Iterativ
new IterationCountStopCriterium<Complex>(1000),
new ResidualStopCriterium(1e-10),
});
var solver = new GpBiCg(monitor);
var matrixX = solver.Solve(matrixA, matrixB);
var solver = new GpBiCg();
var matrixX = solver.Solve(matrixA, matrixB, monitor);
// The solution X row dimension is equal to the column dimension of A
Assert.AreEqual(matrixA.ColumnCount, matrixX.RowCount);

20
src/UnitTests/LinearAlgebraTests/Complex/Solvers/Iterative/MlkBiCgStabTest.cs

@ -102,10 +102,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Iterativ
new FailureStopCriterium()
});
var solver = new MlkBiCgStab(monitor);
var solver = new MlkBiCgStab();
// Solve equation Ax = y
var x = solver.Solve(matrix, y);
var x = solver.Solve(matrix, y, monitor);
// Now compare the results
Assert.IsNotNull(x, "#02");
@ -147,10 +147,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Iterativ
new DivergenceStopCriterium(),
new FailureStopCriterium()
});
var solver = new MlkBiCgStab(monitor);
var solver = new MlkBiCgStab();
// Solve equation Ax = y
var x = solver.Solve(matrix, y);
var x = solver.Solve(matrix, y, monitor);
// Now compare the results
Assert.IsNotNull(x, "#02");
@ -225,10 +225,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Iterativ
new DivergenceStopCriterium(),
new FailureStopCriterium()
});
var solver = new MlkBiCgStab(monitor);
var solver = new MlkBiCgStab();
// Solve equation Ax = y
var x = solver.Solve(matrix, y);
var x = solver.Solve(matrix, y, monitor);
// Now compare the results
Assert.IsNotNull(x, "#02");
@ -264,9 +264,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Iterativ
new IterationCountStopCriterium<Complex>(1000),
new ResidualStopCriterium(1e-10),
});
var solver = new MlkBiCgStab(monitor);
var solver = new MlkBiCgStab();
var resultx = solver.Solve(matrixA, vectorb);
var resultx = solver.Solve(matrixA, vectorb, monitor);
Assert.AreEqual(matrixA.ColumnCount, resultx.Count);
var matrixBReconstruct = matrixA*resultx;
@ -296,8 +296,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Iterativ
new IterationCountStopCriterium<Complex>(1000),
new ResidualStopCriterium(1e-10),
});
var solver = new MlkBiCgStab(monitor);
var matrixX = solver.Solve(matrixA, matrixB);
var solver = new MlkBiCgStab();
var matrixX = solver.Solve(matrixA, matrixB, monitor);
// The solution X row dimension is equal to the column dimension of A
Assert.AreEqual(matrixA.ColumnCount, matrixX.RowCount);

20
src/UnitTests/LinearAlgebraTests/Complex/Solvers/Iterative/TFQMRTest.cs

@ -102,10 +102,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Iterativ
new FailureStopCriterium()
});
var solver = new TFQMR(monitor);
var solver = new TFQMR();
// Solve equation Ax = y
var x = solver.Solve(matrix, y);
var x = solver.Solve(matrix, y, monitor);
// Now compare the results
Assert.IsNotNull(x, "#02");
@ -147,10 +147,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Iterativ
new DivergenceStopCriterium(),
new FailureStopCriterium()
});
var solver = new TFQMR(monitor);
var solver = new TFQMR();
// Solve equation Ax = y
var x = solver.Solve(matrix, y);
var x = solver.Solve(matrix, y, monitor);
// Now compare the results
Assert.IsNotNull(x, "#02");
@ -225,10 +225,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Iterativ
new DivergenceStopCriterium(),
new FailureStopCriterium()
});
var solver = new TFQMR(monitor);
var solver = new TFQMR();
// Solve equation Ax = y
var x = solver.Solve(matrix, y);
var x = solver.Solve(matrix, y, monitor);
// Now compare the results
Assert.IsNotNull(x, "#02");
@ -264,9 +264,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Iterativ
new IterationCountStopCriterium<Complex>(1000),
new ResidualStopCriterium(1e-10),
});
var solver = new TFQMR(monitor);
var solver = new TFQMR();
var resultx = solver.Solve(matrixA, vectorb);
var resultx = solver.Solve(matrixA, vectorb, monitor);
Assert.AreEqual(matrixA.ColumnCount, resultx.Count);
var matrixBReconstruct = matrixA*resultx;
@ -296,8 +296,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Iterativ
new IterationCountStopCriterium<Complex>(1000),
new ResidualStopCriterium(1e-10),
});
var solver = new TFQMR(monitor);
var matrixX = solver.Solve(matrixA, matrixB);
var solver = new TFQMR();
var matrixX = solver.Solve(matrixA, matrixB, monitor);
// The solution X row dimension is equal to the column dimension of A
Assert.AreEqual(matrixA.ColumnCount, matrixX.RowCount);

20
src/UnitTests/LinearAlgebraTests/Complex32/Solvers/Iterative/BiCgStabTest.cs

@ -101,10 +101,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.Iterat
new DivergenceStopCriterium(),
new FailureStopCriterium()
});
var solver = new BiCgStab(monitor);
var solver = new BiCgStab();
// Solve equation Ax = y
var x = solver.Solve(matrix, y);
var x = solver.Solve(matrix, y, monitor);
// Now compare the results
Assert.IsNotNull(x, "#02");
@ -146,10 +146,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.Iterat
new DivergenceStopCriterium(),
new FailureStopCriterium()
});
var solver = new BiCgStab(monitor);
var solver = new BiCgStab();
// Solve equation Ax = y
var x = solver.Solve(matrix, y);
var x = solver.Solve(matrix, y, monitor);
// Now compare the results
Assert.IsNotNull(x, "#02");
@ -224,10 +224,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.Iterat
new DivergenceStopCriterium(),
new FailureStopCriterium()
});
var solver = new BiCgStab(monitor);
var solver = new BiCgStab();
// Solve equation Ax = y
var x = solver.Solve(matrix, y);
var x = solver.Solve(matrix, y, monitor);
// Now compare the results
Assert.IsNotNull(x, "#02");
@ -267,9 +267,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.Iterat
new IterationCountStopCriterium<Complex32>(1000),
new ResidualStopCriterium((float) Math.Pow(1.0/10.0, iteration))
});
var solver = new BiCgStab(monitor);
var solver = new BiCgStab();
var resultx = solver.Solve(matrixA, vectorb);
var resultx = solver.Solve(matrixA, vectorb, monitor);
if (!monitor.HasConverged)
{
@ -310,8 +310,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.Iterat
new IterationCountStopCriterium<Complex32>(1000),
new ResidualStopCriterium((float) Math.Pow(1.0/10.0, iteration))
});
var solver = new BiCgStab(monitor);
var matrixX = solver.Solve(matrixA, matrixB);
var solver = new BiCgStab();
var matrixX = solver.Solve(matrixA, matrixB, monitor);
if (!monitor.HasConverged)
{

16
src/UnitTests/LinearAlgebraTests/Complex32/Solvers/Iterative/GpBiCgTest.cs

@ -101,10 +101,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.Iterat
new DivergenceStopCriterium(),
new FailureStopCriterium()
});
var solver = new GpBiCg(monitor);
var solver = new GpBiCg();
// Solve equation Ax = y
var x = solver.Solve(matrix, y);
var x = solver.Solve(matrix, y, monitor);
// Now compare the results
Assert.IsNotNull(x, "#02");
@ -147,10 +147,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.Iterat
new FailureStopCriterium()
});
var solver = new GpBiCg(monitor);
var solver = new GpBiCg();
// Solve equation Ax = y
var x = solver.Solve(matrix, y);
var x = solver.Solve(matrix, y, monitor);
// Now compare the results
Assert.IsNotNull(x, "#02");
@ -226,10 +226,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.Iterat
new FailureStopCriterium()
});
var solver = new GpBiCg(monitor);
var solver = new GpBiCg();
// Solve equation Ax = y
var x = solver.Solve(matrix, y);
var x = solver.Solve(matrix, y, monitor);
// Now compare the results
Assert.IsNotNull(x, "#02");
@ -265,9 +265,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.Iterat
new IterationCountStopCriterium<Complex32>(1000),
new ResidualStopCriterium((float) Math.Pow(1.0/10.0, iteration)),
});
var solver = new GpBiCg(monitor);
var solver = new GpBiCg();
var resultx = solver.Solve(matrixA, vectorb);
var resultx = solver.Solve(matrixA, vectorb, monitor);
if (!monitor.HasConverged)
{

20
src/UnitTests/LinearAlgebraTests/Complex32/Solvers/Iterative/MlkBiCgStabTest.cs

@ -102,10 +102,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.Iterat
new FailureStopCriterium()
});
var solver = new MlkBiCgStab(monitor);
var solver = new MlkBiCgStab();
// Solve equation Ax = y
var x = solver.Solve(matrix, y);
var x = solver.Solve(matrix, y, monitor);
// Now compare the results
Assert.IsNotNull(x, "#02");
@ -147,10 +147,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.Iterat
new DivergenceStopCriterium(),
new FailureStopCriterium()
});
var solver = new MlkBiCgStab(monitor);
var solver = new MlkBiCgStab();
// Solve equation Ax = y
var x = solver.Solve(matrix, y);
var x = solver.Solve(matrix, y, monitor);
// Now compare the results
Assert.IsNotNull(x, "#02");
@ -225,10 +225,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.Iterat
new DivergenceStopCriterium(),
new FailureStopCriterium()
});
var solver = new MlkBiCgStab(monitor);
var solver = new MlkBiCgStab();
// Solve equation Ax = y
var x = solver.Solve(matrix, y);
var x = solver.Solve(matrix, y, monitor);
// Now compare the results
Assert.IsNotNull(x, "#02");
@ -264,9 +264,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.Iterat
new IterationCountStopCriterium<Complex32>(1000),
new ResidualStopCriterium((float) Math.Pow(1.0/10.0, iteration))
});
var solver = new MlkBiCgStab(monitor);
var solver = new MlkBiCgStab();
var resultx = solver.Solve(matrixA, vectorb);
var resultx = solver.Solve(matrixA, vectorb, monitor);
if (!monitor.HasConverged)
{
@ -307,8 +307,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.Iterat
new IterationCountStopCriterium<Complex32>(1000),
new ResidualStopCriterium((float) Math.Pow(1.0/10.0, iteration))
});
var solver = new MlkBiCgStab(monitor);
var matrixX = solver.Solve(matrixA, matrixB);
var solver = new MlkBiCgStab();
var matrixX = solver.Solve(matrixA, matrixB, monitor);
if (!monitor.HasConverged)
{

20
src/UnitTests/LinearAlgebraTests/Complex32/Solvers/Iterative/TFQMRTest.cs

@ -102,10 +102,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.Iterat
new FailureStopCriterium()
});
var solver = new TFQMR(monitor);
var solver = new TFQMR();
// Solve equation Ax = y
var x = solver.Solve(matrix, y);
var x = solver.Solve(matrix, y, monitor);
// Now compare the results
Assert.IsNotNull(x, "#02");
@ -147,10 +147,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.Iterat
new DivergenceStopCriterium(),
new FailureStopCriterium()
});
var solver = new TFQMR(monitor);
var solver = new TFQMR();
// Solve equation Ax = y
var x = solver.Solve(matrix, y);
var x = solver.Solve(matrix, y, monitor);
// Now compare the results
Assert.IsNotNull(x, "#02");
@ -225,10 +225,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.Iterat
new DivergenceStopCriterium(),
new FailureStopCriterium()
});
var solver = new TFQMR(monitor);
var solver = new TFQMR();
// Solve equation Ax = y
var x = solver.Solve(matrix, y);
var x = solver.Solve(matrix, y, monitor);
// Now compare the results
Assert.IsNotNull(x, "#02");
@ -264,9 +264,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.Iterat
new IterationCountStopCriterium<Complex32>(1000),
new ResidualStopCriterium((float) Math.Pow(1.0/10.0, iteration))
});
var solver = new TFQMR(monitor);
var solver = new TFQMR();
var resultx = solver.Solve(matrixA, vectorb);
var resultx = solver.Solve(matrixA, vectorb, monitor);
if (!monitor.HasConverged)
{
@ -307,8 +307,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.Iterat
new IterationCountStopCriterium<Complex32>(1000),
new ResidualStopCriterium((float) Math.Pow(1.0/10.0, iteration))
});
var solver = new TFQMR(monitor);
var matrixX = solver.Solve(matrixA, matrixB);
var solver = new TFQMR();
var matrixX = solver.Solve(matrixA, matrixB, monitor);
if (!monitor.HasConverged)
{

20
src/UnitTests/LinearAlgebraTests/Double/Solvers/Iterative/BiCgStabTest.cs

@ -99,10 +99,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
new DivergenceStopCriterium(),
new FailureStopCriterium()
});
var solver = new BiCgStab(monitor);
var solver = new BiCgStab();
// Solve equation Ax = y
var x = solver.Solve(matrix, y);
var x = solver.Solve(matrix, y, monitor);
// Now compare the results
Assert.IsNotNull(x, "#02");
@ -144,10 +144,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
new DivergenceStopCriterium(),
new FailureStopCriterium()
});
var solver = new BiCgStab(monitor);
var solver = new BiCgStab();
// Solve equation Ax = y
var x = solver.Solve(matrix, y);
var x = solver.Solve(matrix, y, monitor);
// Now compare the results
Assert.IsNotNull(x, "#02");
@ -222,10 +222,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
new DivergenceStopCriterium(),
new FailureStopCriterium()
});
var solver = new BiCgStab(monitor);
var solver = new BiCgStab();
// Solve equation Ax = y
var x = solver.Solve(matrix, y);
var x = solver.Solve(matrix, y, monitor);
// Now compare the results
Assert.IsNotNull(x, "#02");
@ -265,9 +265,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
new IterationCountStopCriterium<double>(1000),
new ResidualStopCriterium(1e-10),
});
var solver = new BiCgStab(monitor);
var solver = new BiCgStab();
var resultx = solver.Solve(matrixA, vectorb);
var resultx = solver.Solve(matrixA, vectorb, monitor);
Assert.AreEqual(matrixA.ColumnCount, resultx.Count);
var matrixBReconstruct = matrixA*resultx;
@ -296,8 +296,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
new IterationCountStopCriterium<double>(1000),
new ResidualStopCriterium(1e-10)
});
var solver = new BiCgStab(monitor);
var matrixX = solver.Solve(matrixA, matrixB);
var solver = new BiCgStab();
var matrixX = solver.Solve(matrixA, matrixB, monitor);
// The solution X row dimension is equal to the column dimension of A
Assert.AreEqual(matrixA.ColumnCount, matrixX.RowCount);

20
src/UnitTests/LinearAlgebraTests/Double/Solvers/Iterative/GpBiCgTest.cs

@ -99,10 +99,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
new DivergenceStopCriterium(),
new FailureStopCriterium()
});
var solver = new GpBiCg(monitor);
var solver = new GpBiCg();
// Solve equation Ax = y
var x = solver.Solve(matrix, y);
var x = solver.Solve(matrix, y, monitor);
// Now compare the results
Assert.IsNotNull(x, "#02");
@ -145,10 +145,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
new FailureStopCriterium()
});
var solver = new GpBiCg(monitor);
var solver = new GpBiCg();
// Solve equation Ax = y
var x = solver.Solve(matrix, y);
var x = solver.Solve(matrix, y, monitor);
// Now compare the results
Assert.IsNotNull(x, "#02");
@ -224,10 +224,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
new FailureStopCriterium()
});
var solver = new GpBiCg(monitor);
var solver = new GpBiCg();
// Solve equation Ax = y
var x = solver.Solve(matrix, y);
var x = solver.Solve(matrix, y, monitor);
// Now compare the results
Assert.IsNotNull(x, "#02");
@ -267,9 +267,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
new IterationCountStopCriterium<double>(1000),
new ResidualStopCriterium(1e-10),
});
var solver = new GpBiCg(monitor);
var solver = new GpBiCg();
var resultx = solver.Solve(matrixA, vectorb);
var resultx = solver.Solve(matrixA, vectorb, monitor);
Assert.AreEqual(matrixA.ColumnCount, resultx.Count);
var matrixBReconstruct = matrixA*resultx;
@ -298,8 +298,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
new IterationCountStopCriterium<double>(1000),
new ResidualStopCriterium(1e-10)
});
var solver = new GpBiCg(monitor);
var matrixX = solver.Solve(matrixA, matrixB);
var solver = new GpBiCg();
var matrixX = solver.Solve(matrixA, matrixB, monitor);
// The solution X row dimension is equal to the column dimension of A
Assert.AreEqual(matrixA.ColumnCount, matrixX.RowCount);

20
src/UnitTests/LinearAlgebraTests/Double/Solvers/Iterative/MlkBiCgStabTest.cs

@ -100,10 +100,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
new FailureStopCriterium()
});
var solver = new MlkBiCgStab(monitor);
var solver = new MlkBiCgStab();
// Solve equation Ax = y
var x = solver.Solve(matrix, y);
var x = solver.Solve(matrix, y, monitor);
// Now compare the results
Assert.IsNotNull(x, "#02");
@ -145,10 +145,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
new DivergenceStopCriterium(),
new FailureStopCriterium()
});
var solver = new MlkBiCgStab(monitor);
var solver = new MlkBiCgStab();
// Solve equation Ax = y
var x = solver.Solve(matrix, y);
var x = solver.Solve(matrix, y, monitor);
// Now compare the results
Assert.IsNotNull(x, "#02");
@ -223,10 +223,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
new DivergenceStopCriterium(),
new FailureStopCriterium()
});
var solver = new MlkBiCgStab(monitor);
var solver = new MlkBiCgStab();
// Solve equation Ax = y
var x = solver.Solve(matrix, y);
var x = solver.Solve(matrix, y, monitor);
// Now compare the results
Assert.IsNotNull(x, "#02");
@ -266,9 +266,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
new IterationCountStopCriterium<double>(1000),
new ResidualStopCriterium(1e-10),
});
var solver = new MlkBiCgStab(monitor);
var solver = new MlkBiCgStab();
var resultx = solver.Solve(matrixA, vectorb);
var resultx = solver.Solve(matrixA, vectorb, monitor);
Assert.AreEqual(matrixA.ColumnCount, resultx.Count);
var matrixBReconstruct = matrixA*resultx;
@ -297,8 +297,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
new IterationCountStopCriterium<double>(1000),
new ResidualStopCriterium(1e-10)
});
var solver = new MlkBiCgStab(monitor);
var matrixX = solver.Solve(matrixA, matrixB);
var solver = new MlkBiCgStab();
var matrixX = solver.Solve(matrixA, matrixB, monitor);
// The solution X row dimension is equal to the column dimension of A
Assert.AreEqual(matrixA.ColumnCount, matrixX.RowCount);

20
src/UnitTests/LinearAlgebraTests/Double/Solvers/Iterative/TFQMRTest.cs

@ -100,10 +100,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
new FailureStopCriterium()
});
var solver = new TFQMR(monitor);
var solver = new TFQMR();
// Solve equation Ax = y
var x = solver.Solve(matrix, y);
var x = solver.Solve(matrix, y, monitor);
// Now compare the results
Assert.IsNotNull(x, "#02");
@ -145,10 +145,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
new DivergenceStopCriterium(),
new FailureStopCriterium()
});
var solver = new TFQMR(monitor);
var solver = new TFQMR();
// Solve equation Ax = y
var x = solver.Solve(matrix, y);
var x = solver.Solve(matrix, y, monitor);
// Now compare the results
Assert.IsNotNull(x, "#02");
@ -223,10 +223,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
new DivergenceStopCriterium(),
new FailureStopCriterium()
});
var solver = new TFQMR(monitor);
var solver = new TFQMR();
// Solve equation Ax = y
var x = solver.Solve(matrix, y);
var x = solver.Solve(matrix, y, monitor);
// Now compare the results
Assert.IsNotNull(x, "#02");
@ -262,9 +262,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
new IterationCountStopCriterium<double>(1000),
new ResidualStopCriterium(1e-10),
});
var solver = new TFQMR(monitor);
var solver = new TFQMR();
var resultx = solver.Solve(matrixA, vectorb);
var resultx = solver.Solve(matrixA, vectorb, monitor);
Assert.AreEqual(matrixA.ColumnCount, resultx.Count);
var matrixBReconstruct = matrixA*resultx;
@ -293,8 +293,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
new IterationCountStopCriterium<double>(1000),
new ResidualStopCriterium(1e-10)
});
var solver = new TFQMR(monitor);
var matrixX = solver.Solve(matrixA, matrixB);
var solver = new TFQMR();
var matrixX = solver.Solve(matrixA, matrixB, monitor);
// The solution X row dimension is equal to the column dimension of A
Assert.AreEqual(matrixA.ColumnCount, matrixX.RowCount);

20
src/UnitTests/LinearAlgebraTests/Single/Solvers/Iterative/BiCgStabTest.cs

@ -99,10 +99,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.Iterative
new DivergenceStopCriterium(),
new FailureStopCriterium()
});
var solver = new BiCgStab(monitor);
var solver = new BiCgStab();
// Solve equation Ax = y
var x = solver.Solve(matrix, y);
var x = solver.Solve(matrix, y, monitor);
// Now compare the results
Assert.IsNotNull(x, "#02");
@ -144,10 +144,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.Iterative
new DivergenceStopCriterium(),
new FailureStopCriterium()
});
var solver = new BiCgStab(monitor);
var solver = new BiCgStab();
// Solve equation Ax = y
var x = solver.Solve(matrix, y);
var x = solver.Solve(matrix, y, monitor);
// Now compare the results
Assert.IsNotNull(x, "#02");
@ -222,10 +222,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.Iterative
new DivergenceStopCriterium(),
new FailureStopCriterium()
});
var solver = new BiCgStab(monitor);
var solver = new BiCgStab();
// Solve equation Ax = y
var x = solver.Solve(matrix, y);
var x = solver.Solve(matrix, y, monitor);
// Now compare the results
Assert.IsNotNull(x, "#02");
@ -263,8 +263,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.Iterative
new IterationCountStopCriterium<float>(MaximumIterations),
new ResidualStopCriterium((float) Math.Pow(1.0/10.0, iteration))
});
var solver = new BiCgStab(monitor);
var resultx = solver.Solve(matrixA, vectorb);
var solver = new BiCgStab();
var resultx = solver.Solve(matrixA, vectorb, monitor);
if (!monitor.HasConverged)
{
@ -304,8 +304,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.Iterative
new IterationCountStopCriterium<float>(MaximumIterations),
new ResidualStopCriterium((float) Math.Pow(1.0/10.0, iteration))
});
var solver = new BiCgStab(monitor);
var matrixX = solver.Solve(matrixA, matrixB);
var solver = new BiCgStab();
var matrixX = solver.Solve(matrixA, matrixB, monitor);
if (!monitor.HasConverged)
{

20
src/UnitTests/LinearAlgebraTests/Single/Solvers/Iterative/GpBiCgTest.cs

@ -99,10 +99,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.Iterative
new DivergenceStopCriterium(),
new FailureStopCriterium()
});
var solver = new GpBiCg(monitor);
var solver = new GpBiCg();
// Solve equation Ax = y
var x = solver.Solve(matrix, y);
var x = solver.Solve(matrix, y, monitor);
// Now compare the results
Assert.IsNotNull(x, "#02");
@ -145,10 +145,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.Iterative
new FailureStopCriterium()
});
var solver = new GpBiCg(monitor);
var solver = new GpBiCg();
// Solve equation Ax = y
var x = solver.Solve(matrix, y);
var x = solver.Solve(matrix, y, monitor);
// Now compare the results
Assert.IsNotNull(x, "#02");
@ -224,10 +224,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.Iterative
new FailureStopCriterium()
});
var solver = new GpBiCg(monitor);
var solver = new GpBiCg();
// Solve equation Ax = y
var x = solver.Solve(matrix, y);
var x = solver.Solve(matrix, y, monitor);
// Now compare the results
Assert.IsNotNull(x, "#02");
@ -265,8 +265,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.Iterative
new IterationCountStopCriterium<float>(MaximumIterations),
new ResidualStopCriterium((float) Math.Pow(1.0/10.0, iteration))
});
var solver = new GpBiCg(monitor);
var resultx = solver.Solve(matrixA, vectorb);
var solver = new GpBiCg();
var resultx = solver.Solve(matrixA, vectorb, monitor);
if (!monitor.HasConverged)
{
@ -306,8 +306,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.Iterative
new IterationCountStopCriterium<float>(MaximumIterations),
new ResidualStopCriterium((float) Math.Pow(1.0/10.0, iteration))
});
var solver = new GpBiCg(monitor);
var matrixX = solver.Solve(matrixA, matrixB);
var solver = new GpBiCg();
var matrixX = solver.Solve(matrixA, matrixB, monitor);
if (!monitor.HasConverged)
{

20
src/UnitTests/LinearAlgebraTests/Single/Solvers/Iterative/MlkBiCgStabTest.cs

@ -101,10 +101,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.Iterative
new FailureStopCriterium()
});
var solver = new MlkBiCgStab(monitor);
var solver = new MlkBiCgStab();
// Solve equation Ax = y
var x = solver.Solve(matrix, y);
var x = solver.Solve(matrix, y, monitor);
// Now compare the results
Assert.IsNotNull(x, "#02");
@ -146,10 +146,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.Iterative
new DivergenceStopCriterium(),
new FailureStopCriterium()
});
var solver = new MlkBiCgStab(monitor);
var solver = new MlkBiCgStab();
// Solve equation Ax = y
var x = solver.Solve(matrix, y);
var x = solver.Solve(matrix, y, monitor);
// Now compare the results
Assert.IsNotNull(x, "#02");
@ -228,13 +228,13 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.Iterative
new DivergenceStopCriterium(),
new FailureStopCriterium()
});
var solver = new MlkBiCgStab(monitor);
var solver = new MlkBiCgStab();
// Solve equation Ax = y
Vector<float> x;
try
{
x = solver.Solve(matrix, y);
x = solver.Solve(matrix, y, monitor);
}
catch (Exception)
{
@ -282,8 +282,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.Iterative
new IterationCountStopCriterium<float>(MaximumIterations),
new ResidualStopCriterium((float) Math.Pow(1.0/10.0, iteration))
});
var solver = new MlkBiCgStab(monitor);
var resultx = solver.Solve(matrixA, vectorb);
var solver = new MlkBiCgStab();
var resultx = solver.Solve(matrixA, vectorb, monitor);
if (!monitor.HasConverged)
{
@ -325,8 +325,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.Iterative
new IterationCountStopCriterium<float>(MaximumIterations),
new ResidualStopCriterium((float) Math.Pow(1.0/10.0, iteration))
});
var solver = new MlkBiCgStab(monitor);
var matrixX = solver.Solve(matrixA, matrixB);
var solver = new MlkBiCgStab();
var matrixX = solver.Solve(matrixA, matrixB, monitor);
if (!monitor.HasConverged)
{

20
src/UnitTests/LinearAlgebraTests/Single/Solvers/Iterative/TFQMRTest.cs

@ -100,10 +100,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.Iterative
new FailureStopCriterium()
});
var solver = new TFQMR(monitor);
var solver = new TFQMR();
// Solve equation Ax = y
var x = solver.Solve(matrix, y);
var x = solver.Solve(matrix, y, monitor);
// Now compare the results
Assert.IsNotNull(x, "#02");
@ -145,10 +145,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.Iterative
new DivergenceStopCriterium(),
new FailureStopCriterium()
});
var solver = new TFQMR(monitor);
var solver = new TFQMR();
// Solve equation Ax = y
var x = solver.Solve(matrix, y);
var x = solver.Solve(matrix, y, monitor);
// Now compare the results
Assert.IsNotNull(x, "#02");
@ -223,10 +223,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.Iterative
new DivergenceStopCriterium(),
new FailureStopCriterium()
});
var solver = new TFQMR(monitor);
var solver = new TFQMR();
// Solve equation Ax = y
var x = solver.Solve(matrix, y);
var x = solver.Solve(matrix, y, monitor);
// Now compare the results
Assert.IsNotNull(x, "#02");
@ -264,8 +264,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.Iterative
new IterationCountStopCriterium<float>(MaximumIterations),
new ResidualStopCriterium((float) Math.Pow(1.0/10.0, iteration))
});
var solver = new TFQMR(monitor);
var resultx = solver.Solve(matrixA, vectorb);
var solver = new TFQMR();
var resultx = solver.Solve(matrixA, vectorb, monitor);
if (!monitor.HasConverged)
{
@ -305,8 +305,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Solvers.Iterative
new IterationCountStopCriterium<float>(MaximumIterations),
new ResidualStopCriterium((float) Math.Pow(1.0/10.0, iteration))
});
var solver = new TFQMR(monitor);
var matrixX = solver.Solve(matrixA, matrixB);
var solver = new TFQMR();
var matrixX = solver.Solve(matrixA, matrixB, monitor);
if (!monitor.HasConverged)
{

Loading…
Cancel
Save