Browse Source

iterative solvers: cleaned up api

la-knuth
Marcus Cuda 16 years ago
parent
commit
c3dd1b7d3f
  1. 3
      src/Examples/LinearAlgebra/IterativeSolvers/BiCgStabSolver.cs
  2. 12
      src/Examples/LinearAlgebra/IterativeSolvers/CompositeSolverExample.cs
  3. 3
      src/Examples/LinearAlgebra/IterativeSolvers/GpBiCgSolver.cs
  4. 3
      src/Examples/LinearAlgebra/IterativeSolvers/MlkBiCgStabSolver.cs
  5. 3
      src/Examples/LinearAlgebra/IterativeSolvers/TFQMRSolver.cs
  6. 9
      src/MathNet.Numerics.5.1.ReSharper
  7. 23
      src/Numerics/LinearAlgebra/Complex/Solvers/IIterativeSolver.cs
  8. 10
      src/Numerics/LinearAlgebra/Complex/Solvers/IIterativeSolverSetup.cs
  9. 33
      src/Numerics/LinearAlgebra/Complex/Solvers/IIterator.cs
  10. 116
      src/Numerics/LinearAlgebra/Complex/Solvers/Iterative/BiCgStab.cs
  11. 72
      src/Numerics/LinearAlgebra/Complex/Solvers/Iterative/CompositeSolver.cs
  12. 107
      src/Numerics/LinearAlgebra/Complex/Solvers/Iterative/GpBiCg.cs
  13. 114
      src/Numerics/LinearAlgebra/Complex/Solvers/Iterative/MlkBiCgStab.cs
  14. 77
      src/Numerics/LinearAlgebra/Complex/Solvers/Iterative/TFQMR.cs
  15. 40
      src/Numerics/LinearAlgebra/Complex/Solvers/Iterator.cs
  16. 14
      src/Numerics/LinearAlgebra/Complex/Solvers/Preconditioners/Diagonal.cs
  17. 14
      src/Numerics/LinearAlgebra/Complex/Solvers/Preconditioners/IPreConditioner.cs
  18. 52
      src/Numerics/LinearAlgebra/Complex/Solvers/Preconditioners/Ilutp.cs
  19. 18
      src/Numerics/LinearAlgebra/Complex/Solvers/Preconditioners/IlutpElementSorter.cs
  20. 18
      src/Numerics/LinearAlgebra/Complex/Solvers/Preconditioners/IncompleteLU.cs
  21. 16
      src/Numerics/LinearAlgebra/Complex/Solvers/Preconditioners/UnitPreconditioner.cs
  22. 16
      src/Numerics/LinearAlgebra/Complex/Solvers/StopCriterium/DivergenceStopCriterium.cs
  23. 16
      src/Numerics/LinearAlgebra/Complex/Solvers/StopCriterium/FailureStopCriterium.cs
  24. 24
      src/Numerics/LinearAlgebra/Complex/Solvers/StopCriterium/IIterationStopCriterium.cs
  25. 10
      src/Numerics/LinearAlgebra/Complex/Solvers/StopCriterium/IterationCountStopCriterium.cs
  26. 16
      src/Numerics/LinearAlgebra/Complex/Solvers/StopCriterium/ResidualStopCriterium.cs
  27. 96
      src/Numerics/LinearAlgebra/Complex32/Solvers/IIterativeSolver.cs
  28. 71
      src/Numerics/LinearAlgebra/Complex32/Solvers/IIterativeSolverSetup.cs
  29. 108
      src/Numerics/LinearAlgebra/Complex32/Solvers/IIterator.cs
  30. 117
      src/Numerics/LinearAlgebra/Complex32/Solvers/Iterative/BiCgStab.cs
  31. 75
      src/Numerics/LinearAlgebra/Complex32/Solvers/Iterative/CompositeSolver.cs
  32. 107
      src/Numerics/LinearAlgebra/Complex32/Solvers/Iterative/GpBiCg.cs
  33. 117
      src/Numerics/LinearAlgebra/Complex32/Solvers/Iterative/MlkBiCgStab.cs
  34. 77
      src/Numerics/LinearAlgebra/Complex32/Solvers/Iterative/TFQMR.cs
  35. 40
      src/Numerics/LinearAlgebra/Complex32/Solvers/Iterator.cs
  36. 14
      src/Numerics/LinearAlgebra/Complex32/Solvers/Preconditioners/Diagonal.cs
  37. 73
      src/Numerics/LinearAlgebra/Complex32/Solvers/Preconditioners/IPreConditioner.cs
  38. 52
      src/Numerics/LinearAlgebra/Complex32/Solvers/Preconditioners/Ilutp.cs
  39. 37
      src/Numerics/LinearAlgebra/Complex32/Solvers/Preconditioners/IlutpElementSorter.cs
  40. 18
      src/Numerics/LinearAlgebra/Complex32/Solvers/Preconditioners/IncompleteLU.cs
  41. 16
      src/Numerics/LinearAlgebra/Complex32/Solvers/Preconditioners/UnitPreconditioner.cs
  42. 16
      src/Numerics/LinearAlgebra/Complex32/Solvers/StopCriterium/DivergenceStopCriterium.cs
  43. 16
      src/Numerics/LinearAlgebra/Complex32/Solvers/StopCriterium/FailureStopCriterium.cs
  44. 80
      src/Numerics/LinearAlgebra/Complex32/Solvers/StopCriterium/IIterationStopCriterium.cs
  45. 10
      src/Numerics/LinearAlgebra/Complex32/Solvers/StopCriterium/IterationCountStopCriterium.cs
  46. 16
      src/Numerics/LinearAlgebra/Complex32/Solvers/StopCriterium/ResidualStopCriterium.cs
  47. 96
      src/Numerics/LinearAlgebra/Double/Solvers/IIterativeSolver.cs
  48. 71
      src/Numerics/LinearAlgebra/Double/Solvers/IIterativeSolverSetup.cs
  49. 108
      src/Numerics/LinearAlgebra/Double/Solvers/IIterator.cs
  50. 119
      src/Numerics/LinearAlgebra/Double/Solvers/Iterative/BiCgStab.cs
  51. 80
      src/Numerics/LinearAlgebra/Double/Solvers/Iterative/CompositeSolver.cs
  52. 105
      src/Numerics/LinearAlgebra/Double/Solvers/Iterative/GpBiCg.cs
  53. 112
      src/Numerics/LinearAlgebra/Double/Solvers/Iterative/MlkBiCgStab.cs
  54. 77
      src/Numerics/LinearAlgebra/Double/Solvers/Iterative/TFQMR.cs
  55. 43
      src/Numerics/LinearAlgebra/Double/Solvers/Iterator.cs
  56. 14
      src/Numerics/LinearAlgebra/Double/Solvers/Preconditioners/Diagonal.cs
  57. 73
      src/Numerics/LinearAlgebra/Double/Solvers/Preconditioners/IPreConditioner.cs
  58. 52
      src/Numerics/LinearAlgebra/Double/Solvers/Preconditioners/Ilutp.cs
  59. 36
      src/Numerics/LinearAlgebra/Double/Solvers/Preconditioners/IlutpElementSorter.cs
  60. 18
      src/Numerics/LinearAlgebra/Double/Solvers/Preconditioners/IncompleteLU.cs
  61. 15
      src/Numerics/LinearAlgebra/Double/Solvers/Preconditioners/UnitPreconditioner.cs
  62. 15
      src/Numerics/LinearAlgebra/Double/Solvers/StopCriterium/DivergenceStopCriterium.cs
  63. 15
      src/Numerics/LinearAlgebra/Double/Solvers/StopCriterium/FailureStopCriterium.cs
  64. 80
      src/Numerics/LinearAlgebra/Double/Solvers/StopCriterium/IIterationStopCriterium.cs
  65. 9
      src/Numerics/LinearAlgebra/Double/Solvers/StopCriterium/IterationCountStopCriterium.cs
  66. 15
      src/Numerics/LinearAlgebra/Double/Solvers/StopCriterium/ResidualStopCriterium.cs
  67. 11
      src/Numerics/LinearAlgebra/Generic/Solvers/StopCriterium/StopLevel.cs
  68. 96
      src/Numerics/LinearAlgebra/Single/Solvers/IIterativeSolver.cs
  69. 71
      src/Numerics/LinearAlgebra/Single/Solvers/IIterativeSolverSetup.cs
  70. 108
      src/Numerics/LinearAlgebra/Single/Solvers/IIterator.cs
  71. 117
      src/Numerics/LinearAlgebra/Single/Solvers/Iterative/BiCgStab.cs
  72. 76
      src/Numerics/LinearAlgebra/Single/Solvers/Iterative/CompositeSolver.cs
  73. 107
      src/Numerics/LinearAlgebra/Single/Solvers/Iterative/GpBiCg.cs
  74. 119
      src/Numerics/LinearAlgebra/Single/Solvers/Iterative/MlkBiCgStab.cs
  75. 81
      src/Numerics/LinearAlgebra/Single/Solvers/Iterative/TFQMR.cs
  76. 41
      src/Numerics/LinearAlgebra/Single/Solvers/Iterator.cs
  77. 14
      src/Numerics/LinearAlgebra/Single/Solvers/Preconditioners/Diagonal.cs
  78. 73
      src/Numerics/LinearAlgebra/Single/Solvers/Preconditioners/IPreConditioner.cs
  79. 52
      src/Numerics/LinearAlgebra/Single/Solvers/Preconditioners/Ilutp.cs
  80. 36
      src/Numerics/LinearAlgebra/Single/Solvers/Preconditioners/IlutpElementSorter.cs
  81. 18
      src/Numerics/LinearAlgebra/Single/Solvers/Preconditioners/IncompleteLU.cs
  82. 15
      src/Numerics/LinearAlgebra/Single/Solvers/Preconditioners/UnitPreconditioner.cs
  83. 15
      src/Numerics/LinearAlgebra/Single/Solvers/StopCriterium/DivergenceStopCriterium.cs
  84. 15
      src/Numerics/LinearAlgebra/Single/Solvers/StopCriterium/FailureStopCriterium.cs
  85. 80
      src/Numerics/LinearAlgebra/Single/Solvers/StopCriterium/IIterationStopCriterium.cs
  86. 9
      src/Numerics/LinearAlgebra/Single/Solvers/StopCriterium/IterationCountStopCriterium.cs
  87. 15
      src/Numerics/LinearAlgebra/Single/Solvers/StopCriterium/ResidualStopCriterium.cs
  88. 25
      src/Numerics/Numerics.csproj
  89. 75
      src/Silverlight/Silverlight.csproj
  90. 33
      src/UnitTests/LinearAlgebraTests/Complex/Solvers/Iterative/BiCgStabTest.cs
  91. 32
      src/UnitTests/LinearAlgebraTests/Complex/Solvers/Iterative/GpBiCgTest.cs
  92. 32
      src/UnitTests/LinearAlgebraTests/Complex/Solvers/Iterative/MlkBiCgStabTest.cs
  93. 35
      src/UnitTests/LinearAlgebraTests/Complex/Solvers/Iterative/TFQMRTest.cs
  94. 30
      src/UnitTests/LinearAlgebraTests/Complex/Solvers/IteratorTest.cs
  95. 9
      src/UnitTests/LinearAlgebraTests/Complex/Solvers/Preconditioners/DiagonalTest.cs
  96. 15
      src/UnitTests/LinearAlgebraTests/Complex/Solvers/Preconditioners/IlutpTest.cs
  97. 17
      src/UnitTests/LinearAlgebraTests/Complex/Solvers/Preconditioners/IncompleteLUTest.cs
  98. 18
      src/UnitTests/LinearAlgebraTests/Complex/Solvers/Preconditioners/PreConditionerTest.cs
  99. 7
      src/UnitTests/LinearAlgebraTests/Complex/Solvers/Preconditioners/UnitPreconditionerTest.cs
  100. 32
      src/UnitTests/LinearAlgebraTests/Complex32/Solvers/Iterative/BiCgStabTest.cs

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

@ -32,7 +32,6 @@ namespace Examples.LinearAlgebra.IterativeSolvers
using MathNet.Numerics.LinearAlgebra.Double.Solvers; using MathNet.Numerics.LinearAlgebra.Double.Solvers;
using MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative; using MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative;
using MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium; using MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium;
using MathNet.Numerics.LinearAlgebra.Generic.Solvers.StopCriterium;
/// <summary> /// <summary>
/// BiCGStab Iterative solver /// BiCGStab Iterative solver
@ -102,7 +101,7 @@ namespace Examples.LinearAlgebra.IterativeSolvers
var residualStopCriterium = new ResidualStopCriterium(1e-10); var residualStopCriterium = new ResidualStopCriterium(1e-10);
// Create monitor with defined stop criteriums // Create monitor with defined stop criteriums
var monitor = new Iterator(new IIterationStopCriterium<double>[] { iterationCountStopCriterium, residualStopCriterium }); var monitor = new Iterator(new IIterationStopCriterium[] { iterationCountStopCriterium, residualStopCriterium });
// Create Bi-Conjugate Gradient Stabilized solver // Create Bi-Conjugate Gradient Stabilized solver
var solver = new BiCgStab(monitor); var solver = new BiCgStab(monitor);

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

@ -33,11 +33,9 @@ namespace Examples.LinearAlgebra.IterativeSolvers
using MathNet.Numerics.LinearAlgebra.Double.Solvers; using MathNet.Numerics.LinearAlgebra.Double.Solvers;
using MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative; using MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative;
using MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium; using MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium;
using MathNet.Numerics.LinearAlgebra.Generic.Solvers;
using MathNet.Numerics.LinearAlgebra.Generic.Solvers.StopCriterium;
/// <summary> /// <summary>
/// Сomposite matrix solver /// Composite matrix solver
/// </summary> /// </summary>
public class CompositeSolverExample : IExample public class CompositeSolverExample : IExample
{ {
@ -102,7 +100,7 @@ namespace Examples.LinearAlgebra.IterativeSolvers
var residualStopCriterium = new ResidualStopCriterium(1e-10); var residualStopCriterium = new ResidualStopCriterium(1e-10);
// Create monitor with defined stop criteriums // Create monitor with defined stop criteriums
var monitor = new Iterator(new IIterationStopCriterium<double>[] { iterationCountStopCriterium, residualStopCriterium }); var monitor = new Iterator(new IIterationStopCriterium[] { iterationCountStopCriterium, residualStopCriterium });
// Load all suitable solvers from current assembly. Below in this example, there is user-defined solver // Load all suitable solvers from current assembly. Below in this example, there is user-defined solver
// "class UserBiCgStab : IIterativeSolverSetup<double>" which uses regular BiCgStab solver. But user may create any other solver // "class UserBiCgStab : IIterativeSolverSetup<double>" which uses regular BiCgStab solver. But user may create any other solver
@ -147,7 +145,7 @@ namespace Examples.LinearAlgebra.IterativeSolvers
/// <summary> /// <summary>
/// Sample of user-defined solver setup /// Sample of user-defined solver setup
/// </summary> /// </summary>
public class UserBiCgStab : IIterativeSolverSetup<double> public class UserBiCgStab : IIterativeSolverSetup
{ {
/// <summary> /// <summary>
/// Gets the type of the solver that will be created by this setup object. /// Gets the type of the solver that will be created by this setup object.
@ -175,8 +173,8 @@ namespace Examples.LinearAlgebra.IterativeSolvers
/// Creates a fully functional iterative solver with the default settings /// Creates a fully functional iterative solver with the default settings
/// given by this setup. /// given by this setup.
/// </summary> /// </summary>
/// <returns>A new <see cref="IIterativeSolver{T}"/>.</returns> /// <returns>A new <see cref="IIterativeSolver"/>.</returns>
public IIterativeSolver<double> CreateNew() public IIterativeSolver CreateNew()
{ {
return new BiCgStab(); return new BiCgStab();
} }

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

@ -32,7 +32,6 @@ namespace Examples.LinearAlgebra.IterativeSolvers
using MathNet.Numerics.LinearAlgebra.Double.Solvers; using MathNet.Numerics.LinearAlgebra.Double.Solvers;
using MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative; using MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative;
using MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium; using MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium;
using MathNet.Numerics.LinearAlgebra.Generic.Solvers.StopCriterium;
/// <summary> /// <summary>
/// GpBiCg Iterative solver /// GpBiCg Iterative solver
@ -100,7 +99,7 @@ namespace Examples.LinearAlgebra.IterativeSolvers
var residualStopCriterium = new ResidualStopCriterium(1e-10); var residualStopCriterium = new ResidualStopCriterium(1e-10);
// Create monitor with defined stop criteriums // Create monitor with defined stop criteriums
var monitor = new Iterator(new IIterationStopCriterium<double>[] { iterationCountStopCriterium, residualStopCriterium }); var monitor = new Iterator(new IIterationStopCriterium[] { iterationCountStopCriterium, residualStopCriterium });
// Create Generalized Product Bi-Conjugate Gradient solver // Create Generalized Product Bi-Conjugate Gradient solver
var solver = new GpBiCg(monitor); var solver = new GpBiCg(monitor);

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

@ -32,7 +32,6 @@ namespace Examples.LinearAlgebra.IterativeSolvers
using MathNet.Numerics.LinearAlgebra.Double.Solvers; using MathNet.Numerics.LinearAlgebra.Double.Solvers;
using MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative; using MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative;
using MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium; using MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium;
using MathNet.Numerics.LinearAlgebra.Generic.Solvers.StopCriterium;
/// <summary> /// <summary>
/// Multiple-Lanczos Bi-Conjugate Gradient stabilized Iterative solver /// Multiple-Lanczos Bi-Conjugate Gradient stabilized Iterative solver
@ -101,7 +100,7 @@ namespace Examples.LinearAlgebra.IterativeSolvers
var residualStopCriterium = new ResidualStopCriterium(1e-10); var residualStopCriterium = new ResidualStopCriterium(1e-10);
// Create monitor with defined stop criteriums // Create monitor with defined stop criteriums
var monitor = new Iterator(new IIterationStopCriterium<double>[] { iterationCountStopCriterium, residualStopCriterium }); var monitor = new Iterator(new IIterationStopCriterium[] { iterationCountStopCriterium, residualStopCriterium });
// Create Multiple-Lanczos Bi-Conjugate Gradient Stabilized solver // Create Multiple-Lanczos Bi-Conjugate Gradient Stabilized solver
var solver = new MlkBiCgStab(monitor); var solver = new MlkBiCgStab(monitor);

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

@ -32,7 +32,6 @@ namespace Examples.LinearAlgebra.IterativeSolvers
using MathNet.Numerics.LinearAlgebra.Double.Solvers; using MathNet.Numerics.LinearAlgebra.Double.Solvers;
using MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative; using MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative;
using MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium; using MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium;
using MathNet.Numerics.LinearAlgebra.Generic.Solvers.StopCriterium;
/// <summary> /// <summary>
/// Transpose Free Quasi-Minimal Residual iterative solver /// Transpose Free Quasi-Minimal Residual iterative solver
@ -101,7 +100,7 @@ namespace Examples.LinearAlgebra.IterativeSolvers
var residualStopCriterium = new ResidualStopCriterium(1e-10); var residualStopCriterium = new ResidualStopCriterium(1e-10);
// Create monitor with defined stop criteriums // Create monitor with defined stop criteriums
var monitor = new Iterator(new IIterationStopCriterium<double>[] { iterationCountStopCriterium, residualStopCriterium }); var monitor = new Iterator(new IIterationStopCriterium[] { iterationCountStopCriterium, residualStopCriterium });
// Create Transpose Free Quasi-Minimal Residual solver // Create Transpose Free Quasi-Minimal Residual solver
var solver = new TFQMR(monitor); var solver = new TFQMR(monitor);

9
src/MathNet.Numerics.5.1.ReSharper

@ -10,7 +10,12 @@
<CustomDictionary> <CustomDictionary>
<Name>en-US</Name> <Name>en-US</Name>
<CaseSensitive>false</CaseSensitive> <CaseSensitive>false</CaseSensitive>
<UserWords /> <UserWords>Criterium
cancelled
pre
preconditioner
Preconditioners
indetermined</UserWords>
</CustomDictionary> </CustomDictionary>
</Dictionaries> </Dictionaries>
</CustomDictionaries> </CustomDictionaries>
@ -238,7 +243,7 @@
<MustNotHaveSuffixes /> <MustNotHaveSuffixes />
</NamingConventionRule> </NamingConventionRule>
<NamingConventionRule> <NamingConventionRule>
<IsDisabled>false</IsDisabled> <IsDisabled>true</IsDisabled>
<Matches> <Matches>
<Match> <Match>
<AccessLevel>Any</AccessLevel> <AccessLevel>Any</AccessLevel>

23
src/Numerics/LinearAlgebra/Generic/Solvers/IIterativeSolver.cs → src/Numerics/LinearAlgebra/Complex/Solvers/IIterativeSolver.cs

@ -28,18 +28,15 @@
// OTHER DEALINGS IN THE SOFTWARE. // OTHER DEALINGS IN THE SOFTWARE.
// </copyright> // </copyright>
namespace MathNet.Numerics.LinearAlgebra.Generic.Solvers namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
{ {
using System; using Generic.Solvers.Status;
using System.Numerics;
using Status;
/// <summary> /// <summary>
/// Defines the interface for <see cref="IIterativeSolver{T}"/> classes that solve the matrix equation Ax = b in /// Defines the interface for <see cref="IIterativeSolver"/> classes that solve the matrix equation Ax = b in
/// an iterative manner. /// an iterative manner.
/// </summary> /// </summary>
/// <typeparam name="T">Supported data types are double, single, <see cref="Complex"/>, and <see cref="Complex32"/>.</typeparam> public interface IIterativeSolver
public interface IIterativeSolver<T> where T : struct, IEquatable<T>, IFormattable
{ {
/// <summary> /// <summary>
/// Stops the solve process. /// Stops the solve process.
@ -50,10 +47,10 @@ namespace MathNet.Numerics.LinearAlgebra.Generic.Solvers
void StopSolve(); void StopSolve();
/// <summary> /// <summary>
/// Sets the <see cref="IIterator{T}"/> that will be used to track the iterative process. /// Sets the <see cref="IIterator"/> that will be used to track the iterative process.
/// </summary> /// </summary>
/// <param name="iterator">The iterator.</param> /// <param name="iterator">The iterator.</param>
void SetIterator(IIterator<T> iterator); void SetIterator(IIterator iterator);
/// <summary> /// <summary>
/// Gets the status of the iteration once the calculation is finished. /// Gets the status of the iteration once the calculation is finished.
@ -67,7 +64,7 @@ namespace MathNet.Numerics.LinearAlgebra.Generic.Solvers
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param> /// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="vector">The solution vector, <c>b</c>.</param> /// <param name="vector">The solution vector, <c>b</c>.</param>
/// <returns>The result vector, <c>x</c>.</returns> /// <returns>The result vector, <c>x</c>.</returns>
Vector<T> Solve(Matrix<T> matrix, Vector<T> vector); Vector Solve(Matrix matrix, Vector vector);
/// <summary> /// <summary>
/// Solves the matrix equation Ax = b, where A is the coefficient matrix, b is the /// Solves the matrix equation Ax = b, where A is the coefficient matrix, b is the
@ -76,7 +73,7 @@ namespace MathNet.Numerics.LinearAlgebra.Generic.Solvers
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param> /// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution vector, <c>b</c></param> /// <param name="input">The solution vector, <c>b</c></param>
/// <param name="result">The result vector, <c>x</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 matrix, Vector input, Vector result);
/// <summary> /// <summary>
/// Solves the matrix equation AX = B, where A is the coefficient matrix, B is the /// Solves the matrix equation AX = B, where A is the coefficient matrix, B is the
@ -85,7 +82,7 @@ namespace MathNet.Numerics.LinearAlgebra.Generic.Solvers
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param> /// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution matrix, <c>B</c>.</param> /// <param name="input">The solution matrix, <c>B</c>.</param>
/// <returns>The result matrix, <c>X</c>.</returns> /// <returns>The result matrix, <c>X</c>.</returns>
Matrix<T> Solve(Matrix<T> matrix, Matrix<T> input); Matrix Solve(Matrix matrix, Matrix input);
/// <summary> /// <summary>
/// Solves the matrix equation AX = B, where A is the coefficient matrix, B is the /// Solves the matrix equation AX = B, where A is the coefficient matrix, B is the
@ -94,6 +91,6 @@ namespace MathNet.Numerics.LinearAlgebra.Generic.Solvers
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param> /// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution matrix, <c>B</c>.</param> /// <param name="input">The solution matrix, <c>B</c>.</param>
/// <param name="result">The result matrix, <c>X</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 matrix, Matrix input, Matrix result);
} }
} }

10
src/Numerics/LinearAlgebra/Generic/Solvers/IIterativeSolverSetup.cs → src/Numerics/LinearAlgebra/Complex/Solvers/IIterativeSolverSetup.cs

@ -28,18 +28,16 @@
// OTHER DEALINGS IN THE SOFTWARE. // OTHER DEALINGS IN THE SOFTWARE.
// </copyright> // </copyright>
namespace MathNet.Numerics.LinearAlgebra.Generic.Solvers namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
{ {
using System; using System;
using System.Numerics;
/// <summary> /// <summary>
/// Defines the interface for objects that can create an iterative solver with /// Defines the interface for objects that can create an iterative solver with
/// specific settings. This interface is used to pass iterative solver creation /// specific settings. This interface is used to pass iterative solver creation
/// setup information around. /// setup information around.
/// </summary> /// </summary>
/// <typeparam name="T">Supported data types are double, single, <see cref="Complex"/>, and <see cref="Complex32"/>.</typeparam> public interface IIterativeSolverSetup
public interface IIterativeSolverSetup<T> where T : struct, IEquatable<T>, IFormattable
{ {
/// <summary> /// <summary>
/// Gets the type of the solver that will be created by this setup object. /// Gets the type of the solver that will be created by this setup object.
@ -55,8 +53,8 @@ namespace MathNet.Numerics.LinearAlgebra.Generic.Solvers
/// Creates a fully functional iterative solver with the default settings /// Creates a fully functional iterative solver with the default settings
/// given by this setup. /// given by this setup.
/// </summary> /// </summary>
/// <returns>A new <see cref="IIterativeSolver{T}"/>.</returns> /// <returns>A new <see cref="IIterativeSolver"/>.</returns>
IIterativeSolver<T> CreateNew(); IIterativeSolver CreateNew();
/// <summary> /// <summary>
/// Gets the relative speed of the solver. /// Gets the relative speed of the solver.

33
src/Numerics/LinearAlgebra/Generic/Solvers/IIterator.cs → src/Numerics/LinearAlgebra/Complex/Solvers/IIterator.cs

@ -28,44 +28,41 @@
// OTHER DEALINGS IN THE SOFTWARE. // OTHER DEALINGS IN THE SOFTWARE.
// </copyright> // </copyright>
namespace MathNet.Numerics.LinearAlgebra.Generic.Solvers namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
{ {
using System; using System;
using System.Numerics; using Generic.Solvers.Status;
using Status;
using StopCriterium; using StopCriterium;
/// <summary> /// <summary>
/// Defines the base interface for iterators that help control an iterative calculation. /// Defines the base interface for iterators that help control an iterative calculation.
/// </summary> /// </summary>
/// <typeparam name="T">Supported data types are double, single, <see cref="Complex"/>, and <see cref="Complex32"/>.</typeparam> public interface IIterator
public interface IIterator<T>
#if !SILVERLIGHT #if !SILVERLIGHT
: ICloneable : ICloneable
#endif #endif
where T : struct, IEquatable<T>, IFormattable
{ {
/// <summary> /// <summary>
/// Adds an <see cref="IIterationStopCriterium{T}"/> to the internal collection of stop-criteria. Only a /// Adds an <see cref="IIterationStopCriterium"/> to the internal collection of stop-criteria. Only a
/// single stop criterium of each type can be stored. /// single stop criterium of each type can be stored.
/// </summary> /// </summary>
/// <param name="stopCriterium">The stop criterium to add.</param> /// <param name="stopCriterium">The stop criterium to add.</param>
/// <exception cref="ArgumentNullException">Thrown if <paramref name="stopCriterium"/> is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">Thrown if <paramref name="stopCriterium"/> is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">Thrown if <paramref name="stopCriterium"/> is of the same type as an already stored criterium.</exception> /// <exception cref="ArgumentException">Thrown if <paramref name="stopCriterium"/> is of the same type as an already stored criterium.</exception>
void Add(IIterationStopCriterium<T> stopCriterium); void Add(IIterationStopCriterium stopCriterium);
/// <summary> /// <summary>
/// Removes the <see cref="IIterationStopCriterium{T}"/> from the internal collection. /// Removes the <see cref="IIterationStopCriterium"/> from the internal collection.
/// </summary> /// </summary>
/// <param name="stopCriterium">The stop criterium that must be removed.</param> /// <param name="stopCriterium">The stop criterium that must be removed.</param>
void Remove(IIterationStopCriterium<T> stopCriterium); void Remove(IIterationStopCriterium stopCriterium);
/// <summary> /// <summary>
/// Indicates if the specific stop criterium is stored by the <see cref="IIterator{T}"/>. /// Indicates if the specific stop criterium is stored by the <see cref="IIterator"/>.
/// </summary> /// </summary>
/// <param name="stopCriterium">The stop criterium.</param> /// <param name="stopCriterium">The stop criterium.</param>
/// <returns><c>true</c> if the <see cref="IIterator{T}"/> contains the stop criterium; otherwise <c>false</c>.</returns> /// <returns><c>true</c> if the <see cref="IIterator"/> contains the stop criterium; otherwise <c>false</c>.</returns>
bool Contains(IIterationStopCriterium<T> stopCriterium); bool Contains(IIterationStopCriterium stopCriterium);
/// <summary> /// <summary>
/// Indicates to the iterator that the iterative process has been cancelled. /// Indicates to the iterator that the iterative process has been cancelled.
@ -75,7 +72,7 @@ namespace MathNet.Numerics.LinearAlgebra.Generic.Solvers
/// <summary> /// <summary>
/// Determines the status of the iterative calculation based on the stop criteria stored /// Determines the status of the iterative calculation based on the stop criteria stored
/// by the current <see cref="IIterator{T}"/>. Status is set to <c>Status</c> field of current object. /// by the current <see cref="IIterator"/>. Status is set to <c>Status</c> field of current object.
/// </summary> /// </summary>
/// <param name="iterationNumber">The number of iterations that have passed so far.</param> /// <param name="iterationNumber">The number of iterations that have passed so far.</param>
/// <param name="solutionVector">The vector containing the current solution values.</param> /// <param name="solutionVector">The vector containing the current solution values.</param>
@ -86,7 +83,7 @@ namespace MathNet.Numerics.LinearAlgebra.Generic.Solvers
/// on the invocation of this method. Therefore this method should only be called if the /// on the invocation of this method. Therefore this method should only be called if the
/// calculation has moved forwards at least one step. /// calculation has moved forwards at least one step.
/// </remarks> /// </remarks>
void DetermineStatus(int iterationNumber, Vector<T> solutionVector, Vector<T> sourceVector, Vector<T> residualVector); void DetermineStatus(int iterationNumber, Vector solutionVector, Vector sourceVector, Vector residualVector);
/// <summary> /// <summary>
/// Gets the current calculation status. /// Gets the current calculation status.
@ -95,7 +92,7 @@ namespace MathNet.Numerics.LinearAlgebra.Generic.Solvers
ICalculationStatus Status { get; } ICalculationStatus Status { get; }
/// <summary> /// <summary>
/// Resets the <see cref="IIterator{T}"/> to the pre-calculation state. /// Resets the <see cref="IIterator"/> to the pre-calculation state.
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// Note to implementers: Invoking this method should not clear the user defined /// Note to implementers: Invoking this method should not clear the user defined
@ -105,7 +102,7 @@ namespace MathNet.Numerics.LinearAlgebra.Generic.Solvers
void ResetToPrecalculationState(); void ResetToPrecalculationState();
#if SILVERLIGHT #if SILVERLIGHT
IIterator<T> Clone(); IIterator Clone();
#endif #endif
} }
} }

116
src/Numerics/LinearAlgebra/Complex/Solvers/Iterative/BiCgStab.cs

@ -33,8 +33,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
using System; using System;
using System.Numerics; using System.Numerics;
using Generic; using Generic;
using Generic.Solvers;
using Generic.Solvers.Preconditioners;
using Generic.Solvers.Status; using Generic.Solvers.Status;
using Preconditioners; using Preconditioners;
using Properties; using Properties;
@ -68,7 +66,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
/// solver. /// solver.
/// </para> /// </para>
/// </remarks> /// </remarks>
public sealed class BiCgStab : IIterativeSolver<Complex> public sealed class BiCgStab : IIterativeSolver
{ {
/// <summary> /// <summary>
/// The status used if there is no status, i.e. the solver hasn't run yet and there is no /// The status used if there is no status, i.e. the solver hasn't run yet and there is no
@ -80,12 +78,12 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
/// The preconditioner that will be used. Can be set to <see langword="null" />, in which case the default /// The preconditioner that will be used. Can be set to <see langword="null" />, in which case the default
/// pre-conditioner will be used. /// pre-conditioner will be used.
/// </summary> /// </summary>
private IPreConditioner<Complex> _preconditioner; private IPreConditioner _preconditioner;
/// <summary> /// <summary>
/// The iterative process controller. /// The iterative process controller.
/// </summary> /// </summary>
private IIterator<Complex> _iterator; private IIterator _iterator;
/// <summary> /// <summary>
/// Indicates if the user has stopped the solver. /// Indicates if the user has stopped the solver.
@ -96,7 +94,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
/// Initializes a new instance of the <see cref="BiCgStab"/> class. /// Initializes a new instance of the <see cref="BiCgStab"/> class.
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// When using this constructor the solver will use the <see cref="IIterator{T}"/> with /// When using this constructor the solver will use the <see cref="IIterator"/> with
/// the standard settings and a default preconditioner. /// the standard settings and a default preconditioner.
/// </remarks> /// </remarks>
public BiCgStab() : this(null, null) public BiCgStab() : this(null, null)
@ -111,18 +109,18 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
/// When using this constructor the solver will use a default preconditioner. /// When using this constructor the solver will use a default preconditioner.
/// </para> /// </para>
/// <para> /// <para>
/// The main advantages of using a user defined <see cref="IIterator{T}"/> are: /// The main advantages of using a user defined <see cref="IIterator"/> are:
/// <list type="number"> /// <list type="number">
/// <item>It is possible to set the desired convergence limits.</item> /// <item>It is possible to set the desired convergence limits.</item>
/// <item> /// <item>
/// It is possible to check the reason for which the solver finished /// It is possible to check the reason for which the solver finished
/// the iterative procedure by calling the <see cref="IIterator{T}.Status"/> property. /// the iterative procedure by calling the <see cref="IIterator.Status"/> property.
/// </item> /// </item>
/// </list> /// </list>
/// </para> /// </para>
/// </remarks> /// </remarks>
/// <param name="iterator">The <see cref="IIterator{T}"/> that will be used to monitor the iterative process. </param> /// <param name="iterator">The <see cref="IIterator"/> that will be used to monitor the iterative process. </param>
public BiCgStab(IIterator<Complex> iterator) : this(null, iterator) public BiCgStab(IIterator iterator) : this(null, iterator)
{ {
} }
@ -130,11 +128,11 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
/// Initializes a new instance of the <see cref="BiCgStab"/> class. /// Initializes a new instance of the <see cref="BiCgStab"/> class.
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// When using this constructor the solver will use the <see cref="IIterator{T}"/> with /// When using this constructor the solver will use the <see cref="IIterator"/> with
/// the standard settings. /// the standard settings.
/// </remarks> /// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation.</param> /// <param name="preconditioner">The <see cref="IPreConditioner"/> that will be used to precondition the matrix equation.</param>
public BiCgStab(IPreConditioner<Complex> preconditioner) : this(preconditioner, null) public BiCgStab(IPreConditioner preconditioner) : this(preconditioner, null)
{ {
} }
@ -143,38 +141,38 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// <para> /// <para>
/// The main advantages of using a user defined <see cref="IIterator{T}"/> are: /// The main advantages of using a user defined <see cref="IIterator"/> are:
/// <list type="number"> /// <list type="number">
/// <item>It is possible to set the desired convergence limits.</item> /// <item>It is possible to set the desired convergence limits.</item>
/// <item> /// <item>
/// It is possible to check the reason for which the solver finished /// It is possible to check the reason for which the solver finished
/// the iterative procedure by calling the <see cref="IIterator{T}.Status"/> property. /// the iterative procedure by calling the <see cref="IIterator.Status"/> property.
/// </item> /// </item>
/// </list> /// </list>
/// </para> /// </para>
/// </remarks> /// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation. </param> /// <param name="preconditioner">The <see cref="IPreConditioner"/> that will be used to precondition the matrix equation. </param>
/// <param name="iterator">The <see cref="IIterator{T}"/> that will be used to monitor the iterative process. </param> /// <param name="iterator">The <see cref="IIterator"/> that will be used to monitor the iterative process. </param>
public BiCgStab(IPreConditioner<Complex> preconditioner, IIterator<Complex> iterator) public BiCgStab(IPreConditioner preconditioner, IIterator iterator)
{ {
_iterator = iterator; _iterator = iterator;
_preconditioner = preconditioner; _preconditioner = preconditioner;
} }
/// <summary> /// <summary>
/// Sets the <see cref="IPreConditioner{T}"/> that will be used to precondition the iterative process. /// Sets the <see cref="IPreConditioner"/> that will be used to precondition the iterative process.
/// </summary> /// </summary>
/// <param name="preconditioner">The preconditioner.</param> /// <param name="preconditioner">The preconditioner.</param>
public void SetPreconditioner(IPreConditioner<Complex> preconditioner) public void SetPreconditioner(IPreConditioner preconditioner)
{ {
_preconditioner = preconditioner; _preconditioner = preconditioner;
} }
/// <summary> /// <summary>
/// Sets the <see cref="IIterator{T}"/> that will be used to track the iterative process. /// Sets the <see cref="IIterator"/> that will be used to track the iterative process.
/// </summary> /// </summary>
/// <param name="iterator">The iterator.</param> /// <param name="iterator">The iterator.</param>
public void SetIterator(IIterator<Complex> iterator) public void SetIterator(IIterator iterator)
{ {
_iterator = iterator; _iterator = iterator;
} }
@ -205,17 +203,17 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
/// Solves the matrix equation Ax = b, where A is the coefficient matrix, b is the /// Solves the matrix equation Ax = b, where A is the coefficient matrix, b is the
/// solution vector and x is the unknown vector. /// solution vector and x is the unknown vector.
/// </summary> /// </summary>
/// <param name="matrix">The coefficient <see cref="Matrix{T}"/>, <c>A</c>.</param> /// <param name="matrix">The coefficient <see cref="Matrix"/>, <c>A</c>.</param>
/// <param name="vector">The solution <see cref="Vector{T}"/>, <c>b</c>.</param> /// <param name="vector">The solution <see cref="Vector"/>, <c>b</c>.</param>
/// <returns>The result <see cref="Vector{T}"/>, <c>x</c>.</returns> /// <returns>The result <see cref="Vector"/>, <c>x</c>.</returns>
public Vector<Complex> Solve(Matrix<Complex> matrix, Vector<Complex> vector) public Vector Solve(Matrix matrix, Vector vector)
{ {
if (vector == null) if (vector == null)
{ {
throw new ArgumentNullException(); throw new ArgumentNullException();
} }
Vector<Complex> result = new DenseVector(matrix.RowCount); Vector result = new DenseVector(matrix.RowCount);
Solve(matrix, vector, result); Solve(matrix, vector, result);
return result; return result;
} }
@ -224,10 +222,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
/// Solves the matrix equation Ax = b, where A is the coefficient matrix, b is the /// Solves the matrix equation Ax = b, where A is the coefficient matrix, b is the
/// solution vector and x is the unknown vector. /// solution vector and x is the unknown vector.
/// </summary> /// </summary>
/// <param name="matrix">The coefficient <see cref="Matrix{T}"/>, <c>A</c>.</param> /// <param name="matrix">The coefficient <see cref="Matrix"/>, <c>A</c>.</param>
/// <param name="input">The solution <see cref="Vector{T}"/>, <c>b</c>.</param> /// <param name="input">The solution <see cref="Vector"/>, <c>b</c>.</param>
/// <param name="result">The result <see cref="Vector{T}"/>, <c>x</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 matrix, Vector input, Vector result)
{ {
// If we were stopped before, we are no longer // If we were stopped before, we are no longer
// We're doing this at the start of the method to ensure // We're doing this at the start of the method to ensure
@ -282,7 +280,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
// Compute r_0 = b - Ax_0 for some initial guess x_0 // Compute r_0 = b - Ax_0 for some initial guess x_0
// In this case we take x_0 = vector // In this case we take x_0 = vector
// This is basically a SAXPY so it could be made a lot faster // This is basically a SAXPY so it could be made a lot faster
Vector<Complex> residuals = new DenseVector(matrix.RowCount); Vector residuals = new DenseVector(matrix.RowCount);
CalculateTrueResidual(matrix, residuals, result, input); CalculateTrueResidual(matrix, residuals, result, input);
// Choose r~ (for example, r~ = r_0) // Choose r~ (for example, r~ = r_0)
@ -291,13 +289,13 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
// create seven temporary vectors needed to hold temporary // create seven temporary vectors needed to hold temporary
// coefficients. All vectors are mangled in each iteration. // coefficients. All vectors are mangled in each iteration.
// These are defined here to prevent stressing the garbage collector // These are defined here to prevent stressing the garbage collector
Vector<Complex> vecP = new DenseVector(residuals.Count); Vector vecP = new DenseVector(residuals.Count);
Vector<Complex> vecPdash = new DenseVector(residuals.Count); Vector vecPdash = new DenseVector(residuals.Count);
Vector<Complex> nu = new DenseVector(residuals.Count); Vector nu = new DenseVector(residuals.Count);
Vector<Complex> vecS = new DenseVector(residuals.Count); Vector vecS = new DenseVector(residuals.Count);
Vector<Complex> vecSdash = new DenseVector(residuals.Count); Vector vecSdash = new DenseVector(residuals.Count);
Vector<Complex> temp = new DenseVector(residuals.Count); Vector temp = new DenseVector(residuals.Count);
Vector<Complex> temp2 = new DenseVector(residuals.Count); Vector temp2 = new DenseVector(residuals.Count);
// create some temporary double variables that are needed // create some temporary double variables that are needed
// to hold values in between iterations // to hold values in between iterations
@ -429,13 +427,13 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
} }
/// <summary> /// <summary>
/// Calculates the true residual of the matrix equation Ax = b according to: residual = b - Ax /// Calculates the <c>true</c> residual of the matrix equation Ax = b according to: residual = b - Ax
/// </summary> /// </summary>
/// <param name="matrix">Instance of the <see cref="Matrix{T}"/> A.</param> /// <param name="matrix">Instance of the <see cref="Matrix"/> A.</param>
/// <param name="residual">Residual values in <see cref="Vector{T}"/>.</param> /// <param name="residual">Residual values in <see cref="Vector"/>.</param>
/// <param name="x">Instance of the <see cref="Vector{T}"/> x.</param> /// <param name="x">Instance of the <see cref="Vector"/> x.</param>
/// <param name="b">Instance of the <see cref="Vector{T}"/> b.</param> /// <param name="b">Instance of the <see cref="Vector"/> b.</param>
private static void CalculateTrueResidual(Matrix<Complex> matrix, Vector<Complex> residual, Vector<Complex> x, Vector<Complex> b) private static void CalculateTrueResidual(Matrix matrix, Vector residual, Vector x, Vector b)
{ {
// -Ax = residual // -Ax = residual
matrix.Multiply(x, residual); matrix.Multiply(x, residual);
@ -451,11 +449,11 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
/// Determine if calculation should continue /// Determine if calculation should continue
/// </summary> /// </summary>
/// <param name="iterationNumber">Number of iterations passed</param> /// <param name="iterationNumber">Number of iterations passed</param>
/// <param name="result">Result <see cref="Vector{T}"/>.</param> /// <param name="result">Result <see cref="Vector"/>.</param>
/// <param name="source">Source <see cref="Vector{T}"/>.</param> /// <param name="source">Source <see cref="Vector"/>.</param>
/// <param name="residuals">Residual <see cref="Vector{T}"/>.</param> /// <param name="residuals">Residual <see cref="Vector"/>.</param>
/// <returns><c>true</c> if continue, otherwise <c>false</c></returns> /// <returns><c>true</c> if continue, otherwise <c>false</c></returns>
private bool ShouldContinue(int iterationNumber, Vector<Complex> result, Vector<Complex> source, Vector<Complex> residuals) private bool ShouldContinue(int iterationNumber, Vector result, Vector source, Vector residuals)
{ {
if (_hasBeenStopped) if (_hasBeenStopped)
{ {
@ -476,10 +474,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
/// Solves the matrix equation AX = B, where A is the coefficient matrix, B is the /// Solves the matrix equation AX = B, where A is the coefficient matrix, B is the
/// solution matrix and X is the unknown matrix. /// solution matrix and X is the unknown matrix.
/// </summary> /// </summary>
/// <param name="matrix">The coefficient <see cref="Matrix{T}"/>, <c>A</c>.</param> /// <param name="matrix">The coefficient <see cref="Matrix"/>, <c>A</c>.</param>
/// <param name="input">The solution <see cref="Matrix{T}"/>, <c>B</c>.</param> /// <param name="input">The solution <see cref="Matrix"/>, <c>B</c>.</param>
/// <returns>The result <see cref="Matrix{T}"/>, <c>X</c>.</returns> /// <returns>The result <see cref="Matrix"/>, <c>X</c>.</returns>
public Matrix<Complex> Solve(Matrix<Complex> matrix, Matrix<Complex> input) public Matrix Solve(Matrix matrix, Matrix input)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -491,7 +489,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
throw new ArgumentNullException("input"); throw new ArgumentNullException("input");
} }
var result = matrix.CreateMatrix(input.RowCount, input.ColumnCount); var result = (Matrix)matrix.CreateMatrix(input.RowCount, input.ColumnCount);
Solve(matrix, input, result); Solve(matrix, input, result);
return result; return result;
} }
@ -500,10 +498,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
/// Solves the matrix equation AX = B, where A is the coefficient matrix, B is the /// Solves the matrix equation AX = B, where A is the coefficient matrix, B is the
/// solution matrix and X is the unknown matrix. /// solution matrix and X is the unknown matrix.
/// </summary> /// </summary>
/// <param name="matrix">The coefficient <see cref="Matrix{T}"/>, <c>A</c>.</param> /// <param name="matrix">The coefficient <see cref="Matrix"/>, <c>A</c>.</param>
/// <param name="input">The solution <see cref="Matrix{T}"/>, <c>B</c>.</param> /// <param name="input">The solution <see cref="Matrix"/>, <c>B</c>.</param>
/// <param name="result">The result <see cref="Matrix{T}"/>, <c>X</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 matrix, Matrix input, Matrix result)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -527,7 +525,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
for (var column = 0; column < input.ColumnCount; column++) for (var column = 0; column < input.ColumnCount; column++)
{ {
var solution = Solve(matrix, input.Column(column)); var solution = Solve(matrix, (Vector)input.Column(column));
foreach (var element in solution.GetIndexedEnumerator()) foreach (var element in solution.GetIndexedEnumerator())
{ {
result.At(element.Key, column, element.Value); result.At(element.Key, column, element.Value);

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

@ -56,7 +56,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
/// Note that if an iterator is passed to this solver it will be used for all the sub-solvers. /// Note that if an iterator is passed to this solver it will be used for all the sub-solvers.
/// </para> /// </para>
/// </remarks> /// </remarks>
public sealed class CompositeSolver : IIterativeSolver<Complex> public sealed class CompositeSolver : IIterativeSolver
{ {
#region Internal class - DoubleComparer #region Internal class - DoubleComparer
/// <summary> /// <summary>
@ -97,19 +97,19 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
private static readonly ICalculationStatus RunningStatus = new CalculationRunning(); private static readonly ICalculationStatus RunningStatus = new CalculationRunning();
#if SILVERLIGHT #if SILVERLIGHT
private static readonly Dictionary<double, List<IIterativeSolverSetup<Complex>>> SolverSetups = new Dictionary<double, List<IIterativeSolverSetup<Complex>>>(); private static readonly Dictionary<double, List<IIterativeSolverSetup>> SolverSetups = new Dictionary<double, List<IIterativeSolverSetup>>();
#else #else
/// <summary> /// <summary>
/// The collection of iterative solver setups. Stored based on the /// The collection of iterative solver setups. Stored based on the
/// ratio between the relative speed and relative accuracy. /// ratio between the relative speed and relative accuracy.
/// </summary> /// </summary>
private static readonly SortedList<double, List<IIterativeSolverSetup<Complex>>> SolverSetups = new SortedList<double, List<IIterativeSolverSetup<Complex>>>(new DoubleComparer()); private static readonly SortedList<double, List<IIterativeSolverSetup>> SolverSetups = new SortedList<double, List<IIterativeSolverSetup>>(new DoubleComparer());
#endif #endif
#region Solver information loading methods #region Solver information loading methods
/// <summary> /// <summary>
/// Loads all the available <see cref="IIterativeSolverSetup{T}"/> objects from the MathNet.Numerics assembly. /// Loads all the available <see cref="IIterativeSolverSetup"/> objects from the MathNet.Numerics assembly.
/// </summary> /// </summary>
public static void LoadSolverInformation() public static void LoadSolverInformation()
{ {
@ -117,16 +117,16 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
} }
/// <summary> /// <summary>
/// Loads the available <see cref="IIterativeSolverSetup{T}"/> objects from the MathNet.Numerics assembly. /// Loads the available <see cref="IIterativeSolverSetup"/> objects from the MathNet.Numerics assembly.
/// </summary> /// </summary>
/// <param name="typesToExclude">The <see cref="IIterativeSolver{T}"/> types that should not be loaded.</param> /// <param name="typesToExclude">The <see cref="IIterativeSolver"/> types that should not be loaded.</param>
public static void LoadSolverInformation(Type[] typesToExclude) public static void LoadSolverInformation(Type[] typesToExclude)
{ {
LoadSolverInformationFromAssembly(Assembly.GetExecutingAssembly(), typesToExclude); LoadSolverInformationFromAssembly(Assembly.GetExecutingAssembly(), typesToExclude);
} }
/// <summary> /// <summary>
/// Loads the available <see cref="IIterativeSolverSetup{T}"/> objects from the assembly specified by the file location. /// Loads the available <see cref="IIterativeSolverSetup"/> objects from the assembly specified by the file location.
/// </summary> /// </summary>
/// <param name="assemblyLocation">The fully qualified path to the assembly.</param> /// <param name="assemblyLocation">The fully qualified path to the assembly.</param>
public static void LoadSolverInformationFromAssembly(string assemblyLocation) public static void LoadSolverInformationFromAssembly(string assemblyLocation)
@ -135,10 +135,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
} }
/// <summary> /// <summary>
/// Loads the available <see cref="IIterativeSolverSetup{T}"/> objects from the assembly specified by the file location. /// Loads the available <see cref="IIterativeSolverSetup"/> objects from the assembly specified by the file location.
/// </summary> /// </summary>
/// <param name="assemblyLocation">The fully qualified path to the assembly.</param> /// <param name="assemblyLocation">The fully qualified path to the assembly.</param>
/// <param name="typesToExclude">The <see cref="IIterativeSolver{T}"/> types that should not be loaded. </param> /// <param name="typesToExclude">The <see cref="IIterativeSolver"/> types that should not be loaded. </param>
public static void LoadSolverInformationFromAssembly(string assemblyLocation, params Type[] typesToExclude) public static void LoadSolverInformationFromAssembly(string assemblyLocation, params Type[] typesToExclude)
{ {
if (assemblyLocation == null) if (assemblyLocation == null)
@ -173,7 +173,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
} }
/// <summary> /// <summary>
/// Loads the available <see cref="IIterativeSolverSetup{T}"/> objects from the assembly specified by the assembly name. /// Loads the available <see cref="IIterativeSolverSetup"/> objects from the assembly specified by the assembly name.
/// </summary> /// </summary>
/// <param name="assemblyName">The <see cref="AssemblyName"/> of the assembly that should be searched for setup objects. </param> /// <param name="assemblyName">The <see cref="AssemblyName"/> of the assembly that should be searched for setup objects. </param>
public static void LoadSolverInformationFromAssembly(AssemblyName assemblyName) public static void LoadSolverInformationFromAssembly(AssemblyName assemblyName)
@ -182,10 +182,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
} }
/// <summary> /// <summary>
/// Loads the available <see cref="IIterativeSolverSetup{T}"/> objects from the assembly specified by the assembly name. /// Loads the available <see cref="IIterativeSolverSetup"/> objects from the assembly specified by the assembly name.
/// </summary> /// </summary>
/// <param name="assemblyName">The <see cref="AssemblyName"/> of the assembly that should be searched for setup objects.</param> /// <param name="assemblyName">The <see cref="AssemblyName"/> of the assembly that should be searched for setup objects.</param>
/// <param name="typesToExclude">The <see cref="IIterativeSolver{T}"/> types that should not be loaded.</param> /// <param name="typesToExclude">The <see cref="IIterativeSolver"/> types that should not be loaded.</param>
public static void LoadSolverInformationFromAssembly(AssemblyName assemblyName, params Type[] typesToExclude) public static void LoadSolverInformationFromAssembly(AssemblyName assemblyName, params Type[] typesToExclude)
{ {
if (assemblyName == null) if (assemblyName == null)
@ -205,7 +205,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
} }
/// <summary> /// <summary>
/// Loads the available <see cref="IIterativeSolverSetup{T}"/> objects from the assembly specified by the type. /// Loads the available <see cref="IIterativeSolverSetup"/> objects from the assembly specified by the type.
/// </summary> /// </summary>
/// <param name="typeInAssembly">The type in the assembly which should be searched for setup objects.</param> /// <param name="typeInAssembly">The type in the assembly which should be searched for setup objects.</param>
public static void LoadSolverInformationFromAssembly(Type typeInAssembly) public static void LoadSolverInformationFromAssembly(Type typeInAssembly)
@ -214,10 +214,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
} }
/// <summary> /// <summary>
/// Loads the available <see cref="IIterativeSolverSetup{T}"/> objects from the assembly specified by the type. /// Loads the available <see cref="IIterativeSolverSetup"/> objects from the assembly specified by the type.
/// </summary> /// </summary>
/// <param name="typeInAssembly">The type in the assembly which should be searched for setup objects.</param> /// <param name="typeInAssembly">The type in the assembly which should be searched for setup objects.</param>
/// <param name="typesToExclude">The <see cref="IIterativeSolver{T}"/> types that should not be loaded.</param> /// <param name="typesToExclude">The <see cref="IIterativeSolver"/> types that should not be loaded.</param>
public static void LoadSolverInformationFromAssembly(Type typeInAssembly, params Type[] typesToExclude) public static void LoadSolverInformationFromAssembly(Type typeInAssembly, params Type[] typesToExclude)
{ {
if (typeInAssembly == null) if (typeInAssembly == null)
@ -229,7 +229,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
} }
/// <summary> /// <summary>
/// Loads the available <see cref="IIterativeSolverSetup{T}"/> objects from the specified assembly. /// Loads the available <see cref="IIterativeSolverSetup"/> objects from the specified assembly.
/// </summary> /// </summary>
/// <param name="assembly">The assembly which will be searched for setup objects.</param> /// <param name="assembly">The assembly which will be searched for setup objects.</param>
public static void LoadSolverInformationFromAssembly(Assembly assembly) public static void LoadSolverInformationFromAssembly(Assembly assembly)
@ -238,10 +238,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
} }
/// <summary> /// <summary>
/// Loads the available <see cref="IIterativeSolverSetup{T}"/> objects from the specified assembly. /// Loads the available <see cref="IIterativeSolverSetup"/> objects from the specified assembly.
/// </summary> /// </summary>
/// <param name="assembly">The assembly which will be searched for setup objects.</param> /// <param name="assembly">The assembly which will be searched for setup objects.</param>
/// <param name="typesToExclude">The <see cref="IIterativeSolver{T}"/> types that should not be loaded.</param> /// <param name="typesToExclude">The <see cref="IIterativeSolver"/> types that should not be loaded.</param>
public static void LoadSolverInformationFromAssembly(Assembly assembly, params Type[] typesToExclude) public static void LoadSolverInformationFromAssembly(Assembly assembly, params Type[] typesToExclude)
{ {
if (assembly == null) if (assembly == null)
@ -266,18 +266,18 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
{ {
interfaceTypes.Clear(); interfaceTypes.Clear();
interfaceTypes.AddRange(type.GetInterfaces()); interfaceTypes.AddRange(type.GetInterfaces());
if (!interfaceTypes.Any(match => typeof(IIterativeSolverSetup<Complex>).IsAssignableFrom(match))) if (!interfaceTypes.Any(match => typeof(IIterativeSolverSetup).IsAssignableFrom(match)))
{ {
continue; continue;
} }
// See if we actually want this type of iterative solver // See if we actually want this type of iterative solver
IIterativeSolverSetup<Complex> setup; IIterativeSolverSetup setup;
try try
{ {
// If something goes wrong we just ignore it and move on with the next type. // If something goes wrong we just ignore it and move on with the next type.
// There should probably be a log somewhere indicating that something went wrong? // There should probably be a log somewhere indicating that something went wrong?
setup = (IIterativeSolverSetup<Complex>)Activator.CreateInstance(type); setup = (IIterativeSolverSetup)Activator.CreateInstance(type);
} }
catch (ArgumentException) catch (ArgumentException)
{ {
@ -318,7 +318,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
var ratio = setup.SolutionSpeed / setup.Reliability; var ratio = setup.SolutionSpeed / setup.Reliability;
if (!SolverSetups.ContainsKey(ratio)) if (!SolverSetups.ContainsKey(ratio))
{ {
SolverSetups.Add(ratio, new List<IIterativeSolverSetup<Complex>>()); SolverSetups.Add(ratio, new List<IIterativeSolverSetup>());
} }
var list = SolverSetups[ratio]; var list = SolverSetups[ratio];
@ -331,7 +331,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
/// <summary> /// <summary>
/// The collection of solvers that will be used to /// The collection of solvers that will be used to
/// </summary> /// </summary>
private readonly List<IIterativeSolver<Complex>> _solvers = new List<IIterativeSolver<Complex>>(); private readonly List<IIterativeSolver> _solvers = new List<IIterativeSolver>();
/// <summary> /// <summary>
/// The status of the calculation. /// The status of the calculation.
@ -341,7 +341,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
/// <summary> /// <summary>
/// The iterator that is used to control the iteration process. /// The iterator that is used to control the iteration process.
/// </summary> /// </summary>
private IIterator<Complex> _iterator; private IIterator _iterator;
/// <summary> /// <summary>
/// A flag indicating if the solver has been stopped or not. /// A flag indicating if the solver has been stopped or not.
@ -352,7 +352,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
/// The solver that is currently running. Reference is used to be able to stop the /// The solver that is currently running. Reference is used to be able to stop the
/// solver if the user cancels the solve process. /// solver if the user cancels the solve process.
/// </summary> /// </summary>
private IIterativeSolver<Complex> _currentSolver; private IIterativeSolver _currentSolver;
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="CompositeSolver"/> class with the default iterator. /// Initializes a new instance of the <see cref="CompositeSolver"/> class with the default iterator.
@ -365,7 +365,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
/// Initializes a new instance of the <see cref="CompositeSolver"/> class with the specified iterator. /// Initializes a new instance of the <see cref="CompositeSolver"/> class with the specified iterator.
/// </summary> /// </summary>
/// <param name="iterator">The iterator that will be used to control the iteration process. </param> /// <param name="iterator">The iterator that will be used to control the iteration process. </param>
public CompositeSolver(IIterator<Complex> iterator) public CompositeSolver(IIterator iterator)
{ {
_iterator = iterator; _iterator = iterator;
} }
@ -374,7 +374,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
/// Sets the <c>IIterator</c> that will be used to track the iterative process. /// Sets the <c>IIterator</c> that will be used to track the iterative process.
/// </summary> /// </summary>
/// <param name="iterator">The iterator.</param> /// <param name="iterator">The iterator.</param>
public void SetIterator(IIterator<Complex> iterator) public void SetIterator(IIterator iterator)
{ {
_iterator = iterator; _iterator = iterator;
} }
@ -412,14 +412,14 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param> /// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="vector">The solution vector, <c>b</c>.</param> /// <param name="vector">The solution vector, <c>b</c>.</param>
/// <returns>The result vector, <c>x</c>.</returns> /// <returns>The result vector, <c>x</c>.</returns>
public Vector<Complex> Solve(Matrix<Complex> matrix, Vector<Complex> vector) public Vector Solve(Matrix matrix, Vector vector)
{ {
if (vector == null) if (vector == null)
{ {
throw new ArgumentNullException(); throw new ArgumentNullException();
} }
Vector<Complex> result = new DenseVector(matrix.RowCount); Vector result = new DenseVector(matrix.RowCount);
Solve(matrix, vector, result); Solve(matrix, vector, result);
return result; return result;
} }
@ -431,7 +431,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param> /// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution vector, <c>b</c></param> /// <param name="input">The solution vector, <c>b</c></param>
/// <param name="result">The result vector, <c>x</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 matrix, Vector input, Vector result)
{ {
// If we were stopped before, we are no longer // If we were stopped before, we are no longer
// We're doing this at the start of the method to ensure // We're doing this at the start of the method to ensure
@ -481,8 +481,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
// Create a copy of the solution and result vectors so we can use them // Create a copy of the solution and result vectors so we can use them
// later on // later on
var internalInput = input.Clone(); var internalInput = (Vector)input.Clone();
var internalResult = result.Clone(); var internalResult = (Vector)result.Clone();
foreach (var solver in _solvers.TakeWhile(solver => !_hasBeenStopped)) foreach (var solver in _solvers.TakeWhile(solver => !_hasBeenStopped))
{ {
@ -573,7 +573,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param> /// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution matrix, <c>B</c>.</param> /// <param name="input">The solution matrix, <c>B</c>.</param>
/// <returns>The result matrix, <c>X</c>.</returns> /// <returns>The result matrix, <c>X</c>.</returns>
public Matrix<Complex> Solve(Matrix<Complex> matrix, Matrix<Complex> input) public Matrix Solve(Matrix matrix, Matrix input)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -585,7 +585,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
throw new ArgumentNullException("input"); throw new ArgumentNullException("input");
} }
var result = matrix.CreateMatrix(input.RowCount, input.ColumnCount); var result = (Matrix)matrix.CreateMatrix(input.RowCount, input.ColumnCount);
Solve(matrix, input, result); Solve(matrix, input, result);
return result; return result;
} }
@ -597,7 +597,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param> /// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution matrix, <c>B</c>.</param> /// <param name="input">The solution matrix, <c>B</c>.</param>
/// <param name="result">The result matrix, <c>X</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 matrix, Matrix input, Matrix result)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -621,7 +621,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
for (var column = 0; column < input.ColumnCount; column++) for (var column = 0; column < input.ColumnCount; column++)
{ {
var solution = Solve(matrix, input.Column(column)); var solution = Solve(matrix, (Vector)input.Column(column));
foreach (var element in solution.GetIndexedEnumerator()) foreach (var element in solution.GetIndexedEnumerator())
{ {
result.At(element.Key, column, element.Value); result.At(element.Key, column, element.Value);

107
src/Numerics/LinearAlgebra/Complex/Solvers/Iterative/GpBiCg.cs

@ -32,9 +32,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
{ {
using System; using System;
using System.Numerics; using System.Numerics;
using Generic;
using Generic.Solvers;
using Generic.Solvers.Preconditioners;
using Generic.Solvers.Status; using Generic.Solvers.Status;
using Preconditioners; using Preconditioners;
using Properties; using Properties;
@ -66,7 +63,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
/// solver. /// solver.
/// </para> /// </para>
/// </remarks> /// </remarks>
public sealed class GpBiCg : IIterativeSolver<Complex> public sealed class GpBiCg : IIterativeSolver
{ {
/// <summary> /// <summary>
/// The status used if there is no status, i.e. the solver hasn't run yet and there is no /// The status used if there is no status, i.e. the solver hasn't run yet and there is no
@ -78,12 +75,12 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
/// The preconditioner that will be used. Can be set to <c>null</c>, in which case the default /// The preconditioner that will be used. Can be set to <c>null</c>, in which case the default
/// pre-conditioner will be used. /// pre-conditioner will be used.
/// </summary> /// </summary>
private IPreConditioner<Complex> _preconditioner; private IPreConditioner _preconditioner;
/// <summary> /// <summary>
/// The iterative process controller. /// The iterative process controller.
/// </summary> /// </summary>
private IIterator<Complex> _iterator; private IIterator _iterator;
/// <summary> /// <summary>
/// Indicates the number of <c>BiCGStab</c> steps should be taken /// Indicates the number of <c>BiCGStab</c> steps should be taken
@ -106,7 +103,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
/// Initializes a new instance of the <see cref="GpBiCg"/> class. /// Initializes a new instance of the <see cref="GpBiCg"/> class.
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// When using this constructor the solver will use the <see cref="IIterator{T}"/> with /// When using this constructor the solver will use the <see cref="IIterator"/> with
/// the standard settings and a default preconditioner. /// the standard settings and a default preconditioner.
/// </remarks> /// </remarks>
public GpBiCg() : this(null, null) public GpBiCg() : this(null, null)
@ -121,18 +118,18 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
/// When using this constructor the solver will use a default preconditioner. /// When using this constructor the solver will use a default preconditioner.
/// </para> /// </para>
/// <para> /// <para>
/// The main advantages of using a user defined <see cref="IIterator{T}"/> are: /// The main advantages of using a user defined <see cref="IIterator"/> are:
/// <list type="number"> /// <list type="number">
/// <item>It is possible to set the desired convergence limits.</item> /// <item>It is possible to set the desired convergence limits.</item>
/// <item> /// <item>
/// It is possible to check the reason for which the solver finished /// It is possible to check the reason for which the solver finished
/// the iterative procedure by calling the <see cref="IIterator{T}.Status"/> property. /// the iterative procedure by calling the <see cref="IIterator.Status"/> property.
/// </item> /// </item>
/// </list> /// </list>
/// </para> /// </para>
/// </remarks> /// </remarks>
/// <param name="iterator">The <see cref="IIterator{T}"/> that will be used to monitor the iterative process.</param> /// <param name="iterator">The <see cref="IIterator"/> that will be used to monitor the iterative process.</param>
public GpBiCg(IIterator<Complex> iterator) : this(null, iterator) public GpBiCg(IIterator iterator) : this(null, iterator)
{ {
} }
@ -140,11 +137,11 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
/// Initializes a new instance of the <see cref="GpBiCg"/> class. /// Initializes a new instance of the <see cref="GpBiCg"/> class.
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// When using this constructor the solver will use the <see cref="IIterator{T}"/> with /// When using this constructor the solver will use the <see cref="IIterator"/> with
/// the standard settings. /// the standard settings.
/// </remarks> /// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation.</param> /// <param name="preconditioner">The <see cref="IPreConditioner"/> that will be used to precondition the matrix equation.</param>
public GpBiCg(IPreConditioner<Complex> preconditioner) : this(preconditioner, null) public GpBiCg(IPreConditioner preconditioner) : this(preconditioner, null)
{ {
} }
@ -153,19 +150,19 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// <para> /// <para>
/// The main advantages of using a user defined <see cref="IIterator{T}"/> are: /// The main advantages of using a user defined <see cref="IIterator"/> are:
/// <list type="number"> /// <list type="number">
/// <item>It is possible to set the desired convergence limits.</item> /// <item>It is possible to set the desired convergence limits.</item>
/// <item> /// <item>
/// It is possible to check the reason for which the solver finished /// It is possible to check the reason for which the solver finished
/// the iterative procedure by calling the <see cref="IIterator{T}.Status"/> property. /// the iterative procedure by calling the <see cref="IIterator.Status"/> property.
/// </item> /// </item>
/// </list> /// </list>
/// </para> /// </para>
/// </remarks> /// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation.</param> /// <param name="preconditioner">The <see cref="IPreConditioner"/> that will be used to precondition the matrix equation.</param>
/// <param name="iterator">The <see cref="IIterator{T}"/> that will be used to monitor the iterative process.</param> /// <param name="iterator">The <see cref="IIterator"/> that will be used to monitor the iterative process.</param>
public GpBiCg(IPreConditioner<Complex> preconditioner, IIterator<Complex> iterator) public GpBiCg(IPreConditioner preconditioner, IIterator iterator)
{ {
_iterator = iterator; _iterator = iterator;
_preconditioner = preconditioner; _preconditioner = preconditioner;
@ -216,19 +213,19 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
} }
/// <summary> /// <summary>
/// Sets the <see cref="IPreConditioner{T}"/> that will be used to precondition the iterative process. /// Sets the <see cref="IPreConditioner"/> that will be used to precondition the iterative process.
/// </summary> /// </summary>
/// <param name="preconditioner">The preconditioner.</param> /// <param name="preconditioner">The preconditioner.</param>
public void SetPreconditioner(IPreConditioner<Complex> preconditioner) public void SetPreconditioner(IPreConditioner preconditioner)
{ {
_preconditioner = preconditioner; _preconditioner = preconditioner;
} }
/// <summary> /// <summary>
/// Sets the <see cref="IIterator{T}"/> that will be used to track the iterative process. /// Sets the <see cref="IIterator"/> that will be used to track the iterative process.
/// </summary> /// </summary>
/// <param name="iterator">The iterator.</param> /// <param name="iterator">The iterator.</param>
public void SetIterator(IIterator<Complex> iterator) public void SetIterator(IIterator iterator)
{ {
_iterator = iterator; _iterator = iterator;
} }
@ -263,14 +260,14 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param> /// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="vector">The solution vector, <c>b</c>.</param> /// <param name="vector">The solution vector, <c>b</c>.</param>
/// <returns>The result vector, <c>x</c>.</returns> /// <returns>The result vector, <c>x</c>.</returns>
public Vector<Complex> Solve(Matrix<Complex> matrix, Vector<Complex> vector) public Vector Solve(Matrix matrix, Vector vector)
{ {
if (vector == null) if (vector == null)
{ {
throw new ArgumentNullException(); throw new ArgumentNullException();
} }
Vector<Complex> result = new DenseVector(matrix.RowCount); Vector result = new DenseVector(matrix.RowCount);
Solve(matrix, vector, result); Solve(matrix, vector, result);
return result; return result;
} }
@ -282,7 +279,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param> /// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution vector, <c>b</c></param> /// <param name="input">The solution vector, <c>b</c></param>
/// <param name="result">The result vector, <c>x</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 matrix, Vector input, Vector result)
{ {
// If we were stopped before, we are no longer // If we were stopped before, we are no longer
// We're doing this at the start of the method to ensure // We're doing this at the start of the method to ensure
@ -336,11 +333,11 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
// x_0 is initial guess // x_0 is initial guess
// Take x_0 = 0 // Take x_0 = 0
Vector<Complex> xtemp = new DenseVector(input.Count); Vector xtemp = new DenseVector(input.Count);
// r_0 = b - Ax_0 // r_0 = b - Ax_0
// This is basically a SAXPY so it could be made a lot faster // This is basically a SAXPY so it could be made a lot faster
Vector<Complex> residuals = new DenseVector(matrix.RowCount); Vector residuals = new DenseVector(matrix.RowCount);
CalculateTrueResidual(matrix, residuals, xtemp, input); CalculateTrueResidual(matrix, residuals, xtemp, input);
// Define the temporary scalars // Define the temporary scalars
@ -349,26 +346,26 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
// Define the temporary vectors // Define the temporary vectors
// rDash_0 = r_0 // rDash_0 = r_0
Vector<Complex> rdash = new DenseVector(residuals); Vector rdash = new DenseVector(residuals);
// t_-1 = 0 // t_-1 = 0
Vector<Complex> t = new DenseVector(residuals.Count); Vector t = new DenseVector(residuals.Count);
Vector<Complex> t0 = new DenseVector(residuals.Count); Vector t0 = new DenseVector(residuals.Count);
// w_-1 = 0 // w_-1 = 0
Vector<Complex> w = new DenseVector(residuals.Count); Vector w = new DenseVector(residuals.Count);
// Define the remaining temporary vectors // Define the remaining temporary vectors
Vector<Complex> c = new DenseVector(residuals.Count); Vector c = new DenseVector(residuals.Count);
Vector<Complex> p = new DenseVector(residuals.Count); Vector p = new DenseVector(residuals.Count);
Vector<Complex> s = new DenseVector(residuals.Count); Vector s = new DenseVector(residuals.Count);
Vector<Complex> u = new DenseVector(residuals.Count); Vector u = new DenseVector(residuals.Count);
Vector<Complex> y = new DenseVector(residuals.Count); Vector y = new DenseVector(residuals.Count);
Vector<Complex> z = new DenseVector(residuals.Count); Vector z = new DenseVector(residuals.Count);
Vector<Complex> temp = new DenseVector(residuals.Count); Vector temp = new DenseVector(residuals.Count);
Vector<Complex> temp2 = new DenseVector(residuals.Count); Vector temp2 = new DenseVector(residuals.Count);
Vector<Complex> temp3 = new DenseVector(residuals.Count); Vector temp3 = new DenseVector(residuals.Count);
// for (k = 0, 1, .... ) // for (k = 0, 1, .... )
var iterationNumber = 0; var iterationNumber = 0;
@ -525,13 +522,13 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
} }
/// <summary> /// <summary>
/// Calculates the true residual of the matrix equation Ax = b according to: residual = b - Ax /// Calculates the <c>true</c> residual of the matrix equation Ax = b according to: residual = b - Ax
/// </summary> /// </summary>
/// <param name="matrix">Instance of the <see cref="Matrix{T}"/> A.</param> /// <param name="matrix">Instance of the <see cref="Matrix"/> A.</param>
/// <param name="residual">Residual values in <see cref="Vector{T}"/>.</param> /// <param name="residual">Residual values in <see cref="Vector"/>.</param>
/// <param name="x">Instance of the <see cref="Vector{T}"/> x.</param> /// <param name="x">Instance of the <see cref="Vector"/> x.</param>
/// <param name="b">Instance of the <see cref="Vector{T}"/> b.</param> /// <param name="b">Instance of the <see cref="Vector"/> b.</param>
private static void CalculateTrueResidual(Matrix<Complex> matrix, Vector<Complex> residual, Vector<Complex> x, Vector<Complex> b) private static void CalculateTrueResidual(Matrix matrix, Vector residual, Vector x, Vector b)
{ {
// -Ax = residual // -Ax = residual
matrix.Multiply(x, residual); matrix.Multiply(x, residual);
@ -545,11 +542,11 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
/// Determine if calculation should continue /// Determine if calculation should continue
/// </summary> /// </summary>
/// <param name="iterationNumber">Number of iterations passed</param> /// <param name="iterationNumber">Number of iterations passed</param>
/// <param name="result">Result <see cref="Vector{T}"/>.</param> /// <param name="result">Result <see cref="Vector"/>.</param>
/// <param name="source">Source <see cref="Vector{T}"/>.</param> /// <param name="source">Source <see cref="Vector"/>.</param>
/// <param name="residuals">Residual <see cref="Vector{T}"/>.</param> /// <param name="residuals">Residual <see cref="Vector"/>.</param>
/// <returns><c>true</c> if continue, otherwise <c>false</c></returns> /// <returns><c>true</c> if continue, otherwise <c>false</c></returns>
private bool ShouldContinue(int iterationNumber, Vector<Complex> result, Vector<Complex> source, Vector<Complex> residuals) private bool ShouldContinue(int iterationNumber, Vector result, Vector source, Vector residuals)
{ {
if (_hasBeenStopped) if (_hasBeenStopped)
{ {
@ -590,7 +587,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param> /// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution matrix, <c>B</c>.</param> /// <param name="input">The solution matrix, <c>B</c>.</param>
/// <returns>The result matrix, <c>X</c>.</returns> /// <returns>The result matrix, <c>X</c>.</returns>
public Matrix<Complex> Solve(Matrix<Complex> matrix, Matrix<Complex> input) public Matrix Solve(Matrix matrix, Matrix input)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -602,7 +599,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
throw new ArgumentNullException("input"); throw new ArgumentNullException("input");
} }
var result = matrix.CreateMatrix(input.RowCount, input.ColumnCount); var result = (Matrix)matrix.CreateMatrix(input.RowCount, input.ColumnCount);
Solve(matrix, input, result); Solve(matrix, input, result);
return result; return result;
} }
@ -614,7 +611,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param> /// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution matrix, <c>B</c>.</param> /// <param name="input">The solution matrix, <c>B</c>.</param>
/// <param name="result">The result matrix, <c>X</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 matrix, Matrix input, Matrix result)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -638,7 +635,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
for (var column = 0; column < input.ColumnCount; column++) for (var column = 0; column < input.ColumnCount; column++)
{ {
var solution = Solve(matrix, input.Column(column)); var solution = Solve(matrix, (Vector)input.Column(column));
foreach (var element in solution.GetIndexedEnumerator()) foreach (var element in solution.GetIndexedEnumerator())
{ {
result.At(element.Key, column, element.Value); result.At(element.Key, column, element.Value);

114
src/Numerics/LinearAlgebra/Complex/Solvers/Iterative/MlkBiCgStab.cs

@ -38,8 +38,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
using Distributions; using Distributions;
using Generic; using Generic;
using Generic.Factorization; using Generic.Factorization;
using Generic.Solvers;
using Generic.Solvers.Preconditioners;
using Generic.Solvers.Status; using Generic.Solvers.Status;
using Preconditioners; using Preconditioners;
using Properties; using Properties;
@ -67,7 +65,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
/// solver. /// solver.
/// </para> /// </para>
/// </remarks> /// </remarks>
public sealed class MlkBiCgStab : IIterativeSolver<Complex> public sealed class MlkBiCgStab : IIterativeSolver
{ {
/// <summary> /// <summary>
/// The default number of starting vectors. /// The default number of starting vectors.
@ -84,17 +82,17 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
/// The preconditioner that will be used. Can be set to <see langword="null" />, in which case the default /// The preconditioner that will be used. Can be set to <see langword="null" />, in which case the default
/// pre-conditioner will be used. /// pre-conditioner will be used.
/// </summary> /// </summary>
private IPreConditioner<Complex> _preconditioner; private IPreConditioner _preconditioner;
/// <summary> /// <summary>
/// The iterative process controller. /// The iterative process controller.
/// </summary> /// </summary>
private IIterator<Complex> _iterator; private IIterator _iterator;
/// <summary> /// <summary>
/// The collection of starting vectors which are used as the basis for the Krylov sub-space. /// The collection of starting vectors which are used as the basis for the Krylov sub-space.
/// </summary> /// </summary>
private IList<Vector<Complex>> _startingVectors; private IList<Vector> _startingVectors;
/// <summary> /// <summary>
/// The number of starting vectors used by the algorithm /// The number of starting vectors used by the algorithm
@ -110,7 +108,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
/// Initializes a new instance of the <see cref="MlkBiCgStab"/> class. /// Initializes a new instance of the <see cref="MlkBiCgStab"/> class.
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// When using this constructor the solver will use the <see cref="IIterator{T}"/> with /// When using this constructor the solver will use the <see cref="IIterator"/> with
/// the standard settings and a default preconditioner. /// the standard settings and a default preconditioner.
/// </remarks> /// </remarks>
public MlkBiCgStab() : this(null, null) public MlkBiCgStab() : this(null, null)
@ -125,18 +123,18 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
/// When using this constructor the solver will use a default preconditioner. /// When using this constructor the solver will use a default preconditioner.
/// </para> /// </para>
/// <para> /// <para>
/// The main advantages of using a user defined <see cref="IIterator{T}"/> are: /// The main advantages of using a user defined <see cref="IIterator"/> are:
/// <list type="number"> /// <list type="number">
/// <item>It is possible to set the desired convergence limits.</item> /// <item>It is possible to set the desired convergence limits.</item>
/// <item> /// <item>
/// It is possible to check the reason for which the solver finished /// It is possible to check the reason for which the solver finished
/// the iterative procedure by calling the <see cref="IIterator{T}.Status"/> property. /// the iterative procedure by calling the <see cref="IIterator.Status"/> property.
/// </item> /// </item>
/// </list> /// </list>
/// </para> /// </para>
/// </remarks> /// </remarks>
/// <param name="iterator">The <see cref="IIterator{T}"/> that will be used to monitor the iterative process.</param> /// <param name="iterator">The <see cref="IIterator"/> that will be used to monitor the iterative process.</param>
public MlkBiCgStab(IIterator<Complex> iterator) : this(null, iterator) public MlkBiCgStab(IIterator iterator) : this(null, iterator)
{ {
} }
@ -144,11 +142,11 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
/// Initializes a new instance of the <see cref="MlkBiCgStab"/> class. /// Initializes a new instance of the <see cref="MlkBiCgStab"/> class.
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// When using this constructor the solver will use the <see cref="IIterator{T}"/> with /// When using this constructor the solver will use the <see cref="IIterator"/> with
/// the standard settings. /// the standard settings.
/// </remarks> /// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation.</param> /// <param name="preconditioner">The <see cref="IPreConditioner"/> that will be used to precondition the matrix equation.</param>
public MlkBiCgStab(IPreConditioner<Complex> preconditioner) : this(preconditioner, null) public MlkBiCgStab(IPreConditioner preconditioner) : this(preconditioner, null)
{ {
} }
@ -157,19 +155,19 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// <para> /// <para>
/// The main advantages of using a user defined <see cref="IIterator{T}"/> are: /// The main advantages of using a user defined <see cref="IIterator"/> are:
/// <list type="number"> /// <list type="number">
/// <item>It is possible to set the desired convergence limits.</item> /// <item>It is possible to set the desired convergence limits.</item>
/// <item> /// <item>
/// It is possible to check the reason for which the solver finished /// It is possible to check the reason for which the solver finished
/// the iterative procedure by calling the <see cref="IIterator{T}.Status"/> property. /// the iterative procedure by calling the <see cref="IIterator.Status"/> property.
/// </item> /// </item>
/// </list> /// </list>
/// </para> /// </para>
/// </remarks> /// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation.</param> /// <param name="preconditioner">The <see cref="IPreConditioner"/> that will be used to precondition the matrix equation.</param>
/// <param name="iterator">The <see cref="IIterator{T}"/> that will be used to monitor the iterative process.</param> /// <param name="iterator">The <see cref="IIterator"/> that will be used to monitor the iterative process.</param>
public MlkBiCgStab(IPreConditioner<Complex> preconditioner, IIterator<Complex> iterator) public MlkBiCgStab(IPreConditioner preconditioner, IIterator iterator)
{ {
_iterator = iterator; _iterator = iterator;
_preconditioner = preconditioner; _preconditioner = preconditioner;
@ -211,19 +209,19 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
} }
/// <summary> /// <summary>
/// Sets the <see cref="IPreConditioner{T}"/> that will be used to precondition the iterative process. /// Sets the <see cref="IPreConditioner"/> that will be used to precondition the iterative process.
/// </summary> /// </summary>
/// <param name="preconditioner">The preconditioner.</param> /// <param name="preconditioner">The preconditioner.</param>
public void SetPreconditioner(IPreConditioner<Complex> preconditioner) public void SetPreconditioner(IPreConditioner preconditioner)
{ {
_preconditioner = preconditioner; _preconditioner = preconditioner;
} }
/// <summary> /// <summary>
/// Sets the <see cref="IIterator{T}"/> that will be used to track the iterative process. /// Sets the <see cref="IIterator"/> that will be used to track the iterative process.
/// </summary> /// </summary>
/// <param name="iterator">The iterator.</param> /// <param name="iterator">The iterator.</param>
public void SetIterator(IIterator<Complex> iterator) public void SetIterator(IIterator iterator)
{ {
_iterator = iterator; _iterator = iterator;
} }
@ -232,7 +230,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
/// Gets or sets a series of orthonormal vectors which will be used as basis for the /// Gets or sets a series of orthonormal vectors which will be used as basis for the
/// Krylov sub-space. /// Krylov sub-space.
/// </summary> /// </summary>
public IList<Vector<Complex>> StartingVectors public IList<Vector> StartingVectors
{ {
[DebuggerStepThrough] [DebuggerStepThrough]
get get
@ -284,14 +282,14 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param> /// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="vector">The solution vector, <c>b</c>.</param> /// <param name="vector">The solution vector, <c>b</c>.</param>
/// <returns>The result vector, <c>x</c>.</returns> /// <returns>The result vector, <c>x</c>.</returns>
public Vector<Complex> Solve(Matrix<Complex> matrix, Vector<Complex> vector) public Vector Solve(Matrix matrix, Vector vector)
{ {
if (vector == null) if (vector == null)
{ {
throw new ArgumentNullException(); throw new ArgumentNullException();
} }
Vector<Complex> result = new DenseVector(matrix.RowCount); Vector result = new DenseVector(matrix.RowCount);
Solve(matrix, vector, result); Solve(matrix, vector, result);
return result; return result;
} }
@ -303,7 +301,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param> /// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution vector, <c>b</c></param> /// <param name="input">The solution vector, <c>b</c></param>
/// <param name="result">The result vector, <c>x</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 matrix, Vector input, Vector result)
{ {
// If we were stopped before, we are no longer // If we were stopped before, we are no longer
// We're doing this at the start of the method to ensure // We're doing this at the start of the method to ensure
@ -357,7 +355,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
// Choose an initial guess x_0 // Choose an initial guess x_0
// Take x_0 = 0 // Take x_0 = 0
Vector<Complex> xtemp = new DenseVector(input.Count); Vector xtemp = new DenseVector(input.Count);
// Choose k vectors q_1, q_2, ..., q_k // Choose k vectors q_1, q_2, ..., q_k
// Build a new set if: // Build a new set if:
@ -386,24 +384,24 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
// r_0 = b - Ax_0 // r_0 = b - Ax_0
// This is basically a SAXPY so it could be made a lot faster // This is basically a SAXPY so it could be made a lot faster
Vector<Complex> residuals = new DenseVector(matrix.RowCount); Vector residuals = new DenseVector(matrix.RowCount);
CalculateTrueResidual(matrix, residuals, xtemp, input); CalculateTrueResidual(matrix, residuals, xtemp, input);
// Define the temporary values // Define the temporary values
var c = new Complex[k]; var c = new Complex[k];
// Define the temporary vectors // Define the temporary vectors
Vector<Complex> gtemp = new DenseVector(residuals.Count); Vector gtemp = new DenseVector(residuals.Count);
Vector<Complex> u = new DenseVector(residuals.Count); Vector u = new DenseVector(residuals.Count);
Vector<Complex> utemp = new DenseVector(residuals.Count); Vector utemp = new DenseVector(residuals.Count);
Vector<Complex> temp = new DenseVector(residuals.Count); Vector temp = new DenseVector(residuals.Count);
Vector<Complex> temp1 = new DenseVector(residuals.Count); Vector temp1 = new DenseVector(residuals.Count);
Vector<Complex> temp2 = new DenseVector(residuals.Count); Vector temp2 = new DenseVector(residuals.Count);
Vector<Complex> zd = new DenseVector(residuals.Count); Vector zd = new DenseVector(residuals.Count);
Vector<Complex> zg = new DenseVector(residuals.Count); Vector zg = new DenseVector(residuals.Count);
Vector<Complex> zw = new DenseVector(residuals.Count); Vector zw = new DenseVector(residuals.Count);
var d = CreateVectorArray(_startingVectors.Count, residuals.Count); var d = CreateVectorArray(_startingVectors.Count, residuals.Count);
@ -647,7 +645,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
/// the <paramref name="numberOfVariables"/> is smaller than /// the <paramref name="numberOfVariables"/> is smaller than
/// the <paramref name="maximumNumberOfStartingVectors"/>. /// the <paramref name="maximumNumberOfStartingVectors"/>.
/// </returns> /// </returns>
private static IList<Vector<Complex>> CreateStartingVectors(int maximumNumberOfStartingVectors, int numberOfVariables) private static IList<Vector> CreateStartingVectors(int maximumNumberOfStartingVectors, int numberOfVariables)
{ {
// Create no more starting vectors than the size of the problem - 1 // Create no more starting vectors than the size of the problem - 1
// Get random values and then orthogonalize them with // Get random values and then orthogonalize them with
@ -658,7 +656,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
// mean = 0 and sd = 1 // mean = 0 and sd = 1
var distribution = new Normal(); var distribution = new Normal();
Matrix<Complex> matrix = new DenseMatrix(numberOfVariables, count); Matrix matrix = new DenseMatrix(numberOfVariables, count);
for (var i = 0; i < matrix.ColumnCount; i++) for (var i = 0; i < matrix.ColumnCount; i++)
{ {
var samples = new Complex[matrix.RowCount]; var samples = new Complex[matrix.RowCount];
@ -678,10 +676,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
var orthogonalMatrix = gs.Q; var orthogonalMatrix = gs.Q;
// Now transfer this to vectors // Now transfer this to vectors
var result = new List<Vector<Complex>>(); var result = new List<Vector>();
for (var i = 0; i < orthogonalMatrix.ColumnCount; i++) for (var i = 0; i < orthogonalMatrix.ColumnCount; i++)
{ {
result.Add(orthogonalMatrix.Column(i)); result.Add((Vector)orthogonalMatrix.Column(i));
// Normalize the result vector // Normalize the result vector
result[i].Multiply(1 / result[i].Norm(2), result[i]); result[i].Multiply(1 / result[i].Norm(2), result[i]);
@ -696,9 +694,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
/// <param name="arraySize">Number of vectors</param> /// <param name="arraySize">Number of vectors</param>
/// <param name="vectorSize">Size of each vector</param> /// <param name="vectorSize">Size of each vector</param>
/// <returns>Array of random vectors</returns> /// <returns>Array of random vectors</returns>
private static Vector<Complex>[] CreateVectorArray(int arraySize, int vectorSize) private static Vector[] CreateVectorArray(int arraySize, int vectorSize)
{ {
var result = new Vector<Complex>[arraySize]; var result = new Vector[arraySize];
for (var i = 0; i < result.Length; i++) for (var i = 0; i < result.Length; i++)
{ {
result[i] = new DenseVector(vectorSize); result[i] = new DenseVector(vectorSize);
@ -708,13 +706,13 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
} }
/// <summary> /// <summary>
/// Calculates the true residual of the matrix equation Ax = b according to: residual = b - Ax /// Calculates the <c>true</c> residual of the matrix equation Ax = b according to: residual = b - Ax
/// </summary> /// </summary>
/// <param name="matrix">Source <see cref="Matrix{T}"/>A.</param> /// <param name="matrix">Source <see cref="Matrix"/>A.</param>
/// <param name="residual">Residual <see cref="Vector{T}"/> data.</param> /// <param name="residual">Residual <see cref="Vector"/> data.</param>
/// <param name="x">x <see cref="Vector{T}"/> data.</param> /// <param name="x">x <see cref="Vector"/> data.</param>
/// <param name="b">b <see cref="Vector{T}"/> data.</param> /// <param name="b">b <see cref="Vector"/> data.</param>
private static void CalculateTrueResidual(Matrix<Complex> matrix, Vector<Complex> residual, Vector<Complex> x, Vector<Complex> b) private static void CalculateTrueResidual(Matrix matrix, Vector residual, Vector x, Vector b)
{ {
// -Ax = residual // -Ax = residual
matrix.Multiply(x, residual); matrix.Multiply(x, residual);
@ -728,11 +726,11 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
/// Determine if calculation should continue /// Determine if calculation should continue
/// </summary> /// </summary>
/// <param name="iterationNumber">Number of iterations passed</param> /// <param name="iterationNumber">Number of iterations passed</param>
/// <param name="result">Result <see cref="Vector{T}"/>.</param> /// <param name="result">Result <see cref="Vector"/>.</param>
/// <param name="source">Source <see cref="Vector{T}"/>.</param> /// <param name="source">Source <see cref="Vector"/>.</param>
/// <param name="residuals">Residual <see cref="Vector{T}"/>.</param> /// <param name="residuals">Residual <see cref="Vector"/>.</param>
/// <returns><c>true</c> if continue, otherwise <c>false</c></returns> /// <returns><c>true</c> if continue, otherwise <c>false</c></returns>
private bool ShouldContinue(int iterationNumber, Vector<Complex> result, Vector<Complex> source, Vector<Complex> residuals) private bool ShouldContinue(int iterationNumber, Vector result, Vector source, Vector residuals)
{ {
if (_hasBeenStopped) if (_hasBeenStopped)
{ {
@ -756,7 +754,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param> /// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution matrix, <c>B</c>.</param> /// <param name="input">The solution matrix, <c>B</c>.</param>
/// <returns>The result matrix, <c>X</c>.</returns> /// <returns>The result matrix, <c>X</c>.</returns>
public Matrix<Complex> Solve(Matrix<Complex> matrix, Matrix<Complex> input) public Matrix Solve(Matrix matrix, Matrix input)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -768,7 +766,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
throw new ArgumentNullException("input"); throw new ArgumentNullException("input");
} }
var result = matrix.CreateMatrix(input.RowCount, input.ColumnCount); var result = (Matrix)matrix.CreateMatrix(input.RowCount, input.ColumnCount);
Solve(matrix, input, result); Solve(matrix, input, result);
return result; return result;
} }
@ -780,7 +778,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param> /// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution matrix, <c>B</c>.</param> /// <param name="input">The solution matrix, <c>B</c>.</param>
/// <param name="result">The result matrix, <c>X</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 matrix, Matrix input, Matrix result)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -804,7 +802,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
for (var column = 0; column < input.ColumnCount; column++) for (var column = 0; column < input.ColumnCount; column++)
{ {
var solution = Solve(matrix, input.Column(column)); var solution = Solve(matrix, (Vector)input.Column(column));
foreach (var element in solution.GetIndexedEnumerator()) foreach (var element in solution.GetIndexedEnumerator())
{ {
result.At(element.Key, column, element.Value); result.At(element.Key, column, element.Value);

77
src/Numerics/LinearAlgebra/Complex/Solvers/Iterative/TFQMR.cs

@ -32,9 +32,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
{ {
using System; using System;
using System.Numerics; using System.Numerics;
using Generic;
using Generic.Solvers;
using Generic.Solvers.Preconditioners;
using Generic.Solvers.Status; using Generic.Solvers.Status;
using Preconditioners; using Preconditioners;
using Properties; using Properties;
@ -56,7 +53,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
/// solver. /// solver.
/// </para> /// </para>
/// </remarks> /// </remarks>
public sealed class TFQMR : IIterativeSolver<Complex> public sealed class TFQMR : IIterativeSolver
{ {
/// <summary> /// <summary>
/// The status used if there is no status, i.e. the solver hasn't run yet and there is no /// The status used if there is no status, i.e. the solver hasn't run yet and there is no
@ -68,12 +65,12 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
/// The preconditioner that will be used. Can be set to <see langword="null" />, in which case the default /// The preconditioner that will be used. Can be set to <see langword="null" />, in which case the default
/// pre-conditioner will be used. /// pre-conditioner will be used.
/// </summary> /// </summary>
private IPreConditioner<Complex> _preconditioner; private IPreConditioner _preconditioner;
/// <summary> /// <summary>
/// The iterative process controller. /// The iterative process controller.
/// </summary> /// </summary>
private IIterator<Complex> _iterator; private IIterator _iterator;
/// <summary> /// <summary>
/// Indicates if the user has stopped the solver. /// Indicates if the user has stopped the solver.
@ -84,7 +81,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
/// Initializes a new instance of the <see cref="TFQMR"/> class. /// Initializes a new instance of the <see cref="TFQMR"/> class.
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// When using this constructor the solver will use the <see cref="IIterator{T}"/> with /// When using this constructor the solver will use the <see cref="IIterator"/> with
/// the standard settings and a default preconditioner. /// the standard settings and a default preconditioner.
/// </remarks> /// </remarks>
public TFQMR() : this(null, null) public TFQMR() : this(null, null)
@ -99,18 +96,18 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
/// When using this constructor the solver will use a default preconditioner. /// When using this constructor the solver will use a default preconditioner.
/// </para> /// </para>
/// <para> /// <para>
/// The main advantages of using a user defined <see cref="IIterator{T}"/> are: /// The main advantages of using a user defined <see cref="IIterator"/> are:
/// <list type="number"> /// <list type="number">
/// <item>It is possible to set the desired convergence limits.</item> /// <item>It is possible to set the desired convergence limits.</item>
/// <item> /// <item>
/// It is possible to check the reason for which the solver finished /// It is possible to check the reason for which the solver finished
/// the iterative procedure by calling the <see cref="IIterator{T}.Status"/> property. /// the iterative procedure by calling the <see cref="IIterator.Status"/> property.
/// </item> /// </item>
/// </list> /// </list>
/// </para> /// </para>
/// </remarks> /// </remarks>
/// <param name="iterator">The <see cref="IIterator{T}"/> that will be used to monitor the iterative process.</param> /// <param name="iterator">The <see cref="IIterator"/> that will be used to monitor the iterative process.</param>
public TFQMR(IIterator<Complex> iterator) : this(null, iterator) public TFQMR(IIterator iterator) : this(null, iterator)
{ {
} }
@ -118,11 +115,11 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
/// Initializes a new instance of the <see cref="TFQMR"/> class. /// Initializes a new instance of the <see cref="TFQMR"/> class.
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// When using this constructor the solver will use the <see cref="IIterator{T}"/> with /// When using this constructor the solver will use the <see cref="IIterator"/> with
/// the standard settings. /// the standard settings.
/// </remarks> /// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation.</param> /// <param name="preconditioner">The <see cref="IPreConditioner"/> that will be used to precondition the matrix equation.</param>
public TFQMR(IPreConditioner<Complex> preconditioner) : this(preconditioner, null) public TFQMR(IPreConditioner preconditioner) : this(preconditioner, null)
{ {
} }
@ -131,38 +128,38 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// <para> /// <para>
/// The main advantages of using a user defined <see cref="IIterator{T}"/> are: /// The main advantages of using a user defined <see cref="IIterator"/> are:
/// <list type="number"> /// <list type="number">
/// <item>It is possible to set the desired convergence limits.</item> /// <item>It is possible to set the desired convergence limits.</item>
/// <item> /// <item>
/// It is possible to check the reason for which the solver finished /// It is possible to check the reason for which the solver finished
/// the iterative procedure by calling the <see cref="IIterator{T}.Status"/> property. /// the iterative procedure by calling the <see cref="IIterator.Status"/> property.
/// </item> /// </item>
/// </list> /// </list>
/// </para> /// </para>
/// </remarks> /// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation.</param> /// <param name="preconditioner">The <see cref="IPreConditioner"/> that will be used to precondition the matrix equation.</param>
/// <param name="iterator">The <see cref="IIterator{T}"/> that will be used to monitor the iterative process.</param> /// <param name="iterator">The <see cref="IIterator"/> that will be used to monitor the iterative process.</param>
public TFQMR(IPreConditioner<Complex> preconditioner, IIterator<Complex> iterator) public TFQMR(IPreConditioner preconditioner, IIterator iterator)
{ {
_iterator = iterator; _iterator = iterator;
_preconditioner = preconditioner; _preconditioner = preconditioner;
} }
/// <summary> /// <summary>
/// Sets the <see cref="IPreConditioner{T}"/> that will be used to precondition the iterative process. /// Sets the <see cref="IPreConditioner"/> that will be used to precondition the iterative process.
/// </summary> /// </summary>
/// <param name="preconditioner">The preconditioner.</param> /// <param name="preconditioner">The preconditioner.</param>
public void SetPreconditioner(IPreConditioner<Complex> preconditioner) public void SetPreconditioner(IPreConditioner preconditioner)
{ {
_preconditioner = preconditioner; _preconditioner = preconditioner;
} }
/// <summary> /// <summary>
/// Sets the <see cref="IIterator{T}"/> that will be used to track the iterative process. /// Sets the <see cref="IIterator"/> that will be used to track the iterative process.
/// </summary> /// </summary>
/// <param name="iterator">The iterator.</param> /// <param name="iterator">The iterator.</param>
public void SetIterator(IIterator<Complex> iterator) public void SetIterator(IIterator iterator)
{ {
_iterator = iterator; _iterator = iterator;
} }
@ -196,14 +193,14 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param> /// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="vector">The solution vector, <c>b</c>.</param> /// <param name="vector">The solution vector, <c>b</c>.</param>
/// <returns>The result vector, <c>x</c>.</returns> /// <returns>The result vector, <c>x</c>.</returns>
public Vector<Complex> Solve(Matrix<Complex> matrix, Vector<Complex> vector) public Vector Solve(Matrix matrix, Vector vector)
{ {
if (vector == null) if (vector == null)
{ {
throw new ArgumentNullException(); throw new ArgumentNullException();
} }
Vector<Complex> result = new DenseVector(matrix.RowCount); Vector result = new DenseVector(matrix.RowCount);
Solve(matrix, vector, result); Solve(matrix, vector, result);
return result; return result;
} }
@ -215,7 +212,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param> /// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution vector, <c>b</c></param> /// <param name="input">The solution vector, <c>b</c></param>
/// <param name="result">The result vector, <c>x</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 matrix, Vector input, Vector result)
{ {
// If we were stopped before, we are no longer // If we were stopped before, we are no longer
// We're doing this at the start of the method to ensure // We're doing this at the start of the method to ensure
@ -427,13 +424,13 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
} }
/// <summary> /// <summary>
/// Calculates the true residual of the matrix equation Ax = b according to: residual = b - Ax /// Calculates the <c>true</c> residual of the matrix equation Ax = b according to: residual = b - Ax
/// </summary> /// </summary>
/// <param name="matrix">Instance of the <see cref="Matrix{T}"/> A.</param> /// <param name="matrix">Instance of the <see cref="Matrix"/> A.</param>
/// <param name="residual">Residual values in <see cref="Vector{T}"/>.</param> /// <param name="residual">Residual values in <see cref="Vector"/>.</param>
/// <param name="x">Instance of the <see cref="Vector{T}"/> x.</param> /// <param name="x">Instance of the <see cref="Vector"/> x.</param>
/// <param name="b">Instance of the <see cref="Vector{T}"/> b.</param> /// <param name="b">Instance of the <see cref="Vector"/> b.</param>
private static void CalculateTrueResidual(Matrix<Complex> matrix, Vector<Complex> residual, Vector<Complex> x, Vector<Complex> b) private static void CalculateTrueResidual(Matrix matrix, Vector residual, Vector x, Vector b)
{ {
// -Ax = residual // -Ax = residual
matrix.Multiply(x, residual); matrix.Multiply(x, residual);
@ -447,11 +444,11 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
/// Determine if calculation should continue /// Determine if calculation should continue
/// </summary> /// </summary>
/// <param name="iterationNumber">Number of iterations passed</param> /// <param name="iterationNumber">Number of iterations passed</param>
/// <param name="result">Result <see cref="Vector{T}"/>.</param> /// <param name="result">Result <see cref="Vector"/>.</param>
/// <param name="source">Source <see cref="Vector{T}"/>.</param> /// <param name="source">Source <see cref="Vector"/>.</param>
/// <param name="residuals">Residual <see cref="Vector{T}"/>.</param> /// <param name="residuals">Residual <see cref="Vector"/>.</param>
/// <returns><c>true</c> if continue, otherwise <c>false</c></returns> /// <returns><c>true</c> if continue, otherwise <c>false</c></returns>
private bool ShouldContinue(int iterationNumber, Vector<Complex> result, Vector<Complex> source, Vector<Complex> residuals) private bool ShouldContinue(int iterationNumber, Vector result, Vector source, Vector residuals)
{ {
if (_hasBeenStopped) if (_hasBeenStopped)
{ {
@ -485,7 +482,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param> /// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution matrix, <c>B</c>.</param> /// <param name="input">The solution matrix, <c>B</c>.</param>
/// <returns>The result matrix, <c>X</c>.</returns> /// <returns>The result matrix, <c>X</c>.</returns>
public Matrix<Complex> Solve(Matrix<Complex> matrix, Matrix<Complex> input) public Matrix Solve(Matrix matrix, Matrix input)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -497,7 +494,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
throw new ArgumentNullException("input"); throw new ArgumentNullException("input");
} }
var result = matrix.CreateMatrix(input.RowCount, input.ColumnCount); var result = (Matrix)matrix.CreateMatrix(input.RowCount, input.ColumnCount);
Solve(matrix, input, result); Solve(matrix, input, result);
return result; return result;
} }
@ -509,7 +506,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param> /// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution matrix, <c>B</c>.</param> /// <param name="input">The solution matrix, <c>B</c>.</param>
/// <param name="result">The result matrix, <c>X</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 matrix, Matrix input, Matrix result)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -533,7 +530,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative
for (var column = 0; column < input.ColumnCount; column++) for (var column = 0; column < input.ColumnCount; column++)
{ {
var solution = Solve(matrix, input.Column(column)); var solution = Solve(matrix, (Vector)input.Column(column));
foreach (var element in solution.GetIndexedEnumerator()) foreach (var element in solution.GetIndexedEnumerator())
{ {
result.At(element.Key, column, element.Value); result.At(element.Key, column, element.Value);

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

@ -33,18 +33,14 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Numerics;
using Generic;
using Generic.Solvers;
using Generic.Solvers.Status; using Generic.Solvers.Status;
using Generic.Solvers.StopCriterium;
using Properties; using Properties;
using StopCriterium; using StopCriterium;
/// <summary> /// <summary>
/// An iterator that is used to check if an iterative calculation should continue or stop. /// An iterator that is used to check if an iterative calculation should continue or stop.
/// </summary> /// </summary>
public sealed class Iterator : IIterator<Complex> public sealed class Iterator : IIterator
{ {
/// <summary> /// <summary>
/// The default status for the iterator. /// The default status for the iterator.
@ -52,10 +48,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
private static readonly ICalculationStatus DefaultStatus = new CalculationIndetermined(); private static readonly ICalculationStatus DefaultStatus = new CalculationIndetermined();
/// <summary> /// <summary>
/// Creates a default iterator with all the <see cref="IIterationStopCriterium{T}"/> objects. /// Creates a default iterator with all the <see cref="IIterationStopCriterium"/> objects.
/// </summary> /// </summary>
/// <returns>A new <see cref="IIterator{T}"/> object.</returns> /// <returns>A new <see cref="IIterator"/> object.</returns>
public static IIterator<Complex> CreateDefault() public static IIterator CreateDefault()
{ {
var iterator = new Iterator(); var iterator = new Iterator();
iterator.Add(new FailureStopCriterium()); iterator.Add(new FailureStopCriterium());
@ -70,7 +66,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
/// The collection that holds all the stop criteria and the flag indicating if they should be added /// The collection that holds all the stop criteria and the flag indicating if they should be added
/// to the child iterators. /// to the child iterators.
/// </summary> /// </summary>
private readonly Dictionary<Type, IIterationStopCriterium<Complex>> _stopCriterias = new Dictionary<Type, IIterationStopCriterium<Complex>>(); private readonly Dictionary<Type, IIterationStopCriterium> _stopCriterias = new Dictionary<Type, IIterationStopCriterium>();
/// <summary> /// <summary>
/// The status of the iterator. /// The status of the iterator.
@ -97,7 +93,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
/// of the stop criteria will be passed on to child iterators. /// of the stop criteria will be passed on to child iterators.
/// </param> /// </param>
/// <exception cref="ArgumentException">Thrown if <paramref name="stopCriteria"/> contains multiple stop criteria of the same type.</exception> /// <exception cref="ArgumentException">Thrown if <paramref name="stopCriteria"/> contains multiple stop criteria of the same type.</exception>
public Iterator(IEnumerable<IIterationStopCriterium<Complex>> stopCriteria) public Iterator(IEnumerable<IIterationStopCriterium> stopCriteria)
{ {
// Add the stop criteria // Add the stop criteria
if (stopCriteria == null) if (stopCriteria == null)
@ -112,7 +108,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
} }
/// <summary> /// <summary>
/// Adds an <see cref="IIterationStopCriterium{T}"/> to the internal collection of stop-criteria. Only a /// Adds an <see cref="IIterationStopCriterium"/> to the internal collection of stop-criteria. Only a
/// single stop criterium of each type can be stored. /// single stop criterium of each type can be stored.
/// </summary> /// </summary>
/// <param name="stopCriterium">The stop criterium to add.</param> /// <param name="stopCriterium">The stop criterium to add.</param>
@ -121,7 +117,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
/// Thrown if <paramref name="stopCriterium"/> is of the same type as an already /// Thrown if <paramref name="stopCriterium"/> is of the same type as an already
/// stored criterium. /// stored criterium.
/// </exception> /// </exception>
public void Add(IIterationStopCriterium<Complex> stopCriterium) public void Add(IIterationStopCriterium stopCriterium)
{ {
if (stopCriterium == null) if (stopCriterium == null)
{ {
@ -138,10 +134,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
} }
/// <summary> /// <summary>
/// Removes the <see cref="IIterationStopCriterium{T}"/> from the internal collection. /// Removes the <see cref="IIterationStopCriterium"/> from the internal collection.
/// </summary> /// </summary>
/// <param name="stopCriterium">The stop criterium that must be removed.</param> /// <param name="stopCriterium">The stop criterium that must be removed.</param>
public void Remove(IIterationStopCriterium<Complex> stopCriterium) public void Remove(IIterationStopCriterium stopCriterium)
{ {
if (stopCriterium == null) if (stopCriterium == null)
{ {
@ -158,11 +154,11 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
} }
/// <summary> /// <summary>
/// Indicates if the specific stop criterium is stored by the <see cref="IIterator{T}"/>. /// Indicates if the specific stop criterium is stored by the <see cref="IIterator"/>.
/// </summary> /// </summary>
/// <param name="stopCriterium">The stop criterium.</param> /// <param name="stopCriterium">The stop criterium.</param>
/// <returns><c>true</c> if the <see cref="IIterator{T}"/> contains the stop criterium; otherwise <c>false</c>.</returns> /// <returns><c>true</c> if the <see cref="IIterator"/> contains the stop criterium; otherwise <c>false</c>.</returns>
public bool Contains(IIterationStopCriterium<Complex> stopCriterium) public bool Contains(IIterationStopCriterium stopCriterium)
{ {
return stopCriterium != null && _stopCriterias.ContainsKey(stopCriterium.GetType()); return stopCriterium != null && _stopCriterias.ContainsKey(stopCriterium.GetType());
} }
@ -183,7 +179,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
/// Gets an <c>IEnumerator</c> that enumerates over all the stored stop criteria. /// Gets an <c>IEnumerator</c> that enumerates over all the stored stop criteria.
/// </summary> /// </summary>
/// <remarks>Used for testing only.</remarks> /// <remarks>Used for testing only.</remarks>
internal IEnumerator<IIterationStopCriterium<Complex>> StoredStopCriteria internal IEnumerator<IIterationStopCriterium> StoredStopCriteria
{ {
get get
{ {
@ -216,7 +212,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
/// on the invocation of this method. Therefore this method should only be called if the /// on the invocation of this method. Therefore this method should only be called if the
/// calculation has moved forwards at least one step. /// calculation has moved forwards at least one step.
/// </remarks> /// </remarks>
public void DetermineStatus(int iterationNumber, Vector<Complex> solutionVector, Vector<Complex> sourceVector, Vector<Complex> residualVector) public void DetermineStatus(int iterationNumber, Vector solutionVector, Vector sourceVector, Vector residualVector)
{ {
if (_stopCriterias.Count == 0) if (_stopCriterias.Count == 0)
{ {
@ -288,7 +284,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
} }
/// <summary> /// <summary>
/// Resets the <see cref="IIterator{T}"/> to the pre-calculation state. /// Resets the <see cref="IIterator"/> to the pre-calculation state.
/// </summary> /// </summary>
public void ResetToPrecalculationState() public void ResetToPrecalculationState()
{ {
@ -309,9 +305,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers
/// Creates a deep clone of the current iterator. /// Creates a deep clone of the current iterator.
/// </summary> /// </summary>
/// <returns>The deep clone of the current iterator.</returns> /// <returns>The deep clone of the current iterator.</returns>
public IIterator<Complex> Clone() public IIterator Clone()
{ {
var stopCriteria = _stopCriterias.Select(pair => pair.Value).Select(stopCriterium => (IIterationStopCriterium<Complex>)stopCriterium.Clone()).ToList(); var stopCriteria = _stopCriterias.Select(pair => pair.Value).Select(stopCriterium => (IIterationStopCriterium)stopCriterium.Clone()).ToList();
return new Iterator(stopCriteria); return new Iterator(stopCriteria);
} }

14
src/Numerics/LinearAlgebra/Complex/Solvers/Preconditioners/Diagonal.cs

@ -32,15 +32,13 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Preconditioners
{ {
using System; using System;
using System.Numerics; using System.Numerics;
using Generic;
using Generic.Solvers.Preconditioners;
using Properties; using Properties;
/// <summary> /// <summary>
/// A diagonal preconditioner. The preconditioner uses the inverse /// A diagonal preconditioner. The preconditioner uses the inverse
/// of the matrix diagonal as preconditioning values. /// of the matrix diagonal as preconditioning values.
/// </summary> /// </summary>
public sealed class Diagonal : IPreConditioner<Complex> public sealed class Diagonal : IPreConditioner
{ {
/// <summary> /// <summary>
/// The inverse of the matrix diagonal. /// The inverse of the matrix diagonal.
@ -66,10 +64,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Preconditioners
/// Initializes the preconditioner and loads the internal data structures. /// Initializes the preconditioner and loads the internal data structures.
/// </summary> /// </summary>
/// <param name="matrix"> /// <param name="matrix">
/// The <see cref="Matrix{T}"/> upon which this preconditioner is based.</param> /// The <see cref="Matrix"/> upon which this preconditioner is based.</param>
/// <exception cref="ArgumentNullException">If <paramref name="matrix"/> is <see langword="null" />. </exception> /// <exception cref="ArgumentNullException">If <paramref name="matrix"/> is <see langword="null" />. </exception>
/// <exception cref="ArgumentException">If <paramref name="matrix"/> is not a square matrix.</exception> /// <exception cref="ArgumentException">If <paramref name="matrix"/> is not a square matrix.</exception>
public void Initialize(Matrix<Complex> matrix) public void Initialize(Matrix matrix)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -93,7 +91,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Preconditioners
/// </summary> /// </summary>
/// <param name="rhs">The right hand side vector.</param> /// <param name="rhs">The right hand side vector.</param>
/// <returns>The left hand side vector.</returns> /// <returns>The left hand side vector.</returns>
public Vector<Complex> Approximate(Vector<Complex> rhs) public Vector Approximate(Vector rhs)
{ {
if (rhs == null) if (rhs == null)
{ {
@ -110,7 +108,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Preconditioners
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "rhs"); throw new ArgumentException(Resources.ArgumentVectorsSameLength, "rhs");
} }
Vector<Complex> result = new DenseVector(rhs.Count); Vector result = new DenseVector(rhs.Count);
Approximate(rhs, result); Approximate(rhs, result);
return result; return result;
} }
@ -120,7 +118,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Preconditioners
/// </summary> /// </summary>
/// <param name="rhs">The right hand side vector.</param> /// <param name="rhs">The right hand side vector.</param>
/// <param name="lhs">The left hand side vector. Also known as the result vector.</param> /// <param name="lhs">The left hand side vector. Also known as the result vector.</param>
public void Approximate(Vector<Complex> rhs, Vector<Complex> lhs) public void Approximate(Vector rhs, Vector lhs)
{ {
if (rhs == null) if (rhs == null)
{ {

14
src/Numerics/LinearAlgebra/Generic/Solvers/Preconditioners/IPreConditioner.cs → src/Numerics/LinearAlgebra/Complex/Solvers/Preconditioners/IPreConditioner.cs

@ -28,11 +28,8 @@
// OTHER DEALINGS IN THE SOFTWARE. // OTHER DEALINGS IN THE SOFTWARE.
// </copyright> // </copyright>
namespace MathNet.Numerics.LinearAlgebra.Generic.Solvers.Preconditioners namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Preconditioners
{ {
using System;
using System.Numerics;
/// <summary> /// <summary>
/// The base interface for preconditioner classes. /// The base interface for preconditioner classes.
/// </summary> /// </summary>
@ -51,27 +48,26 @@ namespace MathNet.Numerics.LinearAlgebra.Generic.Solvers.Preconditioners
/// if the changes occur after creating the preconditioner. /// if the changes occur after creating the preconditioner.
/// </para> /// </para>
/// </remarks> /// </remarks>
/// <typeparam name="T">Supported data types are double, single, <see cref="Complex"/>, and <see cref="Complex32"/>.</typeparam> public interface IPreConditioner
public interface IPreConditioner<T> where T : struct, IEquatable<T>, IFormattable
{ {
/// <summary> /// <summary>
/// Initializes the preconditioner and loads the internal data structures. /// Initializes the preconditioner and loads the internal data structures.
/// </summary> /// </summary>
/// <param name="matrix">The matrix on which the preconditioner is based.</param> /// <param name="matrix">The matrix on which the preconditioner is based.</param>
void Initialize(Matrix<T> matrix); void Initialize(Matrix matrix);
/// <summary> /// <summary>
/// Approximates the solution to the matrix equation <b>Mx = b</b>. /// Approximates the solution to the matrix equation <b>Mx = b</b>.
/// </summary> /// </summary>
/// <param name="rhs">The right hand side vector.</param> /// <param name="rhs">The right hand side vector.</param>
/// <returns>The left hand side vector.</returns> /// <returns>The left hand side vector.</returns>
Vector<T> Approximate(Vector<T> rhs); Vector Approximate(Vector rhs);
/// <summary> /// <summary>
/// Approximates the solution to the matrix equation <b>Mx = b</b>. /// Approximates the solution to the matrix equation <b>Mx = b</b>.
/// </summary> /// </summary>
/// <param name="rhs">The right hand side vector.</param> /// <param name="rhs">The right hand side vector.</param>
/// <param name="lhs">The left hand side vector. Also known as the result vector.</param> /// <param name="lhs">The left hand side vector. Also known as the result vector.</param>
void Approximate(Vector<T> rhs, Vector<T> lhs); void Approximate(Vector rhs, Vector lhs);
} }
} }

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

@ -33,8 +33,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Preconditioners
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Numerics; using System.Numerics;
using Generic;
using Generic.Solvers.Preconditioners;
using Properties; using Properties;
/// <summary> /// <summary>
@ -54,7 +52,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Preconditioners
/// pp. 20 - 28 <br/> /// pp. 20 - 28 <br/>
/// Algorithm is described in Section 2, page 22 /// Algorithm is described in Section 2, page 22
/// </remarks> /// </remarks>
public sealed class Ilutp : IPreConditioner<Complex> public sealed class Ilutp : IPreConditioner
{ {
/// <summary> /// <summary>
/// The default fill level. /// The default fill level.
@ -258,9 +256,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Preconditioners
/// This method is used for debugging purposes only and should normally not be used. /// This method is used for debugging purposes only and should normally not be used.
/// </remarks> /// </remarks>
/// <returns>A new matrix containing the upper triagonal elements.</returns> /// <returns>A new matrix containing the upper triagonal elements.</returns>
internal Matrix<Complex> UpperTriangle() internal Matrix UpperTriangle()
{ {
return _upper.Clone(); return (Matrix)_upper.Clone();
} }
/// <summary> /// <summary>
@ -270,9 +268,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Preconditioners
/// This method is used for debugging purposes only and should normally not be used. /// This method is used for debugging purposes only and should normally not be used.
/// </remarks> /// </remarks>
/// <returns>A new matrix containing the lower triagonal elements.</returns> /// <returns>A new matrix containing the lower triagonal elements.</returns>
internal Matrix<Complex> LowerTriangle() internal Matrix LowerTriangle()
{ {
return _lower.Clone(); return (Matrix)_lower.Clone();
} }
/// <summary> /// <summary>
@ -298,13 +296,13 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Preconditioners
/// Initializes the preconditioner and loads the internal data structures. /// Initializes the preconditioner and loads the internal data structures.
/// </summary> /// </summary>
/// <param name="matrix"> /// <param name="matrix">
/// The <see cref="Matrix{T}"/> upon which this preconditioner is based. Note that the /// The <see cref="Matrix"/> upon which this preconditioner is based. Note that the
/// method takes a general matrix type. However internally the data is stored /// method takes a general matrix type. However internally the data is stored
/// as a sparse matrix. Therefore it is not recommended to pass a dense matrix. /// as a sparse matrix. Therefore it is not recommended to pass a dense matrix.
/// </param> /// </param>
/// <exception cref="ArgumentNullException"> If <paramref name="matrix"/> is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException"> If <paramref name="matrix"/> is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If <paramref name="matrix"/> is not a square matrix.</exception> /// <exception cref="ArgumentException">If <paramref name="matrix"/> is not a square matrix.</exception>
public void Initialize(Matrix<Complex> matrix) public void Initialize(Matrix matrix)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -376,8 +374,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Preconditioners
_pivots[i] = i; _pivots[i] = i;
} }
Vector<Complex> workVector = new DenseVector(sparseMatrix.RowCount); Vector workVector = new DenseVector(sparseMatrix.RowCount);
Vector<Complex> rowVector = new DenseVector(sparseMatrix.ColumnCount); Vector rowVector = new DenseVector(sparseMatrix.ColumnCount);
var indexSorting = new int[sparseMatrix.RowCount]; var indexSorting = new int[sparseMatrix.RowCount];
// spaceLeft = lfilNnz * nnz(A) // spaceLeft = lfilNnz * nnz(A)
@ -532,8 +530,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Preconditioners
/// <summary> /// <summary>
/// Pivot elements in the <paramref name="row"/> according to internal pivot array /// Pivot elements in the <paramref name="row"/> according to internal pivot array
/// </summary> /// </summary>
/// <param name="row">Row <see cref="Vector{T}"/> to pivot in</param> /// <param name="row">Row <see cref="Vector"/> to pivot in</param>
private void PivotRow(Vector<Complex> row) private void PivotRow(Vector row)
{ {
var knownPivots = new Dictionary<int, int>(); var knownPivots = new Dictionary<int, int>();
@ -580,12 +578,12 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Preconditioners
} }
/// <summary> /// <summary>
/// Swap columns in the <see cref="Matrix{T}"/> /// Swap columns in the <see cref="Matrix"/>
/// </summary> /// </summary>
/// <param name="matrix">Source <see cref="Matrix{T}"/>.</param> /// <param name="matrix">Source <see cref="Matrix"/>.</param>
/// <param name="firstColumn">First column index to swap</param> /// <param name="firstColumn">First column index to swap</param>
/// <param name="secondColumn">Second column index to swap</param> /// <param name="secondColumn">Second column index to swap</param>
private static void SwapColumns(Matrix<Complex> matrix, int firstColumn, int secondColumn) private static void SwapColumns(Matrix matrix, int firstColumn, int secondColumn)
{ {
for (var i = 0; i < matrix.RowCount; i++) for (var i = 0; i < matrix.RowCount; i++)
{ {
@ -601,8 +599,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Preconditioners
/// <param name="lowerBound">Start sort form</param> /// <param name="lowerBound">Start sort form</param>
/// <param name="upperBound">Sort till upper bound</param> /// <param name="upperBound">Sort till upper bound</param>
/// <param name="sortedIndices">Array with sorted vector indicies</param> /// <param name="sortedIndices">Array with sorted vector indicies</param>
/// <param name="values">Source <see cref="Vector{T}"/></param> /// <param name="values">Source <see cref="Vector"/></param>
private static void FindLargestItems(int lowerBound, int upperBound, int[] sortedIndices, Vector<Complex> values) private static void FindLargestItems(int lowerBound, int upperBound, int[] sortedIndices, Vector values)
{ {
// Copy the indices for the values into the array // Copy the indices for the values into the array
for (var i = 0; i < upperBound + 1 - lowerBound; i++) for (var i = 0; i < upperBound + 1 - lowerBound; i++)
@ -627,7 +625,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Preconditioners
/// </summary> /// </summary>
/// <param name="rhs">The right hand side vector.</param> /// <param name="rhs">The right hand side vector.</param>
/// <returns>The left hand side vector.</returns> /// <returns>The left hand side vector.</returns>
public Vector<Complex> Approximate(Vector<Complex> rhs) public Vector Approximate(Vector rhs)
{ {
if (rhs == null) if (rhs == null)
{ {
@ -644,7 +642,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Preconditioners
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "rhs"); throw new ArgumentException(Resources.ArgumentVectorsSameLength, "rhs");
} }
Vector<Complex> result = new DenseVector(rhs.Count); Vector result = new DenseVector(rhs.Count);
Approximate(rhs, result); Approximate(rhs, result);
return result; return result;
} }
@ -654,7 +652,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Preconditioners
/// </summary> /// </summary>
/// <param name="rhs">The right hand side vector.</param> /// <param name="rhs">The right hand side vector.</param>
/// <param name="lhs">The left hand side vector. Also known as the result vector.</param> /// <param name="lhs">The left hand side vector. Also known as the result vector.</param>
public void Approximate(Vector<Complex> rhs, Vector<Complex> lhs) public void Approximate(Vector rhs, Vector lhs)
{ {
if (rhs == null) if (rhs == null)
{ {
@ -679,7 +677,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Preconditioners
// Solve equation here // Solve equation here
// Pivot(vector, result); // Pivot(vector, result);
// Solve L*Y = B(piv,:) // Solve L*Y = B(piv,:)
Vector<Complex> rowValues = new DenseVector(_lower.RowCount); Vector rowValues = new DenseVector(_lower.RowCount);
for (var i = 0; i < _lower.RowCount; i++) for (var i = 0; i < _lower.RowCount; i++)
{ {
_lower.Row(i, rowValues); _lower.Row(i, rowValues);
@ -709,17 +707,17 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Preconditioners
// We have a column pivot so we only need to pivot the // We have a column pivot so we only need to pivot the
// end result not the incoming right hand side vector // end result not the incoming right hand side vector
var temp = lhs.Clone(); var temp = (Vector)lhs.Clone();
Pivot(temp, lhs); Pivot(temp, lhs);
} }
/// <summary> /// <summary>
/// Pivot elements in <see cref="Vector{T}"/> accoring to internal pivot array /// Pivot elements in <see cref="Vector"/> according to internal pivot array
/// </summary> /// </summary>
/// <param name="vector">Source <see cref="Vector{T}"/>.</param> /// <param name="vector">Source <see cref="Vector"/>.</param>
/// <param name="result">Result <see cref="Vector{T}"/> after pivoting.</param> /// <param name="result">Result <see cref="Vector"/> after pivoting.</param>
private void Pivot(Vector<Complex> vector, Vector<Complex> result) private void Pivot(Vector vector, Vector result)
{ {
for (var i = 0; i < _pivots.Length; i++) for (var i = 0; i < _pivots.Length; i++)
{ {

18
src/Numerics/LinearAlgebra/Complex/Solvers/Preconditioners/IlutpElementSorter.cs

@ -95,7 +95,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Preconditioners
/// Build heap for double indicies /// Build heap for double indicies
/// </summary> /// </summary>
/// <param name="start">Root position</param> /// <param name="start">Root position</param>
/// <param name="count">Lenght of <paramref name="values"/></param> /// <param name="count">Length of <paramref name="values"/></param>
/// <param name="sortedIndices">Indicies of <paramref name="values"/></param> /// <param name="sortedIndices">Indicies of <paramref name="values"/></param>
/// <param name="values">Target <see cref="Vector{T}"/></param> /// <param name="values">Target <see cref="Vector{T}"/></param>
private static void BuildDoubleIndexHeap(int start, int count, int[] sortedIndices, Vector<Complex> values) private static void BuildDoubleIndexHeap(int start, int count, int[] sortedIndices, Vector<Complex> values)
@ -113,15 +113,14 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Preconditioners
/// <param name="sortedIndices">Indicies of <paramref name="values"/></param> /// <param name="sortedIndices">Indicies of <paramref name="values"/></param>
/// <param name="values">Target <see cref="Vector{T}"/></param> /// <param name="values">Target <see cref="Vector{T}"/></param>
/// <param name="begin">Root position</param> /// <param name="begin">Root position</param>
/// <param name="count">Lenght of <paramref name="values"/></param> /// <param name="count">Length of <paramref name="values"/></param>
private static void SiftDoubleIndices(int[] sortedIndices, Vector<Complex> values, int begin, int count) private static void SiftDoubleIndices(int[] sortedIndices, Vector<Complex> values, int begin, int count)
{ {
var root = begin; var root = begin;
int child;
while (root * 2 < count) while (root * 2 < count)
{ {
child = root * 2; var child = root * 2;
if ((child < count - 1) && (values[sortedIndices[child]].Magnitude > values[sortedIndices[child + 1]].Magnitude)) if ((child < count - 1) && (values[sortedIndices[child]].Magnitude > values[sortedIndices[child + 1]].Magnitude))
{ {
child += 1; child += 1;
@ -171,7 +170,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Preconditioners
/// </summary> /// </summary>
/// <param name="values">Target values array</param> /// <param name="values">Target values array</param>
/// <param name="start">Root position</param> /// <param name="start">Root position</param>
/// <param name="count">Lenght of <paramref name="values"/></param> /// <param name="count">Length of <paramref name="values"/></param>
private static void BuildHeap(int[] values, int start, int count) private static void BuildHeap(int[] values, int start, int count)
{ {
while (start >= 0) while (start >= 0)
@ -186,15 +185,14 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Preconditioners
/// </summary> /// </summary>
/// <param name="values">Target value array</param> /// <param name="values">Target value array</param>
/// <param name="start">Root position</param> /// <param name="start">Root position</param>
/// <param name="count">Lenght of <paramref name="values"/></param> /// <param name="count">Length of <paramref name="values"/></param>
private static void Sift(int[] values, int start, int count) private static void Sift(int[] values, int start, int count)
{ {
var root = start; var root = start;
int child;
while (root * 2 < count) while (root * 2 < count)
{ {
child = root * 2; var child = root * 2;
if ((child < count - 1) && (values[child] > values[child + 1])) if ((child < count - 1) && (values[child] > values[child + 1]))
{ {
child += 1; child += 1;
@ -216,8 +214,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Preconditioners
/// Exchange values in array /// Exchange values in array
/// </summary> /// </summary>
/// <param name="values">Target values array</param> /// <param name="values">Target values array</param>
/// <param name="first">First value to exchanghe</param> /// <param name="first">First value to exchange</param>
/// <param name="second">Second value to exchanghe</param> /// <param name="second">Second value to exchange</param>
private static void Exchange(int[] values, int first, int second) private static void Exchange(int[] values, int first, int second)
{ {
var t = values[first]; var t = values[first];

18
src/Numerics/LinearAlgebra/Complex/Solvers/Preconditioners/IncompleteLU.cs

@ -32,8 +32,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Preconditioners
{ {
using System; using System;
using System.Numerics; using System.Numerics;
using Generic;
using Generic.Solvers.Preconditioners;
using Properties; using Properties;
/// <summary> /// <summary>
@ -45,7 +43,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Preconditioners
/// Yousef Saad <br/> /// Yousef Saad <br/>
/// Algorithm is described in Chapter 10, section 10.3.2, page 275 <br/> /// Algorithm is described in Chapter 10, section 10.3.2, page 275 <br/>
/// </remarks> /// </remarks>
public sealed class IncompleteLU : IPreConditioner<Complex> public sealed class IncompleteLU : IPreConditioner
{ {
/// <summary> /// <summary>
/// The matrix holding the lower (L) and upper (U) matrices. The /// The matrix holding the lower (L) and upper (U) matrices. The
@ -57,7 +55,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Preconditioners
/// Returns the upper triagonal matrix that was created during the LU decomposition. /// Returns the upper triagonal matrix that was created during the LU decomposition.
/// </summary> /// </summary>
/// <returns>A new matrix containing the upper triagonal elements.</returns> /// <returns>A new matrix containing the upper triagonal elements.</returns>
internal Matrix<Complex> UpperTriangle() internal Matrix UpperTriangle()
{ {
var result = new SparseMatrix(_decompositionLU.RowCount); var result = new SparseMatrix(_decompositionLU.RowCount);
for (var i = 0; i < _decompositionLU.RowCount; i++) for (var i = 0; i < _decompositionLU.RowCount; i++)
@ -75,7 +73,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Preconditioners
/// Returns the lower triagonal matrix that was created during the LU decomposition. /// Returns the lower triagonal matrix that was created during the LU decomposition.
/// </summary> /// </summary>
/// <returns>A new matrix containing the lower triagonal elements.</returns> /// <returns>A new matrix containing the lower triagonal elements.</returns>
internal Matrix<Complex> LowerTriangle() internal Matrix LowerTriangle()
{ {
var result = new SparseMatrix(_decompositionLU.RowCount); var result = new SparseMatrix(_decompositionLU.RowCount);
for (var i = 0; i < _decompositionLU.RowCount; i++) for (var i = 0; i < _decompositionLU.RowCount; i++)
@ -102,7 +100,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Preconditioners
/// <param name="matrix">The matrix upon which the preconditioner is based. </param> /// <param name="matrix">The matrix upon which the preconditioner is based. </param>
/// <exception cref="ArgumentNullException">If <paramref name="matrix"/> is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If <paramref name="matrix"/> is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If <paramref name="matrix"/> is not a square matrix.</exception> /// <exception cref="ArgumentException">If <paramref name="matrix"/> is not a square matrix.</exception>
public void Initialize(Matrix<Complex> matrix) public void Initialize(Matrix matrix)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -164,7 +162,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Preconditioners
/// </summary> /// </summary>
/// <param name="rhs">The right hand side vector.</param> /// <param name="rhs">The right hand side vector.</param>
/// <returns>The left hand side vector.</returns> /// <returns>The left hand side vector.</returns>
public Vector<Complex> Approximate(Vector<Complex> rhs) public Vector Approximate(Vector rhs)
{ {
if (rhs == null) if (rhs == null)
{ {
@ -181,7 +179,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Preconditioners
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "rhs"); throw new ArgumentException(Resources.ArgumentVectorsSameLength, "rhs");
} }
Vector<Complex> result = new DenseVector(rhs.Count); Vector result = new DenseVector(rhs.Count);
Approximate(rhs, result); Approximate(rhs, result);
return result; return result;
} }
@ -191,7 +189,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Preconditioners
/// </summary> /// </summary>
/// <param name="rhs">The right hand side vector.</param> /// <param name="rhs">The right hand side vector.</param>
/// <param name="lhs">The left hand side vector. Also known as the result vector.</param> /// <param name="lhs">The left hand side vector. Also known as the result vector.</param>
public void Approximate(Vector<Complex> rhs, Vector<Complex> lhs) public void Approximate(Vector rhs, Vector lhs)
{ {
if (rhs == null) if (rhs == null)
{ {
@ -221,7 +219,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Preconditioners
// z_i = l_ii^-1 * (y_i - SUM_(j<i) l_ij * z_j) // z_i = l_ii^-1 * (y_i - SUM_(j<i) l_ij * z_j)
// } // }
// NOTE: l_ii should be 1 because u_ii has to be the value // NOTE: l_ii should be 1 because u_ii has to be the value
Vector<Complex> rowValues = new DenseVector(_decompositionLU.RowCount); Vector rowValues = new DenseVector(_decompositionLU.RowCount);
for (var i = 0; i < _decompositionLU.RowCount; i++) for (var i = 0; i < _decompositionLU.RowCount; i++)
{ {
// Clear the rowValues // Clear the rowValues

16
src/Numerics/LinearAlgebra/Complex/Solvers/Preconditioners/UnitPreconditioner.cs

@ -31,18 +31,14 @@
namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Preconditioners namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Preconditioners
{ {
using System; using System;
using System.Numerics;
using Generic;
using Generic.Solvers;
using Generic.Solvers.Preconditioners;
using Properties; using Properties;
/// <summary> /// <summary>
/// A unit preconditioner. This preconditioner does not actually do anything /// A unit preconditioner. This preconditioner does not actually do anything
/// it is only used when running an <see cref="IIterativeSolver{T}"/> without /// it is only used when running an <see cref="IIterativeSolver"/> without
/// a preconditioner. /// a preconditioner.
/// </summary> /// </summary>
internal sealed class UnitPreconditioner : IPreConditioner<Complex> internal sealed class UnitPreconditioner : IPreConditioner
{ {
/// <summary> /// <summary>
/// The coefficient matrix on which this preconditioner operates. /// The coefficient matrix on which this preconditioner operates.
@ -58,7 +54,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Preconditioners
/// </param> /// </param>
/// <exception cref="ArgumentNullException">If <paramref name="matrix"/> is <see langword="null"/>. </exception> /// <exception cref="ArgumentNullException">If <paramref name="matrix"/> is <see langword="null"/>. </exception>
/// <exception cref="ArgumentException">If <paramref name="matrix"/> is not a square matrix.</exception> /// <exception cref="ArgumentException">If <paramref name="matrix"/> is not a square matrix.</exception>
public void Initialize(Matrix<Complex> matrix) public void Initialize(Matrix matrix)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -91,7 +87,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Preconditioners
/// If the size of <paramref name="rhs"/> is different the number of rows of the coefficient matrix. /// If the size of <paramref name="rhs"/> is different the number of rows of the coefficient matrix.
/// </para> /// </para>
/// </exception> /// </exception>
public void Approximate(Vector<Complex> rhs, Vector<Complex> lhs) public void Approximate(Vector rhs, Vector lhs)
{ {
if (rhs == null) if (rhs == null)
{ {
@ -120,7 +116,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Preconditioners
/// <exception cref="ArgumentException"> /// <exception cref="ArgumentException">
/// If the size of <paramref name="rhs"/> is different the number of rows of the coefficient matrix. /// If the size of <paramref name="rhs"/> is different the number of rows of the coefficient matrix.
/// </exception> /// </exception>
public Vector<Complex> Approximate(Vector<Complex> rhs) public Vector Approximate(Vector rhs)
{ {
if (rhs == null) if (rhs == null)
{ {
@ -132,7 +128,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Preconditioners
throw new ArgumentException(Resources.ArgumentMatrixDimensions); throw new ArgumentException(Resources.ArgumentMatrixDimensions);
} }
Vector<Complex> result = new DenseVector(rhs.Count); Vector result = new DenseVector(rhs.Count);
Approximate(rhs, result); Approximate(rhs, result);
return result; return result;
} }

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

@ -32,15 +32,13 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.StopCriterium
{ {
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using System.Numerics;
using Generic;
using Generic.Solvers.Status; using Generic.Solvers.Status;
using Generic.Solvers.StopCriterium; using Generic.Solvers.StopCriterium;
/// <summary> /// <summary>
/// Monitors an iterative calculation for signs of divergence. /// Monitors an iterative calculation for signs of divergence.
/// </summary> /// </summary>
public sealed class DivergenceStopCriterium : IIterationStopCriterium<Complex> public sealed class DivergenceStopCriterium : IIterationStopCriterium
{ {
/// <summary> /// <summary>
/// Default value for the maximum relative increase that the /// Default value for the maximum relative increase that the
@ -208,7 +206,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.StopCriterium
/// <summary> /// <summary>
/// Determines the status of the iterative calculation based on the stop criteria stored /// Determines the status of the iterative calculation based on the stop criteria stored
/// by the current <see cref="IIterationStopCriterium{T}"/>. Result is set into <c>Status</c> field. /// by the current <see cref="IIterationStopCriterium"/>. Result is set into <c>Status</c> field.
/// </summary> /// </summary>
/// <param name="iterationNumber">The number of iterations that have passed so far.</param> /// <param name="iterationNumber">The number of iterations that have passed so far.</param>
/// <param name="solutionVector">The vector containing the current solution values.</param> /// <param name="solutionVector">The vector containing the current solution values.</param>
@ -219,7 +217,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.StopCriterium
/// on the invocation of this method. Therefore this method should only be called if the /// on the invocation of this method. Therefore this method should only be called if the
/// calculation has moved forwards at least one step. /// calculation has moved forwards at least one step.
/// </remarks> /// </remarks>
public void DetermineStatus(int iterationNumber, Vector<Complex> solutionVector, Vector<Complex> sourceVector, Vector<Complex> residualVector) public void DetermineStatus(int iterationNumber, Vector solutionVector, Vector sourceVector, Vector residualVector)
{ {
if (iterationNumber < 0) if (iterationNumber < 0)
{ {
@ -302,7 +300,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.StopCriterium
} }
/// <summary> /// <summary>
/// Gets required history lenght /// Gets required history Length
/// </summary> /// </summary>
private int RequiredHistoryLength private int RequiredHistoryLength
{ {
@ -348,7 +346,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.StopCriterium
} }
/// <summary> /// <summary>
/// Resets the <see cref="IIterationStopCriterium{T}"/> to the pre-calculation state. /// Resets the <see cref="IIterationStopCriterium"/> to the pre-calculation state.
/// </summary> /// </summary>
public void ResetToPrecalculationState() public void ResetToPrecalculationState()
{ {
@ -359,7 +357,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.StopCriterium
/// <summary> /// <summary>
/// Gets the <see cref="StopLevel"/> which indicates what sort of stop criterium this /// Gets the <see cref="StopLevel"/> which indicates what sort of stop criterium this
/// <see cref="IIterationStopCriterium{T}"/> monitors. /// <see cref="IIterationStopCriterium"/> monitors.
/// </summary> /// </summary>
/// <value>Returns <see cref="Generic.Solvers.StopCriterium.StopLevel.Divergence"/>.</value> /// <value>Returns <see cref="Generic.Solvers.StopCriterium.StopLevel.Divergence"/>.</value>
public StopLevel StopLevel public StopLevel StopLevel
@ -375,7 +373,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.StopCriterium
/// Clones the current <see cref="DivergenceStopCriterium"/> and its settings. /// Clones the current <see cref="DivergenceStopCriterium"/> and its settings.
/// </summary> /// </summary>
/// <returns>A new instance of the <see cref="DivergenceStopCriterium"/> class.</returns> /// <returns>A new instance of the <see cref="DivergenceStopCriterium"/> class.</returns>
public IIterationStopCriterium<Complex> Clone() public IIterationStopCriterium Clone()
{ {
return new DivergenceStopCriterium(_maximumRelativeIncrease, _minimumNumberOfIterations); return new DivergenceStopCriterium(_maximumRelativeIncrease, _minimumNumberOfIterations);
} }

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

@ -32,16 +32,14 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.StopCriterium
{ {
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using System.Numerics;
using Generic;
using Generic.Solvers.Status; using Generic.Solvers.Status;
using Generic.Solvers.StopCriterium; using Generic.Solvers.StopCriterium;
using Properties; using Properties;
/// <summary> /// <summary>
/// Defines an <see cref="Generic.Solvers.StopCriterium.IIterationStopCriterium{T}"/> that monitors residuals for NaN's. /// Defines an <see cref="IIterationStopCriterium"/> that monitors residuals for NaN's.
/// </summary> /// </summary>
public sealed class FailureStopCriterium : IIterationStopCriterium<Complex> public sealed class FailureStopCriterium : IIterationStopCriterium
{ {
/// <summary> /// <summary>
/// Defines the default last iteration number. Set to -1 because iterations normally /// Defines the default last iteration number. Set to -1 because iterations normally
@ -66,7 +64,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.StopCriterium
/// <summary> /// <summary>
/// Determines the status of the iterative calculation based on the stop criteria stored /// Determines the status of the iterative calculation based on the stop criteria stored
/// by the current <see cref="IIterationStopCriterium{T}"/>. Result is set into <c>Status</c> field. /// by the current <see cref="IIterationStopCriterium"/>. Result is set into <c>Status</c> field.
/// </summary> /// </summary>
/// <param name="iterationNumber">The number of iterations that have passed so far.</param> /// <param name="iterationNumber">The number of iterations that have passed so far.</param>
/// <param name="solutionVector">The vector containing the current solution values.</param> /// <param name="solutionVector">The vector containing the current solution values.</param>
@ -77,7 +75,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.StopCriterium
/// on the invocation of this method. Therefore this method should only be called if the /// on the invocation of this method. Therefore this method should only be called if the
/// calculation has moved forwards at least one step. /// calculation has moved forwards at least one step.
/// </remarks> /// </remarks>
public void DetermineStatus(int iterationNumber, Vector<Complex> solutionVector, Vector<Complex> sourceVector, Vector<Complex> residualVector) public void DetermineStatus(int iterationNumber, Vector solutionVector, Vector sourceVector, Vector residualVector)
{ {
if (iterationNumber < 0) if (iterationNumber < 0)
{ {
@ -157,7 +155,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.StopCriterium
} }
/// <summary> /// <summary>
/// Resets the <see cref="IIterationStopCriterium{T}"/> to the pre-calculation state. /// Resets the <see cref="IIterationStopCriterium"/> to the pre-calculation state.
/// </summary> /// </summary>
public void ResetToPrecalculationState() public void ResetToPrecalculationState()
{ {
@ -167,7 +165,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.StopCriterium
/// <summary> /// <summary>
/// Gets the <see cref="StopLevel"/>which indicates what sort of stop criterium this /// Gets the <see cref="StopLevel"/>which indicates what sort of stop criterium this
/// <see cref="IIterationStopCriterium{T}"/> monitors. /// <see cref="IIterationStopCriterium"/> monitors.
/// </summary> /// </summary>
/// <value>Returns <see cref="CalculationFailure"/>.</value> /// <value>Returns <see cref="CalculationFailure"/>.</value>
public StopLevel StopLevel public StopLevel StopLevel
@ -183,7 +181,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.StopCriterium
/// Clones the current <see cref="FailureStopCriterium"/> and its settings. /// Clones the current <see cref="FailureStopCriterium"/> and its settings.
/// </summary> /// </summary>
/// <returns>A new instance of the <see cref="FailureStopCriterium"/> class.</returns> /// <returns>A new instance of the <see cref="FailureStopCriterium"/> class.</returns>
public IIterationStopCriterium<Complex> Clone() public IIterationStopCriterium Clone()
{ {
return new FailureStopCriterium(); return new FailureStopCriterium();
} }

24
src/Numerics/LinearAlgebra/Generic/Solvers/StopCriterium/IIterationStopCriterium.cs → src/Numerics/LinearAlgebra/Complex/Solvers/StopCriterium/IIterationStopCriterium.cs

@ -24,36 +24,34 @@
// OTHER DEALINGS IN THE SOFTWARE. // OTHER DEALINGS IN THE SOFTWARE.
// </copyright> // </copyright>
namespace MathNet.Numerics.LinearAlgebra.Generic.Solvers.StopCriterium namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.StopCriterium
{ {
using System; using System;
using System.Numerics; using Generic.Solvers.Status;
using Status; using Generic.Solvers.StopCriterium;
/// <summary> /// <summary>
/// The base interface for classes that provide stop criteria for iterative calculations. /// The base interface for classes that provide stop criteria for iterative calculations.
/// </summary> /// </summary>
/// <typeparam name="T">Supported data types are double, single, <see cref="Complex"/>, and <see cref="Complex32"/>.</typeparam> public interface IIterationStopCriterium
public interface IIterationStopCriterium<T>
#if !SILVERLIGHT #if !SILVERLIGHT
: ICloneable : ICloneable
#endif #endif
where T : struct, IEquatable<T>, IFormattable
{ {
/// <summary> /// <summary>
/// Determines the status of the iterative calculation based on the stop criteria stored /// Determines the status of the iterative calculation based on the stop criteria stored
/// by the current <see cref="IIterationStopCriterium{T}"/>. Status is set to <c>Status</c> field of current object. /// by the current <see cref="IIterationStopCriterium"/>. Status is set to <c>Status</c> field of current object.
/// </summary> /// </summary>
/// <param name="iterationNumber">The number of iterations that have passed so far.</param> /// <param name="iterationNumber">The number of iterations that have passed so far.</param>
/// <param name="solutionVector">The vector containing the current solution values.</param> /// <param name="solutionVector">The vector containing the current solution values.</param>
/// <param name="sourceVector">The right hand side vector.</param> /// <param name="sourceVector">The right hand side vector.</param>
/// <param name="residualVector">The vector containing the current residual vectors.</param> /// <param name="residualVector">The vector containing the current residual vectors.</param>
/// <remarks> /// <remarks>
/// The individual stop criteria may internally track the progress of the calculation based /// The individual stop criteria may internally track the progress of the calculation based
/// on the invocation of this method. Therefore this method should only be called if the /// on the invocation of this method. Therefore this method should only be called if the
/// calculation has moved forwards at least one step. /// calculation has moved forwards at least one step.
/// </remarks> /// </remarks>
void DetermineStatus(int iterationNumber, Vector<T> solutionVector, Vector<T> sourceVector, Vector<T> residualVector); void DetermineStatus(int iterationNumber, Vector solutionVector, Vector sourceVector, Vector residualVector);
/// <summary> /// <summary>
/// Gets the current calculation status. /// Gets the current calculation status.
@ -62,7 +60,7 @@ namespace MathNet.Numerics.LinearAlgebra.Generic.Solvers.StopCriterium
ICalculationStatus Status { get; } ICalculationStatus Status { get; }
/// <summary> /// <summary>
/// Resets the <see cref="IIterationStopCriterium{T}"/> to the pre-calculation state. /// Resets the <see cref="IIterationStopCriterium"/> to the pre-calculation state.
/// </summary> /// </summary>
/// <remarks>To implementers: Invoking this method should not clear the user defined /// <remarks>To implementers: Invoking this method should not clear the user defined
/// property values, only the state that is used to track the progress of the /// property values, only the state that is used to track the progress of the
@ -71,12 +69,12 @@ namespace MathNet.Numerics.LinearAlgebra.Generic.Solvers.StopCriterium
/// <summary> /// <summary>
/// Gets the <see cref="StopLevel"/> which indicates what sort of stop criterium this /// Gets the <see cref="StopLevel"/> which indicates what sort of stop criterium this
/// <see cref="IIterationStopCriterium{T}"/> monitors. /// <see cref="IIterationStopCriterium"/> monitors.
/// </summary> /// </summary>
StopLevel StopLevel { get; } StopLevel StopLevel { get; }
#if SILVERLIGHT #if SILVERLIGHT
IIterationStopCriterium<T> Clone(); IIterationStopCriterium Clone();
#endif #endif
} }
} }

10
src/Numerics/LinearAlgebra/Complex/Solvers/StopCriterium/IterationCountStopCriterium.cs

@ -32,16 +32,14 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.StopCriterium
{ {
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using System.Numerics;
using Generic;
using Generic.Solvers.Status; using Generic.Solvers.Status;
using Generic.Solvers.StopCriterium; using Generic.Solvers.StopCriterium;
/// <summary> /// <summary>
/// Defines an <see cref="IIterationStopCriterium{T}"/> that monitors the numbers of iteration /// Defines an <see cref="IIterationStopCriterium"/> that monitors the numbers of iteration
/// steps as stop criterium. /// steps as stop criterium.
/// </summary> /// </summary>
public sealed class IterationCountStopCriterium : IIterationStopCriterium<Complex> public sealed class IterationCountStopCriterium : IIterationStopCriterium
{ {
/// <summary> /// <summary>
/// The default value for the maximum number of iterations the process is allowed /// The default value for the maximum number of iterations the process is allowed
@ -132,7 +130,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.StopCriterium
/// on the invocation of this method. Therefore this method should only be called if the /// on the invocation of this method. Therefore this method should only be called if the
/// calculation has moved forwards at least one step. /// calculation has moved forwards at least one step.
/// </remarks> /// </remarks>
public void DetermineStatus(int iterationNumber, Vector<Complex> solutionVector, Vector<Complex> sourceVector, Vector<Complex> residualVector) public void DetermineStatus(int iterationNumber, Vector solutionVector, Vector sourceVector, Vector residualVector)
{ {
if (iterationNumber < 0) if (iterationNumber < 0)
{ {
@ -209,7 +207,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.StopCriterium
/// Clones the current <see cref="IterationCountStopCriterium"/> and its settings. /// Clones the current <see cref="IterationCountStopCriterium"/> and its settings.
/// </summary> /// </summary>
/// <returns>A new instance of the <see cref="IterationCountStopCriterium"/> class.</returns> /// <returns>A new instance of the <see cref="IterationCountStopCriterium"/> class.</returns>
public IIterationStopCriterium<Complex> Clone() public IIterationStopCriterium Clone()
{ {
return new IterationCountStopCriterium(_maximumNumberOfIterations); return new IterationCountStopCriterium(_maximumNumberOfIterations);
} }

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

@ -32,16 +32,14 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.StopCriterium
{ {
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using System.Numerics;
using Generic;
using Generic.Solvers.Status; using Generic.Solvers.Status;
using Generic.Solvers.StopCriterium; using Generic.Solvers.StopCriterium;
using Properties; using Properties;
/// <summary> /// <summary>
/// Defines an <see cref="IIterationStopCriterium{T}"/> that monitors residuals as stop criterium. /// Defines an <see cref="IIterationStopCriterium"/> that monitors residuals as stop criterium.
/// </summary> /// </summary>
public sealed class ResidualStopCriterium : IIterationStopCriterium<Complex> public sealed class ResidualStopCriterium : IIterationStopCriterium
{ {
/// <summary> /// <summary>
/// The default value for the maximum value of the residual. /// The default value for the maximum value of the residual.
@ -213,7 +211,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.StopCriterium
/// <summary> /// <summary>
/// Determines the status of the iterative calculation based on the stop criteria stored /// Determines the status of the iterative calculation based on the stop criteria stored
/// by the current <see cref="IIterationStopCriterium{T}"/>. Result is set into <c>Status</c> field. /// by the current <see cref="IIterationStopCriterium"/>. Result is set into <c>Status</c> field.
/// </summary> /// </summary>
/// <param name="iterationNumber">The number of iterations that have passed so far.</param> /// <param name="iterationNumber">The number of iterations that have passed so far.</param>
/// <param name="solutionVector">The vector containing the current solution values.</param> /// <param name="solutionVector">The vector containing the current solution values.</param>
@ -224,7 +222,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.StopCriterium
/// on the invocation of this method. Therefore this method should only be called if the /// on the invocation of this method. Therefore this method should only be called if the
/// calculation has moved forwards at least one step. /// calculation has moved forwards at least one step.
/// </remarks> /// </remarks>
public void DetermineStatus(int iterationNumber, Vector<Complex> solutionVector, Vector<Complex> sourceVector, Vector<Complex> residualVector) public void DetermineStatus(int iterationNumber, Vector solutionVector, Vector sourceVector, Vector residualVector)
{ {
if (iterationNumber < 0) if (iterationNumber < 0)
{ {
@ -364,7 +362,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.StopCriterium
} }
/// <summary> /// <summary>
/// Resets the <see cref="IIterationStopCriterium{T}"/> to the pre-calculation state. /// Resets the <see cref="IIterationStopCriterium"/> to the pre-calculation state.
/// </summary> /// </summary>
public void ResetToPrecalculationState() public void ResetToPrecalculationState()
{ {
@ -375,7 +373,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.StopCriterium
/// <summary> /// <summary>
/// Gets the <see cref="StopLevel"/> which indicates what sort of stop criterium this /// Gets the <see cref="StopLevel"/> which indicates what sort of stop criterium this
/// <see cref="IIterationStopCriterium{T}"/> monitors. /// <see cref="IIterationStopCriterium"/> monitors.
/// </summary> /// </summary>
/// <value>Returns <see cref="StopLevel"/>.</value> /// <value>Returns <see cref="StopLevel"/>.</value>
public StopLevel StopLevel public StopLevel StopLevel
@ -391,7 +389,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.StopCriterium
/// Clones the current <see cref="ResidualStopCriterium"/> and its settings. /// Clones the current <see cref="ResidualStopCriterium"/> and its settings.
/// </summary> /// </summary>
/// <returns>A new instance of the <see cref="ResidualStopCriterium"/> class.</returns> /// <returns>A new instance of the <see cref="ResidualStopCriterium"/> class.</returns>
public IIterationStopCriterium<Complex> Clone() public IIterationStopCriterium Clone()
{ {
return new ResidualStopCriterium(_maximum, _minimumIterationsBelowMaximum); return new ResidualStopCriterium(_maximum, _minimumIterationsBelowMaximum);
} }

96
src/Numerics/LinearAlgebra/Complex32/Solvers/IIterativeSolver.cs

@ -0,0 +1,96 @@
// <copyright file="IIterativeSolver.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
//
// Copyright (c) 2009-2010 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
{
using Generic.Solvers.Status;
/// <summary>
/// Defines the interface for <see cref="IIterativeSolver"/> classes that solve the matrix equation Ax = b in
/// an iterative manner.
/// </summary>
public interface IIterativeSolver
{
/// <summary>
/// Stops the solve process.
/// </summary>
/// <remarks>
/// Note that it may take an indetermined amount of time for the solver to actually stop the process.
/// </remarks>
void StopSolve();
/// <summary>
/// Sets the <see cref="IIterator"/> that will be used to track the iterative process.
/// </summary>
/// <param name="iterator">The iterator.</param>
void SetIterator(IIterator iterator);
/// <summary>
/// Gets the status of the iteration once the calculation is finished.
/// </summary>
ICalculationStatus 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.
/// </summary>
/// <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 Solve(Matrix matrix, Vector vector);
/// <summary>
/// Solves the matrix equation Ax = b, where A is the coefficient matrix, b is the
/// solution vector and x is the unknown vector.
/// </summary>
/// <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 matrix, Vector input, Vector result);
/// <summary>
/// Solves the matrix equation AX = B, where A is the coefficient matrix, B is the
/// solution matrix and X is the unknown matrix.
/// </summary>
/// <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 Solve(Matrix matrix, Matrix input);
/// <summary>
/// Solves the matrix equation AX = B, where A is the coefficient matrix, B is the
/// solution matrix and X is the unknown matrix.
/// </summary>
/// <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 matrix, Matrix input, Matrix result);
}
}

71
src/Numerics/LinearAlgebra/Complex32/Solvers/IIterativeSolverSetup.cs

@ -0,0 +1,71 @@
// <copyright file="IIterativeSolverSetup.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
//
// Copyright (c) 2009-2010 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
{
using System;
/// <summary>
/// Defines the interface for objects that can create an iterative solver with
/// specific settings. This interface is used to pass iterative solver creation
/// setup information around.
/// </summary>
public interface IIterativeSolverSetup
{
/// <summary>
/// Gets the type of the solver that will be created by this setup object.
/// </summary>
Type SolverType { get; }
/// <summary>
/// Gets type of preconditioner, if any, that will be created by this setup object.
/// </summary>
Type PreconditionerType { get; }
/// <summary>
/// Creates a fully functional iterative solver with the default settings
/// given by this setup.
/// </summary>
/// <returns>A new <see cref="IIterativeSolver"/>.</returns>
IIterativeSolver CreateNew();
/// <summary>
/// Gets the relative speed of the solver.
/// </summary>
/// <value>Returns a value between 0 and 1, inclusive.</value>
double SolutionSpeed { get; }
/// <summary>
/// Gets the relative reliability of the solver.
/// </summary>
/// <value>Returns a value between 0 and 1 inclusive.</value>
double Reliability { get; }
}
}

108
src/Numerics/LinearAlgebra/Complex32/Solvers/IIterator.cs

@ -0,0 +1,108 @@
// <copyright file="IIterator.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
//
// Copyright (c) 2009-2010 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
{
using System;
using Generic.Solvers.Status;
using StopCriterium;
/// <summary>
/// Defines the base interface for iterators that help control an iterative calculation.
/// </summary>
public interface IIterator
#if !SILVERLIGHT
: ICloneable
#endif
{
/// <summary>
/// Adds an <see cref="IIterationStopCriterium"/> to the internal collection of stop-criteria. Only a
/// single stop criterium of each type can be stored.
/// </summary>
/// <param name="stopCriterium">The stop criterium to add.</param>
/// <exception cref="ArgumentNullException">Thrown if <paramref name="stopCriterium"/> is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">Thrown if <paramref name="stopCriterium"/> is of the same type as an already stored criterium.</exception>
void Add(IIterationStopCriterium stopCriterium);
/// <summary>
/// Removes the <see cref="IIterationStopCriterium"/> from the internal collection.
/// </summary>
/// <param name="stopCriterium">The stop criterium that must be removed.</param>
void Remove(IIterationStopCriterium stopCriterium);
/// <summary>
/// Indicates if the specific stop criterium is stored by the <see cref="IIterator"/>.
/// </summary>
/// <param name="stopCriterium">The stop criterium.</param>
/// <returns><c>true</c> if the <see cref="IIterator"/> contains the stop criterium; otherwise <c>false</c>.</returns>
bool Contains(IIterationStopCriterium stopCriterium);
/// <summary>
/// Indicates to the iterator that the iterative process has been cancelled.
/// </summary>
/// <remarks>Does not reset the stop-criteria.</remarks>
void IterationCancelled();
/// <summary>
/// Determines the status of the iterative calculation based on the stop criteria stored
/// by the current <see cref="IIterator"/>. Status is set to <c>Status</c> field of current object.
/// </summary>
/// <param name="iterationNumber">The number of iterations that have passed so far.</param>
/// <param name="solutionVector">The vector containing the current solution values.</param>
/// <param name="sourceVector">The right hand side vector.</param>
/// <param name="residualVector">The vector containing the current residual vectors.</param>
/// <remarks>
/// The individual iterators may internally track the progress of the calculation based
/// on the invocation of this method. Therefore this method should only be called if the
/// calculation has moved forwards at least one step.
/// </remarks>
void DetermineStatus(int iterationNumber, Vector solutionVector, Vector sourceVector, Vector residualVector);
/// <summary>
/// Gets the current calculation status.
/// </summary>
/// <remarks><see langword="null" /> is not a legal value. Status should be set in <see cref="DetermineStatus"/> implementation.</remarks>.
ICalculationStatus Status { get; }
/// <summary>
/// Resets the <see cref="IIterator"/> to the pre-calculation state.
/// </summary>
/// <remarks>
/// Note to implementers: Invoking this method should not clear the user defined
/// property values, only the state that is used to track the progress of the
/// calculation.
/// </remarks>
void ResetToPrecalculationState();
#if SILVERLIGHT
IIterator Clone();
#endif
}
}

117
src/Numerics/LinearAlgebra/Complex32/Solvers/Iterative/BiCgStab.cs

@ -31,9 +31,6 @@
namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
{ {
using System; using System;
using Generic;
using Generic.Solvers;
using Generic.Solvers.Preconditioners;
using Generic.Solvers.Status; using Generic.Solvers.Status;
using Numerics; using Numerics;
using Preconditioners; using Preconditioners;
@ -68,7 +65,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
/// solver. /// solver.
/// </para> /// </para>
/// </remarks> /// </remarks>
public sealed class BiCgStab : IIterativeSolver<Complex32> public sealed class BiCgStab : IIterativeSolver
{ {
/// <summary> /// <summary>
/// The status used if there is no status, i.e. the solver hasn't run yet and there is no /// The status used if there is no status, i.e. the solver hasn't run yet and there is no
@ -80,12 +77,12 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
/// The preconditioner that will be used. Can be set to <see langword="null" />, in which case the default /// The preconditioner that will be used. Can be set to <see langword="null" />, in which case the default
/// pre-conditioner will be used. /// pre-conditioner will be used.
/// </summary> /// </summary>
private IPreConditioner<Complex32> _preconditioner; private IPreConditioner _preconditioner;
/// <summary> /// <summary>
/// The iterative process controller. /// The iterative process controller.
/// </summary> /// </summary>
private IIterator<Complex32> _iterator; private IIterator _iterator;
/// <summary> /// <summary>
/// Indicates if the user has stopped the solver. /// Indicates if the user has stopped the solver.
@ -96,7 +93,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
/// Initializes a new instance of the <see cref="BiCgStab"/> class. /// Initializes a new instance of the <see cref="BiCgStab"/> class.
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// When using this constructor the solver will use the <see cref="IIterator{T}"/> with /// When using this constructor the solver will use the <see cref="IIterator"/> with
/// the standard settings and a default preconditioner. /// the standard settings and a default preconditioner.
/// </remarks> /// </remarks>
public BiCgStab() : this(null, null) public BiCgStab() : this(null, null)
@ -111,18 +108,18 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
/// When using this constructor the solver will use a default preconditioner. /// When using this constructor the solver will use a default preconditioner.
/// </para> /// </para>
/// <para> /// <para>
/// The main advantages of using a user defined <see cref="IIterator{T}"/> are: /// The main advantages of using a user defined <see cref="IIterator"/> are:
/// <list type="number"> /// <list type="number">
/// <item>It is possible to set the desired convergence limits.</item> /// <item>It is possible to set the desired convergence limits.</item>
/// <item> /// <item>
/// It is possible to check the reason for which the solver finished /// It is possible to check the reason for which the solver finished
/// the iterative procedure by calling the <see cref="IIterator{T}.Status"/> property. /// the iterative procedure by calling the <see cref="IIterator.Status"/> property.
/// </item> /// </item>
/// </list> /// </list>
/// </para> /// </para>
/// </remarks> /// </remarks>
/// <param name="iterator">The <see cref="IIterator{T}"/> that will be used to monitor the iterative process. </param> /// <param name="iterator">The <see cref="IIterator"/> that will be used to monitor the iterative process. </param>
public BiCgStab(IIterator<Complex32> iterator) : this(null, iterator) public BiCgStab(IIterator iterator) : this(null, iterator)
{ {
} }
@ -130,11 +127,11 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
/// Initializes a new instance of the <see cref="BiCgStab"/> class. /// Initializes a new instance of the <see cref="BiCgStab"/> class.
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// When using this constructor the solver will use the <see cref="IIterator{T}"/> with /// When using this constructor the solver will use the <see cref="IIterator"/> with
/// the standard settings. /// the standard settings.
/// </remarks> /// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation.</param> /// <param name="preconditioner">The <see cref="IPreConditioner"/> that will be used to precondition the matrix equation.</param>
public BiCgStab(IPreConditioner<Complex32> preconditioner) : this(preconditioner, null) public BiCgStab(IPreConditioner preconditioner) : this(preconditioner, null)
{ {
} }
@ -143,38 +140,38 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// <para> /// <para>
/// The main advantages of using a user defined <see cref="IIterator{T}"/> are: /// The main advantages of using a user defined <see cref="IIterator"/> are:
/// <list type="number"> /// <list type="number">
/// <item>It is possible to set the desired convergence limits.</item> /// <item>It is possible to set the desired convergence limits.</item>
/// <item> /// <item>
/// It is possible to check the reason for which the solver finished /// It is possible to check the reason for which the solver finished
/// the iterative procedure by calling the <see cref="IIterator{T}.Status"/> property. /// the iterative procedure by calling the <see cref="IIterator.Status"/> property.
/// </item> /// </item>
/// </list> /// </list>
/// </para> /// </para>
/// </remarks> /// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation. </param> /// <param name="preconditioner">The <see cref="IPreConditioner"/> that will be used to precondition the matrix equation. </param>
/// <param name="iterator">The <see cref="IIterator{T}"/> that will be used to monitor the iterative process. </param> /// <param name="iterator">The <see cref="IIterator"/> that will be used to monitor the iterative process. </param>
public BiCgStab(IPreConditioner<Complex32> preconditioner, IIterator<Complex32> iterator) public BiCgStab(IPreConditioner preconditioner, IIterator iterator)
{ {
_iterator = iterator; _iterator = iterator;
_preconditioner = preconditioner; _preconditioner = preconditioner;
} }
/// <summary> /// <summary>
/// Sets the <see cref="IPreConditioner{T}"/> that will be used to precondition the iterative process. /// Sets the <see cref="IPreConditioner"/> that will be used to precondition the iterative process.
/// </summary> /// </summary>
/// <param name="preconditioner">The preconditioner.</param> /// <param name="preconditioner">The preconditioner.</param>
public void SetPreconditioner(IPreConditioner<Complex32> preconditioner) public void SetPreconditioner(IPreConditioner preconditioner)
{ {
_preconditioner = preconditioner; _preconditioner = preconditioner;
} }
/// <summary> /// <summary>
/// Sets the <see cref="IIterator{T}"/> that will be used to track the iterative process. /// Sets the <see cref="IIterator"/> that will be used to track the iterative process.
/// </summary> /// </summary>
/// <param name="iterator">The iterator.</param> /// <param name="iterator">The iterator.</param>
public void SetIterator(IIterator<Complex32> iterator) public void SetIterator(IIterator iterator)
{ {
_iterator = iterator; _iterator = iterator;
} }
@ -205,17 +202,17 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
/// Solves the matrix equation Ax = b, where A is the coefficient matrix, b is the /// Solves the matrix equation Ax = b, where A is the coefficient matrix, b is the
/// solution vector and x is the unknown vector. /// solution vector and x is the unknown vector.
/// </summary> /// </summary>
/// <param name="matrix">The coefficient <see cref="Matrix{T}"/>, <c>A</c>.</param> /// <param name="matrix">The coefficient <see cref="Matrix"/>, <c>A</c>.</param>
/// <param name="vector">The solution <see cref="Vector{T}"/>, <c>b</c>.</param> /// <param name="vector">The solution <see cref="Vector"/>, <c>b</c>.</param>
/// <returns>The result <see cref="Vector{T}"/>, <c>x</c>.</returns> /// <returns>The result <see cref="Vector"/>, <c>x</c>.</returns>
public Vector<Complex32> Solve(Matrix<Complex32> matrix, Vector<Complex32> vector) public Vector Solve(Matrix matrix, Vector vector)
{ {
if (vector == null) if (vector == null)
{ {
throw new ArgumentNullException(); throw new ArgumentNullException();
} }
Vector<Complex32> result = new DenseVector(matrix.RowCount); Vector result = new DenseVector(matrix.RowCount);
Solve(matrix, vector, result); Solve(matrix, vector, result);
return result; return result;
} }
@ -224,10 +221,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
/// Solves the matrix equation Ax = b, where A is the coefficient matrix, b is the /// Solves the matrix equation Ax = b, where A is the coefficient matrix, b is the
/// solution vector and x is the unknown vector. /// solution vector and x is the unknown vector.
/// </summary> /// </summary>
/// <param name="matrix">The coefficient <see cref="Matrix{T}"/>, <c>A</c>.</param> /// <param name="matrix">The coefficient <see cref="Matrix"/>, <c>A</c>.</param>
/// <param name="input">The solution <see cref="Vector{T}"/>, <c>b</c>.</param> /// <param name="input">The solution <see cref="Vector"/>, <c>b</c>.</param>
/// <param name="result">The result <see cref="Vector{T}"/>, <c>x</c>.</param> /// <param name="result">The result <see cref="Vector"/>, <c>x</c>.</param>
public void Solve(Matrix<Complex32> matrix, Vector<Complex32> input, Vector<Complex32> result) public void Solve(Matrix matrix, Vector input, Vector result)
{ {
// If we were stopped before, we are no longer // If we were stopped before, we are no longer
// We're doing this at the start of the method to ensure // We're doing this at the start of the method to ensure
@ -282,7 +279,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
// Compute r_0 = b - Ax_0 for some initial guess x_0 // Compute r_0 = b - Ax_0 for some initial guess x_0
// In this case we take x_0 = vector // In this case we take x_0 = vector
// This is basically a SAXPY so it could be made a lot faster // This is basically a SAXPY so it could be made a lot faster
Vector<Complex32> residuals = new DenseVector(matrix.RowCount); Vector residuals = new DenseVector(matrix.RowCount);
CalculateTrueResidual(matrix, residuals, result, input); CalculateTrueResidual(matrix, residuals, result, input);
// Choose r~ (for example, r~ = r_0) // Choose r~ (for example, r~ = r_0)
@ -291,13 +288,13 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
// create seven temporary vectors needed to hold temporary // create seven temporary vectors needed to hold temporary
// coefficients. All vectors are mangled in each iteration. // coefficients. All vectors are mangled in each iteration.
// These are defined here to prevent stressing the garbage collector // These are defined here to prevent stressing the garbage collector
Vector<Complex32> vecP = new DenseVector(residuals.Count); Vector vecP = new DenseVector(residuals.Count);
Vector<Complex32> vecPdash = new DenseVector(residuals.Count); Vector vecPdash = new DenseVector(residuals.Count);
Vector<Complex32> nu = new DenseVector(residuals.Count); Vector nu = new DenseVector(residuals.Count);
Vector<Complex32> vecS = new DenseVector(residuals.Count); Vector vecS = new DenseVector(residuals.Count);
Vector<Complex32> vecSdash = new DenseVector(residuals.Count); Vector vecSdash = new DenseVector(residuals.Count);
Vector<Complex32> temp = new DenseVector(residuals.Count); Vector temp = new DenseVector(residuals.Count);
Vector<Complex32> temp2 = new DenseVector(residuals.Count); Vector temp2 = new DenseVector(residuals.Count);
// create some temporary float variables that are needed // create some temporary float variables that are needed
// to hold values in between iterations // to hold values in between iterations
@ -429,13 +426,13 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
} }
/// <summary> /// <summary>
/// Calculates the true residual of the matrix equation Ax = b according to: residual = b - Ax /// Calculates the <c>true</c> residual of the matrix equation Ax = b according to: residual = b - Ax
/// </summary> /// </summary>
/// <param name="matrix">Instance of the <see cref="Matrix{T}"/> A.</param> /// <param name="matrix">Instance of the <see cref="Matrix"/> A.</param>
/// <param name="residual">Residual values in <see cref="Vector{T}"/>.</param> /// <param name="residual">Residual values in <see cref="Vector"/>.</param>
/// <param name="x">Instance of the <see cref="Vector{T}"/> x.</param> /// <param name="x">Instance of the <see cref="Vector"/> x.</param>
/// <param name="b">Instance of the <see cref="Vector{T}"/> b.</param> /// <param name="b">Instance of the <see cref="Vector"/> b.</param>
private static void CalculateTrueResidual(Matrix<Complex32> matrix, Vector<Complex32> residual, Vector<Complex32> x, Vector<Complex32> b) private static void CalculateTrueResidual(Matrix matrix, Vector residual, Vector x, Vector b)
{ {
// -Ax = residual // -Ax = residual
matrix.Multiply(x, residual); matrix.Multiply(x, residual);
@ -451,11 +448,11 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
/// Determine if calculation should continue /// Determine if calculation should continue
/// </summary> /// </summary>
/// <param name="iterationNumber">Number of iterations passed</param> /// <param name="iterationNumber">Number of iterations passed</param>
/// <param name="result">Result <see cref="Vector{T}"/>.</param> /// <param name="result">Result <see cref="Vector"/>.</param>
/// <param name="source">Source <see cref="Vector{T}"/>.</param> /// <param name="source">Source <see cref="Vector"/>.</param>
/// <param name="residuals">Residual <see cref="Vector{T}"/>.</param> /// <param name="residuals">Residual <see cref="Vector"/>.</param>
/// <returns><c>true</c> if continue, otherwise <c>false</c></returns> /// <returns><c>true</c> if continue, otherwise <c>false</c></returns>
private bool ShouldContinue(int iterationNumber, Vector<Complex32> result, Vector<Complex32> source, Vector<Complex32> residuals) private bool ShouldContinue(int iterationNumber, Vector result, Vector source, Vector residuals)
{ {
if (_hasBeenStopped) if (_hasBeenStopped)
{ {
@ -476,10 +473,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
/// Solves the matrix equation AX = B, where A is the coefficient matrix, B is the /// Solves the matrix equation AX = B, where A is the coefficient matrix, B is the
/// solution matrix and X is the unknown matrix. /// solution matrix and X is the unknown matrix.
/// </summary> /// </summary>
/// <param name="matrix">The coefficient <see cref="Matrix{T}"/>, <c>A</c>.</param> /// <param name="matrix">The coefficient <see cref="Matrix"/>, <c>A</c>.</param>
/// <param name="input">The solution <see cref="Matrix{T}"/>, <c>B</c>.</param> /// <param name="input">The solution <see cref="Matrix"/>, <c>B</c>.</param>
/// <returns>The result <see cref="Matrix{T}"/>, <c>X</c>.</returns> /// <returns>The result <see cref="Matrix"/>, <c>X</c>.</returns>
public Matrix<Complex32> Solve(Matrix<Complex32> matrix, Matrix<Complex32> input) public Matrix Solve(Matrix matrix, Matrix input)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -491,7 +488,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
throw new ArgumentNullException("input"); throw new ArgumentNullException("input");
} }
var result = matrix.CreateMatrix(input.RowCount, input.ColumnCount); var result = (Matrix)matrix.CreateMatrix(input.RowCount, input.ColumnCount);
Solve(matrix, input, result); Solve(matrix, input, result);
return result; return result;
} }
@ -500,10 +497,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
/// Solves the matrix equation AX = B, where A is the coefficient matrix, B is the /// Solves the matrix equation AX = B, where A is the coefficient matrix, B is the
/// solution matrix and X is the unknown matrix. /// solution matrix and X is the unknown matrix.
/// </summary> /// </summary>
/// <param name="matrix">The coefficient <see cref="Matrix{T}"/>, <c>A</c>.</param> /// <param name="matrix">The coefficient <see cref="Matrix"/>, <c>A</c>.</param>
/// <param name="input">The solution <see cref="Matrix{T}"/>, <c>B</c>.</param> /// <param name="input">The solution <see cref="Matrix"/>, <c>B</c>.</param>
/// <param name="result">The result <see cref="Matrix{T}"/>, <c>X</c></param> /// <param name="result">The result <see cref="Matrix"/>, <c>X</c></param>
public void Solve(Matrix<Complex32> matrix, Matrix<Complex32> input, Matrix<Complex32> result) public void Solve(Matrix matrix, Matrix input, Matrix result)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -527,7 +524,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
for (var column = 0; column < input.ColumnCount; column++) for (var column = 0; column < input.ColumnCount; column++)
{ {
var solution = Solve(matrix, input.Column(column)); var solution = Solve(matrix, (Vector)input.Column(column));
foreach (var element in solution.GetIndexedEnumerator()) foreach (var element in solution.GetIndexedEnumerator())
{ {
result.At(element.Key, column, element.Value); result.At(element.Key, column, element.Value);

75
src/Numerics/LinearAlgebra/Complex32/Solvers/Iterative/CompositeSolver.cs

@ -35,10 +35,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using Generic;
using Generic.Solvers;
using Generic.Solvers.Status; using Generic.Solvers.Status;
using Numerics;
using Properties; using Properties;
/// <summary> /// <summary>
@ -56,7 +53,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
/// Note that if an iterator is passed to this solver it will be used for all the sub-solvers. /// Note that if an iterator is passed to this solver it will be used for all the sub-solvers.
/// </para> /// </para>
/// </remarks> /// </remarks>
public sealed class CompositeSolver : IIterativeSolver<Complex32> public sealed class CompositeSolver : IIterativeSolver
{ {
#region Internal class - DoubleComparer #region Internal class - DoubleComparer
/// <summary> /// <summary>
@ -97,19 +94,19 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
private static readonly ICalculationStatus RunningStatus = new CalculationRunning(); private static readonly ICalculationStatus RunningStatus = new CalculationRunning();
#if SILVERLIGHT #if SILVERLIGHT
private static readonly Dictionary<double, List<IIterativeSolverSetup<Complex32>>> SolverSetups = new Dictionary<double, List<IIterativeSolverSetup<Complex32>>>(); private static readonly Dictionary<double, List<IIterativeSolverSetup>> SolverSetups = new Dictionary<double, List<IIterativeSolverSetup>>();
#else #else
/// <summary> /// <summary>
/// The collection of iterative solver setups. Stored based on the /// The collection of iterative solver setups. Stored based on the
/// ratio between the relative speed and relative accuracy. /// ratio between the relative speed and relative accuracy.
/// </summary> /// </summary>
private static readonly SortedList<double, List<IIterativeSolverSetup<Complex32>>> SolverSetups = new SortedList<double, List<IIterativeSolverSetup<Complex32>>>(new DoubleComparer()); private static readonly SortedList<double, List<IIterativeSolverSetup>> SolverSetups = new SortedList<double, List<IIterativeSolverSetup>>(new DoubleComparer());
#endif #endif
#region Solver information loading methods #region Solver information loading methods
/// <summary> /// <summary>
/// Loads all the available <see cref="IIterativeSolverSetup{T}"/> objects from the MathNet.Numerics assembly. /// Loads all the available <see cref="IIterativeSolverSetup"/> objects from the MathNet.Numerics assembly.
/// </summary> /// </summary>
public static void LoadSolverInformation() public static void LoadSolverInformation()
{ {
@ -117,16 +114,16 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
} }
/// <summary> /// <summary>
/// Loads the available <see cref="IIterativeSolverSetup{T}"/> objects from the MathNet.Numerics assembly. /// Loads the available <see cref="IIterativeSolverSetup"/> objects from the MathNet.Numerics assembly.
/// </summary> /// </summary>
/// <param name="typesToExclude">The <see cref="IIterativeSolver{T}"/> types that should not be loaded.</param> /// <param name="typesToExclude">The <see cref="IIterativeSolver"/> types that should not be loaded.</param>
public static void LoadSolverInformation(Type[] typesToExclude) public static void LoadSolverInformation(Type[] typesToExclude)
{ {
LoadSolverInformationFromAssembly(Assembly.GetExecutingAssembly(), typesToExclude); LoadSolverInformationFromAssembly(Assembly.GetExecutingAssembly(), typesToExclude);
} }
/// <summary> /// <summary>
/// Loads the available <see cref="IIterativeSolverSetup{T}"/> objects from the assembly specified by the file location. /// Loads the available <see cref="IIterativeSolverSetup"/> objects from the assembly specified by the file location.
/// </summary> /// </summary>
/// <param name="assemblyLocation">The fully qualified path to the assembly.</param> /// <param name="assemblyLocation">The fully qualified path to the assembly.</param>
public static void LoadSolverInformationFromAssembly(string assemblyLocation) public static void LoadSolverInformationFromAssembly(string assemblyLocation)
@ -135,10 +132,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
} }
/// <summary> /// <summary>
/// Loads the available <see cref="IIterativeSolverSetup{T}"/> objects from the assembly specified by the file location. /// Loads the available <see cref="IIterativeSolverSetup"/> objects from the assembly specified by the file location.
/// </summary> /// </summary>
/// <param name="assemblyLocation">The fully qualified path to the assembly.</param> /// <param name="assemblyLocation">The fully qualified path to the assembly.</param>
/// <param name="typesToExclude">The <see cref="IIterativeSolver{T}"/> types that should not be loaded. </param> /// <param name="typesToExclude">The <see cref="IIterativeSolver"/> types that should not be loaded. </param>
public static void LoadSolverInformationFromAssembly(string assemblyLocation, params Type[] typesToExclude) public static void LoadSolverInformationFromAssembly(string assemblyLocation, params Type[] typesToExclude)
{ {
if (assemblyLocation == null) if (assemblyLocation == null)
@ -173,7 +170,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
} }
/// <summary> /// <summary>
/// Loads the available <see cref="IIterativeSolverSetup{T}"/> objects from the assembly specified by the assembly name. /// Loads the available <see cref="IIterativeSolverSetup"/> objects from the assembly specified by the assembly name.
/// </summary> /// </summary>
/// <param name="assemblyName">The <see cref="AssemblyName"/> of the assembly that should be searched for setup objects. </param> /// <param name="assemblyName">The <see cref="AssemblyName"/> of the assembly that should be searched for setup objects. </param>
public static void LoadSolverInformationFromAssembly(AssemblyName assemblyName) public static void LoadSolverInformationFromAssembly(AssemblyName assemblyName)
@ -182,10 +179,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
} }
/// <summary> /// <summary>
/// Loads the available <see cref="IIterativeSolverSetup{T}"/> objects from the assembly specified by the assembly name. /// Loads the available <see cref="IIterativeSolverSetup"/> objects from the assembly specified by the assembly name.
/// </summary> /// </summary>
/// <param name="assemblyName">The <see cref="AssemblyName"/> of the assembly that should be searched for setup objects.</param> /// <param name="assemblyName">The <see cref="AssemblyName"/> of the assembly that should be searched for setup objects.</param>
/// <param name="typesToExclude">The <see cref="IIterativeSolver{T}"/> types that should not be loaded.</param> /// <param name="typesToExclude">The <see cref="IIterativeSolver"/> types that should not be loaded.</param>
public static void LoadSolverInformationFromAssembly(AssemblyName assemblyName, params Type[] typesToExclude) public static void LoadSolverInformationFromAssembly(AssemblyName assemblyName, params Type[] typesToExclude)
{ {
if (assemblyName == null) if (assemblyName == null)
@ -205,7 +202,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
} }
/// <summary> /// <summary>
/// Loads the available <see cref="IIterativeSolverSetup{T}"/> objects from the assembly specified by the type. /// Loads the available <see cref="IIterativeSolverSetup"/> objects from the assembly specified by the type.
/// </summary> /// </summary>
/// <param name="typeInAssembly">The type in the assembly which should be searched for setup objects.</param> /// <param name="typeInAssembly">The type in the assembly which should be searched for setup objects.</param>
public static void LoadSolverInformationFromAssembly(Type typeInAssembly) public static void LoadSolverInformationFromAssembly(Type typeInAssembly)
@ -214,10 +211,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
} }
/// <summary> /// <summary>
/// Loads the available <see cref="IIterativeSolverSetup{T}"/> objects from the assembly specified by the type. /// Loads the available <see cref="IIterativeSolverSetup"/> objects from the assembly specified by the type.
/// </summary> /// </summary>
/// <param name="typeInAssembly">The type in the assembly which should be searched for setup objects.</param> /// <param name="typeInAssembly">The type in the assembly which should be searched for setup objects.</param>
/// <param name="typesToExclude">The <see cref="IIterativeSolver{T}"/> types that should not be loaded.</param> /// <param name="typesToExclude">The <see cref="IIterativeSolver"/> types that should not be loaded.</param>
public static void LoadSolverInformationFromAssembly(Type typeInAssembly, params Type[] typesToExclude) public static void LoadSolverInformationFromAssembly(Type typeInAssembly, params Type[] typesToExclude)
{ {
if (typeInAssembly == null) if (typeInAssembly == null)
@ -229,7 +226,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
} }
/// <summary> /// <summary>
/// Loads the available <see cref="IIterativeSolverSetup{T}"/> objects from the specified assembly. /// Loads the available <see cref="IIterativeSolverSetup"/> objects from the specified assembly.
/// </summary> /// </summary>
/// <param name="assembly">The assembly which will be searched for setup objects.</param> /// <param name="assembly">The assembly which will be searched for setup objects.</param>
public static void LoadSolverInformationFromAssembly(Assembly assembly) public static void LoadSolverInformationFromAssembly(Assembly assembly)
@ -238,10 +235,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
} }
/// <summary> /// <summary>
/// Loads the available <see cref="IIterativeSolverSetup{T}"/> objects from the specified assembly. /// Loads the available <see cref="IIterativeSolverSetup"/> objects from the specified assembly.
/// </summary> /// </summary>
/// <param name="assembly">The assembly which will be searched for setup objects.</param> /// <param name="assembly">The assembly which will be searched for setup objects.</param>
/// <param name="typesToExclude">The <see cref="IIterativeSolver{T}"/> types that should not be loaded.</param> /// <param name="typesToExclude">The <see cref="IIterativeSolver"/> types that should not be loaded.</param>
public static void LoadSolverInformationFromAssembly(Assembly assembly, params Type[] typesToExclude) public static void LoadSolverInformationFromAssembly(Assembly assembly, params Type[] typesToExclude)
{ {
if (assembly == null) if (assembly == null)
@ -266,18 +263,18 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
{ {
interfaceTypes.Clear(); interfaceTypes.Clear();
interfaceTypes.AddRange(type.GetInterfaces()); interfaceTypes.AddRange(type.GetInterfaces());
if (!interfaceTypes.Any(match => typeof(IIterativeSolverSetup<Complex32>).IsAssignableFrom(match))) if (!interfaceTypes.Any(match => typeof(IIterativeSolverSetup).IsAssignableFrom(match)))
{ {
continue; continue;
} }
// See if we actually want this type of iterative solver // See if we actually want this type of iterative solver
IIterativeSolverSetup<Complex32> setup; IIterativeSolverSetup setup;
try try
{ {
// If something goes wrong we just ignore it and move on with the next type. // If something goes wrong we just ignore it and move on with the next type.
// There should probably be a log somewhere indicating that something went wrong? // There should probably be a log somewhere indicating that something went wrong?
setup = (IIterativeSolverSetup<Complex32>)Activator.CreateInstance(type); setup = (IIterativeSolverSetup)Activator.CreateInstance(type);
} }
catch (ArgumentException) catch (ArgumentException)
{ {
@ -318,7 +315,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
var ratio = setup.SolutionSpeed / setup.Reliability; var ratio = setup.SolutionSpeed / setup.Reliability;
if (!SolverSetups.ContainsKey(ratio)) if (!SolverSetups.ContainsKey(ratio))
{ {
SolverSetups.Add(ratio, new List<IIterativeSolverSetup<Complex32>>()); SolverSetups.Add(ratio, new List<IIterativeSolverSetup>());
} }
var list = SolverSetups[ratio]; var list = SolverSetups[ratio];
@ -331,7 +328,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
/// <summary> /// <summary>
/// The collection of solvers that will be used to /// The collection of solvers that will be used to
/// </summary> /// </summary>
private readonly List<IIterativeSolver<Complex32>> _solvers = new List<IIterativeSolver<Complex32>>(); private readonly List<IIterativeSolver> _solvers = new List<IIterativeSolver>();
/// <summary> /// <summary>
/// The status of the calculation. /// The status of the calculation.
@ -341,7 +338,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
/// <summary> /// <summary>
/// The iterator that is used to control the iteration process. /// The iterator that is used to control the iteration process.
/// </summary> /// </summary>
private IIterator<Complex32> _iterator; private IIterator _iterator;
/// <summary> /// <summary>
/// A flag indicating if the solver has been stopped or not. /// A flag indicating if the solver has been stopped or not.
@ -352,7 +349,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
/// The solver that is currently running. Reference is used to be able to stop the /// The solver that is currently running. Reference is used to be able to stop the
/// solver if the user cancels the solve process. /// solver if the user cancels the solve process.
/// </summary> /// </summary>
private IIterativeSolver<Complex32> _currentSolver; private IIterativeSolver _currentSolver;
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="CompositeSolver"/> class with the default iterator. /// Initializes a new instance of the <see cref="CompositeSolver"/> class with the default iterator.
@ -365,7 +362,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
/// Initializes a new instance of the <see cref="CompositeSolver"/> class with the specified iterator. /// Initializes a new instance of the <see cref="CompositeSolver"/> class with the specified iterator.
/// </summary> /// </summary>
/// <param name="iterator">The iterator that will be used to control the iteration process. </param> /// <param name="iterator">The iterator that will be used to control the iteration process. </param>
public CompositeSolver(IIterator<Complex32> iterator) public CompositeSolver(IIterator iterator)
{ {
_iterator = iterator; _iterator = iterator;
} }
@ -374,7 +371,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
/// Sets the <c>IIterator</c> that will be used to track the iterative process. /// Sets the <c>IIterator</c> that will be used to track the iterative process.
/// </summary> /// </summary>
/// <param name="iterator">The iterator.</param> /// <param name="iterator">The iterator.</param>
public void SetIterator(IIterator<Complex32> iterator) public void SetIterator(IIterator iterator)
{ {
_iterator = iterator; _iterator = iterator;
} }
@ -412,14 +409,14 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param> /// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="vector">The solution vector, <c>b</c>.</param> /// <param name="vector">The solution vector, <c>b</c>.</param>
/// <returns>The result vector, <c>x</c>.</returns> /// <returns>The result vector, <c>x</c>.</returns>
public Vector<Complex32> Solve(Matrix<Complex32> matrix, Vector<Complex32> vector) public Vector Solve(Matrix matrix, Vector vector)
{ {
if (vector == null) if (vector == null)
{ {
throw new ArgumentNullException(); throw new ArgumentNullException();
} }
Vector<Complex32> result = new DenseVector(matrix.RowCount); Vector result = new DenseVector(matrix.RowCount);
Solve(matrix, vector, result); Solve(matrix, vector, result);
return result; return result;
} }
@ -431,7 +428,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param> /// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution vector, <c>b</c></param> /// <param name="input">The solution vector, <c>b</c></param>
/// <param name="result">The result vector, <c>x</c></param> /// <param name="result">The result vector, <c>x</c></param>
public void Solve(Matrix<Complex32> matrix, Vector<Complex32> input, Vector<Complex32> result) public void Solve(Matrix matrix, Vector input, Vector result)
{ {
// If we were stopped before, we are no longer // If we were stopped before, we are no longer
// We're doing this at the start of the method to ensure // We're doing this at the start of the method to ensure
@ -481,8 +478,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
// Create a copy of the solution and result vectors so we can use them // Create a copy of the solution and result vectors so we can use them
// later on // later on
var internalInput = input.Clone(); var internalInput = (Vector)input.Clone();
var internalResult = result.Clone(); var internalResult = (Vector)result.Clone();
foreach (var solver in _solvers.TakeWhile(solver => !_hasBeenStopped)) foreach (var solver in _solvers.TakeWhile(solver => !_hasBeenStopped))
{ {
@ -573,7 +570,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param> /// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution matrix, <c>B</c>.</param> /// <param name="input">The solution matrix, <c>B</c>.</param>
/// <returns>The result matrix, <c>X</c>.</returns> /// <returns>The result matrix, <c>X</c>.</returns>
public Matrix<Complex32> Solve(Matrix<Complex32> matrix, Matrix<Complex32> input) public Matrix Solve(Matrix matrix, Matrix input)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -585,7 +582,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
throw new ArgumentNullException("input"); throw new ArgumentNullException("input");
} }
var result = matrix.CreateMatrix(input.RowCount, input.ColumnCount); var result = (Matrix)matrix.CreateMatrix(input.RowCount, input.ColumnCount);
Solve(matrix, input, result); Solve(matrix, input, result);
return result; return result;
} }
@ -597,7 +594,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param> /// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution matrix, <c>B</c>.</param> /// <param name="input">The solution matrix, <c>B</c>.</param>
/// <param name="result">The result matrix, <c>X</c></param> /// <param name="result">The result matrix, <c>X</c></param>
public void Solve(Matrix<Complex32> matrix, Matrix<Complex32> input, Matrix<Complex32> result) public void Solve(Matrix matrix, Matrix input, Matrix result)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -621,7 +618,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
for (var column = 0; column < input.ColumnCount; column++) for (var column = 0; column < input.ColumnCount; column++)
{ {
var solution = Solve(matrix, input.Column(column)); var solution = Solve(matrix, (Vector)input.Column(column));
foreach (var element in solution.GetIndexedEnumerator()) foreach (var element in solution.GetIndexedEnumerator())
{ {
result.At(element.Key, column, element.Value); result.At(element.Key, column, element.Value);

107
src/Numerics/LinearAlgebra/Complex32/Solvers/Iterative/GpBiCg.cs

@ -31,9 +31,6 @@
namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
{ {
using System; using System;
using Generic;
using Generic.Solvers;
using Generic.Solvers.Preconditioners;
using Generic.Solvers.Status; using Generic.Solvers.Status;
using Numerics; using Numerics;
using Preconditioners; using Preconditioners;
@ -66,7 +63,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
/// solver. /// solver.
/// </para> /// </para>
/// </remarks> /// </remarks>
public sealed class GpBiCg : IIterativeSolver<Complex32> public sealed class GpBiCg : IIterativeSolver
{ {
/// <summary> /// <summary>
/// The status used if there is no status, i.e. the solver hasn't run yet and there is no /// The status used if there is no status, i.e. the solver hasn't run yet and there is no
@ -78,12 +75,12 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
/// The preconditioner that will be used. Can be set to <c>null</c>, in which case the default /// The preconditioner that will be used. Can be set to <c>null</c>, in which case the default
/// pre-conditioner will be used. /// pre-conditioner will be used.
/// </summary> /// </summary>
private IPreConditioner<Complex32> _preconditioner; private IPreConditioner _preconditioner;
/// <summary> /// <summary>
/// The iterative process controller. /// The iterative process controller.
/// </summary> /// </summary>
private IIterator<Complex32> _iterator; private IIterator _iterator;
/// <summary> /// <summary>
/// Indicates the number of <c>BiCGStab</c> steps should be taken /// Indicates the number of <c>BiCGStab</c> steps should be taken
@ -106,7 +103,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
/// Initializes a new instance of the <see cref="GpBiCg"/> class. /// Initializes a new instance of the <see cref="GpBiCg"/> class.
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// When using this constructor the solver will use the <see cref="IIterator{T}"/> with /// When using this constructor the solver will use the <see cref="IIterator"/> with
/// the standard settings and a default preconditioner. /// the standard settings and a default preconditioner.
/// </remarks> /// </remarks>
public GpBiCg() : this(null, null) public GpBiCg() : this(null, null)
@ -121,18 +118,18 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
/// When using this constructor the solver will use a default preconditioner. /// When using this constructor the solver will use a default preconditioner.
/// </para> /// </para>
/// <para> /// <para>
/// The main advantages of using a user defined <see cref="IIterator{T}"/> are: /// The main advantages of using a user defined <see cref="IIterator"/> are:
/// <list type="number"> /// <list type="number">
/// <item>It is possible to set the desired convergence limits.</item> /// <item>It is possible to set the desired convergence limits.</item>
/// <item> /// <item>
/// It is possible to check the reason for which the solver finished /// It is possible to check the reason for which the solver finished
/// the iterative procedure by calling the <see cref="IIterator{T}.Status"/> property. /// the iterative procedure by calling the <see cref="IIterator.Status"/> property.
/// </item> /// </item>
/// </list> /// </list>
/// </para> /// </para>
/// </remarks> /// </remarks>
/// <param name="iterator">The <see cref="IIterator{T}"/> that will be used to monitor the iterative process.</param> /// <param name="iterator">The <see cref="IIterator"/> that will be used to monitor the iterative process.</param>
public GpBiCg(IIterator<Complex32> iterator) : this(null, iterator) public GpBiCg(IIterator iterator) : this(null, iterator)
{ {
} }
@ -140,11 +137,11 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
/// Initializes a new instance of the <see cref="GpBiCg"/> class. /// Initializes a new instance of the <see cref="GpBiCg"/> class.
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// When using this constructor the solver will use the <see cref="IIterator{T}"/> with /// When using this constructor the solver will use the <see cref="IIterator"/> with
/// the standard settings. /// the standard settings.
/// </remarks> /// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation.</param> /// <param name="preconditioner">The <see cref="IPreConditioner"/> that will be used to precondition the matrix equation.</param>
public GpBiCg(IPreConditioner<Complex32> preconditioner) : this(preconditioner, null) public GpBiCg(IPreConditioner preconditioner) : this(preconditioner, null)
{ {
} }
@ -153,19 +150,19 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// <para> /// <para>
/// The main advantages of using a user defined <see cref="IIterator{T}"/> are: /// The main advantages of using a user defined <see cref="IIterator"/> are:
/// <list type="number"> /// <list type="number">
/// <item>It is possible to set the desired convergence limits.</item> /// <item>It is possible to set the desired convergence limits.</item>
/// <item> /// <item>
/// It is possible to check the reason for which the solver finished /// It is possible to check the reason for which the solver finished
/// the iterative procedure by calling the <see cref="IIterator{T}.Status"/> property. /// the iterative procedure by calling the <see cref="IIterator.Status"/> property.
/// </item> /// </item>
/// </list> /// </list>
/// </para> /// </para>
/// </remarks> /// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation.</param> /// <param name="preconditioner">The <see cref="IPreConditioner"/> that will be used to precondition the matrix equation.</param>
/// <param name="iterator">The <see cref="IIterator{T}"/> that will be used to monitor the iterative process.</param> /// <param name="iterator">The <see cref="IIterator"/> that will be used to monitor the iterative process.</param>
public GpBiCg(IPreConditioner<Complex32> preconditioner, IIterator<Complex32> iterator) public GpBiCg(IPreConditioner preconditioner, IIterator iterator)
{ {
_iterator = iterator; _iterator = iterator;
_preconditioner = preconditioner; _preconditioner = preconditioner;
@ -216,19 +213,19 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
} }
/// <summary> /// <summary>
/// Sets the <see cref="IPreConditioner{T}"/> that will be used to precondition the iterative process. /// Sets the <see cref="IPreConditioner"/> that will be used to precondition the iterative process.
/// </summary> /// </summary>
/// <param name="preconditioner">The preconditioner.</param> /// <param name="preconditioner">The preconditioner.</param>
public void SetPreconditioner(IPreConditioner<Complex32> preconditioner) public void SetPreconditioner(IPreConditioner preconditioner)
{ {
_preconditioner = preconditioner; _preconditioner = preconditioner;
} }
/// <summary> /// <summary>
/// Sets the <see cref="IIterator{T}"/> that will be used to track the iterative process. /// Sets the <see cref="IIterator"/> that will be used to track the iterative process.
/// </summary> /// </summary>
/// <param name="iterator">The iterator.</param> /// <param name="iterator">The iterator.</param>
public void SetIterator(IIterator<Complex32> iterator) public void SetIterator(IIterator iterator)
{ {
_iterator = iterator; _iterator = iterator;
} }
@ -263,14 +260,14 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param> /// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="vector">The solution vector, <c>b</c>.</param> /// <param name="vector">The solution vector, <c>b</c>.</param>
/// <returns>The result vector, <c>x</c>.</returns> /// <returns>The result vector, <c>x</c>.</returns>
public Vector<Complex32> Solve(Matrix<Complex32> matrix, Vector<Complex32> vector) public Vector Solve(Matrix matrix, Vector vector)
{ {
if (vector == null) if (vector == null)
{ {
throw new ArgumentNullException(); throw new ArgumentNullException();
} }
Vector<Complex32> result = new DenseVector(matrix.RowCount); Vector result = new DenseVector(matrix.RowCount);
Solve(matrix, vector, result); Solve(matrix, vector, result);
return result; return result;
} }
@ -282,7 +279,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param> /// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution vector, <c>b</c></param> /// <param name="input">The solution vector, <c>b</c></param>
/// <param name="result">The result vector, <c>x</c></param> /// <param name="result">The result vector, <c>x</c></param>
public void Solve(Matrix<Complex32> matrix, Vector<Complex32> input, Vector<Complex32> result) public void Solve(Matrix matrix, Vector input, Vector result)
{ {
// If we were stopped before, we are no longer // If we were stopped before, we are no longer
// We're doing this at the start of the method to ensure // We're doing this at the start of the method to ensure
@ -336,11 +333,11 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
// x_0 is initial guess // x_0 is initial guess
// Take x_0 = 0 // Take x_0 = 0
Vector<Complex32> xtemp = new DenseVector(input.Count); Vector xtemp = new DenseVector(input.Count);
// r_0 = b - Ax_0 // r_0 = b - Ax_0
// This is basically a SAXPY so it could be made a lot faster // This is basically a SAXPY so it could be made a lot faster
Vector<Complex32> residuals = new DenseVector(matrix.RowCount); Vector residuals = new DenseVector(matrix.RowCount);
CalculateTrueResidual(matrix, residuals, xtemp, input); CalculateTrueResidual(matrix, residuals, xtemp, input);
// Define the temporary scalars // Define the temporary scalars
@ -349,26 +346,26 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
// Define the temporary vectors // Define the temporary vectors
// rDash_0 = r_0 // rDash_0 = r_0
Vector<Complex32> rdash = new DenseVector(residuals); Vector rdash = new DenseVector(residuals);
// t_-1 = 0 // t_-1 = 0
Vector<Complex32> t = new DenseVector(residuals.Count); Vector t = new DenseVector(residuals.Count);
Vector<Complex32> t0 = new DenseVector(residuals.Count); Vector t0 = new DenseVector(residuals.Count);
// w_-1 = 0 // w_-1 = 0
Vector<Complex32> w = new DenseVector(residuals.Count); Vector w = new DenseVector(residuals.Count);
// Define the remaining temporary vectors // Define the remaining temporary vectors
Vector<Complex32> c = new DenseVector(residuals.Count); Vector c = new DenseVector(residuals.Count);
Vector<Complex32> p = new DenseVector(residuals.Count); Vector p = new DenseVector(residuals.Count);
Vector<Complex32> s = new DenseVector(residuals.Count); Vector s = new DenseVector(residuals.Count);
Vector<Complex32> u = new DenseVector(residuals.Count); Vector u = new DenseVector(residuals.Count);
Vector<Complex32> y = new DenseVector(residuals.Count); Vector y = new DenseVector(residuals.Count);
Vector<Complex32> z = new DenseVector(residuals.Count); Vector z = new DenseVector(residuals.Count);
Vector<Complex32> temp = new DenseVector(residuals.Count); Vector temp = new DenseVector(residuals.Count);
Vector<Complex32> temp2 = new DenseVector(residuals.Count); Vector temp2 = new DenseVector(residuals.Count);
Vector<Complex32> temp3 = new DenseVector(residuals.Count); Vector temp3 = new DenseVector(residuals.Count);
// for (k = 0, 1, .... ) // for (k = 0, 1, .... )
var iterationNumber = 0; var iterationNumber = 0;
@ -525,13 +522,13 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
} }
/// <summary> /// <summary>
/// Calculates the true residual of the matrix equation Ax = b according to: residual = b - Ax /// Calculates the <c>true</c> residual of the matrix equation Ax = b according to: residual = b - Ax
/// </summary> /// </summary>
/// <param name="matrix">Instance of the <see cref="Matrix{T}"/> A.</param> /// <param name="matrix">Instance of the <see cref="Matrix"/> A.</param>
/// <param name="residual">Residual values in <see cref="Vector{T}"/>.</param> /// <param name="residual">Residual values in <see cref="Vector"/>.</param>
/// <param name="x">Instance of the <see cref="Vector{T}"/> x.</param> /// <param name="x">Instance of the <see cref="Vector"/> x.</param>
/// <param name="b">Instance of the <see cref="Vector{T}"/> b.</param> /// <param name="b">Instance of the <see cref="Vector"/> b.</param>
private static void CalculateTrueResidual(Matrix<Complex32> matrix, Vector<Complex32> residual, Vector<Complex32> x, Vector<Complex32> b) private static void CalculateTrueResidual(Matrix matrix, Vector residual, Vector x, Vector b)
{ {
// -Ax = residual // -Ax = residual
matrix.Multiply(x, residual); matrix.Multiply(x, residual);
@ -545,11 +542,11 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
/// Determine if calculation should continue /// Determine if calculation should continue
/// </summary> /// </summary>
/// <param name="iterationNumber">Number of iterations passed</param> /// <param name="iterationNumber">Number of iterations passed</param>
/// <param name="result">Result <see cref="Vector{T}"/>.</param> /// <param name="result">Result <see cref="Vector"/>.</param>
/// <param name="source">Source <see cref="Vector{T}"/>.</param> /// <param name="source">Source <see cref="Vector"/>.</param>
/// <param name="residuals">Residual <see cref="Vector{T}"/>.</param> /// <param name="residuals">Residual <see cref="Vector"/>.</param>
/// <returns><c>true</c> if continue, otherwise <c>false</c></returns> /// <returns><c>true</c> if continue, otherwise <c>false</c></returns>
private bool ShouldContinue(int iterationNumber, Vector<Complex32> result, Vector<Complex32> source, Vector<Complex32> residuals) private bool ShouldContinue(int iterationNumber, Vector result, Vector source, Vector residuals)
{ {
if (_hasBeenStopped) if (_hasBeenStopped)
{ {
@ -590,7 +587,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param> /// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution matrix, <c>B</c>.</param> /// <param name="input">The solution matrix, <c>B</c>.</param>
/// <returns>The result matrix, <c>X</c>.</returns> /// <returns>The result matrix, <c>X</c>.</returns>
public Matrix<Complex32> Solve(Matrix<Complex32> matrix, Matrix<Complex32> input) public Matrix Solve(Matrix matrix, Matrix input)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -602,7 +599,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
throw new ArgumentNullException("input"); throw new ArgumentNullException("input");
} }
var result = matrix.CreateMatrix(input.RowCount, input.ColumnCount); var result = (Matrix)matrix.CreateMatrix(input.RowCount, input.ColumnCount);
Solve(matrix, input, result); Solve(matrix, input, result);
return result; return result;
} }
@ -614,7 +611,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param> /// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution matrix, <c>B</c>.</param> /// <param name="input">The solution matrix, <c>B</c>.</param>
/// <param name="result">The result matrix, <c>X</c></param> /// <param name="result">The result matrix, <c>X</c></param>
public void Solve(Matrix<Complex32> matrix, Matrix<Complex32> input, Matrix<Complex32> result) public void Solve(Matrix matrix, Matrix input, Matrix result)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -638,7 +635,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
for (var column = 0; column < input.ColumnCount; column++) for (var column = 0; column < input.ColumnCount; column++)
{ {
var solution = Solve(matrix, input.Column(column)); var solution = Solve(matrix, (Vector)input.Column(column));
foreach (var element in solution.GetIndexedEnumerator()) foreach (var element in solution.GetIndexedEnumerator())
{ {
result.At(element.Key, column, element.Value); result.At(element.Key, column, element.Value);

117
src/Numerics/LinearAlgebra/Complex32/Solvers/Iterative/MlkBiCgStab.cs

@ -35,10 +35,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
using System.Diagnostics; using System.Diagnostics;
using System.Linq; using System.Linq;
using Distributions; using Distributions;
using Generic;
using Generic.Factorization; using Generic.Factorization;
using Generic.Solvers;
using Generic.Solvers.Preconditioners;
using Generic.Solvers.Status; using Generic.Solvers.Status;
using Numerics; using Numerics;
using Preconditioners; using Preconditioners;
@ -67,7 +64,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
/// solver. /// solver.
/// </para> /// </para>
/// </remarks> /// </remarks>
public sealed class MlkBiCgStab : IIterativeSolver<Complex32> public sealed class MlkBiCgStab : IIterativeSolver
{ {
/// <summary> /// <summary>
/// The default number of starting vectors. /// The default number of starting vectors.
@ -84,17 +81,17 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
/// The preconditioner that will be used. Can be set to <see langword="null" />, in which case the default /// The preconditioner that will be used. Can be set to <see langword="null" />, in which case the default
/// pre-conditioner will be used. /// pre-conditioner will be used.
/// </summary> /// </summary>
private IPreConditioner<Complex32> _preconditioner; private IPreConditioner _preconditioner;
/// <summary> /// <summary>
/// The iterative process controller. /// The iterative process controller.
/// </summary> /// </summary>
private IIterator<Complex32> _iterator; private IIterator _iterator;
/// <summary> /// <summary>
/// The collection of starting vectors which are used as the basis for the Krylov sub-space. /// The collection of starting vectors which are used as the basis for the Krylov sub-space.
/// </summary> /// </summary>
private IList<Vector<Complex32>> _startingVectors; private IList<Vector> _startingVectors;
/// <summary> /// <summary>
/// The number of starting vectors used by the algorithm /// The number of starting vectors used by the algorithm
@ -110,7 +107,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
/// Initializes a new instance of the <see cref="MlkBiCgStab"/> class. /// Initializes a new instance of the <see cref="MlkBiCgStab"/> class.
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// When using this constructor the solver will use the <see cref="IIterator{T}"/> with /// When using this constructor the solver will use the <see cref="IIterator"/> with
/// the standard settings and a default preconditioner. /// the standard settings and a default preconditioner.
/// </remarks> /// </remarks>
public MlkBiCgStab() : this(null, null) public MlkBiCgStab() : this(null, null)
@ -125,18 +122,18 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
/// When using this constructor the solver will use a default preconditioner. /// When using this constructor the solver will use a default preconditioner.
/// </para> /// </para>
/// <para> /// <para>
/// The main advantages of using a user defined <see cref="IIterator{T}"/> are: /// The main advantages of using a user defined <see cref="IIterator"/> are:
/// <list type="number"> /// <list type="number">
/// <item>It is possible to set the desired convergence limits.</item> /// <item>It is possible to set the desired convergence limits.</item>
/// <item> /// <item>
/// It is possible to check the reason for which the solver finished /// It is possible to check the reason for which the solver finished
/// the iterative procedure by calling the <see cref="IIterator{T}.Status"/> property. /// the iterative procedure by calling the <see cref="IIterator.Status"/> property.
/// </item> /// </item>
/// </list> /// </list>
/// </para> /// </para>
/// </remarks> /// </remarks>
/// <param name="iterator">The <see cref="IIterator{T}"/> that will be used to monitor the iterative process.</param> /// <param name="iterator">The <see cref="IIterator"/> that will be used to monitor the iterative process.</param>
public MlkBiCgStab(IIterator<Complex32> iterator) : this(null, iterator) public MlkBiCgStab(IIterator iterator) : this(null, iterator)
{ {
} }
@ -144,11 +141,11 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
/// Initializes a new instance of the <see cref="MlkBiCgStab"/> class. /// Initializes a new instance of the <see cref="MlkBiCgStab"/> class.
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// When using this constructor the solver will use the <see cref="IIterator{T}"/> with /// When using this constructor the solver will use the <see cref="IIterator"/> with
/// the standard settings. /// the standard settings.
/// </remarks> /// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation.</param> /// <param name="preconditioner">The <see cref="IPreConditioner"/> that will be used to precondition the matrix equation.</param>
public MlkBiCgStab(IPreConditioner<Complex32> preconditioner) : this(preconditioner, null) public MlkBiCgStab(IPreConditioner preconditioner) : this(preconditioner, null)
{ {
} }
@ -157,19 +154,19 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// <para> /// <para>
/// The main advantages of using a user defined <see cref="IIterator{T}"/> are: /// The main advantages of using a user defined <see cref="IIterator"/> are:
/// <list type="number"> /// <list type="number">
/// <item>It is possible to set the desired convergence limits.</item> /// <item>It is possible to set the desired convergence limits.</item>
/// <item> /// <item>
/// It is possible to check the reason for which the solver finished /// It is possible to check the reason for which the solver finished
/// the iterative procedure by calling the <see cref="IIterator{T}.Status"/> property. /// the iterative procedure by calling the <see cref="IIterator.Status"/> property.
/// </item> /// </item>
/// </list> /// </list>
/// </para> /// </para>
/// </remarks> /// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation.</param> /// <param name="preconditioner">The <see cref="IPreConditioner"/> that will be used to precondition the matrix equation.</param>
/// <param name="iterator">The <see cref="IIterator{T}"/> that will be used to monitor the iterative process.</param> /// <param name="iterator">The <see cref="IIterator"/> that will be used to monitor the iterative process.</param>
public MlkBiCgStab(IPreConditioner<Complex32> preconditioner, IIterator<Complex32> iterator) public MlkBiCgStab(IPreConditioner preconditioner, IIterator iterator)
{ {
_iterator = iterator; _iterator = iterator;
_preconditioner = preconditioner; _preconditioner = preconditioner;
@ -211,19 +208,19 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
} }
/// <summary> /// <summary>
/// Sets the <see cref="IPreConditioner{T}"/> that will be used to precondition the iterative process. /// Sets the <see cref="IPreConditioner"/> that will be used to precondition the iterative process.
/// </summary> /// </summary>
/// <param name="preconditioner">The preconditioner.</param> /// <param name="preconditioner">The preconditioner.</param>
public void SetPreconditioner(IPreConditioner<Complex32> preconditioner) public void SetPreconditioner(IPreConditioner preconditioner)
{ {
_preconditioner = preconditioner; _preconditioner = preconditioner;
} }
/// <summary> /// <summary>
/// Sets the <see cref="IIterator{T}"/> that will be used to track the iterative process. /// Sets the <see cref="IIterator"/> that will be used to track the iterative process.
/// </summary> /// </summary>
/// <param name="iterator">The iterator.</param> /// <param name="iterator">The iterator.</param>
public void SetIterator(IIterator<Complex32> iterator) public void SetIterator(IIterator iterator)
{ {
_iterator = iterator; _iterator = iterator;
} }
@ -232,7 +229,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
/// Gets or sets a series of orthonormal vectors which will be used as basis for the /// Gets or sets a series of orthonormal vectors which will be used as basis for the
/// Krylov sub-space. /// Krylov sub-space.
/// </summary> /// </summary>
public IList<Vector<Complex32>> StartingVectors public IList<Vector> StartingVectors
{ {
[DebuggerStepThrough] [DebuggerStepThrough]
get get
@ -284,14 +281,14 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param> /// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="vector">The solution vector, <c>b</c>.</param> /// <param name="vector">The solution vector, <c>b</c>.</param>
/// <returns>The result vector, <c>x</c>.</returns> /// <returns>The result vector, <c>x</c>.</returns>
public Vector<Complex32> Solve(Matrix<Complex32> matrix, Vector<Complex32> vector) public Vector Solve(Matrix matrix, Vector vector)
{ {
if (vector == null) if (vector == null)
{ {
throw new ArgumentNullException(); throw new ArgumentNullException();
} }
Vector<Complex32> result = new DenseVector(matrix.RowCount); Vector result = new DenseVector(matrix.RowCount);
Solve(matrix, vector, result); Solve(matrix, vector, result);
return result; return result;
} }
@ -303,7 +300,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param> /// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution vector, <c>b</c></param> /// <param name="input">The solution vector, <c>b</c></param>
/// <param name="result">The result vector, <c>x</c></param> /// <param name="result">The result vector, <c>x</c></param>
public void Solve(Matrix<Complex32> matrix, Vector<Complex32> input, Vector<Complex32> result) public void Solve(Matrix matrix, Vector input, Vector result)
{ {
// If we were stopped before, we are no longer // If we were stopped before, we are no longer
// We're doing this at the start of the method to ensure // We're doing this at the start of the method to ensure
@ -357,7 +354,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
// Choose an initial guess x_0 // Choose an initial guess x_0
// Take x_0 = 0 // Take x_0 = 0
Vector<Complex32> xtemp = new DenseVector(input.Count); Vector xtemp = new DenseVector(input.Count);
// Choose k vectors q_1, q_2, ..., q_k // Choose k vectors q_1, q_2, ..., q_k
// Build a new set if: // Build a new set if:
@ -386,24 +383,24 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
// r_0 = b - Ax_0 // r_0 = b - Ax_0
// This is basically a SAXPY so it could be made a lot faster // This is basically a SAXPY so it could be made a lot faster
Vector<Complex32> residuals = new DenseVector(matrix.RowCount); Vector residuals = new DenseVector(matrix.RowCount);
CalculateTrueResidual(matrix, residuals, xtemp, input); CalculateTrueResidual(matrix, residuals, xtemp, input);
// Define the temporary values // Define the temporary values
var c = new Complex32[k]; var c = new Complex32[k];
// Define the temporary vectors // Define the temporary vectors
Vector<Complex32> gtemp = new DenseVector(residuals.Count); Vector gtemp = new DenseVector(residuals.Count);
Vector<Complex32> u = new DenseVector(residuals.Count); Vector u = new DenseVector(residuals.Count);
Vector<Complex32> utemp = new DenseVector(residuals.Count); Vector utemp = new DenseVector(residuals.Count);
Vector<Complex32> temp = new DenseVector(residuals.Count); Vector temp = new DenseVector(residuals.Count);
Vector<Complex32> temp1 = new DenseVector(residuals.Count); Vector temp1 = new DenseVector(residuals.Count);
Vector<Complex32> temp2 = new DenseVector(residuals.Count); Vector temp2 = new DenseVector(residuals.Count);
Vector<Complex32> zd = new DenseVector(residuals.Count); Vector zd = new DenseVector(residuals.Count);
Vector<Complex32> zg = new DenseVector(residuals.Count); Vector zg = new DenseVector(residuals.Count);
Vector<Complex32> zw = new DenseVector(residuals.Count); Vector zw = new DenseVector(residuals.Count);
var d = CreateVectorArray(_startingVectors.Count, residuals.Count); var d = CreateVectorArray(_startingVectors.Count, residuals.Count);
@ -647,7 +644,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
/// the <paramref name="numberOfVariables"/> is smaller than /// the <paramref name="numberOfVariables"/> is smaller than
/// the <paramref name="maximumNumberOfStartingVectors"/>. /// the <paramref name="maximumNumberOfStartingVectors"/>.
/// </returns> /// </returns>
private static IList<Vector<Complex32>> CreateStartingVectors(int maximumNumberOfStartingVectors, int numberOfVariables) private static IList<Vector> CreateStartingVectors(int maximumNumberOfStartingVectors, int numberOfVariables)
{ {
// Create no more starting vectors than the size of the problem - 1 // Create no more starting vectors than the size of the problem - 1
// Get random values and then orthogonalize them with // Get random values and then orthogonalize them with
@ -658,7 +655,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
// mean = 0 and sd = 1 // mean = 0 and sd = 1
var distribution = new Normal(); var distribution = new Normal();
Matrix<Complex32> matrix = new DenseMatrix(numberOfVariables, count); Matrix matrix = new DenseMatrix(numberOfVariables, count);
for (var i = 0; i < matrix.ColumnCount; i++) for (var i = 0; i < matrix.ColumnCount; i++)
{ {
var samples = new Complex32[matrix.RowCount]; var samples = new Complex32[matrix.RowCount];
@ -678,10 +675,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
var orthogonalMatrix = gs.Q; var orthogonalMatrix = gs.Q;
// Now transfer this to vectors // Now transfer this to vectors
var result = new List<Vector<Complex32>>(); var result = new List<Vector>();
for (var i = 0; i < orthogonalMatrix.ColumnCount; i++) for (var i = 0; i < orthogonalMatrix.ColumnCount; i++)
{ {
result.Add(orthogonalMatrix.Column(i)); result.Add((Vector)orthogonalMatrix.Column(i));
// Normalize the result vector // Normalize the result vector
result[i].Multiply(1 / result[i].Norm(2).Real, result[i]); result[i].Multiply(1 / result[i].Norm(2).Real, result[i]);
@ -691,14 +688,14 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
} }
/// <summary> /// <summary>
/// Create random vecrors array /// Create random vectors array
/// </summary> /// </summary>
/// <param name="arraySize">Number of vectors</param> /// <param name="arraySize">Number of vectors</param>
/// <param name="vectorSize">Size of each vector</param> /// <param name="vectorSize">Size of each vector</param>
/// <returns>Array of random vectors</returns> /// <returns>Array of random vectors</returns>
private static Vector<Complex32>[] CreateVectorArray(int arraySize, int vectorSize) private static Vector[] CreateVectorArray(int arraySize, int vectorSize)
{ {
var result = new Vector<Complex32>[arraySize]; var result = new Vector[arraySize];
for (var i = 0; i < result.Length; i++) for (var i = 0; i < result.Length; i++)
{ {
result[i] = new DenseVector(vectorSize); result[i] = new DenseVector(vectorSize);
@ -708,13 +705,13 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
} }
/// <summary> /// <summary>
/// Calculates the true residual of the matrix equation Ax = b according to: residual = b - Ax /// Calculates the <c>true</c> residual of the matrix equation Ax = b according to: residual = b - Ax
/// </summary> /// </summary>
/// <param name="matrix">Source <see cref="Matrix{T}"/>A.</param> /// <param name="matrix">Source <see cref="Matrix"/>A.</param>
/// <param name="residual">Residual <see cref="Vector{T}"/> data.</param> /// <param name="residual">Residual <see cref="Vector"/> data.</param>
/// <param name="x">x <see cref="Vector{T}"/> data.</param> /// <param name="x">x <see cref="Vector"/> data.</param>
/// <param name="b">b <see cref="Vector{T}"/> data.</param> /// <param name="b">b <see cref="Vector"/> data.</param>
private static void CalculateTrueResidual(Matrix<Complex32> matrix, Vector<Complex32> residual, Vector<Complex32> x, Vector<Complex32> b) private static void CalculateTrueResidual(Matrix matrix, Vector residual, Vector x, Vector b)
{ {
// -Ax = residual // -Ax = residual
matrix.Multiply(x, residual); matrix.Multiply(x, residual);
@ -728,11 +725,11 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
/// Determine if calculation should continue /// Determine if calculation should continue
/// </summary> /// </summary>
/// <param name="iterationNumber">Number of iterations passed</param> /// <param name="iterationNumber">Number of iterations passed</param>
/// <param name="result">Result <see cref="Vector{T}"/>.</param> /// <param name="result">Result <see cref="Vector"/>.</param>
/// <param name="source">Source <see cref="Vector{T}"/>.</param> /// <param name="source">Source <see cref="Vector"/>.</param>
/// <param name="residuals">Residual <see cref="Vector{T}"/>.</param> /// <param name="residuals">Residual <see cref="Vector"/>.</param>
/// <returns><c>true</c> if continue, otherwise <c>false</c></returns> /// <returns><c>true</c> if continue, otherwise <c>false</c></returns>
private bool ShouldContinue(int iterationNumber, Vector<Complex32> result, Vector<Complex32> source, Vector<Complex32> residuals) private bool ShouldContinue(int iterationNumber, Vector result, Vector source, Vector residuals)
{ {
if (_hasBeenStopped) if (_hasBeenStopped)
{ {
@ -756,7 +753,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param> /// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution matrix, <c>B</c>.</param> /// <param name="input">The solution matrix, <c>B</c>.</param>
/// <returns>The result matrix, <c>X</c>.</returns> /// <returns>The result matrix, <c>X</c>.</returns>
public Matrix<Complex32> Solve(Matrix<Complex32> matrix, Matrix<Complex32> input) public Matrix Solve(Matrix matrix, Matrix input)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -768,7 +765,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
throw new ArgumentNullException("input"); throw new ArgumentNullException("input");
} }
var result = matrix.CreateMatrix(input.RowCount, input.ColumnCount); var result = (Matrix)matrix.CreateMatrix(input.RowCount, input.ColumnCount);
Solve(matrix, input, result); Solve(matrix, input, result);
return result; return result;
} }
@ -780,7 +777,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param> /// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution matrix, <c>B</c>.</param> /// <param name="input">The solution matrix, <c>B</c>.</param>
/// <param name="result">The result matrix, <c>X</c></param> /// <param name="result">The result matrix, <c>X</c></param>
public void Solve(Matrix<Complex32> matrix, Matrix<Complex32> input, Matrix<Complex32> result) public void Solve(Matrix matrix, Matrix input, Matrix result)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -804,7 +801,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
for (var column = 0; column < input.ColumnCount; column++) for (var column = 0; column < input.ColumnCount; column++)
{ {
var solution = Solve(matrix, input.Column(column)); var solution = Solve(matrix, (Vector)input.Column(column));
foreach (var element in solution.GetIndexedEnumerator()) foreach (var element in solution.GetIndexedEnumerator())
{ {
result.At(element.Key, column, element.Value); result.At(element.Key, column, element.Value);

77
src/Numerics/LinearAlgebra/Complex32/Solvers/Iterative/TFQMR.cs

@ -31,9 +31,6 @@
namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
{ {
using System; using System;
using Generic;
using Generic.Solvers;
using Generic.Solvers.Preconditioners;
using Generic.Solvers.Status; using Generic.Solvers.Status;
using Numerics; using Numerics;
using Preconditioners; using Preconditioners;
@ -56,7 +53,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
/// solver. /// solver.
/// </para> /// </para>
/// </remarks> /// </remarks>
public sealed class TFQMR : IIterativeSolver<Complex32> public sealed class TFQMR : IIterativeSolver
{ {
/// <summary> /// <summary>
/// The status used if there is no status, i.e. the solver hasn't run yet and there is no /// The status used if there is no status, i.e. the solver hasn't run yet and there is no
@ -68,12 +65,12 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
/// The preconditioner that will be used. Can be set to <see langword="null" />, in which case the default /// The preconditioner that will be used. Can be set to <see langword="null" />, in which case the default
/// pre-conditioner will be used. /// pre-conditioner will be used.
/// </summary> /// </summary>
private IPreConditioner<Complex32> _preconditioner; private IPreConditioner _preconditioner;
/// <summary> /// <summary>
/// The iterative process controller. /// The iterative process controller.
/// </summary> /// </summary>
private IIterator<Complex32> _iterator; private IIterator _iterator;
/// <summary> /// <summary>
/// Indicates if the user has stopped the solver. /// Indicates if the user has stopped the solver.
@ -84,7 +81,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
/// Initializes a new instance of the <see cref="TFQMR"/> class. /// Initializes a new instance of the <see cref="TFQMR"/> class.
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// When using this constructor the solver will use the <see cref="IIterator{T}"/> with /// When using this constructor the solver will use the <see cref="IIterator"/> with
/// the standard settings and a default preconditioner. /// the standard settings and a default preconditioner.
/// </remarks> /// </remarks>
public TFQMR() : this(null, null) public TFQMR() : this(null, null)
@ -99,18 +96,18 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
/// When using this constructor the solver will use a default preconditioner. /// When using this constructor the solver will use a default preconditioner.
/// </para> /// </para>
/// <para> /// <para>
/// The main advantages of using a user defined <see cref="IIterator{T}"/> are: /// The main advantages of using a user defined <see cref="IIterator"/> are:
/// <list type="number"> /// <list type="number">
/// <item>It is possible to set the desired convergence limits.</item> /// <item>It is possible to set the desired convergence limits.</item>
/// <item> /// <item>
/// It is possible to check the reason for which the solver finished /// It is possible to check the reason for which the solver finished
/// the iterative procedure by calling the <see cref="IIterator{T}.Status"/> property. /// the iterative procedure by calling the <see cref="IIterator.Status"/> property.
/// </item> /// </item>
/// </list> /// </list>
/// </para> /// </para>
/// </remarks> /// </remarks>
/// <param name="iterator">The <see cref="IIterator{T}"/> that will be used to monitor the iterative process.</param> /// <param name="iterator">The <see cref="IIterator"/> that will be used to monitor the iterative process.</param>
public TFQMR(IIterator<Complex32> iterator) : this(null, iterator) public TFQMR(IIterator iterator) : this(null, iterator)
{ {
} }
@ -118,11 +115,11 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
/// Initializes a new instance of the <see cref="TFQMR"/> class. /// Initializes a new instance of the <see cref="TFQMR"/> class.
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// When using this constructor the solver will use the <see cref="IIterator{T}"/> with /// When using this constructor the solver will use the <see cref="IIterator"/> with
/// the standard settings. /// the standard settings.
/// </remarks> /// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation.</param> /// <param name="preconditioner">The <see cref="IPreConditioner"/> that will be used to precondition the matrix equation.</param>
public TFQMR(IPreConditioner<Complex32> preconditioner) : this(preconditioner, null) public TFQMR(IPreConditioner preconditioner) : this(preconditioner, null)
{ {
} }
@ -131,38 +128,38 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// <para> /// <para>
/// The main advantages of using a user defined <see cref="IIterator{T}"/> are: /// The main advantages of using a user defined <see cref="IIterator"/> are:
/// <list type="number"> /// <list type="number">
/// <item>It is possible to set the desired convergence limits.</item> /// <item>It is possible to set the desired convergence limits.</item>
/// <item> /// <item>
/// It is possible to check the reason for which the solver finished /// It is possible to check the reason for which the solver finished
/// the iterative procedure by calling the <see cref="IIterator{T}.Status"/> property. /// the iterative procedure by calling the <see cref="IIterator.Status"/> property.
/// </item> /// </item>
/// </list> /// </list>
/// </para> /// </para>
/// </remarks> /// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation.</param> /// <param name="preconditioner">The <see cref="IPreConditioner"/> that will be used to precondition the matrix equation.</param>
/// <param name="iterator">The <see cref="IIterator{T}"/> that will be used to monitor the iterative process.</param> /// <param name="iterator">The <see cref="IIterator"/> that will be used to monitor the iterative process.</param>
public TFQMR(IPreConditioner<Complex32> preconditioner, IIterator<Complex32> iterator) public TFQMR(IPreConditioner preconditioner, IIterator iterator)
{ {
_iterator = iterator; _iterator = iterator;
_preconditioner = preconditioner; _preconditioner = preconditioner;
} }
/// <summary> /// <summary>
/// Sets the <see cref="IPreConditioner{T}"/> that will be used to precondition the iterative process. /// Sets the <see cref="IPreConditioner"/> that will be used to precondition the iterative process.
/// </summary> /// </summary>
/// <param name="preconditioner">The preconditioner.</param> /// <param name="preconditioner">The preconditioner.</param>
public void SetPreconditioner(IPreConditioner<Complex32> preconditioner) public void SetPreconditioner(IPreConditioner preconditioner)
{ {
_preconditioner = preconditioner; _preconditioner = preconditioner;
} }
/// <summary> /// <summary>
/// Sets the <see cref="IIterator{T}"/> that will be used to track the iterative process. /// Sets the <see cref="IIterator"/> that will be used to track the iterative process.
/// </summary> /// </summary>
/// <param name="iterator">The iterator.</param> /// <param name="iterator">The iterator.</param>
public void SetIterator(IIterator<Complex32> iterator) public void SetIterator(IIterator iterator)
{ {
_iterator = iterator; _iterator = iterator;
} }
@ -196,14 +193,14 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param> /// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="vector">The solution vector, <c>b</c>.</param> /// <param name="vector">The solution vector, <c>b</c>.</param>
/// <returns>The result vector, <c>x</c>.</returns> /// <returns>The result vector, <c>x</c>.</returns>
public Vector<Complex32> Solve(Matrix<Complex32> matrix, Vector<Complex32> vector) public Vector Solve(Matrix matrix, Vector vector)
{ {
if (vector == null) if (vector == null)
{ {
throw new ArgumentNullException(); throw new ArgumentNullException();
} }
Vector<Complex32> result = new DenseVector(matrix.RowCount); Vector result = new DenseVector(matrix.RowCount);
Solve(matrix, vector, result); Solve(matrix, vector, result);
return result; return result;
} }
@ -215,7 +212,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param> /// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution vector, <c>b</c></param> /// <param name="input">The solution vector, <c>b</c></param>
/// <param name="result">The result vector, <c>x</c></param> /// <param name="result">The result vector, <c>x</c></param>
public void Solve(Matrix<Complex32> matrix, Vector<Complex32> input, Vector<Complex32> result) public void Solve(Matrix matrix, Vector input, Vector result)
{ {
// If we were stopped before, we are no longer // If we were stopped before, we are no longer
// We're doing this at the start of the method to ensure // We're doing this at the start of the method to ensure
@ -427,13 +424,13 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
} }
/// <summary> /// <summary>
/// Calculates the true residual of the matrix equation Ax = b according to: residual = b - Ax /// Calculates the <c>true</c> residual of the matrix equation Ax = b according to: residual = b - Ax
/// </summary> /// </summary>
/// <param name="matrix">Instance of the <see cref="Matrix{T}"/> A.</param> /// <param name="matrix">Instance of the <see cref="Matrix"/> A.</param>
/// <param name="residual">Residual values in <see cref="Vector{T}"/>.</param> /// <param name="residual">Residual values in <see cref="Vector"/>.</param>
/// <param name="x">Instance of the <see cref="Vector{T}"/> x.</param> /// <param name="x">Instance of the <see cref="Vector"/> x.</param>
/// <param name="b">Instance of the <see cref="Vector{T}"/> b.</param> /// <param name="b">Instance of the <see cref="Vector"/> b.</param>
private static void CalculateTrueResidual(Matrix<Complex32> matrix, Vector<Complex32> residual, Vector<Complex32> x, Vector<Complex32> b) private static void CalculateTrueResidual(Matrix matrix, Vector residual, Vector x, Vector b)
{ {
// -Ax = residual // -Ax = residual
matrix.Multiply(x, residual); matrix.Multiply(x, residual);
@ -447,11 +444,11 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
/// Determine if calculation should continue /// Determine if calculation should continue
/// </summary> /// </summary>
/// <param name="iterationNumber">Number of iterations passed</param> /// <param name="iterationNumber">Number of iterations passed</param>
/// <param name="result">Result <see cref="Vector{T}"/>.</param> /// <param name="result">Result <see cref="Vector"/>.</param>
/// <param name="source">Source <see cref="Vector{T}"/>.</param> /// <param name="source">Source <see cref="Vector"/>.</param>
/// <param name="residuals">Residual <see cref="Vector{T}"/>.</param> /// <param name="residuals">Residual <see cref="Vector"/>.</param>
/// <returns><c>true</c> if continue, otherwise <c>false</c></returns> /// <returns><c>true</c> if continue, otherwise <c>false</c></returns>
private bool ShouldContinue(int iterationNumber, Vector<Complex32> result, Vector<Complex32> source, Vector<Complex32> residuals) private bool ShouldContinue(int iterationNumber, Vector result, Vector source, Vector residuals)
{ {
if (_hasBeenStopped) if (_hasBeenStopped)
{ {
@ -485,7 +482,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param> /// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution matrix, <c>B</c>.</param> /// <param name="input">The solution matrix, <c>B</c>.</param>
/// <returns>The result matrix, <c>X</c>.</returns> /// <returns>The result matrix, <c>X</c>.</returns>
public Matrix<Complex32> Solve(Matrix<Complex32> matrix, Matrix<Complex32> input) public Matrix Solve(Matrix matrix, Matrix input)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -497,7 +494,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
throw new ArgumentNullException("input"); throw new ArgumentNullException("input");
} }
var result = matrix.CreateMatrix(input.RowCount, input.ColumnCount); var result = (Matrix)matrix.CreateMatrix(input.RowCount, input.ColumnCount);
Solve(matrix, input, result); Solve(matrix, input, result);
return result; return result;
} }
@ -509,7 +506,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param> /// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution matrix, <c>B</c>.</param> /// <param name="input">The solution matrix, <c>B</c>.</param>
/// <param name="result">The result matrix, <c>X</c></param> /// <param name="result">The result matrix, <c>X</c></param>
public void Solve(Matrix<Complex32> matrix, Matrix<Complex32> input, Matrix<Complex32> result) public void Solve(Matrix matrix, Matrix input, Matrix result)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -533,7 +530,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative
for (var column = 0; column < input.ColumnCount; column++) for (var column = 0; column < input.ColumnCount; column++)
{ {
var solution = Solve(matrix, input.Column(column)); var solution = Solve(matrix, (Vector)input.Column(column));
foreach (var element in solution.GetIndexedEnumerator()) foreach (var element in solution.GetIndexedEnumerator())
{ {
result.At(element.Key, column, element.Value); result.At(element.Key, column, element.Value);

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

@ -33,18 +33,14 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using Generic;
using Generic.Solvers;
using Generic.Solvers.Status; using Generic.Solvers.Status;
using Generic.Solvers.StopCriterium;
using Numerics;
using Properties; using Properties;
using StopCriterium; using StopCriterium;
/// <summary> /// <summary>
/// An iterator that is used to check if an iterative calculation should continue or stop. /// An iterator that is used to check if an iterative calculation should continue or stop.
/// </summary> /// </summary>
public sealed class Iterator : IIterator<Complex32> public sealed class Iterator : IIterator
{ {
/// <summary> /// <summary>
/// The default status for the iterator. /// The default status for the iterator.
@ -52,10 +48,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
private static readonly ICalculationStatus DefaultStatus = new CalculationIndetermined(); private static readonly ICalculationStatus DefaultStatus = new CalculationIndetermined();
/// <summary> /// <summary>
/// Creates a default iterator with all the <see cref="IIterationStopCriterium{T}"/> objects. /// Creates a default iterator with all the <see cref="IIterationStopCriterium"/> objects.
/// </summary> /// </summary>
/// <returns>A new <see cref="IIterator{T}"/> object.</returns> /// <returns>A new <see cref="IIterator"/> object.</returns>
public static IIterator<Complex32> CreateDefault() public static IIterator CreateDefault()
{ {
var iterator = new Iterator(); var iterator = new Iterator();
iterator.Add(new FailureStopCriterium()); iterator.Add(new FailureStopCriterium());
@ -70,7 +66,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
/// The collection that holds all the stop criteria and the flag indicating if they should be added /// The collection that holds all the stop criteria and the flag indicating if they should be added
/// to the child iterators. /// to the child iterators.
/// </summary> /// </summary>
private readonly Dictionary<Type, IIterationStopCriterium<Complex32>> _stopCriterias = new Dictionary<Type, IIterationStopCriterium<Complex32>>(); private readonly Dictionary<Type, IIterationStopCriterium> _stopCriterias = new Dictionary<Type, IIterationStopCriterium>();
/// <summary> /// <summary>
/// The status of the iterator. /// The status of the iterator.
@ -97,7 +93,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
/// of the stop criteria will be passed on to child iterators. /// of the stop criteria will be passed on to child iterators.
/// </param> /// </param>
/// <exception cref="ArgumentException">Thrown if <paramref name="stopCriteria"/> contains multiple stop criteria of the same type.</exception> /// <exception cref="ArgumentException">Thrown if <paramref name="stopCriteria"/> contains multiple stop criteria of the same type.</exception>
public Iterator(IEnumerable<IIterationStopCriterium<Complex32>> stopCriteria) public Iterator(IEnumerable<IIterationStopCriterium> stopCriteria)
{ {
// Add the stop criteria // Add the stop criteria
if (stopCriteria == null) if (stopCriteria == null)
@ -112,7 +108,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
} }
/// <summary> /// <summary>
/// Adds an <see cref="IIterationStopCriterium{T}"/> to the internal collection of stop-criteria. Only a /// Adds an <see cref="IIterationStopCriterium"/> to the internal collection of stop-criteria. Only a
/// single stop criterium of each type can be stored. /// single stop criterium of each type can be stored.
/// </summary> /// </summary>
/// <param name="stopCriterium">The stop criterium to add.</param> /// <param name="stopCriterium">The stop criterium to add.</param>
@ -121,7 +117,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
/// Thrown if <paramref name="stopCriterium"/> is of the same type as an already /// Thrown if <paramref name="stopCriterium"/> is of the same type as an already
/// stored criterium. /// stored criterium.
/// </exception> /// </exception>
public void Add(IIterationStopCriterium<Complex32> stopCriterium) public void Add(IIterationStopCriterium stopCriterium)
{ {
if (stopCriterium == null) if (stopCriterium == null)
{ {
@ -138,10 +134,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
} }
/// <summary> /// <summary>
/// Removes the <see cref="IIterationStopCriterium{T}"/> from the internal collection. /// Removes the <see cref="IIterationStopCriterium"/> from the internal collection.
/// </summary> /// </summary>
/// <param name="stopCriterium">The stop criterium that must be removed.</param> /// <param name="stopCriterium">The stop criterium that must be removed.</param>
public void Remove(IIterationStopCriterium<Complex32> stopCriterium) public void Remove(IIterationStopCriterium stopCriterium)
{ {
if (stopCriterium == null) if (stopCriterium == null)
{ {
@ -158,11 +154,11 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
} }
/// <summary> /// <summary>
/// Indicates if the specific stop criterium is stored by the <see cref="IIterator{T}"/>. /// Indicates if the specific stop criterium is stored by the <see cref="IIterator"/>.
/// </summary> /// </summary>
/// <param name="stopCriterium">The stop criterium.</param> /// <param name="stopCriterium">The stop criterium.</param>
/// <returns><c>true</c> if the <see cref="IIterator{T}"/> contains the stop criterium; otherwise <c>false</c>.</returns> /// <returns><c>true</c> if the <see cref="IIterator"/> contains the stop criterium; otherwise <c>false</c>.</returns>
public bool Contains(IIterationStopCriterium<Complex32> stopCriterium) public bool Contains(IIterationStopCriterium stopCriterium)
{ {
return stopCriterium != null && _stopCriterias.ContainsKey(stopCriterium.GetType()); return stopCriterium != null && _stopCriterias.ContainsKey(stopCriterium.GetType());
} }
@ -183,7 +179,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
/// Gets an <c>IEnumerator</c> that enumerates over all the stored stop criteria. /// Gets an <c>IEnumerator</c> that enumerates over all the stored stop criteria.
/// </summary> /// </summary>
/// <remarks>Used for testing only.</remarks> /// <remarks>Used for testing only.</remarks>
internal IEnumerator<IIterationStopCriterium<Complex32>> StoredStopCriteria internal IEnumerator<IIterationStopCriterium> StoredStopCriteria
{ {
get get
{ {
@ -216,7 +212,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
/// on the invocation of this method. Therefore this method should only be called if the /// on the invocation of this method. Therefore this method should only be called if the
/// calculation has moved forwards at least one step. /// calculation has moved forwards at least one step.
/// </remarks> /// </remarks>
public void DetermineStatus(int iterationNumber, Vector<Complex32> solutionVector, Vector<Complex32> sourceVector, Vector<Complex32> residualVector) public void DetermineStatus(int iterationNumber, Vector solutionVector, Vector sourceVector, Vector residualVector)
{ {
if (_stopCriterias.Count == 0) if (_stopCriterias.Count == 0)
{ {
@ -288,7 +284,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
} }
/// <summary> /// <summary>
/// Resets the <see cref="IIterator{T}"/> to the pre-calculation state. /// Resets the <see cref="IIterator"/> to the pre-calculation state.
/// </summary> /// </summary>
public void ResetToPrecalculationState() public void ResetToPrecalculationState()
{ {
@ -309,9 +305,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers
/// Creates a deep clone of the current iterator. /// Creates a deep clone of the current iterator.
/// </summary> /// </summary>
/// <returns>The deep clone of the current iterator.</returns> /// <returns>The deep clone of the current iterator.</returns>
public IIterator<Complex32> Clone() public IIterator Clone()
{ {
var stopCriteria = _stopCriterias.Select(pair => pair.Value).Select(stopCriterium => (IIterationStopCriterium<Complex32>)stopCriterium.Clone()).ToList(); var stopCriteria = _stopCriterias.Select(pair => pair.Value).Select(stopCriterium => (IIterationStopCriterium)stopCriterium.Clone()).ToList();
return new Iterator(stopCriteria); return new Iterator(stopCriteria);
} }

14
src/Numerics/LinearAlgebra/Complex32/Solvers/Preconditioners/Diagonal.cs

@ -31,8 +31,6 @@
namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Preconditioners namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Preconditioners
{ {
using System; using System;
using Generic;
using Generic.Solvers.Preconditioners;
using Numerics; using Numerics;
using Properties; using Properties;
@ -40,7 +38,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Preconditioners
/// A diagonal preconditioner. The preconditioner uses the inverse /// A diagonal preconditioner. The preconditioner uses the inverse
/// of the matrix diagonal as preconditioning values. /// of the matrix diagonal as preconditioning values.
/// </summary> /// </summary>
public sealed class Diagonal : IPreConditioner<Complex32> public sealed class Diagonal : IPreConditioner
{ {
/// <summary> /// <summary>
/// The inverse of the matrix diagonal. /// The inverse of the matrix diagonal.
@ -66,10 +64,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Preconditioners
/// Initializes the preconditioner and loads the internal data structures. /// Initializes the preconditioner and loads the internal data structures.
/// </summary> /// </summary>
/// <param name="matrix"> /// <param name="matrix">
/// The <see cref="Matrix{T}"/> upon which this preconditioner is based.</param> /// The <see cref="Matrix"/> upon which this preconditioner is based.</param>
/// <exception cref="ArgumentNullException">If <paramref name="matrix"/> is <see langword="null" />. </exception> /// <exception cref="ArgumentNullException">If <paramref name="matrix"/> is <see langword="null" />. </exception>
/// <exception cref="ArgumentException">If <paramref name="matrix"/> is not a square matrix.</exception> /// <exception cref="ArgumentException">If <paramref name="matrix"/> is not a square matrix.</exception>
public void Initialize(Matrix<Complex32> matrix) public void Initialize(Matrix matrix)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -93,7 +91,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Preconditioners
/// </summary> /// </summary>
/// <param name="rhs">The right hand side vector.</param> /// <param name="rhs">The right hand side vector.</param>
/// <returns>The left hand side vector.</returns> /// <returns>The left hand side vector.</returns>
public Vector<Complex32> Approximate(Vector<Complex32> rhs) public Vector Approximate(Vector rhs)
{ {
if (rhs == null) if (rhs == null)
{ {
@ -110,7 +108,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Preconditioners
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "rhs"); throw new ArgumentException(Resources.ArgumentVectorsSameLength, "rhs");
} }
Vector<Complex32> result = new DenseVector(rhs.Count); Vector result = new DenseVector(rhs.Count);
Approximate(rhs, result); Approximate(rhs, result);
return result; return result;
} }
@ -120,7 +118,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Preconditioners
/// </summary> /// </summary>
/// <param name="rhs">The right hand side vector.</param> /// <param name="rhs">The right hand side vector.</param>
/// <param name="lhs">The left hand side vector. Also known as the result vector.</param> /// <param name="lhs">The left hand side vector. Also known as the result vector.</param>
public void Approximate(Vector<Complex32> rhs, Vector<Complex32> lhs) public void Approximate(Vector rhs, Vector lhs)
{ {
if (rhs == null) if (rhs == null)
{ {

73
src/Numerics/LinearAlgebra/Complex32/Solvers/Preconditioners/IPreConditioner.cs

@ -0,0 +1,73 @@
// <copyright file="IPreConditioner.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
//
// Copyright (c) 2009-2010 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Preconditioners
{
/// <summary>
/// The base interface for preconditioner classes.
/// </summary>
/// <remarks>
/// <para>
/// Preconditioners are used by iterative solvers to improve the convergence
/// speed of the solving process. Increase in convergence speed
/// is related to the number of iterations necessary to get a converged solution.
/// So while in general the use of a preconditioner means that the iterative
/// solver will perform fewer iterations it does not guarantee that the actual
/// solution time decreases given that some preconditioners can be expensive to
/// setup and run.
/// </para>
/// <para>
/// Note that in general changes to the matrix will invalidate the preconditioner
/// if the changes occur after creating the preconditioner.
/// </para>
/// </remarks>
public interface IPreConditioner
{
/// <summary>
/// Initializes the preconditioner and loads the internal data structures.
/// </summary>
/// <param name="matrix">The matrix on which the preconditioner is based.</param>
void Initialize(Matrix matrix);
/// <summary>
/// Approximates the solution to the matrix equation <b>Mx = b</b>.
/// </summary>
/// <param name="rhs">The right hand side vector.</param>
/// <returns>The left hand side vector.</returns>
Vector Approximate(Vector rhs);
/// <summary>
/// Approximates the solution to the matrix equation <b>Mx = b</b>.
/// </summary>
/// <param name="rhs">The right hand side vector.</param>
/// <param name="lhs">The left hand side vector. Also known as the result vector.</param>
void Approximate(Vector rhs, Vector lhs);
}
}

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

@ -32,8 +32,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Preconditioners
{ {
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Generic;
using Generic.Solvers.Preconditioners;
using Numerics; using Numerics;
using Properties; using Properties;
@ -54,7 +52,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Preconditioners
/// pp. 20 - 28 <br/> /// pp. 20 - 28 <br/>
/// Algorithm is described in Section 2, page 22 /// Algorithm is described in Section 2, page 22
/// </remarks> /// </remarks>
public sealed class Ilutp : IPreConditioner<Complex32> public sealed class Ilutp : IPreConditioner
{ {
/// <summary> /// <summary>
/// The default fill level. /// The default fill level.
@ -258,9 +256,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Preconditioners
/// This method is used for debugging purposes only and should normally not be used. /// This method is used for debugging purposes only and should normally not be used.
/// </remarks> /// </remarks>
/// <returns>A new matrix containing the upper triagonal elements.</returns> /// <returns>A new matrix containing the upper triagonal elements.</returns>
internal Matrix<Complex32> UpperTriangle() internal Matrix UpperTriangle()
{ {
return _upper.Clone(); return (Matrix)_upper.Clone();
} }
/// <summary> /// <summary>
@ -270,9 +268,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Preconditioners
/// This method is used for debugging purposes only and should normally not be used. /// This method is used for debugging purposes only and should normally not be used.
/// </remarks> /// </remarks>
/// <returns>A new matrix containing the lower triagonal elements.</returns> /// <returns>A new matrix containing the lower triagonal elements.</returns>
internal Matrix<Complex32> LowerTriangle() internal Matrix LowerTriangle()
{ {
return _lower.Clone(); return (Matrix)_lower.Clone();
} }
/// <summary> /// <summary>
@ -298,13 +296,13 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Preconditioners
/// Initializes the preconditioner and loads the internal data structures. /// Initializes the preconditioner and loads the internal data structures.
/// </summary> /// </summary>
/// <param name="matrix"> /// <param name="matrix">
/// The <see cref="Matrix{T}"/> upon which this preconditioner is based. Note that the /// The <see cref="Matrix"/> upon which this preconditioner is based. Note that the
/// method takes a general matrix type. However internally the data is stored /// method takes a general matrix type. However internally the data is stored
/// as a sparse matrix. Therefore it is not recommended to pass a dense matrix. /// as a sparse matrix. Therefore it is not recommended to pass a dense matrix.
/// </param> /// </param>
/// <exception cref="ArgumentNullException"> If <paramref name="matrix"/> is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException"> If <paramref name="matrix"/> is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If <paramref name="matrix"/> is not a square matrix.</exception> /// <exception cref="ArgumentException">If <paramref name="matrix"/> is not a square matrix.</exception>
public void Initialize(Matrix<Complex32> matrix) public void Initialize(Matrix matrix)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -376,8 +374,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Preconditioners
_pivots[i] = i; _pivots[i] = i;
} }
Vector<Complex32> workVector = new DenseVector(sparseMatrix.RowCount); Vector workVector = new DenseVector(sparseMatrix.RowCount);
Vector<Complex32> rowVector = new DenseVector(sparseMatrix.ColumnCount); Vector rowVector = new DenseVector(sparseMatrix.ColumnCount);
var indexSorting = new int[sparseMatrix.RowCount]; var indexSorting = new int[sparseMatrix.RowCount];
// spaceLeft = lfilNnz * nnz(A) // spaceLeft = lfilNnz * nnz(A)
@ -532,8 +530,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Preconditioners
/// <summary> /// <summary>
/// Pivot elements in the <paramref name="row"/> according to internal pivot array /// Pivot elements in the <paramref name="row"/> according to internal pivot array
/// </summary> /// </summary>
/// <param name="row">Row <see cref="Vector{T}"/> to pivot in</param> /// <param name="row">Row <see cref="Vector"/> to pivot in</param>
private void PivotRow(Vector<Complex32> row) private void PivotRow(Vector row)
{ {
var knownPivots = new Dictionary<int, int>(); var knownPivots = new Dictionary<int, int>();
@ -580,12 +578,12 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Preconditioners
} }
/// <summary> /// <summary>
/// Swap columns in the <see cref="Matrix{T}"/> /// Swap columns in the <see cref="Matrix"/>
/// </summary> /// </summary>
/// <param name="matrix">Source <see cref="Matrix{T}"/>.</param> /// <param name="matrix">Source <see cref="Matrix"/>.</param>
/// <param name="firstColumn">First column index to swap</param> /// <param name="firstColumn">First column index to swap</param>
/// <param name="secondColumn">Second column index to swap</param> /// <param name="secondColumn">Second column index to swap</param>
private static void SwapColumns(Matrix<Complex32> matrix, int firstColumn, int secondColumn) private static void SwapColumns(Matrix matrix, int firstColumn, int secondColumn)
{ {
for (var i = 0; i < matrix.RowCount; i++) for (var i = 0; i < matrix.RowCount; i++)
{ {
@ -601,8 +599,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Preconditioners
/// <param name="lowerBound">Start sort form</param> /// <param name="lowerBound">Start sort form</param>
/// <param name="upperBound">Sort till upper bound</param> /// <param name="upperBound">Sort till upper bound</param>
/// <param name="sortedIndices">Array with sorted vector indicies</param> /// <param name="sortedIndices">Array with sorted vector indicies</param>
/// <param name="values">Source <see cref="Vector{T}"/></param> /// <param name="values">Source <see cref="Vector"/></param>
private static void FindLargestItems(int lowerBound, int upperBound, int[] sortedIndices, Vector<Complex32> values) private static void FindLargestItems(int lowerBound, int upperBound, int[] sortedIndices, Vector values)
{ {
// Copy the indices for the values into the array // Copy the indices for the values into the array
for (var i = 0; i < upperBound + 1 - lowerBound; i++) for (var i = 0; i < upperBound + 1 - lowerBound; i++)
@ -627,7 +625,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Preconditioners
/// </summary> /// </summary>
/// <param name="rhs">The right hand side vector.</param> /// <param name="rhs">The right hand side vector.</param>
/// <returns>The left hand side vector.</returns> /// <returns>The left hand side vector.</returns>
public Vector<Complex32> Approximate(Vector<Complex32> rhs) public Vector Approximate(Vector rhs)
{ {
if (rhs == null) if (rhs == null)
{ {
@ -644,7 +642,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Preconditioners
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "rhs"); throw new ArgumentException(Resources.ArgumentVectorsSameLength, "rhs");
} }
Vector<Complex32> result = new DenseVector(rhs.Count); Vector result = new DenseVector(rhs.Count);
Approximate(rhs, result); Approximate(rhs, result);
return result; return result;
} }
@ -654,7 +652,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Preconditioners
/// </summary> /// </summary>
/// <param name="rhs">The right hand side vector.</param> /// <param name="rhs">The right hand side vector.</param>
/// <param name="lhs">The left hand side vector. Also known as the result vector.</param> /// <param name="lhs">The left hand side vector. Also known as the result vector.</param>
public void Approximate(Vector<Complex32> rhs, Vector<Complex32> lhs) public void Approximate(Vector rhs, Vector lhs)
{ {
if (rhs == null) if (rhs == null)
{ {
@ -679,7 +677,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Preconditioners
// Solve equation here // Solve equation here
// Pivot(vector, result); // Pivot(vector, result);
// Solve L*Y = B(piv,:) // Solve L*Y = B(piv,:)
Vector<Complex32> rowValues = new DenseVector(_lower.RowCount); Vector rowValues = new DenseVector(_lower.RowCount);
for (var i = 0; i < _lower.RowCount; i++) for (var i = 0; i < _lower.RowCount; i++)
{ {
_lower.Row(i, rowValues); _lower.Row(i, rowValues);
@ -709,17 +707,17 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Preconditioners
// We have a column pivot so we only need to pivot the // We have a column pivot so we only need to pivot the
// end result not the incoming right hand side vector // end result not the incoming right hand side vector
var temp = lhs.Clone(); var temp = (Vector)lhs.Clone();
Pivot(temp, lhs); Pivot(temp, lhs);
} }
/// <summary> /// <summary>
/// Pivot elements in <see cref="Vector{T}"/> accoring to internal pivot array /// Pivot elements in <see cref="Vector"/> according to internal pivot array
/// </summary> /// </summary>
/// <param name="vector">Source <see cref="Vector{T}"/>.</param> /// <param name="vector">Source <see cref="Vector"/>.</param>
/// <param name="result">Result <see cref="Vector{T}"/> after pivoting.</param> /// <param name="result">Result <see cref="Vector"/> after pivoting.</param>
private void Pivot(Vector<Complex32> vector, Vector<Complex32> result) private void Pivot(Vector vector, Vector result)
{ {
for (var i = 0; i < _pivots.Length; i++) for (var i = 0; i < _pivots.Length; i++)
{ {

37
src/Numerics/LinearAlgebra/Complex32/Solvers/Preconditioners/IlutpElementSorter.cs

@ -30,9 +30,6 @@
namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Preconditioners namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Preconditioners
{ {
using Generic;
using Numerics;
/// <summary> /// <summary>
/// An element sort algorithm for the <see cref="Ilutp"/> class. /// An element sort algorithm for the <see cref="Ilutp"/> class.
/// </summary> /// </summary>
@ -49,8 +46,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Preconditioners
/// <param name="lowerBound">The starting index.</param> /// <param name="lowerBound">The starting index.</param>
/// <param name="upperBound">The stopping index.</param> /// <param name="upperBound">The stopping index.</param>
/// <param name="sortedIndices">An array that will contain the sorted indices once the algorithm finishes.</param> /// <param name="sortedIndices">An array that will contain the sorted indices once the algorithm finishes.</param>
/// <param name="values">The <see cref="Vector{T}"/> that contains the values that need to be sorted.</param> /// <param name="values">The <see cref="Vector"/> that contains the values that need to be sorted.</param>
public static void SortDoubleIndicesDecreasing(int lowerBound, int upperBound, int[] sortedIndices, Vector<Complex32> values) public static void SortDoubleIndicesDecreasing(int lowerBound, int upperBound, int[] sortedIndices, Vector values)
{ {
// Move all the indices that we're interested in to the beginning of the // Move all the indices that we're interested in to the beginning of the
// array. Ignore the rest of the indices. // array. Ignore the rest of the indices.
@ -75,8 +72,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Preconditioners
/// <param name="lowerBound">The starting index.</param> /// <param name="lowerBound">The starting index.</param>
/// <param name="upperBound">The stopping index.</param> /// <param name="upperBound">The stopping index.</param>
/// <param name="sortedIndices">An array that will contain the sorted indices once the algorithm finishes.</param> /// <param name="sortedIndices">An array that will contain the sorted indices once the algorithm finishes.</param>
/// <param name="values">The <see cref="Vector{T}"/> that contains the values that need to be sorted.</param> /// <param name="values">The <see cref="Vector"/> that contains the values that need to be sorted.</param>
private static void HeapSortDoublesIndices(int lowerBound, int upperBound, int[] sortedIndices, Vector<Complex32> values) private static void HeapSortDoublesIndices(int lowerBound, int upperBound, int[] sortedIndices, Vector values)
{ {
var start = ((upperBound - lowerBound + 1) / 2) - 1 + lowerBound; var start = ((upperBound - lowerBound + 1) / 2) - 1 + lowerBound;
var end = (upperBound - lowerBound + 1) - 1 + lowerBound; var end = (upperBound - lowerBound + 1) - 1 + lowerBound;
@ -95,10 +92,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Preconditioners
/// Build heap for double indicies /// Build heap for double indicies
/// </summary> /// </summary>
/// <param name="start">Root position</param> /// <param name="start">Root position</param>
/// <param name="count">Lenght of <paramref name="values"/></param> /// <param name="count">Length of <paramref name="values"/></param>
/// <param name="sortedIndices">Indicies of <paramref name="values"/></param> /// <param name="sortedIndices">Indicies of <paramref name="values"/></param>
/// <param name="values">Target <see cref="Vector{T}"/></param> /// <param name="values">Target <see cref="Vector"/></param>
private static void BuildDoubleIndexHeap(int start, int count, int[] sortedIndices, Vector<Complex32> values) private static void BuildDoubleIndexHeap(int start, int count, int[] sortedIndices, Vector values)
{ {
while (start >= 0) while (start >= 0)
{ {
@ -111,17 +108,16 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Preconditioners
/// Sift double indicies /// Sift double indicies
/// </summary> /// </summary>
/// <param name="sortedIndices">Indicies of <paramref name="values"/></param> /// <param name="sortedIndices">Indicies of <paramref name="values"/></param>
/// <param name="values">Target <see cref="Vector{T}"/></param> /// <param name="values">Target <see cref="Vector"/></param>
/// <param name="begin">Root position</param> /// <param name="begin">Root position</param>
/// <param name="count">Lenght of <paramref name="values"/></param> /// <param name="count">Length of <paramref name="values"/></param>
private static void SiftDoubleIndices(int[] sortedIndices, Vector<Complex32> values, int begin, int count) private static void SiftDoubleIndices(int[] sortedIndices, Vector values, int begin, int count)
{ {
var root = begin; var root = begin;
int child;
while (root * 2 < count) while (root * 2 < count)
{ {
child = root * 2; var child = root * 2;
if ((child < count - 1) && (values[sortedIndices[child]].Magnitude > values[sortedIndices[child + 1]].Magnitude)) if ((child < count - 1) && (values[sortedIndices[child]].Magnitude > values[sortedIndices[child + 1]].Magnitude))
{ {
child += 1; child += 1;
@ -171,7 +167,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Preconditioners
/// </summary> /// </summary>
/// <param name="values">Target values array</param> /// <param name="values">Target values array</param>
/// <param name="start">Root position</param> /// <param name="start">Root position</param>
/// <param name="count">Lenght of <paramref name="values"/></param> /// <param name="count">Length of <paramref name="values"/></param>
private static void BuildHeap(int[] values, int start, int count) private static void BuildHeap(int[] values, int start, int count)
{ {
while (start >= 0) while (start >= 0)
@ -186,15 +182,14 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Preconditioners
/// </summary> /// </summary>
/// <param name="values">Target value array</param> /// <param name="values">Target value array</param>
/// <param name="start">Root position</param> /// <param name="start">Root position</param>
/// <param name="count">Lenght of <paramref name="values"/></param> /// <param name="count">Length of <paramref name="values"/></param>
private static void Sift(int[] values, int start, int count) private static void Sift(int[] values, int start, int count)
{ {
var root = start; var root = start;
int child;
while (root * 2 < count) while (root * 2 < count)
{ {
child = root * 2; var child = root * 2;
if ((child < count - 1) && (values[child] > values[child + 1])) if ((child < count - 1) && (values[child] > values[child + 1]))
{ {
child += 1; child += 1;
@ -216,8 +211,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Preconditioners
/// Exchange values in array /// Exchange values in array
/// </summary> /// </summary>
/// <param name="values">Target values array</param> /// <param name="values">Target values array</param>
/// <param name="first">First value to exchanghe</param> /// <param name="first">First value to exchange</param>
/// <param name="second">Second value to exchanghe</param> /// <param name="second">Second value to exchange</param>
private static void Exchange(int[] values, int first, int second) private static void Exchange(int[] values, int first, int second)
{ {
var t = values[first]; var t = values[first];

18
src/Numerics/LinearAlgebra/Complex32/Solvers/Preconditioners/IncompleteLU.cs

@ -31,8 +31,6 @@
namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Preconditioners namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Preconditioners
{ {
using System; using System;
using Generic;
using Generic.Solvers.Preconditioners;
using Numerics; using Numerics;
using Properties; using Properties;
@ -45,7 +43,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Preconditioners
/// Yousef Saad <br/> /// Yousef Saad <br/>
/// Algorithm is described in Chapter 10, section 10.3.2, page 275 <br/> /// Algorithm is described in Chapter 10, section 10.3.2, page 275 <br/>
/// </remarks> /// </remarks>
public sealed class IncompleteLU : IPreConditioner<Complex32> public sealed class IncompleteLU : IPreConditioner
{ {
/// <summary> /// <summary>
/// The matrix holding the lower (L) and upper (U) matrices. The /// The matrix holding the lower (L) and upper (U) matrices. The
@ -57,7 +55,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Preconditioners
/// Returns the upper triagonal matrix that was created during the LU decomposition. /// Returns the upper triagonal matrix that was created during the LU decomposition.
/// </summary> /// </summary>
/// <returns>A new matrix containing the upper triagonal elements.</returns> /// <returns>A new matrix containing the upper triagonal elements.</returns>
internal Matrix<Complex32> UpperTriangle() internal Matrix UpperTriangle()
{ {
var result = new SparseMatrix(_decompositionLU.RowCount); var result = new SparseMatrix(_decompositionLU.RowCount);
for (var i = 0; i < _decompositionLU.RowCount; i++) for (var i = 0; i < _decompositionLU.RowCount; i++)
@ -75,7 +73,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Preconditioners
/// Returns the lower triagonal matrix that was created during the LU decomposition. /// Returns the lower triagonal matrix that was created during the LU decomposition.
/// </summary> /// </summary>
/// <returns>A new matrix containing the lower triagonal elements.</returns> /// <returns>A new matrix containing the lower triagonal elements.</returns>
internal Matrix<Complex32> LowerTriangle() internal Matrix LowerTriangle()
{ {
var result = new SparseMatrix(_decompositionLU.RowCount); var result = new SparseMatrix(_decompositionLU.RowCount);
for (var i = 0; i < _decompositionLU.RowCount; i++) for (var i = 0; i < _decompositionLU.RowCount; i++)
@ -102,7 +100,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Preconditioners
/// <param name="matrix">The matrix upon which the preconditioner is based. </param> /// <param name="matrix">The matrix upon which the preconditioner is based. </param>
/// <exception cref="ArgumentNullException">If <paramref name="matrix"/> is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If <paramref name="matrix"/> is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If <paramref name="matrix"/> is not a square matrix.</exception> /// <exception cref="ArgumentException">If <paramref name="matrix"/> is not a square matrix.</exception>
public void Initialize(Matrix<Complex32> matrix) public void Initialize(Matrix matrix)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -164,7 +162,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Preconditioners
/// </summary> /// </summary>
/// <param name="rhs">The right hand side vector.</param> /// <param name="rhs">The right hand side vector.</param>
/// <returns>The left hand side vector.</returns> /// <returns>The left hand side vector.</returns>
public Vector<Complex32> Approximate(Vector<Complex32> rhs) public Vector Approximate(Vector rhs)
{ {
if (rhs == null) if (rhs == null)
{ {
@ -181,7 +179,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Preconditioners
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "rhs"); throw new ArgumentException(Resources.ArgumentVectorsSameLength, "rhs");
} }
Vector<Complex32> result = new DenseVector(rhs.Count); Vector result = new DenseVector(rhs.Count);
Approximate(rhs, result); Approximate(rhs, result);
return result; return result;
} }
@ -191,7 +189,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Preconditioners
/// </summary> /// </summary>
/// <param name="rhs">The right hand side vector.</param> /// <param name="rhs">The right hand side vector.</param>
/// <param name="lhs">The left hand side vector. Also known as the result vector.</param> /// <param name="lhs">The left hand side vector. Also known as the result vector.</param>
public void Approximate(Vector<Complex32> rhs, Vector<Complex32> lhs) public void Approximate(Vector rhs, Vector lhs)
{ {
if (rhs == null) if (rhs == null)
{ {
@ -221,7 +219,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Preconditioners
// z_i = l_ii^-1 * (y_i - SUM_(j<i) l_ij * z_j) // z_i = l_ii^-1 * (y_i - SUM_(j<i) l_ij * z_j)
// } // }
// NOTE: l_ii should be 1 because u_ii has to be the value // NOTE: l_ii should be 1 because u_ii has to be the value
Vector<Complex32> rowValues = new DenseVector(_decompositionLU.RowCount); Vector rowValues = new DenseVector(_decompositionLU.RowCount);
for (var i = 0; i < _decompositionLU.RowCount; i++) for (var i = 0; i < _decompositionLU.RowCount; i++)
{ {
// Clear the rowValues // Clear the rowValues

16
src/Numerics/LinearAlgebra/Complex32/Solvers/Preconditioners/UnitPreconditioner.cs

@ -31,18 +31,14 @@
namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Preconditioners namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Preconditioners
{ {
using System; using System;
using Generic;
using Generic.Solvers;
using Generic.Solvers.Preconditioners;
using Numerics;
using Properties; using Properties;
/// <summary> /// <summary>
/// A unit preconditioner. This preconditioner does not actually do anything /// A unit preconditioner. This preconditioner does not actually do anything
/// it is only used when running an <see cref="IIterativeSolver{T}"/> without /// it is only used when running an <see cref="IIterativeSolver"/> without
/// a preconditioner. /// a preconditioner.
/// </summary> /// </summary>
internal sealed class UnitPreconditioner : IPreConditioner<Complex32> internal sealed class UnitPreconditioner : IPreConditioner
{ {
/// <summary> /// <summary>
/// The coefficient matrix on which this preconditioner operates. /// The coefficient matrix on which this preconditioner operates.
@ -58,7 +54,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Preconditioners
/// </param> /// </param>
/// <exception cref="ArgumentNullException">If <paramref name="matrix"/> is <see langword="null"/>. </exception> /// <exception cref="ArgumentNullException">If <paramref name="matrix"/> is <see langword="null"/>. </exception>
/// <exception cref="ArgumentException">If <paramref name="matrix"/> is not a square matrix.</exception> /// <exception cref="ArgumentException">If <paramref name="matrix"/> is not a square matrix.</exception>
public void Initialize(Matrix<Complex32> matrix) public void Initialize(Matrix matrix)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -91,7 +87,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Preconditioners
/// If the size of <paramref name="rhs"/> is different the number of rows of the coefficient matrix. /// If the size of <paramref name="rhs"/> is different the number of rows of the coefficient matrix.
/// </para> /// </para>
/// </exception> /// </exception>
public void Approximate(Vector<Complex32> rhs, Vector<Complex32> lhs) public void Approximate(Vector rhs, Vector lhs)
{ {
if (rhs == null) if (rhs == null)
{ {
@ -120,7 +116,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Preconditioners
/// <exception cref="ArgumentException"> /// <exception cref="ArgumentException">
/// If the size of <paramref name="rhs"/> is different the number of rows of the coefficient matrix. /// If the size of <paramref name="rhs"/> is different the number of rows of the coefficient matrix.
/// </exception> /// </exception>
public Vector<Complex32> Approximate(Vector<Complex32> rhs) public Vector Approximate(Vector rhs)
{ {
if (rhs == null) if (rhs == null)
{ {
@ -132,7 +128,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Preconditioners
throw new ArgumentException(Resources.ArgumentMatrixDimensions); throw new ArgumentException(Resources.ArgumentMatrixDimensions);
} }
Vector<Complex32> result = new DenseVector(rhs.Count); Vector result = new DenseVector(rhs.Count);
Approximate(rhs, result); Approximate(rhs, result);
return result; return result;
} }

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

@ -32,15 +32,13 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.StopCriterium
{ {
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using Generic;
using Generic.Solvers.Status; using Generic.Solvers.Status;
using Generic.Solvers.StopCriterium; using Generic.Solvers.StopCriterium;
using Numerics;
/// <summary> /// <summary>
/// Monitors an iterative calculation for signs of divergence. /// Monitors an iterative calculation for signs of divergence.
/// </summary> /// </summary>
public sealed class DivergenceStopCriterium : IIterationStopCriterium<Complex32> public sealed class DivergenceStopCriterium : IIterationStopCriterium
{ {
/// <summary> /// <summary>
/// Default value for the maximum relative increase that the /// Default value for the maximum relative increase that the
@ -208,7 +206,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.StopCriterium
/// <summary> /// <summary>
/// Determines the status of the iterative calculation based on the stop criteria stored /// Determines the status of the iterative calculation based on the stop criteria stored
/// by the current <see cref="IIterationStopCriterium{T}"/>. Result is set into <c>Status</c> field. /// by the current <see cref="IIterationStopCriterium"/>. Result is set into <c>Status</c> field.
/// </summary> /// </summary>
/// <param name="iterationNumber">The number of iterations that have passed so far.</param> /// <param name="iterationNumber">The number of iterations that have passed so far.</param>
/// <param name="solutionVector">The vector containing the current solution values.</param> /// <param name="solutionVector">The vector containing the current solution values.</param>
@ -219,7 +217,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.StopCriterium
/// on the invocation of this method. Therefore this method should only be called if the /// on the invocation of this method. Therefore this method should only be called if the
/// calculation has moved forwards at least one step. /// calculation has moved forwards at least one step.
/// </remarks> /// </remarks>
public void DetermineStatus(int iterationNumber, Vector<Complex32> solutionVector, Vector<Complex32> sourceVector, Vector<Complex32> residualVector) public void DetermineStatus(int iterationNumber, Vector solutionVector, Vector sourceVector, Vector residualVector)
{ {
if (iterationNumber < 0) if (iterationNumber < 0)
{ {
@ -302,7 +300,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.StopCriterium
} }
/// <summary> /// <summary>
/// Gets required history lenght /// Gets required history Length
/// </summary> /// </summary>
private int RequiredHistoryLength private int RequiredHistoryLength
{ {
@ -348,7 +346,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.StopCriterium
} }
/// <summary> /// <summary>
/// Resets the <see cref="IIterationStopCriterium{T}"/> to the pre-calculation state. /// Resets the <see cref="IIterationStopCriterium"/> to the pre-calculation state.
/// </summary> /// </summary>
public void ResetToPrecalculationState() public void ResetToPrecalculationState()
{ {
@ -359,7 +357,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.StopCriterium
/// <summary> /// <summary>
/// Gets the <see cref="StopLevel"/> which indicates what sort of stop criterium this /// Gets the <see cref="StopLevel"/> which indicates what sort of stop criterium this
/// <see cref="IIterationStopCriterium{T}"/> monitors. /// <see cref="IIterationStopCriterium"/> monitors.
/// </summary> /// </summary>
/// <value>Returns <see cref="Generic.Solvers.StopCriterium.StopLevel.Divergence"/>.</value> /// <value>Returns <see cref="Generic.Solvers.StopCriterium.StopLevel.Divergence"/>.</value>
public StopLevel StopLevel public StopLevel StopLevel
@ -375,7 +373,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.StopCriterium
/// Clones the current <see cref="DivergenceStopCriterium"/> and its settings. /// Clones the current <see cref="DivergenceStopCriterium"/> and its settings.
/// </summary> /// </summary>
/// <returns>A new instance of the <see cref="DivergenceStopCriterium"/> class.</returns> /// <returns>A new instance of the <see cref="DivergenceStopCriterium"/> class.</returns>
public IIterationStopCriterium<Complex32> Clone() public IIterationStopCriterium Clone()
{ {
return new DivergenceStopCriterium(_maximumRelativeIncrease, _minimumNumberOfIterations); return new DivergenceStopCriterium(_maximumRelativeIncrease, _minimumNumberOfIterations);
} }

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

@ -32,16 +32,14 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.StopCriterium
{ {
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using Generic;
using Generic.Solvers.Status; using Generic.Solvers.Status;
using Generic.Solvers.StopCriterium; using Generic.Solvers.StopCriterium;
using Numerics;
using Properties; using Properties;
/// <summary> /// <summary>
/// Defines an <see cref="Generic.Solvers.StopCriterium.IIterationStopCriterium{T}"/> that monitors residuals for NaN's. /// Defines an <see cref="IIterationStopCriterium"/> that monitors residuals for NaN's.
/// </summary> /// </summary>
public sealed class FailureStopCriterium : IIterationStopCriterium<Complex32> public sealed class FailureStopCriterium : IIterationStopCriterium
{ {
/// <summary> /// <summary>
/// Defines the default last iteration number. Set to -1 because iterations normally /// Defines the default last iteration number. Set to -1 because iterations normally
@ -66,7 +64,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.StopCriterium
/// <summary> /// <summary>
/// Determines the status of the iterative calculation based on the stop criteria stored /// Determines the status of the iterative calculation based on the stop criteria stored
/// by the current <see cref="IIterationStopCriterium{T}"/>. Result is set into <c>Status</c> field. /// by the current <see cref="IIterationStopCriterium"/>. Result is set into <c>Status</c> field.
/// </summary> /// </summary>
/// <param name="iterationNumber">The number of iterations that have passed so far.</param> /// <param name="iterationNumber">The number of iterations that have passed so far.</param>
/// <param name="solutionVector">The vector containing the current solution values.</param> /// <param name="solutionVector">The vector containing the current solution values.</param>
@ -77,7 +75,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.StopCriterium
/// on the invocation of this method. Therefore this method should only be called if the /// on the invocation of this method. Therefore this method should only be called if the
/// calculation has moved forwards at least one step. /// calculation has moved forwards at least one step.
/// </remarks> /// </remarks>
public void DetermineStatus(int iterationNumber, Vector<Complex32> solutionVector, Vector<Complex32> sourceVector, Vector<Complex32> residualVector) public void DetermineStatus(int iterationNumber, Vector solutionVector, Vector sourceVector, Vector residualVector)
{ {
if (iterationNumber < 0) if (iterationNumber < 0)
{ {
@ -157,7 +155,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.StopCriterium
} }
/// <summary> /// <summary>
/// Resets the <see cref="IIterationStopCriterium{T}"/> to the pre-calculation state. /// Resets the <see cref="IIterationStopCriterium"/> to the pre-calculation state.
/// </summary> /// </summary>
public void ResetToPrecalculationState() public void ResetToPrecalculationState()
{ {
@ -167,7 +165,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.StopCriterium
/// <summary> /// <summary>
/// Gets the <see cref="StopLevel"/>which indicates what sort of stop criterium this /// Gets the <see cref="StopLevel"/>which indicates what sort of stop criterium this
/// <see cref="IIterationStopCriterium{T}"/> monitors. /// <see cref="IIterationStopCriterium"/> monitors.
/// </summary> /// </summary>
/// <value>Returns <see cref="CalculationFailure"/>.</value> /// <value>Returns <see cref="CalculationFailure"/>.</value>
public StopLevel StopLevel public StopLevel StopLevel
@ -183,7 +181,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.StopCriterium
/// Clones the current <see cref="FailureStopCriterium"/> and its settings. /// Clones the current <see cref="FailureStopCriterium"/> and its settings.
/// </summary> /// </summary>
/// <returns>A new instance of the <see cref="FailureStopCriterium"/> class.</returns> /// <returns>A new instance of the <see cref="FailureStopCriterium"/> class.</returns>
public IIterationStopCriterium<Complex32> Clone() public IIterationStopCriterium Clone()
{ {
return new FailureStopCriterium(); return new FailureStopCriterium();
} }

80
src/Numerics/LinearAlgebra/Complex32/Solvers/StopCriterium/IIterationStopCriterium.cs

@ -0,0 +1,80 @@
// <copyright file="IIterationStopCriterium.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
// Copyright (c) 2009-2010 Math.NET
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.StopCriterium
{
using System;
using Generic.Solvers.Status;
using Generic.Solvers.StopCriterium;
/// <summary>
/// The base interface for classes that provide stop criteria for iterative calculations.
/// </summary>
public interface IIterationStopCriterium
#if !SILVERLIGHT
: ICloneable
#endif
{
/// <summary>
/// Determines the status of the iterative calculation based on the stop criteria stored
/// by the current <see cref="IIterationStopCriterium"/>. Status is set to <c>Status</c> field of current object.
/// </summary>
/// <param name="iterationNumber">The number of iterations that have passed so far.</param>
/// <param name="solutionVector">The vector containing the current solution values.</param>
/// <param name="sourceVector">The right hand side vector.</param>
/// <param name="residualVector">The vector containing the current residual vectors.</param>
/// <remarks>
/// The individual stop criteria may internally track the progress of the calculation based
/// on the invocation of this method. Therefore this method should only be called if the
/// calculation has moved forwards at least one step.
/// </remarks>
void DetermineStatus(int iterationNumber, Vector solutionVector, Vector sourceVector, Vector residualVector);
/// <summary>
/// Gets the current calculation status.
/// </summary>
/// <remarks><see langword="null" /> is not a legal value. Status should be set in <see cref="DetermineStatus"/> implementation.</remarks>
ICalculationStatus Status { get; }
/// <summary>
/// Resets the <see cref="IIterationStopCriterium"/> to the pre-calculation state.
/// </summary>
/// <remarks>To implementers: Invoking this method should not clear the user defined
/// property values, only the state that is used to track the progress of the
/// calculation.</remarks>
void ResetToPrecalculationState();
/// <summary>
/// Gets the <see cref="StopLevel"/> which indicates what sort of stop criterium this
/// <see cref="IIterationStopCriterium"/> monitors.
/// </summary>
StopLevel StopLevel { get; }
#if SILVERLIGHT
IIterationStopCriterium Clone();
#endif
}
}

10
src/Numerics/LinearAlgebra/Complex32/Solvers/StopCriterium/IterationCountStopCriterium.cs

@ -32,16 +32,14 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.StopCriterium
{ {
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using Generic;
using Generic.Solvers.Status; using Generic.Solvers.Status;
using Generic.Solvers.StopCriterium; using Generic.Solvers.StopCriterium;
using Numerics;
/// <summary> /// <summary>
/// Defines an <see cref="IIterationStopCriterium{T}"/> that monitors the numbers of iteration /// Defines an <see cref="IIterationStopCriterium"/> that monitors the numbers of iteration
/// steps as stop criterium. /// steps as stop criterium.
/// </summary> /// </summary>
public sealed class IterationCountStopCriterium : IIterationStopCriterium<Complex32> public sealed class IterationCountStopCriterium : IIterationStopCriterium
{ {
/// <summary> /// <summary>
/// The default value for the maximum number of iterations the process is allowed /// The default value for the maximum number of iterations the process is allowed
@ -132,7 +130,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.StopCriterium
/// on the invocation of this method. Therefore this method should only be called if the /// on the invocation of this method. Therefore this method should only be called if the
/// calculation has moved forwards at least one step. /// calculation has moved forwards at least one step.
/// </remarks> /// </remarks>
public void DetermineStatus(int iterationNumber, Vector<Complex32> solutionVector, Vector<Complex32> sourceVector, Vector<Complex32> residualVector) public void DetermineStatus(int iterationNumber, Vector solutionVector, Vector sourceVector, Vector residualVector)
{ {
if (iterationNumber < 0) if (iterationNumber < 0)
{ {
@ -209,7 +207,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.StopCriterium
/// Clones the current <see cref="IterationCountStopCriterium"/> and its settings. /// Clones the current <see cref="IterationCountStopCriterium"/> and its settings.
/// </summary> /// </summary>
/// <returns>A new instance of the <see cref="IterationCountStopCriterium"/> class.</returns> /// <returns>A new instance of the <see cref="IterationCountStopCriterium"/> class.</returns>
public IIterationStopCriterium<Complex32> Clone() public IIterationStopCriterium Clone()
{ {
return new IterationCountStopCriterium(_maximumNumberOfIterations); return new IterationCountStopCriterium(_maximumNumberOfIterations);
} }

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

@ -32,16 +32,14 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.StopCriterium
{ {
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using Generic;
using Generic.Solvers.Status; using Generic.Solvers.Status;
using Generic.Solvers.StopCriterium; using Generic.Solvers.StopCriterium;
using Numerics;
using Properties; using Properties;
/// <summary> /// <summary>
/// Defines an <see cref="IIterationStopCriterium{T}"/> that monitors residuals as stop criterium. /// Defines an <see cref="IIterationStopCriterium"/> that monitors residuals as stop criterium.
/// </summary> /// </summary>
public sealed class ResidualStopCriterium : IIterationStopCriterium<Complex32> public sealed class ResidualStopCriterium : IIterationStopCriterium
{ {
/// <summary> /// <summary>
/// The default value for the maximum value of the residual. /// The default value for the maximum value of the residual.
@ -213,7 +211,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.StopCriterium
/// <summary> /// <summary>
/// Determines the status of the iterative calculation based on the stop criteria stored /// Determines the status of the iterative calculation based on the stop criteria stored
/// by the current <see cref="IIterationStopCriterium{T}"/>. Result is set into <c>Status</c> field. /// by the current <see cref="IIterationStopCriterium"/>. Result is set into <c>Status</c> field.
/// </summary> /// </summary>
/// <param name="iterationNumber">The number of iterations that have passed so far.</param> /// <param name="iterationNumber">The number of iterations that have passed so far.</param>
/// <param name="solutionVector">The vector containing the current solution values.</param> /// <param name="solutionVector">The vector containing the current solution values.</param>
@ -224,7 +222,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.StopCriterium
/// on the invocation of this method. Therefore this method should only be called if the /// on the invocation of this method. Therefore this method should only be called if the
/// calculation has moved forwards at least one step. /// calculation has moved forwards at least one step.
/// </remarks> /// </remarks>
public void DetermineStatus(int iterationNumber, Vector<Complex32> solutionVector, Vector<Complex32> sourceVector, Vector<Complex32> residualVector) public void DetermineStatus(int iterationNumber, Vector solutionVector, Vector sourceVector, Vector residualVector)
{ {
if (iterationNumber < 0) if (iterationNumber < 0)
{ {
@ -364,7 +362,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.StopCriterium
} }
/// <summary> /// <summary>
/// Resets the <see cref="IIterationStopCriterium{T}"/> to the pre-calculation state. /// Resets the <see cref="IIterationStopCriterium"/> to the pre-calculation state.
/// </summary> /// </summary>
public void ResetToPrecalculationState() public void ResetToPrecalculationState()
{ {
@ -375,7 +373,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.StopCriterium
/// <summary> /// <summary>
/// Gets the <see cref="StopLevel"/> which indicates what sort of stop criterium this /// Gets the <see cref="StopLevel"/> which indicates what sort of stop criterium this
/// <see cref="IIterationStopCriterium{T}"/> monitors. /// <see cref="IIterationStopCriterium"/> monitors.
/// </summary> /// </summary>
/// <value>Returns <see cref="StopLevel"/>.</value> /// <value>Returns <see cref="StopLevel"/>.</value>
public StopLevel StopLevel public StopLevel StopLevel
@ -391,7 +389,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.StopCriterium
/// Clones the current <see cref="ResidualStopCriterium"/> and its settings. /// Clones the current <see cref="ResidualStopCriterium"/> and its settings.
/// </summary> /// </summary>
/// <returns>A new instance of the <see cref="ResidualStopCriterium"/> class.</returns> /// <returns>A new instance of the <see cref="ResidualStopCriterium"/> class.</returns>
public IIterationStopCriterium<Complex32> Clone() public IIterationStopCriterium Clone()
{ {
return new ResidualStopCriterium(_maximum, _minimumIterationsBelowMaximum); return new ResidualStopCriterium(_maximum, _minimumIterationsBelowMaximum);
} }

96
src/Numerics/LinearAlgebra/Double/Solvers/IIterativeSolver.cs

@ -0,0 +1,96 @@
// <copyright file="IIterativeSolver.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
//
// Copyright (c) 2009-2010 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
{
using Generic.Solvers.Status;
/// <summary>
/// Defines the interface for <see cref="IIterativeSolver"/> classes that solve the matrix equation Ax = b in
/// an iterative manner.
/// </summary>
public interface IIterativeSolver
{
/// <summary>
/// Stops the solve process.
/// </summary>
/// <remarks>
/// Note that it may take an indetermined amount of time for the solver to actually stop the process.
/// </remarks>
void StopSolve();
/// <summary>
/// Sets the <see cref="IIterator"/> that will be used to track the iterative process.
/// </summary>
/// <param name="iterator">The iterator.</param>
void SetIterator(IIterator iterator);
/// <summary>
/// Gets the status of the iteration once the calculation is finished.
/// </summary>
ICalculationStatus 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.
/// </summary>
/// <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 Solve(Matrix matrix, Vector vector);
/// <summary>
/// Solves the matrix equation Ax = b, where A is the coefficient matrix, b is the
/// solution vector and x is the unknown vector.
/// </summary>
/// <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 matrix, Vector input, Vector result);
/// <summary>
/// Solves the matrix equation AX = B, where A is the coefficient matrix, B is the
/// solution matrix and X is the unknown matrix.
/// </summary>
/// <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 Solve(Matrix matrix, Matrix input);
/// <summary>
/// Solves the matrix equation AX = B, where A is the coefficient matrix, B is the
/// solution matrix and X is the unknown matrix.
/// </summary>
/// <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 matrix, Matrix input, Matrix result);
}
}

71
src/Numerics/LinearAlgebra/Double/Solvers/IIterativeSolverSetup.cs

@ -0,0 +1,71 @@
// <copyright file="IIterativeSolverSetup.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
//
// Copyright (c) 2009-2010 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
{
using System;
/// <summary>
/// Defines the interface for objects that can create an iterative solver with
/// specific settings. This interface is used to pass iterative solver creation
/// setup information around.
/// </summary>
public interface IIterativeSolverSetup
{
/// <summary>
/// Gets the type of the solver that will be created by this setup object.
/// </summary>
Type SolverType { get; }
/// <summary>
/// Gets type of preconditioner, if any, that will be created by this setup object.
/// </summary>
Type PreconditionerType { get; }
/// <summary>
/// Creates a fully functional iterative solver with the default settings
/// given by this setup.
/// </summary>
/// <returns>A new <see cref="IIterativeSolver"/>.</returns>
IIterativeSolver CreateNew();
/// <summary>
/// Gets the relative speed of the solver.
/// </summary>
/// <value>Returns a value between 0 and 1, inclusive.</value>
double SolutionSpeed { get; }
/// <summary>
/// Gets the relative reliability of the solver.
/// </summary>
/// <value>Returns a value between 0 and 1 inclusive.</value>
double Reliability { get; }
}
}

108
src/Numerics/LinearAlgebra/Double/Solvers/IIterator.cs

@ -0,0 +1,108 @@
// <copyright file="IIterator.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
//
// Copyright (c) 2009-2010 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
{
using System;
using Generic.Solvers.Status;
using StopCriterium;
/// <summary>
/// Defines the base interface for iterators that help control an iterative calculation.
/// </summary>
public interface IIterator
#if !SILVERLIGHT
: ICloneable
#endif
{
/// <summary>
/// Adds an <see cref="IIterationStopCriterium"/> to the internal collection of stop-criteria. Only a
/// single stop criterium of each type can be stored.
/// </summary>
/// <param name="stopCriterium">The stop criterium to add.</param>
/// <exception cref="ArgumentNullException">Thrown if <paramref name="stopCriterium"/> is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">Thrown if <paramref name="stopCriterium"/> is of the same type as an already stored criterium.</exception>
void Add(IIterationStopCriterium stopCriterium);
/// <summary>
/// Removes the <see cref="IIterationStopCriterium"/> from the internal collection.
/// </summary>
/// <param name="stopCriterium">The stop criterium that must be removed.</param>
void Remove(IIterationStopCriterium stopCriterium);
/// <summary>
/// Indicates if the specific stop criterium is stored by the <see cref="IIterator"/>.
/// </summary>
/// <param name="stopCriterium">The stop criterium.</param>
/// <returns><c>true</c> if the <see cref="IIterator"/> contains the stop criterium; otherwise <c>false</c>.</returns>
bool Contains(IIterationStopCriterium stopCriterium);
/// <summary>
/// Indicates to the iterator that the iterative process has been cancelled.
/// </summary>
/// <remarks>Does not reset the stop-criteria.</remarks>
void IterationCancelled();
/// <summary>
/// Determines the status of the iterative calculation based on the stop criteria stored
/// by the current <see cref="IIterator"/>. Status is set to <c>Status</c> field of current object.
/// </summary>
/// <param name="iterationNumber">The number of iterations that have passed so far.</param>
/// <param name="solutionVector">The vector containing the current solution values.</param>
/// <param name="sourceVector">The right hand side vector.</param>
/// <param name="residualVector">The vector containing the current residual vectors.</param>
/// <remarks>
/// The individual iterators may internally track the progress of the calculation based
/// on the invocation of this method. Therefore this method should only be called if the
/// calculation has moved forwards at least one step.
/// </remarks>
void DetermineStatus(int iterationNumber, Vector solutionVector, Vector sourceVector, Vector residualVector);
/// <summary>
/// Gets the current calculation status.
/// </summary>
/// <remarks><see langword="null" /> is not a legal value. Status should be set in <see cref="DetermineStatus"/> implementation.</remarks>.
ICalculationStatus Status { get; }
/// <summary>
/// Resets the <see cref="IIterator"/> to the pre-calculation state.
/// </summary>
/// <remarks>
/// Note to implementers: Invoking this method should not clear the user defined
/// property values, only the state that is used to track the progress of the
/// calculation.
/// </remarks>
void ResetToPrecalculationState();
#if SILVERLIGHT
IIterator Clone();
#endif
}
}

119
src/Numerics/LinearAlgebra/Double/Solvers/Iterative/BiCgStab.cs

@ -31,9 +31,6 @@
namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
{ {
using System; using System;
using Generic;
using Generic.Solvers;
using Generic.Solvers.Preconditioners;
using Generic.Solvers.Status; using Generic.Solvers.Status;
using Preconditioners; using Preconditioners;
using Properties; using Properties;
@ -67,7 +64,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// solver. /// solver.
/// </para> /// </para>
/// </remarks> /// </remarks>
public sealed class BiCgStab : IIterativeSolver<double> public sealed class BiCgStab : IIterativeSolver
{ {
/// <summary> /// <summary>
/// The status used if there is no status, i.e. the solver hasn't run yet and there is no /// The status used if there is no status, i.e. the solver hasn't run yet and there is no
@ -79,12 +76,12 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// The preconditioner that will be used. Can be set to <see langword="null" />, in which case the default /// The preconditioner that will be used. Can be set to <see langword="null" />, in which case the default
/// pre-conditioner will be used. /// pre-conditioner will be used.
/// </summary> /// </summary>
private IPreConditioner<double> _preconditioner; private IPreConditioner _preconditioner;
/// <summary> /// <summary>
/// The iterative process controller. /// The iterative process controller.
/// </summary> /// </summary>
private IIterator<double> _iterator; private IIterator _iterator;
/// <summary> /// <summary>
/// Indicates if the user has stopped the solver. /// Indicates if the user has stopped the solver.
@ -95,7 +92,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// Initializes a new instance of the <see cref="BiCgStab"/> class. /// Initializes a new instance of the <see cref="BiCgStab"/> class.
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// When using this constructor the solver will use the <see cref="IIterator{T}"/> with /// When using this constructor the solver will use the <see cref="IIterator"/> with
/// the standard settings and a default preconditioner. /// the standard settings and a default preconditioner.
/// </remarks> /// </remarks>
public BiCgStab() : this(null, null) public BiCgStab() : this(null, null)
@ -110,18 +107,18 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// When using this constructor the solver will use a default preconditioner. /// When using this constructor the solver will use a default preconditioner.
/// </para> /// </para>
/// <para> /// <para>
/// The main advantages of using a user defined <see cref="IIterator{T}"/> are: /// The main advantages of using a user defined <see cref="IIterator"/> are:
/// <list type="number"> /// <list type="number">
/// <item>It is possible to set the desired convergence limits.</item> /// <item>It is possible to set the desired convergence limits.</item>
/// <item> /// <item>
/// It is possible to check the reason for which the solver finished /// It is possible to check the reason for which the solver finished
/// the iterative procedure by calling the <see cref="IIterator{T}.Status"/> property. /// the iterative procedure by calling the <see cref="IIterator.Status"/> property.
/// </item> /// </item>
/// </list> /// </list>
/// </para> /// </para>
/// </remarks> /// </remarks>
/// <param name="iterator">The <see cref="IIterator{T}"/> that will be used to monitor the iterative process. </param> /// <param name="iterator">The <see cref="IIterator"/> that will be used to monitor the iterative process. </param>
public BiCgStab(IIterator<double> iterator) : this(null, iterator) public BiCgStab(IIterator iterator) : this(null, iterator)
{ {
} }
@ -129,11 +126,11 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// Initializes a new instance of the <see cref="BiCgStab"/> class. /// Initializes a new instance of the <see cref="BiCgStab"/> class.
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// When using this constructor the solver will use the <see cref="IIterator{T}"/> with /// When using this constructor the solver will use the <see cref="IIterator"/> with
/// the standard settings. /// the standard settings.
/// </remarks> /// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation.</param> /// <param name="preconditioner">The <see cref="IPreConditioner"/> that will be used to precondition the matrix equation.</param>
public BiCgStab(IPreConditioner<double> preconditioner) : this(preconditioner, null) public BiCgStab(IPreConditioner preconditioner) : this(preconditioner, null)
{ {
} }
@ -142,38 +139,38 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// <para> /// <para>
/// The main advantages of using a user defined <see cref="IIterator{T}"/> are: /// The main advantages of using a user defined <see cref="IIterator"/> are:
/// <list type="number"> /// <list type="number">
/// <item>It is possible to set the desired convergence limits.</item> /// <item>It is possible to set the desired convergence limits.</item>
/// <item> /// <item>
/// It is possible to check the reason for which the solver finished /// It is possible to check the reason for which the solver finished
/// the iterative procedure by calling the <see cref="IIterator{T}.Status"/> property. /// the iterative procedure by calling the <see cref="IIterator.Status"/> property.
/// </item> /// </item>
/// </list> /// </list>
/// </para> /// </para>
/// </remarks> /// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation. </param> /// <param name="preconditioner">The <see cref="IPreConditioner"/> that will be used to precondition the matrix equation. </param>
/// <param name="iterator">The <see cref="IIterator{T}"/> that will be used to monitor the iterative process. </param> /// <param name="iterator">The <see cref="IIterator"/> that will be used to monitor the iterative process. </param>
public BiCgStab(IPreConditioner<double> preconditioner, IIterator<double> iterator) public BiCgStab(IPreConditioner preconditioner, IIterator iterator)
{ {
_iterator = iterator; _iterator = iterator;
_preconditioner = preconditioner; _preconditioner = preconditioner;
} }
/// <summary> /// <summary>
/// Sets the <see cref="IPreConditioner{T}"/> that will be used to precondition the iterative process. /// Sets the <see cref="IPreConditioner"/> that will be used to precondition the iterative process.
/// </summary> /// </summary>
/// <param name="preconditioner">The preconditioner.</param> /// <param name="preconditioner">The preconditioner.</param>
public void SetPreconditioner(IPreConditioner<double> preconditioner) public void SetPreconditioner(IPreConditioner preconditioner)
{ {
_preconditioner = preconditioner; _preconditioner = preconditioner;
} }
/// <summary> /// <summary>
/// Sets the <see cref="IIterator{T}"/> that will be used to track the iterative process. /// Sets the <see cref="IIterator"/> that will be used to track the iterative process.
/// </summary> /// </summary>
/// <param name="iterator">The iterator.</param> /// <param name="iterator">The iterator.</param>
public void SetIterator(IIterator<double> iterator) public void SetIterator(IIterator iterator)
{ {
_iterator = iterator; _iterator = iterator;
} }
@ -193,7 +190,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// Stops the solve process. /// Stops the solve process.
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// Note that it may take an indetermined amount of time for the solver to actually stop the process. /// It may take an indetermined amount of time for the solver to actually stop the process.
/// </remarks> /// </remarks>
public void StopSolve() public void StopSolve()
{ {
@ -204,17 +201,17 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// Solves the matrix equation Ax = b, where A is the coefficient matrix, b is the /// Solves the matrix equation Ax = b, where A is the coefficient matrix, b is the
/// solution vector and x is the unknown vector. /// solution vector and x is the unknown vector.
/// </summary> /// </summary>
/// <param name="matrix">The coefficient <see cref="Matrix{T}"/>, <c>A</c>.</param> /// <param name="matrix">The coefficient <see cref="Matrix"/>, <c>A</c>.</param>
/// <param name="vector">The solution <see cref="Vector{T}"/>, <c>b</c>.</param> /// <param name="vector">The solution <see cref="Vector"/>, <c>b</c>.</param>
/// <returns>The result <see cref="Vector{T}"/>, <c>x</c>.</returns> /// <returns>The result <see cref="Vector"/>, <c>x</c>.</returns>
public Vector<double> Solve(Matrix<double> matrix, Vector<double> vector) public Vector Solve(Matrix matrix, Vector vector)
{ {
if (vector == null) if (vector == null)
{ {
throw new ArgumentNullException(); throw new ArgumentNullException();
} }
Vector<double> result = new DenseVector(matrix.RowCount); var result = new DenseVector(matrix.RowCount);
Solve(matrix, vector, result); Solve(matrix, vector, result);
return result; return result;
} }
@ -223,10 +220,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// Solves the matrix equation Ax = b, where A is the coefficient matrix, b is the /// Solves the matrix equation Ax = b, where A is the coefficient matrix, b is the
/// solution vector and x is the unknown vector. /// solution vector and x is the unknown vector.
/// </summary> /// </summary>
/// <param name="matrix">The coefficient <see cref="Matrix{T}"/>, <c>A</c>.</param> /// <param name="matrix">The coefficient <see cref="Matrix"/>, <c>A</c>.</param>
/// <param name="input">The solution <see cref="Vector{T}"/>, <c>b</c>.</param> /// <param name="input">The solution <see cref="Vector"/>, <c>b</c>.</param>
/// <param name="result">The result <see cref="Vector{T}"/>, <c>x</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 matrix, Vector input, Vector result)
{ {
// If we were stopped before, we are no longer // If we were stopped before, we are no longer
// We're doing this at the start of the method to ensure // We're doing this at the start of the method to ensure
@ -281,7 +278,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
// Compute r_0 = b - Ax_0 for some initial guess x_0 // Compute r_0 = b - Ax_0 for some initial guess x_0
// In this case we take x_0 = vector // In this case we take x_0 = vector
// This is basically a SAXPY so it could be made a lot faster // This is basically a SAXPY so it could be made a lot faster
Vector<double> residuals = new DenseVector(matrix.RowCount); Vector residuals = new DenseVector(matrix.RowCount);
CalculateTrueResidual(matrix, residuals, result, input); CalculateTrueResidual(matrix, residuals, result, input);
// Choose r~ (for example, r~ = r_0) // Choose r~ (for example, r~ = r_0)
@ -290,13 +287,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
// create seven temporary vectors needed to hold temporary // create seven temporary vectors needed to hold temporary
// coefficients. All vectors are mangled in each iteration. // coefficients. All vectors are mangled in each iteration.
// These are defined here to prevent stressing the garbage collector // These are defined here to prevent stressing the garbage collector
Vector<double> vecP = new DenseVector(residuals.Count); Vector vecP = new DenseVector(residuals.Count);
Vector<double> vecPdash = new DenseVector(residuals.Count); Vector vecPdash = new DenseVector(residuals.Count);
Vector<double> nu = new DenseVector(residuals.Count); Vector nu = new DenseVector(residuals.Count);
Vector<double> vecS = new DenseVector(residuals.Count); Vector vecS = new DenseVector(residuals.Count);
Vector<double> vecSdash = new DenseVector(residuals.Count); Vector vecSdash = new DenseVector(residuals.Count);
Vector<double> temp = new DenseVector(residuals.Count); Vector temp = new DenseVector(residuals.Count);
Vector<double> temp2 = new DenseVector(residuals.Count); Vector temp2 = new DenseVector(residuals.Count);
// create some temporary double variables that are needed // create some temporary double variables that are needed
// to hold values in between iterations // to hold values in between iterations
@ -428,13 +425,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
} }
/// <summary> /// <summary>
/// Calculates the true residual of the matrix equation Ax = b according to: residual = b - Ax /// Calculates the <c>true</c> residual of the matrix equation Ax = b according to: residual = b - Ax
/// </summary> /// </summary>
/// <param name="matrix">Instance of the <see cref="Matrix{T}"/> A.</param> /// <param name="matrix">Instance of the <see cref="Matrix"/> A.</param>
/// <param name="residual">Residual values in <see cref="Vector{T}"/>.</param> /// <param name="residual">Residual values in <see cref="Vector"/>.</param>
/// <param name="x">Instance of the <see cref="Vector{T}"/> x.</param> /// <param name="x">Instance of the <see cref="Vector"/> x.</param>
/// <param name="b">Instance of the <see cref="Vector{T}"/> b.</param> /// <param name="b">Instance of the <see cref="Vector"/> b.</param>
private static void CalculateTrueResidual(Matrix<double> matrix, Vector<double> residual, Vector<double> x, Vector<double> b) private static void CalculateTrueResidual(Matrix matrix, Vector residual, Vector x, Vector b)
{ {
// -Ax = residual // -Ax = residual
matrix.Multiply(x, residual); matrix.Multiply(x, residual);
@ -450,11 +447,11 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// Determine if calculation should continue /// Determine if calculation should continue
/// </summary> /// </summary>
/// <param name="iterationNumber">Number of iterations passed</param> /// <param name="iterationNumber">Number of iterations passed</param>
/// <param name="result">Result <see cref="Vector{T}"/>.</param> /// <param name="result">Result <see cref="Vector"/>.</param>
/// <param name="source">Source <see cref="Vector{T}"/>.</param> /// <param name="source">Source <see cref="Vector"/>.</param>
/// <param name="residuals">Residual <see cref="Vector{T}"/>.</param> /// <param name="residuals">Residual <see cref="Vector"/>.</param>
/// <returns><c>true</c> if continue, otherwise <c>false</c></returns> /// <returns><c>true</c> if continue, otherwise <c>false</c></returns>
private bool ShouldContinue(int iterationNumber, Vector<double> result, Vector<double> source, Vector<double> residuals) private bool ShouldContinue(int iterationNumber, Vector result, Vector source, Vector residuals)
{ {
if (_hasBeenStopped) if (_hasBeenStopped)
{ {
@ -475,10 +472,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// Solves the matrix equation AX = B, where A is the coefficient matrix, B is the /// Solves the matrix equation AX = B, where A is the coefficient matrix, B is the
/// solution matrix and X is the unknown matrix. /// solution matrix and X is the unknown matrix.
/// </summary> /// </summary>
/// <param name="matrix">The coefficient <see cref="Matrix{T}"/>, <c>A</c>.</param> /// <param name="matrix">The coefficient <see cref="Matrix"/>, <c>A</c>.</param>
/// <param name="input">The solution <see cref="Matrix{T}"/>, <c>B</c>.</param> /// <param name="input">The solution <see cref="Matrix"/>, <c>B</c>.</param>
/// <returns>The result <see cref="Matrix{T}"/>, <c>X</c>.</returns> /// <returns>The result <see cref="Matrix"/>, <c>X</c>.</returns>
public Matrix<double> Solve(Matrix<double> matrix, Matrix<double> input) public Matrix Solve(Matrix matrix, Matrix input)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -490,7 +487,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
throw new ArgumentNullException("input"); throw new ArgumentNullException("input");
} }
var result = matrix.CreateMatrix(input.RowCount, input.ColumnCount); var result = (Matrix)matrix.CreateMatrix(input.RowCount, input.ColumnCount);
Solve(matrix, input, result); Solve(matrix, input, result);
return result; return result;
} }
@ -499,10 +496,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// Solves the matrix equation AX = B, where A is the coefficient matrix, B is the /// Solves the matrix equation AX = B, where A is the coefficient matrix, B is the
/// solution matrix and X is the unknown matrix. /// solution matrix and X is the unknown matrix.
/// </summary> /// </summary>
/// <param name="matrix">The coefficient <see cref="Matrix{T}"/>, <c>A</c>.</param> /// <param name="matrix">The coefficient <see cref="Matrix"/>, <c>A</c>.</param>
/// <param name="input">The solution <see cref="Matrix{T}"/>, <c>B</c>.</param> /// <param name="input">The solution <see cref="Matrix"/>, <c>B</c>.</param>
/// <param name="result">The result <see cref="Matrix{T}"/>, <c>X</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 matrix, Matrix input, Matrix result)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -526,7 +523,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
for (var column = 0; column < input.ColumnCount; column++) for (var column = 0; column < input.ColumnCount; column++)
{ {
var solution = Solve(matrix, input.Column(column)); var solution = Solve(matrix, (Vector)input.Column(column));
foreach (var element in solution.GetIndexedEnumerator()) foreach (var element in solution.GetIndexedEnumerator())
{ {
result.At(element.Key, column, element.Value); result.At(element.Key, column, element.Value);

80
src/Numerics/LinearAlgebra/Double/Solvers/Iterative/CompositeSolver.cs

@ -31,12 +31,11 @@
namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
{ {
using System; using System;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using Generic;
using Generic.Solvers;
using Generic.Solvers.Status; using Generic.Solvers.Status;
using Properties; using Properties;
@ -55,15 +54,12 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// Note that if an iterator is passed to this solver it will be used for all the sub-solvers. /// Note that if an iterator is passed to this solver it will be used for all the sub-solvers.
/// </para> /// </para>
/// </remarks> /// </remarks>
public sealed class CompositeSolver : IIterativeSolver<double> public sealed class CompositeSolver : IIterativeSolver
{ {
#region Internal class - DoubleComparer #region Internal class - DoubleComparer
/// <summary> /// <summary>
/// An <c>IComparer</c> used to compare double precision floating points. /// An <c>IComparer</c> used to compare double precision floating points.
/// </summary> /// </summary>
/// NOTE: The instance of this class is used only in <see cref="SolverSetups"/>. If C# suppports interface inheritence
/// NOTE: and methods in anonymous types, then this class should be deleted and anonymous type implemented with IComaprer support
/// NOTE: in <see cref="SolverSetups"/> constructor
public sealed class DoubleComparer : IComparer<double> public sealed class DoubleComparer : IComparer<double>
{ {
/// <summary> /// <summary>
@ -96,19 +92,19 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
private static readonly ICalculationStatus RunningStatus = new CalculationRunning(); private static readonly ICalculationStatus RunningStatus = new CalculationRunning();
#if SILVERLIGHT #if SILVERLIGHT
private static readonly Dictionary<double, List<IIterativeSolverSetup<double>>> SolverSetups = new Dictionary<double, List<IIterativeSolverSetup<double>>>(); private static readonly Dictionary<double, List<IIterativeSolverSetup>> SolverSetups = new Dictionary<double, List<IIterativeSolverSetup>>();
#else #else
/// <summary> /// <summary>
/// The collection of iterative solver setups. Stored based on the /// The collection of iterative solver setups. Stored based on the
/// ratio between the relative speed and relative accuracy. /// ratio between the relative speed and relative accuracy.
/// </summary> /// </summary>
private static readonly SortedList<double, List<IIterativeSolverSetup<double>>> SolverSetups = new SortedList<double, List<IIterativeSolverSetup<double>>>(new DoubleComparer()); private static readonly SortedList<double, List<IIterativeSolverSetup>> SolverSetups = new SortedList<double, List<IIterativeSolverSetup>>(new DoubleComparer());
#endif #endif
#region Solver information loading methods #region Solver information loading methods
/// <summary> /// <summary>
/// Loads all the available <see cref="IIterativeSolverSetup{T}"/> objects from the MathNet.Numerics assembly. /// Loads all the available <see cref="IIterativeSolverSetup"/> objects from the MathNet.Numerics assembly.
/// </summary> /// </summary>
public static void LoadSolverInformation() public static void LoadSolverInformation()
{ {
@ -116,16 +112,16 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
} }
/// <summary> /// <summary>
/// Loads the available <see cref="IIterativeSolverSetup{T}"/> objects from the MathNet.Numerics assembly. /// Loads the available <see cref="IIterativeSolverSetup"/> objects from the MathNet.Numerics assembly.
/// </summary> /// </summary>
/// <param name="typesToExclude">The <see cref="IIterativeSolver{T}"/> types that should not be loaded.</param> /// <param name="typesToExclude">The <see cref="IIterativeSolver"/> types that should not be loaded.</param>
public static void LoadSolverInformation(Type[] typesToExclude) public static void LoadSolverInformation(Type[] typesToExclude)
{ {
LoadSolverInformationFromAssembly(Assembly.GetExecutingAssembly(), typesToExclude); LoadSolverInformationFromAssembly(Assembly.GetExecutingAssembly(), typesToExclude);
} }
/// <summary> /// <summary>
/// Loads the available <see cref="IIterativeSolverSetup{T}"/> objects from the assembly specified by the file location. /// Loads the available <see cref="IIterativeSolverSetup"/> objects from the assembly specified by the file location.
/// </summary> /// </summary>
/// <param name="assemblyLocation">The fully qualified path to the assembly.</param> /// <param name="assemblyLocation">The fully qualified path to the assembly.</param>
public static void LoadSolverInformationFromAssembly(string assemblyLocation) public static void LoadSolverInformationFromAssembly(string assemblyLocation)
@ -134,10 +130,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
} }
/// <summary> /// <summary>
/// Loads the available <see cref="IIterativeSolverSetup{T}"/> objects from the assembly specified by the file location. /// Loads the available <see cref="IIterativeSolverSetup"/> objects from the assembly specified by the file location.
/// </summary> /// </summary>
/// <param name="assemblyLocation">The fully qualified path to the assembly.</param> /// <param name="assemblyLocation">The fully qualified path to the assembly.</param>
/// <param name="typesToExclude">The <see cref="IIterativeSolver{T}"/> types that should not be loaded. </param> /// <param name="typesToExclude">The <see cref="IIterativeSolver"/> types that should not be loaded. </param>
public static void LoadSolverInformationFromAssembly(string assemblyLocation, params Type[] typesToExclude) public static void LoadSolverInformationFromAssembly(string assemblyLocation, params Type[] typesToExclude)
{ {
if (assemblyLocation == null) if (assemblyLocation == null)
@ -172,7 +168,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
} }
/// <summary> /// <summary>
/// Loads the available <see cref="IIterativeSolverSetup{T}"/> objects from the assembly specified by the assembly name. /// Loads the available <see cref="IIterativeSolverSetup"/> objects from the assembly specified by the assembly name.
/// </summary> /// </summary>
/// <param name="assemblyName">The <see cref="AssemblyName"/> of the assembly that should be searched for setup objects. </param> /// <param name="assemblyName">The <see cref="AssemblyName"/> of the assembly that should be searched for setup objects. </param>
public static void LoadSolverInformationFromAssembly(AssemblyName assemblyName) public static void LoadSolverInformationFromAssembly(AssemblyName assemblyName)
@ -181,10 +177,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
} }
/// <summary> /// <summary>
/// Loads the available <see cref="IIterativeSolverSetup{T}"/> objects from the assembly specified by the assembly name. /// Loads the available <see cref="IIterativeSolverSetup"/> objects from the assembly specified by the assembly name.
/// </summary> /// </summary>
/// <param name="assemblyName">The <see cref="AssemblyName"/> of the assembly that should be searched for setup objects.</param> /// <param name="assemblyName">The <see cref="AssemblyName"/> of the assembly that should be searched for setup objects.</param>
/// <param name="typesToExclude">The <see cref="IIterativeSolver{T}"/> types that should not be loaded.</param> /// <param name="typesToExclude">The <see cref="IIterativeSolver"/> types that should not be loaded.</param>
public static void LoadSolverInformationFromAssembly(AssemblyName assemblyName, params Type[] typesToExclude) public static void LoadSolverInformationFromAssembly(AssemblyName assemblyName, params Type[] typesToExclude)
{ {
if (assemblyName == null) if (assemblyName == null)
@ -204,7 +200,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
} }
/// <summary> /// <summary>
/// Loads the available <see cref="IIterativeSolverSetup{T}"/> objects from the assembly specified by the type. /// Loads the available <see cref="IIterativeSolverSetup"/> objects from the assembly specified by the type.
/// </summary> /// </summary>
/// <param name="typeInAssembly">The type in the assembly which should be searched for setup objects.</param> /// <param name="typeInAssembly">The type in the assembly which should be searched for setup objects.</param>
public static void LoadSolverInformationFromAssembly(Type typeInAssembly) public static void LoadSolverInformationFromAssembly(Type typeInAssembly)
@ -213,10 +209,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
} }
/// <summary> /// <summary>
/// Loads the available <see cref="IIterativeSolverSetup{T}"/> objects from the assembly specified by the type. /// Loads the available <see cref="IIterativeSolverSetup"/> objects from the assembly specified by the type.
/// </summary> /// </summary>
/// <param name="typeInAssembly">The type in the assembly which should be searched for setup objects.</param> /// <param name="typeInAssembly">The type in the assembly which should be searched for setup objects.</param>
/// <param name="typesToExclude">The <see cref="IIterativeSolver{T}"/> types that should not be loaded.</param> /// <param name="typesToExclude">The <see cref="IIterativeSolver"/> types that should not be loaded.</param>
public static void LoadSolverInformationFromAssembly(Type typeInAssembly, params Type[] typesToExclude) public static void LoadSolverInformationFromAssembly(Type typeInAssembly, params Type[] typesToExclude)
{ {
if (typeInAssembly == null) if (typeInAssembly == null)
@ -228,7 +224,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
} }
/// <summary> /// <summary>
/// Loads the available <see cref="IIterativeSolverSetup{T}"/> objects from the specified assembly. /// Loads the available <see cref="IIterativeSolverSetup"/> objects from the specified assembly.
/// </summary> /// </summary>
/// <param name="assembly">The assembly which will be searched for setup objects.</param> /// <param name="assembly">The assembly which will be searched for setup objects.</param>
public static void LoadSolverInformationFromAssembly(Assembly assembly) public static void LoadSolverInformationFromAssembly(Assembly assembly)
@ -237,10 +233,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
} }
/// <summary> /// <summary>
/// Loads the available <see cref="IIterativeSolverSetup{T}"/> objects from the specified assembly. /// Loads the available <see cref="IIterativeSolverSetup"/> objects from the specified assembly.
/// </summary> /// </summary>
/// <param name="assembly">The assembly which will be searched for setup objects.</param> /// <param name="assembly">The assembly which will be searched for setup objects.</param>
/// <param name="typesToExclude">The <see cref="IIterativeSolver{T}"/> types that should not be loaded.</param> /// <param name="typesToExclude">The <see cref="IIterativeSolver"/> types that should not be loaded.</param>
public static void LoadSolverInformationFromAssembly(Assembly assembly, params Type[] typesToExclude) public static void LoadSolverInformationFromAssembly(Assembly assembly, params Type[] typesToExclude)
{ {
if (assembly == null) if (assembly == null)
@ -265,18 +261,18 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
{ {
interfaceTypes.Clear(); interfaceTypes.Clear();
interfaceTypes.AddRange(type.GetInterfaces()); interfaceTypes.AddRange(type.GetInterfaces());
if (!interfaceTypes.Any(match => typeof(IIterativeSolverSetup<double>).IsAssignableFrom(match))) if (!interfaceTypes.Any(match => typeof(IIterativeSolverSetup).IsAssignableFrom(match)))
{ {
continue; continue;
} }
// See if we actually want this type of iterative solver // See if we actually want this type of iterative solver
IIterativeSolverSetup<double> setup; IIterativeSolverSetup setup;
try try
{ {
// If something goes wrong we just ignore it and move on with the next type. // If something goes wrong we just ignore it and move on with the next type.
// There should probably be a log somewhere indicating that something went wrong? // There should probably be a log somewhere indicating that something went wrong?
setup = (IIterativeSolverSetup<double>)Activator.CreateInstance(type); setup = (IIterativeSolverSetup)Activator.CreateInstance(type);
} }
catch (ArgumentException) catch (ArgumentException)
{ {
@ -317,7 +313,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
var ratio = setup.SolutionSpeed / setup.Reliability; var ratio = setup.SolutionSpeed / setup.Reliability;
if (!SolverSetups.ContainsKey(ratio)) if (!SolverSetups.ContainsKey(ratio))
{ {
SolverSetups.Add(ratio, new List<IIterativeSolverSetup<double>>()); SolverSetups.Add(ratio, new List<IIterativeSolverSetup>());
} }
var list = SolverSetups[ratio]; var list = SolverSetups[ratio];
@ -330,7 +326,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// <summary> /// <summary>
/// The collection of solvers that will be used to /// The collection of solvers that will be used to
/// </summary> /// </summary>
private readonly List<IIterativeSolver<double>> _solvers = new List<IIterativeSolver<double>>(); private readonly List<IIterativeSolver> _solvers = new List<IIterativeSolver>();
/// <summary> /// <summary>
/// The status of the calculation. /// The status of the calculation.
@ -340,7 +336,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// <summary> /// <summary>
/// The iterator that is used to control the iteration process. /// The iterator that is used to control the iteration process.
/// </summary> /// </summary>
private IIterator<double> _iterator; private IIterator _iterator;
/// <summary> /// <summary>
/// A flag indicating if the solver has been stopped or not. /// A flag indicating if the solver has been stopped or not.
@ -351,7 +347,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// The solver that is currently running. Reference is used to be able to stop the /// The solver that is currently running. Reference is used to be able to stop the
/// solver if the user cancels the solve process. /// solver if the user cancels the solve process.
/// </summary> /// </summary>
private IIterativeSolver<double> _currentSolver; private IIterativeSolver _currentSolver;
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="CompositeSolver"/> class with the default iterator. /// Initializes a new instance of the <see cref="CompositeSolver"/> class with the default iterator.
@ -364,16 +360,16 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// Initializes a new instance of the <see cref="CompositeSolver"/> class with the specified iterator. /// Initializes a new instance of the <see cref="CompositeSolver"/> class with the specified iterator.
/// </summary> /// </summary>
/// <param name="iterator">The iterator that will be used to control the iteration process. </param> /// <param name="iterator">The iterator that will be used to control the iteration process. </param>
public CompositeSolver(IIterator<double> iterator) public CompositeSolver(IIterator iterator)
{ {
_iterator = iterator; _iterator = iterator;
} }
/// <summary> /// <summary>
/// Sets the <see cref="IIterator{T}"/> that will be used to track the iterative process. /// Sets the <see cref="IIterator"/> that will be used to track the iterative process.
/// </summary> /// </summary>
/// <param name="iterator">The iterator.</param> /// <param name="iterator">The iterator.</param>
public void SetIterator(IIterator<double> iterator) public void SetIterator(IIterator iterator)
{ {
_iterator = iterator; _iterator = iterator;
} }
@ -411,14 +407,14 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param> /// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="vector">The solution vector, <c>b</c>.</param> /// <param name="vector">The solution vector, <c>b</c>.</param>
/// <returns>The result vector, <c>x</c>.</returns> /// <returns>The result vector, <c>x</c>.</returns>
public Vector<double> Solve(Matrix<double> matrix, Vector<double> vector) public Vector Solve(Matrix matrix, Vector vector)
{ {
if (vector == null) if (vector == null)
{ {
throw new ArgumentNullException(); throw new ArgumentNullException();
} }
Vector<double> result = new DenseVector(matrix.RowCount); Vector result = new DenseVector(matrix.RowCount);
Solve(matrix, vector, result); Solve(matrix, vector, result);
return result; return result;
} }
@ -430,7 +426,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param> /// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution vector, <c>b</c></param> /// <param name="input">The solution vector, <c>b</c></param>
/// <param name="result">The result vector, <c>x</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 matrix, Vector input, Vector result)
{ {
// If we were stopped before, we are no longer // If we were stopped before, we are no longer
// We're doing this at the start of the method to ensure // We're doing this at the start of the method to ensure
@ -480,8 +476,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
// Create a copy of the solution and result vectors so we can use them // Create a copy of the solution and result vectors so we can use them
// later on // later on
var internalInput = input.Clone(); var internalInput = (Vector)input.Clone();
var internalResult = result.Clone(); var internalResult = (Vector)result.Clone();
foreach (var solver in _solvers.TakeWhile(solver => !_hasBeenStopped)) foreach (var solver in _solvers.TakeWhile(solver => !_hasBeenStopped))
{ {
@ -572,7 +568,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param> /// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution matrix, <c>B</c>.</param> /// <param name="input">The solution matrix, <c>B</c>.</param>
/// <returns>The result matrix, <c>X</c>.</returns> /// <returns>The result matrix, <c>X</c>.</returns>
public Matrix<double> Solve(Matrix<double> matrix, Matrix<double> input) public Matrix Solve(Matrix matrix, Matrix input)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -584,7 +580,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
throw new ArgumentNullException("input"); throw new ArgumentNullException("input");
} }
var result = matrix.CreateMatrix(input.RowCount, input.ColumnCount); var result = (Matrix)matrix.CreateMatrix(input.RowCount, input.ColumnCount);
Solve(matrix, input, result); Solve(matrix, input, result);
return result; return result;
} }
@ -596,7 +592,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param> /// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution matrix, <c>B</c>.</param> /// <param name="input">The solution matrix, <c>B</c>.</param>
/// <param name="result">The result matrix, <c>X</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 matrix, Matrix input, Matrix result)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -620,7 +616,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
for (var column = 0; column < input.ColumnCount; column++) for (var column = 0; column < input.ColumnCount; column++)
{ {
var solution = Solve(matrix, input.Column(column)); var solution = Solve(matrix, (Vector)input.Column(column));
foreach (var element in solution.GetIndexedEnumerator()) foreach (var element in solution.GetIndexedEnumerator())
{ {
result.At(element.Key, column, element.Value); result.At(element.Key, column, element.Value);

105
src/Numerics/LinearAlgebra/Double/Solvers/Iterative/GpBiCg.cs

@ -31,9 +31,6 @@
namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
{ {
using System; using System;
using Generic;
using Generic.Solvers;
using Generic.Solvers.Preconditioners;
using Generic.Solvers.Status; using Generic.Solvers.Status;
using Preconditioners; using Preconditioners;
using Properties; using Properties;
@ -65,7 +62,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// solver. /// solver.
/// </para> /// </para>
/// </remarks> /// </remarks>
public sealed class GpBiCg : IIterativeSolver<double> public sealed class GpBiCg : IIterativeSolver
{ {
/// <summary> /// <summary>
/// The status used if there is no status, i.e. the solver hasn't run yet and there is no /// The status used if there is no status, i.e. the solver hasn't run yet and there is no
@ -77,12 +74,12 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// The preconditioner that will be used. Can be set to <c>null</c>, in which case the default /// The preconditioner that will be used. Can be set to <c>null</c>, in which case the default
/// pre-conditioner will be used. /// pre-conditioner will be used.
/// </summary> /// </summary>
private IPreConditioner<double> _preconditioner; private IPreConditioner _preconditioner;
/// <summary> /// <summary>
/// The iterative process controller. /// The iterative process controller.
/// </summary> /// </summary>
private IIterator<double> _iterator; private IIterator _iterator;
/// <summary> /// <summary>
/// Indicates the number of <c>BiCGStab</c> steps should be taken /// Indicates the number of <c>BiCGStab</c> steps should be taken
@ -105,7 +102,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// Initializes a new instance of the <see cref="GpBiCg"/> class. /// Initializes a new instance of the <see cref="GpBiCg"/> class.
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// When using this constructor the solver will use the <see cref="IIterator{T}"/> with /// When using this constructor the solver will use the <see cref="IIterator"/> with
/// the standard settings and a default preconditioner. /// the standard settings and a default preconditioner.
/// </remarks> /// </remarks>
public GpBiCg() : this(null, null) public GpBiCg() : this(null, null)
@ -120,18 +117,18 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// When using this constructor the solver will use a default preconditioner. /// When using this constructor the solver will use a default preconditioner.
/// </para> /// </para>
/// <para> /// <para>
/// The main advantages of using a user defined <see cref="IIterator{T}"/> are: /// The main advantages of using a user defined <see cref="IIterator"/> are:
/// <list type="number"> /// <list type="number">
/// <item>It is possible to set the desired convergence limits.</item> /// <item>It is possible to set the desired convergence limits.</item>
/// <item> /// <item>
/// It is possible to check the reason for which the solver finished /// It is possible to check the reason for which the solver finished
/// the iterative procedure by calling the <see cref="IIterator{T}.Status"/> property. /// the iterative procedure by calling the <see cref="IIterator.Status"/> property.
/// </item> /// </item>
/// </list> /// </list>
/// </para> /// </para>
/// </remarks> /// </remarks>
/// <param name="iterator">The <see cref="IIterator{T}"/> that will be used to monitor the iterative process.</param> /// <param name="iterator">The <see cref="IIterator"/> that will be used to monitor the iterative process.</param>
public GpBiCg(IIterator<double> iterator) : this(null, iterator) public GpBiCg(IIterator iterator) : this(null, iterator)
{ {
} }
@ -139,11 +136,11 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// Initializes a new instance of the <see cref="GpBiCg"/> class. /// Initializes a new instance of the <see cref="GpBiCg"/> class.
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// When using this constructor the solver will use the <see cref="IIterator{T}"/> with /// When using this constructor the solver will use the <see cref="IIterator"/> with
/// the standard settings. /// the standard settings.
/// </remarks> /// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation.</param> /// <param name="preconditioner">The <see cref="IPreConditioner"/> that will be used to precondition the matrix equation.</param>
public GpBiCg(IPreConditioner<double> preconditioner) : this(preconditioner, null) public GpBiCg(IPreConditioner preconditioner) : this(preconditioner, null)
{ {
} }
@ -152,19 +149,19 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// <para> /// <para>
/// The main advantages of using a user defined <see cref="IIterator{T}"/> are: /// The main advantages of using a user defined <see cref="IIterator"/> are:
/// <list type="number"> /// <list type="number">
/// <item>It is possible to set the desired convergence limits.</item> /// <item>It is possible to set the desired convergence limits.</item>
/// <item> /// <item>
/// It is possible to check the reason for which the solver finished /// It is possible to check the reason for which the solver finished
/// the iterative procedure by calling the <see cref="IIterator{T}.Status"/> property. /// the iterative procedure by calling the <see cref="IIterator.Status"/> property.
/// </item> /// </item>
/// </list> /// </list>
/// </para> /// </para>
/// </remarks> /// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation.</param> /// <param name="preconditioner">The <see cref="IPreConditioner"/> that will be used to precondition the matrix equation.</param>
/// <param name="iterator">The <see cref="IIterator{T}"/> that will be used to monitor the iterative process.</param> /// <param name="iterator">The <see cref="IIterator"/> that will be used to monitor the iterative process.</param>
public GpBiCg(IPreConditioner<double> preconditioner, IIterator<double> iterator) public GpBiCg(IPreConditioner preconditioner, IIterator iterator)
{ {
_iterator = iterator; _iterator = iterator;
_preconditioner = preconditioner; _preconditioner = preconditioner;
@ -215,19 +212,19 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
} }
/// <summary> /// <summary>
/// Sets the <see cref="IPreConditioner{T}"/> that will be used to precondition the iterative process. /// Sets the <see cref="IPreConditioner"/> that will be used to precondition the iterative process.
/// </summary> /// </summary>
/// <param name="preconditioner">The preconditioner.</param> /// <param name="preconditioner">The preconditioner.</param>
public void SetPreconditioner(IPreConditioner<double> preconditioner) public void SetPreconditioner(IPreConditioner preconditioner)
{ {
_preconditioner = preconditioner; _preconditioner = preconditioner;
} }
/// <summary> /// <summary>
/// Sets the <see cref="IIterator{T}"/> that will be used to track the iterative process. /// Sets the <see cref="IIterator"/> that will be used to track the iterative process.
/// </summary> /// </summary>
/// <param name="iterator">The iterator.</param> /// <param name="iterator">The iterator.</param>
public void SetIterator(IIterator<double> iterator) public void SetIterator(IIterator iterator)
{ {
_iterator = iterator; _iterator = iterator;
} }
@ -262,14 +259,14 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param> /// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="vector">The solution vector, <c>b</c>.</param> /// <param name="vector">The solution vector, <c>b</c>.</param>
/// <returns>The result vector, <c>x</c>.</returns> /// <returns>The result vector, <c>x</c>.</returns>
public Vector<double> Solve(Matrix<double> matrix, Vector<double> vector) public Vector Solve(Matrix matrix, Vector vector)
{ {
if (vector == null) if (vector == null)
{ {
throw new ArgumentNullException(); throw new ArgumentNullException();
} }
Vector<double> result = new DenseVector(matrix.RowCount); Vector result = new DenseVector(matrix.RowCount);
Solve(matrix, vector, result); Solve(matrix, vector, result);
return result; return result;
} }
@ -281,7 +278,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param> /// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution vector, <c>b</c></param> /// <param name="input">The solution vector, <c>b</c></param>
/// <param name="result">The result vector, <c>x</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 matrix, Vector input, Vector result)
{ {
// If we were stopped before, we are no longer // If we were stopped before, we are no longer
// We're doing this at the start of the method to ensure // We're doing this at the start of the method to ensure
@ -335,11 +332,11 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
// x_0 is initial guess // x_0 is initial guess
// Take x_0 = 0 // Take x_0 = 0
Vector<double> xtemp = new DenseVector(input.Count); Vector xtemp = new DenseVector(input.Count);
// r_0 = b - Ax_0 // r_0 = b - Ax_0
// This is basically a SAXPY so it could be made a lot faster // This is basically a SAXPY so it could be made a lot faster
Vector<double> residuals = new DenseVector(matrix.RowCount); Vector residuals = new DenseVector(matrix.RowCount);
CalculateTrueResidual(matrix, residuals, xtemp, input); CalculateTrueResidual(matrix, residuals, xtemp, input);
// Define the temporary scalars // Define the temporary scalars
@ -348,26 +345,26 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
// Define the temporary vectors // Define the temporary vectors
// rDash_0 = r_0 // rDash_0 = r_0
Vector<double> rdash = new DenseVector(residuals); Vector rdash = new DenseVector(residuals);
// t_-1 = 0 // t_-1 = 0
Vector<double> t = new DenseVector(residuals.Count); Vector t = new DenseVector(residuals.Count);
Vector<double> t0 = new DenseVector(residuals.Count); Vector t0 = new DenseVector(residuals.Count);
// w_-1 = 0 // w_-1 = 0
Vector<double> w = new DenseVector(residuals.Count); Vector w = new DenseVector(residuals.Count);
// Define the remaining temporary vectors // Define the remaining temporary vectors
Vector<double> c = new DenseVector(residuals.Count); Vector c = new DenseVector(residuals.Count);
Vector<double> p = new DenseVector(residuals.Count); Vector p = new DenseVector(residuals.Count);
Vector<double> s = new DenseVector(residuals.Count); Vector s = new DenseVector(residuals.Count);
Vector<double> u = new DenseVector(residuals.Count); Vector u = new DenseVector(residuals.Count);
Vector<double> y = new DenseVector(residuals.Count); Vector y = new DenseVector(residuals.Count);
Vector<double> z = new DenseVector(residuals.Count); Vector z = new DenseVector(residuals.Count);
Vector<double> temp = new DenseVector(residuals.Count); Vector temp = new DenseVector(residuals.Count);
Vector<double> temp2 = new DenseVector(residuals.Count); Vector temp2 = new DenseVector(residuals.Count);
Vector<double> temp3 = new DenseVector(residuals.Count); Vector temp3 = new DenseVector(residuals.Count);
// for (k = 0, 1, .... ) // for (k = 0, 1, .... )
var iterationNumber = 0; var iterationNumber = 0;
@ -526,11 +523,11 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// <summary> /// <summary>
/// Calculates the true residual of the matrix equation Ax = b according to: residual = b - Ax /// Calculates the true residual of the matrix equation Ax = b according to: residual = b - Ax
/// </summary> /// </summary>
/// <param name="matrix">Instance of the <see cref="Matrix{T}"/> A.</param> /// <param name="matrix">Instance of the <see cref="Matrix"/> A.</param>
/// <param name="residual">Residual values in <see cref="Vector{T}"/>.</param> /// <param name="residual">Residual values in <see cref="Vector"/>.</param>
/// <param name="x">Instance of the <see cref="Vector{T}"/> x.</param> /// <param name="x">Instance of the <see cref="Vector"/> x.</param>
/// <param name="b">Instance of the <see cref="Vector{T}"/> b.</param> /// <param name="b">Instance of the <see cref="Vector"/> b.</param>
private static void CalculateTrueResidual(Matrix<double> matrix, Vector<double> residual, Vector<double> x, Vector<double> b) private static void CalculateTrueResidual(Matrix matrix, Vector residual, Vector x, Vector b)
{ {
// -Ax = residual // -Ax = residual
matrix.Multiply(x, residual); matrix.Multiply(x, residual);
@ -544,11 +541,11 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// Determine if calculation should continue /// Determine if calculation should continue
/// </summary> /// </summary>
/// <param name="iterationNumber">Number of iterations passed</param> /// <param name="iterationNumber">Number of iterations passed</param>
/// <param name="result">Result <see cref="Vector{T}"/>.</param> /// <param name="result">Result <see cref="Vector"/>.</param>
/// <param name="source">Source <see cref="Vector{T}"/>.</param> /// <param name="source">Source <see cref="Vector"/>.</param>
/// <param name="residuals">Residual <see cref="Vector{T}"/>.</param> /// <param name="residuals">Residual <see cref="Vector"/>.</param>
/// <returns><c>true</c> if continue, otherwise <c>false</c></returns> /// <returns><c>true</c> if continue, otherwise <c>false</c></returns>
private bool ShouldContinue(int iterationNumber, Vector<double> result, Vector<double> source, Vector<double> residuals) private bool ShouldContinue(int iterationNumber, Vector result, Vector source, Vector residuals)
{ {
if (_hasBeenStopped) if (_hasBeenStopped)
{ {
@ -589,7 +586,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param> /// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution matrix, <c>B</c>.</param> /// <param name="input">The solution matrix, <c>B</c>.</param>
/// <returns>The result matrix, <c>X</c>.</returns> /// <returns>The result matrix, <c>X</c>.</returns>
public Matrix<double> Solve(Matrix<double> matrix, Matrix<double> input) public Matrix Solve(Matrix matrix, Matrix input)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -601,7 +598,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
throw new ArgumentNullException("input"); throw new ArgumentNullException("input");
} }
var result = matrix.CreateMatrix(input.RowCount, input.ColumnCount); var result = (Matrix)matrix.CreateMatrix(input.RowCount, input.ColumnCount);
Solve(matrix, input, result); Solve(matrix, input, result);
return result; return result;
} }
@ -613,7 +610,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param> /// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution matrix, <c>B</c>.</param> /// <param name="input">The solution matrix, <c>B</c>.</param>
/// <param name="result">The result matrix, <c>X</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 matrix, Matrix input, Matrix result)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -637,7 +634,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
for (var column = 0; column < input.ColumnCount; column++) for (var column = 0; column < input.ColumnCount; column++)
{ {
var solution = Solve(matrix, input.Column(column)); var solution = Solve(matrix, (Vector)input.Column(column));
foreach (var element in solution.GetIndexedEnumerator()) foreach (var element in solution.GetIndexedEnumerator())
{ {
result.At(element.Key, column, element.Value); result.At(element.Key, column, element.Value);

112
src/Numerics/LinearAlgebra/Double/Solvers/Iterative/MlkBiCgStab.cs

@ -37,8 +37,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
using Distributions; using Distributions;
using Generic; using Generic;
using Generic.Factorization; using Generic.Factorization;
using Generic.Solvers;
using Generic.Solvers.Preconditioners;
using Generic.Solvers.Status; using Generic.Solvers.Status;
using Preconditioners; using Preconditioners;
using Properties; using Properties;
@ -66,7 +64,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// solver. /// solver.
/// </para> /// </para>
/// </remarks> /// </remarks>
public sealed class MlkBiCgStab : IIterativeSolver<double> public sealed class MlkBiCgStab : IIterativeSolver
{ {
/// <summary> /// <summary>
/// The default number of starting vectors. /// The default number of starting vectors.
@ -83,17 +81,17 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// The preconditioner that will be used. Can be set to <see langword="null" />, in which case the default /// The preconditioner that will be used. Can be set to <see langword="null" />, in which case the default
/// pre-conditioner will be used. /// pre-conditioner will be used.
/// </summary> /// </summary>
private IPreConditioner<double> _preconditioner; private IPreConditioner _preconditioner;
/// <summary> /// <summary>
/// The iterative process controller. /// The iterative process controller.
/// </summary> /// </summary>
private IIterator<double> _iterator; private IIterator _iterator;
/// <summary> /// <summary>
/// The collection of starting vectors which are used as the basis for the Krylov sub-space. /// The collection of starting vectors which are used as the basis for the Krylov sub-space.
/// </summary> /// </summary>
private IList<Vector<double>> _startingVectors; private IList<Vector> _startingVectors;
/// <summary> /// <summary>
/// The number of starting vectors used by the algorithm /// The number of starting vectors used by the algorithm
@ -109,7 +107,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// Initializes a new instance of the <see cref="MlkBiCgStab"/> class. /// Initializes a new instance of the <see cref="MlkBiCgStab"/> class.
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// When using this constructor the solver will use the <see cref="IIterator{T}"/> with /// When using this constructor the solver will use the <see cref="IIterator"/> with
/// the standard settings and a default preconditioner. /// the standard settings and a default preconditioner.
/// </remarks> /// </remarks>
public MlkBiCgStab() : this(null, null) public MlkBiCgStab() : this(null, null)
@ -124,18 +122,18 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// When using this constructor the solver will use a default preconditioner. /// When using this constructor the solver will use a default preconditioner.
/// </para> /// </para>
/// <para> /// <para>
/// The main advantages of using a user defined <see cref="IIterator{T}"/> are: /// The main advantages of using a user defined <see cref="IIterator"/> are:
/// <list type="number"> /// <list type="number">
/// <item>It is possible to set the desired convergence limits.</item> /// <item>It is possible to set the desired convergence limits.</item>
/// <item> /// <item>
/// It is possible to check the reason for which the solver finished /// It is possible to check the reason for which the solver finished
/// the iterative procedure by calling the <see cref="IIterator{T}.Status"/> property. /// the iterative procedure by calling the <see cref="IIterator.Status"/> property.
/// </item> /// </item>
/// </list> /// </list>
/// </para> /// </para>
/// </remarks> /// </remarks>
/// <param name="iterator">The <see cref="IIterator{T}"/> that will be used to monitor the iterative process.</param> /// <param name="iterator">The <see cref="IIterator"/> that will be used to monitor the iterative process.</param>
public MlkBiCgStab(IIterator<double> iterator) : this(null, iterator) public MlkBiCgStab(IIterator iterator) : this(null, iterator)
{ {
} }
@ -143,11 +141,11 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// Initializes a new instance of the <see cref="MlkBiCgStab"/> class. /// Initializes a new instance of the <see cref="MlkBiCgStab"/> class.
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// When using this constructor the solver will use the <see cref="IIterator{T}"/> with /// When using this constructor the solver will use the <see cref="IIterator"/> with
/// the standard settings. /// the standard settings.
/// </remarks> /// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation.</param> /// <param name="preconditioner">The <see cref="IPreConditioner"/> that will be used to precondition the matrix equation.</param>
public MlkBiCgStab(IPreConditioner<double> preconditioner) : this(preconditioner, null) public MlkBiCgStab(IPreConditioner preconditioner) : this(preconditioner, null)
{ {
} }
@ -156,19 +154,19 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// <para> /// <para>
/// The main advantages of using a user defined <see cref="IIterator{T}"/> are: /// The main advantages of using a user defined <see cref="IIterator"/> are:
/// <list type="number"> /// <list type="number">
/// <item>It is possible to set the desired convergence limits.</item> /// <item>It is possible to set the desired convergence limits.</item>
/// <item> /// <item>
/// It is possible to check the reason for which the solver finished /// It is possible to check the reason for which the solver finished
/// the iterative procedure by calling the <see cref="IIterator{T}.Status"/> property. /// the iterative procedure by calling the <see cref="IIterator.Status"/> property.
/// </item> /// </item>
/// </list> /// </list>
/// </para> /// </para>
/// </remarks> /// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation.</param> /// <param name="preconditioner">The <see cref="IPreConditioner"/> that will be used to precondition the matrix equation.</param>
/// <param name="iterator">The <see cref="IIterator{T}"/> that will be used to monitor the iterative process.</param> /// <param name="iterator">The <see cref="IIterator"/> that will be used to monitor the iterative process.</param>
public MlkBiCgStab(IPreConditioner<double> preconditioner, IIterator<double> iterator) public MlkBiCgStab(IPreConditioner preconditioner, IIterator iterator)
{ {
_iterator = iterator; _iterator = iterator;
_preconditioner = preconditioner; _preconditioner = preconditioner;
@ -210,19 +208,19 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
} }
/// <summary> /// <summary>
/// Sets the <see cref="IPreConditioner{T}"/> that will be used to precondition the iterative process. /// Sets the <see cref="IPreConditioner"/> that will be used to precondition the iterative process.
/// </summary> /// </summary>
/// <param name="preconditioner">The preconditioner.</param> /// <param name="preconditioner">The preconditioner.</param>
public void SetPreconditioner(IPreConditioner<double> preconditioner) public void SetPreconditioner(IPreConditioner preconditioner)
{ {
_preconditioner = preconditioner; _preconditioner = preconditioner;
} }
/// <summary> /// <summary>
/// Sets the <see cref="IIterator{T}"/> that will be used to track the iterative process. /// Sets the <see cref="IIterator"/> that will be used to track the iterative process.
/// </summary> /// </summary>
/// <param name="iterator">The iterator.</param> /// <param name="iterator">The iterator.</param>
public void SetIterator(IIterator<double> iterator) public void SetIterator(IIterator iterator)
{ {
_iterator = iterator; _iterator = iterator;
} }
@ -231,7 +229,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// Gets or sets a series of orthonormal vectors which will be used as basis for the /// Gets or sets a series of orthonormal vectors which will be used as basis for the
/// Krylov sub-space. /// Krylov sub-space.
/// </summary> /// </summary>
public IList<Vector<double>> StartingVectors public IList<Vector> StartingVectors
{ {
[DebuggerStepThrough] [DebuggerStepThrough]
get get
@ -283,14 +281,14 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param> /// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="vector">The solution vector, <c>b</c>.</param> /// <param name="vector">The solution vector, <c>b</c>.</param>
/// <returns>The result vector, <c>x</c>.</returns> /// <returns>The result vector, <c>x</c>.</returns>
public Vector<double> Solve(Matrix<double> matrix, Vector<double> vector) public Vector Solve(Matrix matrix, Vector vector)
{ {
if (vector == null) if (vector == null)
{ {
throw new ArgumentNullException(); throw new ArgumentNullException();
} }
Vector<double> result = new DenseVector(matrix.RowCount); Vector result = new DenseVector(matrix.RowCount);
Solve(matrix, vector, result); Solve(matrix, vector, result);
return result; return result;
} }
@ -302,7 +300,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param> /// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution vector, <c>b</c></param> /// <param name="input">The solution vector, <c>b</c></param>
/// <param name="result">The result vector, <c>x</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 matrix, Vector input, Vector result)
{ {
// If we were stopped before, we are no longer // If we were stopped before, we are no longer
// We're doing this at the start of the method to ensure // We're doing this at the start of the method to ensure
@ -356,7 +354,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
// Choose an initial guess x_0 // Choose an initial guess x_0
// Take x_0 = 0 // Take x_0 = 0
Vector<double> xtemp = new DenseVector(input.Count); Vector xtemp = new DenseVector(input.Count);
// Choose k vectors q_1, q_2, ..., q_k // Choose k vectors q_1, q_2, ..., q_k
// Build a new set if: // Build a new set if:
@ -385,24 +383,24 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
// r_0 = b - Ax_0 // r_0 = b - Ax_0
// This is basically a SAXPY so it could be made a lot faster // This is basically a SAXPY so it could be made a lot faster
Vector<double> residuals = new DenseVector(matrix.RowCount); Vector residuals = new DenseVector(matrix.RowCount);
CalculateTrueResidual(matrix, residuals, xtemp, input); CalculateTrueResidual(matrix, residuals, xtemp, input);
// Define the temporary scalars // Define the temporary scalars
var c = new double[k]; var c = new double[k];
// Define the temporary vectors // Define the temporary vectors
Vector<double> gtemp = new DenseVector(residuals.Count); Vector gtemp = new DenseVector(residuals.Count);
Vector<double> u = new DenseVector(residuals.Count); Vector u = new DenseVector(residuals.Count);
Vector<double> utemp = new DenseVector(residuals.Count); Vector utemp = new DenseVector(residuals.Count);
Vector<double> temp = new DenseVector(residuals.Count); Vector temp = new DenseVector(residuals.Count);
Vector<double> temp1 = new DenseVector(residuals.Count); Vector temp1 = new DenseVector(residuals.Count);
Vector<double> temp2 = new DenseVector(residuals.Count); Vector temp2 = new DenseVector(residuals.Count);
Vector<double> zd = new DenseVector(residuals.Count); Vector zd = new DenseVector(residuals.Count);
Vector<double> zg = new DenseVector(residuals.Count); Vector zg = new DenseVector(residuals.Count);
Vector<double> zw = new DenseVector(residuals.Count); Vector zw = new DenseVector(residuals.Count);
var d = CreateVectorArray(_startingVectors.Count, residuals.Count); var d = CreateVectorArray(_startingVectors.Count, residuals.Count);
@ -646,7 +644,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// the <paramref name="numberOfVariables"/> is smaller than /// the <paramref name="numberOfVariables"/> is smaller than
/// the <paramref name="maximumNumberOfStartingVectors"/>. /// the <paramref name="maximumNumberOfStartingVectors"/>.
/// </returns> /// </returns>
private static IList<Vector<double>> CreateStartingVectors(int maximumNumberOfStartingVectors, int numberOfVariables) private static IList<Vector> CreateStartingVectors(int maximumNumberOfStartingVectors, int numberOfVariables)
{ {
// Create no more starting vectors than the size of the problem - 1 // Create no more starting vectors than the size of the problem - 1
// Get random values and then orthogonalize them with // Get random values and then orthogonalize them with
@ -657,7 +655,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
// mean = 0 and sd = 1 // mean = 0 and sd = 1
var distribution = new Normal(); var distribution = new Normal();
Matrix<double> matrix = new DenseMatrix(numberOfVariables, count); Matrix matrix = new DenseMatrix(numberOfVariables, count);
for (var i = 0; i < matrix.ColumnCount; i++) for (var i = 0; i < matrix.ColumnCount; i++)
{ {
var samples = distribution.Samples().Take(matrix.RowCount).ToArray(); var samples = distribution.Samples().Take(matrix.RowCount).ToArray();
@ -671,10 +669,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
var orthogonalMatrix = gs.Q; var orthogonalMatrix = gs.Q;
// Now transfer this to vectors // Now transfer this to vectors
var result = new List<Vector<double>>(); var result = new List<Vector>();
for (var i = 0; i < orthogonalMatrix.ColumnCount; i++) for (var i = 0; i < orthogonalMatrix.ColumnCount; i++)
{ {
result.Add(orthogonalMatrix.Column(i)); result.Add((Vector)orthogonalMatrix.Column(i));
// Normalize the result vector // Normalize the result vector
result[i].Multiply(1 / result[i].Norm(2), result[i]); result[i].Multiply(1 / result[i].Norm(2), result[i]);
@ -689,9 +687,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// <param name="arraySize">Number of vectors</param> /// <param name="arraySize">Number of vectors</param>
/// <param name="vectorSize">Size of each vector</param> /// <param name="vectorSize">Size of each vector</param>
/// <returns>Array of random vectors</returns> /// <returns>Array of random vectors</returns>
private static Vector<double>[] CreateVectorArray(int arraySize, int vectorSize) private static Vector[] CreateVectorArray(int arraySize, int vectorSize)
{ {
var result = new Vector<double>[arraySize]; var result = new Vector[arraySize];
for (var i = 0; i < result.Length; i++) for (var i = 0; i < result.Length; i++)
{ {
result[i] = new DenseVector(vectorSize); result[i] = new DenseVector(vectorSize);
@ -703,11 +701,11 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// <summary> /// <summary>
/// Calculates the true residual of the matrix equation Ax = b according to: residual = b - Ax /// Calculates the true residual of the matrix equation Ax = b according to: residual = b - Ax
/// </summary> /// </summary>
/// <param name="matrix">Source <see cref="Matrix{T}"/>A.</param> /// <param name="matrix">Source <see cref="Matrix"/>A.</param>
/// <param name="residual">Residual <see cref="Vector{T}"/> data.</param> /// <param name="residual">Residual <see cref="Vector"/> data.</param>
/// <param name="x">x <see cref="Vector{T}"/> data.</param> /// <param name="x">x <see cref="Vector"/> data.</param>
/// <param name="b">b <see cref="Vector{T}"/> data.</param> /// <param name="b">b <see cref="Vector"/> data.</param>
private static void CalculateTrueResidual(Matrix<double> matrix, Vector<double> residual, Vector<double> x, Vector<double> b) private static void CalculateTrueResidual(Matrix matrix, Vector residual, Vector x, Vector b)
{ {
// -Ax = residual // -Ax = residual
matrix.Multiply(x, residual); matrix.Multiply(x, residual);
@ -721,11 +719,11 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// Determine if calculation should continue /// Determine if calculation should continue
/// </summary> /// </summary>
/// <param name="iterationNumber">Number of iterations passed</param> /// <param name="iterationNumber">Number of iterations passed</param>
/// <param name="result">Result <see cref="Vector{T}"/>.</param> /// <param name="result">Result <see cref="Vector"/>.</param>
/// <param name="source">Source <see cref="Vector{T}"/>.</param> /// <param name="source">Source <see cref="Vector"/>.</param>
/// <param name="residuals">Residual <see cref="Vector{T}"/>.</param> /// <param name="residuals">Residual <see cref="Vector"/>.</param>
/// <returns><c>true</c> if continue, otherwise <c>false</c></returns> /// <returns><c>true</c> if continue, otherwise <c>false</c></returns>
private bool ShouldContinue(int iterationNumber, Vector<double> result, Vector<double> source, Vector<double> residuals) private bool ShouldContinue(int iterationNumber, Vector result, Vector source, Vector residuals)
{ {
if (_hasBeenStopped) if (_hasBeenStopped)
{ {
@ -749,7 +747,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param> /// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution matrix, <c>B</c>.</param> /// <param name="input">The solution matrix, <c>B</c>.</param>
/// <returns>The result matrix, <c>X</c>.</returns> /// <returns>The result matrix, <c>X</c>.</returns>
public Matrix<double> Solve(Matrix<double> matrix, Matrix<double> input) public Matrix Solve(Matrix matrix, Matrix input)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -761,7 +759,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
throw new ArgumentNullException("input"); throw new ArgumentNullException("input");
} }
var result = matrix.CreateMatrix(input.RowCount, input.ColumnCount); var result = (Matrix)matrix.CreateMatrix(input.RowCount, input.ColumnCount);
Solve(matrix, input, result); Solve(matrix, input, result);
return result; return result;
} }
@ -773,7 +771,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param> /// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution matrix, <c>B</c>.</param> /// <param name="input">The solution matrix, <c>B</c>.</param>
/// <param name="result">The result matrix, <c>X</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 matrix, Matrix input, Matrix result)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -797,7 +795,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
for (var column = 0; column < input.ColumnCount; column++) for (var column = 0; column < input.ColumnCount; column++)
{ {
var solution = Solve(matrix, input.Column(column)); var solution = Solve(matrix, (Vector)input.Column(column));
foreach (var element in solution.GetIndexedEnumerator()) foreach (var element in solution.GetIndexedEnumerator())
{ {
result.At(element.Key, column, element.Value); result.At(element.Key, column, element.Value);

77
src/Numerics/LinearAlgebra/Double/Solvers/Iterative/TFQMR.cs

@ -31,9 +31,6 @@
namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
{ {
using System; using System;
using Generic;
using Generic.Solvers;
using Generic.Solvers.Preconditioners;
using Generic.Solvers.Status; using Generic.Solvers.Status;
using Preconditioners; using Preconditioners;
using Properties; using Properties;
@ -55,7 +52,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// solver. /// solver.
/// </para> /// </para>
/// </remarks> /// </remarks>
public sealed class TFQMR : IIterativeSolver<double> public sealed class TFQMR : IIterativeSolver
{ {
/// <summary> /// <summary>
/// The status used if there is no status, i.e. the solver hasn't run yet and there is no /// The status used if there is no status, i.e. the solver hasn't run yet and there is no
@ -67,12 +64,12 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// The preconditioner that will be used. Can be set to <see langword="null" />, in which case the default /// The preconditioner that will be used. Can be set to <see langword="null" />, in which case the default
/// pre-conditioner will be used. /// pre-conditioner will be used.
/// </summary> /// </summary>
private IPreConditioner<double> _preconditioner; private IPreConditioner _preconditioner;
/// <summary> /// <summary>
/// The iterative process controller. /// The iterative process controller.
/// </summary> /// </summary>
private IIterator<double> _iterator; private IIterator _iterator;
/// <summary> /// <summary>
/// Indicates if the user has stopped the solver. /// Indicates if the user has stopped the solver.
@ -83,7 +80,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// Initializes a new instance of the <see cref="TFQMR"/> class. /// Initializes a new instance of the <see cref="TFQMR"/> class.
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// When using this constructor the solver will use the <see cref="IIterator{T}"/> with /// When using this constructor the solver will use the <see cref="IIterator"/> with
/// the standard settings and a default preconditioner. /// the standard settings and a default preconditioner.
/// </remarks> /// </remarks>
public TFQMR() : this(null, null) public TFQMR() : this(null, null)
@ -98,18 +95,18 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// When using this constructor the solver will use a default preconditioner. /// When using this constructor the solver will use a default preconditioner.
/// </para> /// </para>
/// <para> /// <para>
/// The main advantages of using a user defined <see cref="IIterator{T}"/> are: /// The main advantages of using a user defined <see cref="IIterator"/> are:
/// <list type="number"> /// <list type="number">
/// <item>It is possible to set the desired convergence limits.</item> /// <item>It is possible to set the desired convergence limits.</item>
/// <item> /// <item>
/// It is possible to check the reason for which the solver finished /// It is possible to check the reason for which the solver finished
/// the iterative procedure by calling the <see cref="IIterator{T}.Status"/> property. /// the iterative procedure by calling the <see cref="IIterator.Status"/> property.
/// </item> /// </item>
/// </list> /// </list>
/// </para> /// </para>
/// </remarks> /// </remarks>
/// <param name="iterator">The <see cref="IIterator{T}"/> that will be used to monitor the iterative process.</param> /// <param name="iterator">The <see cref="IIterator"/> that will be used to monitor the iterative process.</param>
public TFQMR(IIterator<double> iterator) : this(null, iterator) public TFQMR(IIterator iterator) : this(null, iterator)
{ {
} }
@ -117,11 +114,11 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// Initializes a new instance of the <see cref="TFQMR"/> class. /// Initializes a new instance of the <see cref="TFQMR"/> class.
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// When using this constructor the solver will use the <see cref="IIterator{T}"/> with /// When using this constructor the solver will use the <see cref="IIterator"/> with
/// the standard settings. /// the standard settings.
/// </remarks> /// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation.</param> /// <param name="preconditioner">The <see cref="IPreConditioner"/> that will be used to precondition the matrix equation.</param>
public TFQMR(IPreConditioner<double> preconditioner) : this(preconditioner, null) public TFQMR(IPreConditioner preconditioner) : this(preconditioner, null)
{ {
} }
@ -130,38 +127,38 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// <para> /// <para>
/// The main advantages of using a user defined <see cref="IIterator{T}"/> are: /// The main advantages of using a user defined <see cref="IIterator"/> are:
/// <list type="number"> /// <list type="number">
/// <item>It is possible to set the desired convergence limits.</item> /// <item>It is possible to set the desired convergence limits.</item>
/// <item> /// <item>
/// It is possible to check the reason for which the solver finished /// It is possible to check the reason for which the solver finished
/// the iterative procedure by calling the <see cref="IIterator{T}.Status"/> property. /// the iterative procedure by calling the <see cref="IIterator.Status"/> property.
/// </item> /// </item>
/// </list> /// </list>
/// </para> /// </para>
/// </remarks> /// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation.</param> /// <param name="preconditioner">The <see cref="IPreConditioner"/> that will be used to precondition the matrix equation.</param>
/// <param name="iterator">The <see cref="IIterator{T}"/> that will be used to monitor the iterative process.</param> /// <param name="iterator">The <see cref="IIterator"/> that will be used to monitor the iterative process.</param>
public TFQMR(IPreConditioner<double> preconditioner, IIterator<double> iterator) public TFQMR(IPreConditioner preconditioner, IIterator iterator)
{ {
_iterator = iterator; _iterator = iterator;
_preconditioner = preconditioner; _preconditioner = preconditioner;
} }
/// <summary> /// <summary>
/// Sets the <see cref="IPreConditioner{T}"/> that will be used to precondition the iterative process. /// Sets the <see cref="IPreConditioner"/> that will be used to precondition the iterative process.
/// </summary> /// </summary>
/// <param name="preconditioner">The preconditioner.</param> /// <param name="preconditioner">The preconditioner.</param>
public void SetPreconditioner(IPreConditioner<double> preconditioner) public void SetPreconditioner(IPreConditioner preconditioner)
{ {
_preconditioner = preconditioner; _preconditioner = preconditioner;
} }
/// <summary> /// <summary>
/// Sets the <see cref="IIterator{T}"/> that will be used to track the iterative process. /// Sets the <see cref="IIterator"/> that will be used to track the iterative process.
/// </summary> /// </summary>
/// <param name="iterator">The iterator.</param> /// <param name="iterator">The iterator.</param>
public void SetIterator(IIterator<double> iterator) public void SetIterator(IIterator iterator)
{ {
_iterator = iterator; _iterator = iterator;
} }
@ -195,14 +192,14 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param> /// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="vector">The solution vector, <c>b</c>.</param> /// <param name="vector">The solution vector, <c>b</c>.</param>
/// <returns>The result vector, <c>x</c>.</returns> /// <returns>The result vector, <c>x</c>.</returns>
public Vector<double> Solve(Matrix<double> matrix, Vector<double> vector) public Vector Solve(Matrix matrix, Vector vector)
{ {
if (vector == null) if (vector == null)
{ {
throw new ArgumentNullException(); throw new ArgumentNullException();
} }
Vector<double> result = new DenseVector(matrix.RowCount); Vector result = new DenseVector(matrix.RowCount);
Solve(matrix, vector, result); Solve(matrix, vector, result);
return result; return result;
} }
@ -214,7 +211,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param> /// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution vector, <c>b</c></param> /// <param name="input">The solution vector, <c>b</c></param>
/// <param name="result">The result vector, <c>x</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 matrix, Vector input, Vector result)
{ {
// If we were stopped before, we are no longer // If we were stopped before, we are no longer
// We're doing this at the start of the method to ensure // We're doing this at the start of the method to ensure
@ -426,13 +423,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
} }
/// <summary> /// <summary>
/// Calculates the true residual of the matrix equation Ax = b according to: residual = b - Ax /// Calculates the <c>true</c> residual of the matrix equation Ax = b according to: residual = b - Ax
/// </summary> /// </summary>
/// <param name="matrix">Instance of the <see cref="Matrix{T}"/> A.</param> /// <param name="matrix">Instance of the <see cref="Matrix"/> A.</param>
/// <param name="residual">Residual values in <see cref="Vector{T}"/>.</param> /// <param name="residual">Residual values in <see cref="Vector"/>.</param>
/// <param name="x">Instance of the <see cref="Vector{T}"/> x.</param> /// <param name="x">Instance of the <see cref="Vector"/> x.</param>
/// <param name="b">Instance of the <see cref="Vector{T}"/> b.</param> /// <param name="b">Instance of the <see cref="Vector"/> b.</param>
private static void CalculateTrueResidual(Matrix<double> matrix, Vector<double> residual, Vector<double> x, Vector<double> b) private static void CalculateTrueResidual(Matrix matrix, Vector residual, Vector x, Vector b)
{ {
// -Ax = residual // -Ax = residual
matrix.Multiply(x, residual); matrix.Multiply(x, residual);
@ -446,11 +443,11 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// Determine if calculation should continue /// Determine if calculation should continue
/// </summary> /// </summary>
/// <param name="iterationNumber">Number of iterations passed</param> /// <param name="iterationNumber">Number of iterations passed</param>
/// <param name="result">Result <see cref="Vector{T}"/>.</param> /// <param name="result">Result <see cref="Vector"/>.</param>
/// <param name="source">Source <see cref="Vector{T}"/>.</param> /// <param name="source">Source <see cref="Vector"/>.</param>
/// <param name="residuals">Residual <see cref="Vector{T}"/>.</param> /// <param name="residuals">Residual <see cref="Vector"/>.</param>
/// <returns><c>true</c> if continue, otherwise <c>false</c></returns> /// <returns><c>true</c> if continue, otherwise <c>false</c></returns>
private bool ShouldContinue(int iterationNumber, Vector<double> result, Vector<double> source, Vector<double> residuals) private bool ShouldContinue(int iterationNumber, Vector result, Vector source, Vector residuals)
{ {
if (_hasBeenStopped) if (_hasBeenStopped)
{ {
@ -484,7 +481,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param> /// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution matrix, <c>B</c>.</param> /// <param name="input">The solution matrix, <c>B</c>.</param>
/// <returns>The result matrix, <c>X</c>.</returns> /// <returns>The result matrix, <c>X</c>.</returns>
public Matrix<double> Solve(Matrix<double> matrix, Matrix<double> input) public Matrix Solve(Matrix matrix, Matrix input)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -496,7 +493,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
throw new ArgumentNullException("input"); throw new ArgumentNullException("input");
} }
var result = matrix.CreateMatrix(input.RowCount, input.ColumnCount); var result = (Matrix)matrix.CreateMatrix(input.RowCount, input.ColumnCount);
Solve(matrix, input, result); Solve(matrix, input, result);
return result; return result;
} }
@ -508,7 +505,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param> /// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution matrix, <c>B</c>.</param> /// <param name="input">The solution matrix, <c>B</c>.</param>
/// <param name="result">The result matrix, <c>X</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 matrix, Matrix input, Matrix result)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -532,7 +529,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
for (var column = 0; column < input.ColumnCount; column++) for (var column = 0; column < input.ColumnCount; column++)
{ {
var solution = Solve(matrix, input.Column(column)); var solution = Solve(matrix, (Vector)input.Column(column));
foreach (var element in solution.GetIndexedEnumerator()) foreach (var element in solution.GetIndexedEnumerator())
{ {
result.At(element.Key, column, element.Value); result.At(element.Key, column, element.Value);

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

@ -33,17 +33,14 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using Generic;
using Generic.Solvers;
using Generic.Solvers.Status; using Generic.Solvers.Status;
using Generic.Solvers.StopCriterium;
using Properties; using Properties;
using StopCriterium; using StopCriterium;
/// <summary> /// <summary>
/// An iterator that is used to check if an iterative calculation should continue or stop. /// An iterator that is used to check if an iterative calculation should continue or stop.
/// </summary> /// </summary>
public sealed class Iterator : IIterator<double> public sealed class Iterator : IIterator
{ {
/// <summary> /// <summary>
/// The default status for the iterator. /// The default status for the iterator.
@ -51,10 +48,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
private static readonly ICalculationStatus DefaultStatus = new CalculationIndetermined(); private static readonly ICalculationStatus DefaultStatus = new CalculationIndetermined();
/// <summary> /// <summary>
/// Creates a default iterator with all the <see cref="IIterationStopCriterium{T}"/> objects. /// Creates a default iterator with all the <see cref="IIterationStopCriterium"/> objects.
/// </summary> /// </summary>
/// <returns>A new <see cref="IIterator{T}"/> object.</returns> /// <returns>A new <see cref="IIterator"/> object.</returns>
public static IIterator<double> CreateDefault() public static IIterator CreateDefault()
{ {
var iterator = new Iterator(); var iterator = new Iterator();
iterator.Add(new FailureStopCriterium()); iterator.Add(new FailureStopCriterium());
@ -69,7 +66,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
/// The collection that holds all the stop criteria and the flag indicating if they should be added /// The collection that holds all the stop criteria and the flag indicating if they should be added
/// to the child iterators. /// to the child iterators.
/// </summary> /// </summary>
private readonly Dictionary<Type, IIterationStopCriterium<double>> _stopCriterias = new Dictionary<Type, IIterationStopCriterium<double>>(); private readonly Dictionary<Type, IIterationStopCriterium> _stopCriterias = new Dictionary<Type, IIterationStopCriterium>();
/// <summary> /// <summary>
/// The status of the iterator. /// The status of the iterator.
@ -77,7 +74,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
private ICalculationStatus _status = DefaultStatus; private ICalculationStatus _status = DefaultStatus;
/// <summary> /// <summary>
/// Indicates if the iteration was cancelled. /// Indicates if the iteration was canceled.
/// </summary> /// </summary>
private bool _wasIterationCancelled; private bool _wasIterationCancelled;
@ -96,7 +93,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
/// of the stop criteria will be passed on to child iterators. /// of the stop criteria will be passed on to child iterators.
/// </param> /// </param>
/// <exception cref="ArgumentException">Thrown if <paramref name="stopCriteria"/> contains multiple stop criteria of the same type.</exception> /// <exception cref="ArgumentException">Thrown if <paramref name="stopCriteria"/> contains multiple stop criteria of the same type.</exception>
public Iterator(IEnumerable<IIterationStopCriterium<double>> stopCriteria) public Iterator(IEnumerable<IIterationStopCriterium> stopCriteria)
{ {
// Add the stop criteria // Add the stop criteria
if (stopCriteria == null) if (stopCriteria == null)
@ -111,7 +108,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
} }
/// <summary> /// <summary>
/// Adds an <see cref="IIterationStopCriterium{T}"/> to the internal collection of stop-criteria. Only a /// Adds an <see cref="IIterationStopCriterium"/> to the internal collection of stop-criteria. Only a
/// single stop criterium of each type can be stored. /// single stop criterium of each type can be stored.
/// </summary> /// </summary>
/// <param name="stopCriterium">The stop criterium to add.</param> /// <param name="stopCriterium">The stop criterium to add.</param>
@ -120,7 +117,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
/// Thrown if <paramref name="stopCriterium"/> is of the same type as an already /// Thrown if <paramref name="stopCriterium"/> is of the same type as an already
/// stored criterium. /// stored criterium.
/// </exception> /// </exception>
public void Add(IIterationStopCriterium<double> stopCriterium) public void Add(IIterationStopCriterium stopCriterium)
{ {
if (stopCriterium == null) if (stopCriterium == null)
{ {
@ -137,10 +134,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
} }
/// <summary> /// <summary>
/// Removes the <see cref="IIterationStopCriterium{T}"/> from the internal collection. /// Removes the <see cref="IIterationStopCriterium"/> from the internal collection.
/// </summary> /// </summary>
/// <param name="stopCriterium">The stop criterium that must be removed.</param> /// <param name="stopCriterium">The stop criterium that must be removed.</param>
public void Remove(IIterationStopCriterium<double> stopCriterium) public void Remove(IIterationStopCriterium stopCriterium)
{ {
if (stopCriterium == null) if (stopCriterium == null)
{ {
@ -157,11 +154,11 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
} }
/// <summary> /// <summary>
/// Indicates if the specific stop criterium is stored by the <see cref="IIterator{T}"/>. /// Indicates if the specific stop criterium is stored by the <see cref="IIterator"/>.
/// </summary> /// </summary>
/// <param name="stopCriterium">The stop criterium.</param> /// <param name="stopCriterium">The stop criterium.</param>
/// <returns><c>true</c> if the <see cref="IIterator{T}"/> contains the stop criterium; otherwise <c>false</c>.</returns> /// <returns><c>true</c> if the <see cref="IIterator"/> contains the stop criterium; otherwise <c>false</c>.</returns>
public bool Contains(IIterationStopCriterium<double> stopCriterium) public bool Contains(IIterationStopCriterium stopCriterium)
{ {
return stopCriterium != null && _stopCriterias.ContainsKey(stopCriterium.GetType()); return stopCriterium != null && _stopCriterias.ContainsKey(stopCriterium.GetType());
} }
@ -182,7 +179,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
/// Gets an <c>IEnumerator</c> that enumerates over all the stored stop criteria. /// Gets an <c>IEnumerator</c> that enumerates over all the stored stop criteria.
/// </summary> /// </summary>
/// <remarks>Used for testing only.</remarks> /// <remarks>Used for testing only.</remarks>
internal IEnumerator<IIterationStopCriterium<double>> StoredStopCriteria internal IEnumerator<IIterationStopCriterium> StoredStopCriteria
{ {
get get
{ {
@ -204,7 +201,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
/// <summary> /// <summary>
/// Determines the status of the iterative calculation based on the stop criteria stored /// Determines the status of the iterative calculation based on the stop criteria stored
/// by the current <see cref="IIterator{T}"/>. Result is set into <c>Status</c> field. /// by the current <see cref="IIterator"/>. Result is set into <c>Status</c> field.
/// </summary> /// </summary>
/// <param name="iterationNumber">The number of iterations that have passed so far.</param> /// <param name="iterationNumber">The number of iterations that have passed so far.</param>
/// <param name="solutionVector">The vector containing the current solution values.</param> /// <param name="solutionVector">The vector containing the current solution values.</param>
@ -215,7 +212,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
/// on the invocation of this method. Therefore this method should only be called if the /// on the invocation of this method. Therefore this method should only be called if the
/// calculation has moved forwards at least one step. /// calculation has moved forwards at least one step.
/// </remarks> /// </remarks>
public void DetermineStatus(int iterationNumber, Vector<double> solutionVector, Vector<double> sourceVector, Vector<double> residualVector) public void DetermineStatus(int iterationNumber, Vector solutionVector, Vector sourceVector, Vector residualVector)
{ {
if (_stopCriterias.Count == 0) if (_stopCriterias.Count == 0)
{ {
@ -287,7 +284,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
} }
/// <summary> /// <summary>
/// Resets the <see cref="IIterator{T}"/> to the pre-calculation state. /// Resets the <see cref="IIterator"/> to the pre-calculation state.
/// </summary> /// </summary>
public void ResetToPrecalculationState() public void ResetToPrecalculationState()
{ {
@ -308,9 +305,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
/// Creates a deep clone of the current iterator. /// Creates a deep clone of the current iterator.
/// </summary> /// </summary>
/// <returns>The deep clone of the current iterator.</returns> /// <returns>The deep clone of the current iterator.</returns>
public IIterator<double> Clone() public IIterator Clone()
{ {
var stopCriteria = _stopCriterias.Select(pair => pair.Value).Select(stopCriterium => (IIterationStopCriterium<double>)stopCriterium.Clone()).ToList(); var stopCriteria = _stopCriterias.Select(pair => pair.Value).Select(stopCriterium => (IIterationStopCriterium)stopCriterium.Clone()).ToList();
return new Iterator(stopCriteria); return new Iterator(stopCriteria);
} }

14
src/Numerics/LinearAlgebra/Double/Solvers/Preconditioners/Diagonal.cs

@ -31,15 +31,13 @@
namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
{ {
using System; using System;
using Generic;
using Generic.Solvers.Preconditioners;
using Properties; using Properties;
/// <summary> /// <summary>
/// A diagonal preconditioner. The preconditioner uses the inverse /// A diagonal preconditioner. The preconditioner uses the inverse
/// of the matrix diagonal as preconditioning values. /// of the matrix diagonal as preconditioning values.
/// </summary> /// </summary>
public sealed class Diagonal : IPreConditioner<double> public sealed class Diagonal : IPreConditioner
{ {
/// <summary> /// <summary>
/// The inverse of the matrix diagonal. /// The inverse of the matrix diagonal.
@ -65,10 +63,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
/// Initializes the preconditioner and loads the internal data structures. /// Initializes the preconditioner and loads the internal data structures.
/// </summary> /// </summary>
/// <param name="matrix"> /// <param name="matrix">
/// The <see cref="Matrix{T}"/> upon which this preconditioner is based.</param> /// The <see cref="Matrix"/> upon which this preconditioner is based.</param>
/// <exception cref="ArgumentNullException">If <paramref name="matrix"/> is <see langword="null" />. </exception> /// <exception cref="ArgumentNullException">If <paramref name="matrix"/> is <see langword="null" />. </exception>
/// <exception cref="ArgumentException">If <paramref name="matrix"/> is not a square matrix.</exception> /// <exception cref="ArgumentException">If <paramref name="matrix"/> is not a square matrix.</exception>
public void Initialize(Matrix<double> matrix) public void Initialize(Matrix matrix)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -92,7 +90,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
/// </summary> /// </summary>
/// <param name="rhs">The right hand side vector.</param> /// <param name="rhs">The right hand side vector.</param>
/// <returns>The left hand side vector.</returns> /// <returns>The left hand side vector.</returns>
public Vector<double> Approximate(Vector<double> rhs) public Vector Approximate(Vector rhs)
{ {
if (rhs == null) if (rhs == null)
{ {
@ -109,7 +107,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "rhs"); throw new ArgumentException(Resources.ArgumentVectorsSameLength, "rhs");
} }
Vector<double> result = new DenseVector(rhs.Count); Vector result = new DenseVector(rhs.Count);
Approximate(rhs, result); Approximate(rhs, result);
return result; return result;
} }
@ -119,7 +117,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
/// </summary> /// </summary>
/// <param name="rhs">The right hand side vector.</param> /// <param name="rhs">The right hand side vector.</param>
/// <param name="lhs">The left hand side vector. Also known as the result vector.</param> /// <param name="lhs">The left hand side vector. Also known as the result vector.</param>
public void Approximate(Vector<double> rhs, Vector<double> lhs) public void Approximate(Vector rhs, Vector lhs)
{ {
if (rhs == null) if (rhs == null)
{ {

73
src/Numerics/LinearAlgebra/Double/Solvers/Preconditioners/IPreConditioner.cs

@ -0,0 +1,73 @@
// <copyright file="IPreConditioner.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
//
// Copyright (c) 2009-2010 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
{
/// <summary>
/// The base interface for preconditioner classes.
/// </summary>
/// <remarks>
/// <para>
/// Preconditioners are used by iterative solvers to improve the convergence
/// speed of the solving process. Increase in convergence speed
/// is related to the number of iterations necessary to get a converged solution.
/// So while in general the use of a preconditioner means that the iterative
/// solver will perform fewer iterations it does not guarantee that the actual
/// solution time decreases given that some preconditioners can be expensive to
/// setup and run.
/// </para>
/// <para>
/// Note that in general changes to the matrix will invalidate the preconditioner
/// if the changes occur after creating the preconditioner.
/// </para>
/// </remarks>
public interface IPreConditioner
{
/// <summary>
/// Initializes the preconditioner and loads the internal data structures.
/// </summary>
/// <param name="matrix">The matrix on which the preconditioner is based.</param>
void Initialize(Matrix matrix);
/// <summary>
/// Approximates the solution to the matrix equation <b>Mx = b</b>.
/// </summary>
/// <param name="rhs">The right hand side vector.</param>
/// <returns>The left hand side vector.</returns>
Vector Approximate(Vector rhs);
/// <summary>
/// Approximates the solution to the matrix equation <b>Mx = b</b>.
/// </summary>
/// <param name="rhs">The right hand side vector.</param>
/// <param name="lhs">The left hand side vector. Also known as the result vector.</param>
void Approximate(Vector rhs, Vector lhs);
}
}

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

@ -32,8 +32,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
{ {
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Generic;
using Generic.Solvers.Preconditioners;
using Properties; using Properties;
/// <summary> /// <summary>
@ -53,7 +51,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
/// pp. 20 - 28 <br/> /// pp. 20 - 28 <br/>
/// Algorithm is described in Section 2, page 22 /// Algorithm is described in Section 2, page 22
/// </remarks> /// </remarks>
public sealed class Ilutp : IPreConditioner<double> public sealed class Ilutp : IPreConditioner
{ {
/// <summary> /// <summary>
/// The default fill level. /// The default fill level.
@ -257,9 +255,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
/// This method is used for debugging purposes only and should normally not be used. /// This method is used for debugging purposes only and should normally not be used.
/// </remarks> /// </remarks>
/// <returns>A new matrix containing the upper triagonal elements.</returns> /// <returns>A new matrix containing the upper triagonal elements.</returns>
internal Matrix<double> UpperTriangle() internal Matrix UpperTriangle()
{ {
return _upper.Clone(); return (Matrix)_upper.Clone();
} }
/// <summary> /// <summary>
@ -269,9 +267,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
/// This method is used for debugging purposes only and should normally not be used. /// This method is used for debugging purposes only and should normally not be used.
/// </remarks> /// </remarks>
/// <returns>A new matrix containing the lower triagonal elements.</returns> /// <returns>A new matrix containing the lower triagonal elements.</returns>
internal Matrix<double> LowerTriangle() internal Matrix LowerTriangle()
{ {
return _lower.Clone(); return (Matrix)_lower.Clone();
} }
/// <summary> /// <summary>
@ -297,13 +295,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
/// Initializes the preconditioner and loads the internal data structures. /// Initializes the preconditioner and loads the internal data structures.
/// </summary> /// </summary>
/// <param name="matrix"> /// <param name="matrix">
/// The <see cref="Matrix{T}"/> upon which this preconditioner is based. Note that the /// The <see cref="Matrix"/> upon which this preconditioner is based. Note that the
/// method takes a general matrix type. However internally the data is stored /// method takes a general matrix type. However internally the data is stored
/// as a sparse matrix. Therefore it is not recommended to pass a dense matrix. /// as a sparse matrix. Therefore it is not recommended to pass a dense matrix.
/// </param> /// </param>
/// <exception cref="ArgumentNullException"> If <paramref name="matrix"/> is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException"> If <paramref name="matrix"/> is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If <paramref name="matrix"/> is not a square matrix.</exception> /// <exception cref="ArgumentException">If <paramref name="matrix"/> is not a square matrix.</exception>
public void Initialize(Matrix<double> matrix) public void Initialize(Matrix matrix)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -375,8 +373,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
_pivots[i] = i; _pivots[i] = i;
} }
Vector<double> workVector = new DenseVector(sparseMatrix.RowCount); Vector workVector = new DenseVector(sparseMatrix.RowCount);
Vector<double> rowVector = new DenseVector(sparseMatrix.ColumnCount); Vector rowVector = new DenseVector(sparseMatrix.ColumnCount);
var indexSorting = new int[sparseMatrix.RowCount]; var indexSorting = new int[sparseMatrix.RowCount];
// spaceLeft = lfilNnz * nnz(A) // spaceLeft = lfilNnz * nnz(A)
@ -531,8 +529,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
/// <summary> /// <summary>
/// Pivot elements in the <paramref name="row"/> according to internal pivot array /// Pivot elements in the <paramref name="row"/> according to internal pivot array
/// </summary> /// </summary>
/// <param name="row">Row <see cref="Vector{T}"/> to pivot in</param> /// <param name="row">Row <see cref="Vector"/> to pivot in</param>
private void PivotRow(Vector<double> row) private void PivotRow(Vector row)
{ {
var knownPivots = new Dictionary<int, int>(); var knownPivots = new Dictionary<int, int>();
@ -579,12 +577,12 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
} }
/// <summary> /// <summary>
/// Swap columns in the <see cref="Matrix{T}"/> /// Swap columns in the <see cref="Matrix"/>
/// </summary> /// </summary>
/// <param name="matrix">Source <see cref="Matrix{T}"/>.</param> /// <param name="matrix">Source <see cref="Matrix"/>.</param>
/// <param name="firstColumn">First column index to swap</param> /// <param name="firstColumn">First column index to swap</param>
/// <param name="secondColumn">Second column index to swap</param> /// <param name="secondColumn">Second column index to swap</param>
private static void SwapColumns(Matrix<double> matrix, int firstColumn, int secondColumn) private static void SwapColumns(Matrix matrix, int firstColumn, int secondColumn)
{ {
for (var i = 0; i < matrix.RowCount; i++) for (var i = 0; i < matrix.RowCount; i++)
{ {
@ -600,8 +598,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
/// <param name="lowerBound">Start sort form</param> /// <param name="lowerBound">Start sort form</param>
/// <param name="upperBound">Sort till upper bound</param> /// <param name="upperBound">Sort till upper bound</param>
/// <param name="sortedIndices">Array with sorted vector indicies</param> /// <param name="sortedIndices">Array with sorted vector indicies</param>
/// <param name="values">Source <see cref="Vector{T}"/></param> /// <param name="values">Source <see cref="Vector"/></param>
private static void FindLargestItems(int lowerBound, int upperBound, int[] sortedIndices, Vector<double> values) private static void FindLargestItems(int lowerBound, int upperBound, int[] sortedIndices, Vector values)
{ {
// Copy the indices for the values into the array // Copy the indices for the values into the array
for (var i = 0; i < upperBound + 1 - lowerBound; i++) for (var i = 0; i < upperBound + 1 - lowerBound; i++)
@ -626,7 +624,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
/// </summary> /// </summary>
/// <param name="rhs">The right hand side vector.</param> /// <param name="rhs">The right hand side vector.</param>
/// <returns>The left hand side vector.</returns> /// <returns>The left hand side vector.</returns>
public Vector<double> Approximate(Vector<double> rhs) public Vector Approximate(Vector rhs)
{ {
if (rhs == null) if (rhs == null)
{ {
@ -643,7 +641,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "rhs"); throw new ArgumentException(Resources.ArgumentVectorsSameLength, "rhs");
} }
Vector<double> result = new DenseVector(rhs.Count); Vector result = new DenseVector(rhs.Count);
Approximate(rhs, result); Approximate(rhs, result);
return result; return result;
} }
@ -653,7 +651,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
/// </summary> /// </summary>
/// <param name="rhs">The right hand side vector.</param> /// <param name="rhs">The right hand side vector.</param>
/// <param name="lhs">The left hand side vector. Also known as the result vector.</param> /// <param name="lhs">The left hand side vector. Also known as the result vector.</param>
public void Approximate(Vector<double> rhs, Vector<double> lhs) public void Approximate(Vector rhs, Vector lhs)
{ {
if (rhs == null) if (rhs == null)
{ {
@ -678,7 +676,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
// Solve equation here // Solve equation here
// Pivot(vector, result); // Pivot(vector, result);
// Solve L*Y = B(piv,:) // Solve L*Y = B(piv,:)
Vector<double> rowValues = new DenseVector(_lower.RowCount); Vector rowValues = new DenseVector(_lower.RowCount);
for (var i = 0; i < _lower.RowCount; i++) for (var i = 0; i < _lower.RowCount; i++)
{ {
_lower.Row(i, rowValues); _lower.Row(i, rowValues);
@ -708,17 +706,17 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
// We have a column pivot so we only need to pivot the // We have a column pivot so we only need to pivot the
// end result not the incoming right hand side vector // end result not the incoming right hand side vector
var temp = lhs.Clone(); var temp = (Vector)lhs.Clone();
Pivot(temp, lhs); Pivot(temp, lhs);
} }
/// <summary> /// <summary>
/// Pivot elements in <see cref="Vector{T}"/> accoring to internal pivot array /// Pivot elements in <see cref="Vector"/> according to internal pivot array
/// </summary> /// </summary>
/// <param name="vector">Source <see cref="Vector{T}"/>.</param> /// <param name="vector">Source <see cref="Vector"/>.</param>
/// <param name="result">Result <see cref="Vector{T}"/> after pivoting.</param> /// <param name="result">Result <see cref="Vector"/> after pivoting.</param>
private void Pivot(Vector<double> vector, Vector<double> result) private void Pivot(Vector vector, Vector result)
{ {
for (var i = 0; i < _pivots.Length; i++) for (var i = 0; i < _pivots.Length; i++)
{ {

36
src/Numerics/LinearAlgebra/Double/Solvers/Preconditioners/IlutpElementSorter.cs

@ -30,8 +30,6 @@
namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
{ {
using Generic;
/// <summary> /// <summary>
/// An element sort algorithm for the <see cref="Ilutp"/> class. /// An element sort algorithm for the <see cref="Ilutp"/> class.
/// </summary> /// </summary>
@ -48,8 +46,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
/// <param name="lowerBound">The starting index.</param> /// <param name="lowerBound">The starting index.</param>
/// <param name="upperBound">The stopping index.</param> /// <param name="upperBound">The stopping index.</param>
/// <param name="sortedIndices">An array that will contain the sorted indices once the algorithm finishes.</param> /// <param name="sortedIndices">An array that will contain the sorted indices once the algorithm finishes.</param>
/// <param name="values">The <see cref="Vector{T}"/> that contains the values that need to be sorted.</param> /// <param name="values">The <see cref="Vector"/> that contains the values that need to be sorted.</param>
public static void SortDoubleIndicesDecreasing(int lowerBound, int upperBound, int[] sortedIndices, Vector<double> values) public static void SortDoubleIndicesDecreasing(int lowerBound, int upperBound, int[] sortedIndices, Vector values)
{ {
// Move all the indices that we're interested in to the beginning of the // Move all the indices that we're interested in to the beginning of the
// array. Ignore the rest of the indices. // array. Ignore the rest of the indices.
@ -74,8 +72,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
/// <param name="lowerBound">The starting index.</param> /// <param name="lowerBound">The starting index.</param>
/// <param name="upperBound">The stopping index.</param> /// <param name="upperBound">The stopping index.</param>
/// <param name="sortedIndices">An array that will contain the sorted indices once the algorithm finishes.</param> /// <param name="sortedIndices">An array that will contain the sorted indices once the algorithm finishes.</param>
/// <param name="values">The <see cref="Vector{T}"/> that contains the values that need to be sorted.</param> /// <param name="values">The <see cref="Vector"/> that contains the values that need to be sorted.</param>
private static void HeapSortDoublesIndices(int lowerBound, int upperBound, int[] sortedIndices, Vector<double> values) private static void HeapSortDoublesIndices(int lowerBound, int upperBound, int[] sortedIndices, Vector values)
{ {
var start = ((upperBound - lowerBound + 1) / 2) - 1 + lowerBound; var start = ((upperBound - lowerBound + 1) / 2) - 1 + lowerBound;
var end = (upperBound - lowerBound + 1) - 1 + lowerBound; var end = (upperBound - lowerBound + 1) - 1 + lowerBound;
@ -94,10 +92,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
/// Build heap for double indicies /// Build heap for double indicies
/// </summary> /// </summary>
/// <param name="start">Root position</param> /// <param name="start">Root position</param>
/// <param name="count">Lenght of <paramref name="values"/></param> /// <param name="count">Length of <paramref name="values"/></param>
/// <param name="sortedIndices">Indicies of <paramref name="values"/></param> /// <param name="sortedIndices">Indicies of <paramref name="values"/></param>
/// <param name="values">Target <see cref="Vector{T}"/></param> /// <param name="values">Target <see cref="Vector"/></param>
private static void BuildDoubleIndexHeap(int start, int count, int[] sortedIndices, Vector<double> values) private static void BuildDoubleIndexHeap(int start, int count, int[] sortedIndices, Vector values)
{ {
while (start >= 0) while (start >= 0)
{ {
@ -110,17 +108,16 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
/// Sift double indicies /// Sift double indicies
/// </summary> /// </summary>
/// <param name="sortedIndices">Indicies of <paramref name="values"/></param> /// <param name="sortedIndices">Indicies of <paramref name="values"/></param>
/// <param name="values">Target <see cref="Vector{T}"/></param> /// <param name="values">Target <see cref="Vector"/></param>
/// <param name="begin">Root position</param> /// <param name="begin">Root position</param>
/// <param name="count">Lenght of <paramref name="values"/></param> /// <param name="count">Length of <paramref name="values"/></param>
private static void SiftDoubleIndices(int[] sortedIndices, Vector<double> values, int begin, int count) private static void SiftDoubleIndices(int[] sortedIndices, Vector values, int begin, int count)
{ {
var root = begin; var root = begin;
int child;
while (root * 2 < count) while (root * 2 < count)
{ {
child = root * 2; var child = root * 2;
if ((child < count - 1) && (values[sortedIndices[child]] > values[sortedIndices[child + 1]])) if ((child < count - 1) && (values[sortedIndices[child]] > values[sortedIndices[child + 1]]))
{ {
child += 1; child += 1;
@ -170,7 +167,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
/// </summary> /// </summary>
/// <param name="values">Target values array</param> /// <param name="values">Target values array</param>
/// <param name="start">Root position</param> /// <param name="start">Root position</param>
/// <param name="count">Lenght of <paramref name="values"/></param> /// <param name="count">Length of <paramref name="values"/></param>
private static void BuildHeap(int[] values, int start, int count) private static void BuildHeap(int[] values, int start, int count)
{ {
while (start >= 0) while (start >= 0)
@ -185,15 +182,14 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
/// </summary> /// </summary>
/// <param name="values">Target value array</param> /// <param name="values">Target value array</param>
/// <param name="start">Root position</param> /// <param name="start">Root position</param>
/// <param name="count">Lenght of <paramref name="values"/></param> /// <param name="count">Length of <paramref name="values"/></param>
private static void Sift(int[] values, int start, int count) private static void Sift(int[] values, int start, int count)
{ {
var root = start; var root = start;
int child;
while (root * 2 < count) while (root * 2 < count)
{ {
child = root * 2; var child = root * 2;
if ((child < count - 1) && (values[child] > values[child + 1])) if ((child < count - 1) && (values[child] > values[child + 1]))
{ {
child += 1; child += 1;
@ -215,8 +211,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
/// Exchange values in array /// Exchange values in array
/// </summary> /// </summary>
/// <param name="values">Target values array</param> /// <param name="values">Target values array</param>
/// <param name="first">First value to exchanghe</param> /// <param name="first">First value to exchange</param>
/// <param name="second">Second value to exchanghe</param> /// <param name="second">Second value to exchange</param>
private static void Exchange(int[] values, int first, int second) private static void Exchange(int[] values, int first, int second)
{ {
var t = values[first]; var t = values[first];

18
src/Numerics/LinearAlgebra/Double/Solvers/Preconditioners/IncompleteLU.cs

@ -31,8 +31,6 @@
namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
{ {
using System; using System;
using Generic;
using Generic.Solvers.Preconditioners;
using Properties; using Properties;
/// <summary> /// <summary>
@ -44,7 +42,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
/// Yousef Saad <br/> /// Yousef Saad <br/>
/// Algorithm is described in Chapter 10, section 10.3.2, page 275 <br/> /// Algorithm is described in Chapter 10, section 10.3.2, page 275 <br/>
/// </remarks> /// </remarks>
public sealed class IncompleteLU : IPreConditioner<double> public sealed class IncompleteLU : IPreConditioner
{ {
/// <summary> /// <summary>
/// The matrix holding the lower (L) and upper (U) matrices. The /// The matrix holding the lower (L) and upper (U) matrices. The
@ -56,7 +54,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
/// Returns the upper triagonal matrix that was created during the LU decomposition. /// Returns the upper triagonal matrix that was created during the LU decomposition.
/// </summary> /// </summary>
/// <returns>A new matrix containing the upper triagonal elements.</returns> /// <returns>A new matrix containing the upper triagonal elements.</returns>
internal Matrix<double> UpperTriangle() internal Matrix UpperTriangle()
{ {
var result = new SparseMatrix(_decompositionLU.RowCount); var result = new SparseMatrix(_decompositionLU.RowCount);
for (var i = 0; i < _decompositionLU.RowCount; i++) for (var i = 0; i < _decompositionLU.RowCount; i++)
@ -74,7 +72,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
/// Returns the lower triagonal matrix that was created during the LU decomposition. /// Returns the lower triagonal matrix that was created during the LU decomposition.
/// </summary> /// </summary>
/// <returns>A new matrix containing the lower triagonal elements.</returns> /// <returns>A new matrix containing the lower triagonal elements.</returns>
internal Matrix<double> LowerTriangle() internal Matrix LowerTriangle()
{ {
var result = new SparseMatrix(_decompositionLU.RowCount); var result = new SparseMatrix(_decompositionLU.RowCount);
for (var i = 0; i < _decompositionLU.RowCount; i++) for (var i = 0; i < _decompositionLU.RowCount; i++)
@ -101,7 +99,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
/// <param name="matrix">The matrix upon which the preconditioner is based. </param> /// <param name="matrix">The matrix upon which the preconditioner is based. </param>
/// <exception cref="ArgumentNullException">If <paramref name="matrix"/> is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If <paramref name="matrix"/> is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If <paramref name="matrix"/> is not a square matrix.</exception> /// <exception cref="ArgumentException">If <paramref name="matrix"/> is not a square matrix.</exception>
public void Initialize(Matrix<double> matrix) public void Initialize(Matrix matrix)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -163,7 +161,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
/// </summary> /// </summary>
/// <param name="rhs">The right hand side vector.</param> /// <param name="rhs">The right hand side vector.</param>
/// <returns>The left hand side vector.</returns> /// <returns>The left hand side vector.</returns>
public Vector<double> Approximate(Vector<double> rhs) public Vector Approximate(Vector rhs)
{ {
if (rhs == null) if (rhs == null)
{ {
@ -180,7 +178,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "rhs"); throw new ArgumentException(Resources.ArgumentVectorsSameLength, "rhs");
} }
Vector<double> result = new DenseVector(rhs.Count); Vector result = new DenseVector(rhs.Count);
Approximate(rhs, result); Approximate(rhs, result);
return result; return result;
} }
@ -190,7 +188,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
/// </summary> /// </summary>
/// <param name="rhs">The right hand side vector.</param> /// <param name="rhs">The right hand side vector.</param>
/// <param name="lhs">The left hand side vector. Also known as the result vector.</param> /// <param name="lhs">The left hand side vector. Also known as the result vector.</param>
public void Approximate(Vector<double> rhs, Vector<double> lhs) public void Approximate(Vector rhs, Vector lhs)
{ {
if (rhs == null) if (rhs == null)
{ {
@ -220,7 +218,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
// z_i = l_ii^-1 * (y_i - SUM_(j<i) l_ij * z_j) // z_i = l_ii^-1 * (y_i - SUM_(j<i) l_ij * z_j)
// } // }
// NOTE: l_ii should be 1 because u_ii has to be the value // NOTE: l_ii should be 1 because u_ii has to be the value
Vector<double> rowValues = new DenseVector(_decompositionLU.RowCount); Vector rowValues = new DenseVector(_decompositionLU.RowCount);
for (var i = 0; i < _decompositionLU.RowCount; i++) for (var i = 0; i < _decompositionLU.RowCount; i++)
{ {
// Clear the rowValues // Clear the rowValues

15
src/Numerics/LinearAlgebra/Double/Solvers/Preconditioners/UnitPreconditioner.cs

@ -31,17 +31,14 @@
namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
{ {
using System; using System;
using Generic;
using Generic.Solvers;
using Generic.Solvers.Preconditioners;
using Properties; using Properties;
/// <summary> /// <summary>
/// A unit preconditioner. This preconditioner does not actually do anything /// A unit preconditioner. This preconditioner does not actually do anything
/// it is only used when running an <see cref="IIterativeSolver{T}"/> without /// it is only used when running an <see cref="IIterativeSolver"/> without
/// a preconditioner. /// a preconditioner.
/// </summary> /// </summary>
internal sealed class UnitPreconditioner : IPreConditioner<double> internal sealed class UnitPreconditioner : IPreConditioner
{ {
/// <summary> /// <summary>
/// The coefficient matrix on which this preconditioner operates. /// The coefficient matrix on which this preconditioner operates.
@ -57,7 +54,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
/// </param> /// </param>
/// <exception cref="ArgumentNullException">If <paramref name="matrix"/> is <see langword="null"/>. </exception> /// <exception cref="ArgumentNullException">If <paramref name="matrix"/> is <see langword="null"/>. </exception>
/// <exception cref="ArgumentException">If <paramref name="matrix"/> is not a square matrix.</exception> /// <exception cref="ArgumentException">If <paramref name="matrix"/> is not a square matrix.</exception>
public void Initialize(Matrix<double> matrix) public void Initialize(Matrix matrix)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -90,7 +87,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
/// If the size of <paramref name="rhs"/> is different the number of rows of the coefficient matrix. /// If the size of <paramref name="rhs"/> is different the number of rows of the coefficient matrix.
/// </para> /// </para>
/// </exception> /// </exception>
public void Approximate(Vector<double> rhs, Vector<double> lhs) public void Approximate(Vector rhs, Vector lhs)
{ {
if (rhs == null) if (rhs == null)
{ {
@ -119,7 +116,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
/// <exception cref="ArgumentException"> /// <exception cref="ArgumentException">
/// If the size of <paramref name="rhs"/> is different the number of rows of the coefficient matrix. /// If the size of <paramref name="rhs"/> is different the number of rows of the coefficient matrix.
/// </exception> /// </exception>
public Vector<double> Approximate(Vector<double> rhs) public Vector Approximate(Vector rhs)
{ {
if (rhs == null) if (rhs == null)
{ {
@ -131,7 +128,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
throw new ArgumentException(Resources.ArgumentMatrixDimensions); throw new ArgumentException(Resources.ArgumentMatrixDimensions);
} }
Vector<double> result = new DenseVector(rhs.Count); Vector result = new DenseVector(rhs.Count);
Approximate(rhs, result); Approximate(rhs, result);
return result; return result;
} }

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

@ -32,14 +32,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium
{ {
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using Generic;
using Generic.Solvers.Status; using Generic.Solvers.Status;
using Generic.Solvers.StopCriterium; using Generic.Solvers.StopCriterium;
/// <summary> /// <summary>
/// Monitors an iterative calculation for signs of divergence. /// Monitors an iterative calculation for signs of divergence.
/// </summary> /// </summary>
public sealed class DivergenceStopCriterium : IIterationStopCriterium<double> public sealed class DivergenceStopCriterium : IIterationStopCriterium
{ {
/// <summary> /// <summary>
/// Default value for the maximum relative increase that the /// Default value for the maximum relative increase that the
@ -207,7 +206,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium
/// <summary> /// <summary>
/// Determines the status of the iterative calculation based on the stop criteria stored /// Determines the status of the iterative calculation based on the stop criteria stored
/// by the current <see cref="IIterationStopCriterium{T}"/>. Result is set into <c>Status</c> field. /// by the current <see cref="IIterationStopCriterium"/>. Result is set into <c>Status</c> field.
/// </summary> /// </summary>
/// <param name="iterationNumber">The number of iterations that have passed so far.</param> /// <param name="iterationNumber">The number of iterations that have passed so far.</param>
/// <param name="solutionVector">The vector containing the current solution values.</param> /// <param name="solutionVector">The vector containing the current solution values.</param>
@ -218,7 +217,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium
/// on the invocation of this method. Therefore this method should only be called if the /// on the invocation of this method. Therefore this method should only be called if the
/// calculation has moved forwards at least one step. /// calculation has moved forwards at least one step.
/// </remarks> /// </remarks>
public void DetermineStatus(int iterationNumber, Vector<double> solutionVector, Vector<double> sourceVector, Vector<double> residualVector) public void DetermineStatus(int iterationNumber, Vector solutionVector, Vector sourceVector, Vector residualVector)
{ {
if (iterationNumber < 0) if (iterationNumber < 0)
{ {
@ -301,7 +300,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium
} }
/// <summary> /// <summary>
/// Gets required history lenght /// Gets required history Length
/// </summary> /// </summary>
private int RequiredHistoryLength private int RequiredHistoryLength
{ {
@ -347,7 +346,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium
} }
/// <summary> /// <summary>
/// Resets the <see cref="IIterationStopCriterium{T}"/> to the pre-calculation state. /// Resets the <see cref="IIterationStopCriterium"/> to the pre-calculation state.
/// </summary> /// </summary>
public void ResetToPrecalculationState() public void ResetToPrecalculationState()
{ {
@ -358,7 +357,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium
/// <summary> /// <summary>
/// Gets the <see cref="StopLevel"/> which indicates what sort of stop criterium this /// Gets the <see cref="StopLevel"/> which indicates what sort of stop criterium this
/// <see cref="IIterationStopCriterium{T}"/> monitors. /// <see cref="IIterationStopCriterium"/> monitors.
/// </summary> /// </summary>
/// <value>Returns <see cref="Generic.Solvers.StopCriterium.StopLevel.Divergence"/>.</value> /// <value>Returns <see cref="Generic.Solvers.StopCriterium.StopLevel.Divergence"/>.</value>
public StopLevel StopLevel public StopLevel StopLevel
@ -374,7 +373,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium
/// Clones the current <see cref="DivergenceStopCriterium"/> and its settings. /// Clones the current <see cref="DivergenceStopCriterium"/> and its settings.
/// </summary> /// </summary>
/// <returns>A new instance of the <see cref="DivergenceStopCriterium"/> class.</returns> /// <returns>A new instance of the <see cref="DivergenceStopCriterium"/> class.</returns>
public IIterationStopCriterium<double> Clone() public IIterationStopCriterium Clone()
{ {
return new DivergenceStopCriterium(_maximumRelativeIncrease, _minimumNumberOfIterations); return new DivergenceStopCriterium(_maximumRelativeIncrease, _minimumNumberOfIterations);
} }

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

@ -32,15 +32,14 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium
{ {
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using Generic;
using Generic.Solvers.Status; using Generic.Solvers.Status;
using Generic.Solvers.StopCriterium; using Generic.Solvers.StopCriterium;
using Properties; using Properties;
/// <summary> /// <summary>
/// Defines an <see cref="IIterationStopCriterium{T}"/> that monitors residuals for NaN's. /// Defines an <see cref="IIterationStopCriterium"/> that monitors residuals for NaN's.
/// </summary> /// </summary>
public sealed class FailureStopCriterium : IIterationStopCriterium<double> public sealed class FailureStopCriterium : IIterationStopCriterium
{ {
/// <summary> /// <summary>
/// Defines the default last iteration number. Set to -1 because iterations normally /// Defines the default last iteration number. Set to -1 because iterations normally
@ -65,7 +64,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium
/// <summary> /// <summary>
/// Determines the status of the iterative calculation based on the stop criteria stored /// Determines the status of the iterative calculation based on the stop criteria stored
/// by the current <see cref="IIterationStopCriterium{T}"/>. Result is set into <c>Status</c> field. /// by the current <see cref="IIterationStopCriterium"/>. Result is set into <c>Status</c> field.
/// </summary> /// </summary>
/// <param name="iterationNumber">The number of iterations that have passed so far.</param> /// <param name="iterationNumber">The number of iterations that have passed so far.</param>
/// <param name="solutionVector">The vector containing the current solution values.</param> /// <param name="solutionVector">The vector containing the current solution values.</param>
@ -76,7 +75,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium
/// on the invocation of this method. Therefore this method should only be called if the /// on the invocation of this method. Therefore this method should only be called if the
/// calculation has moved forwards at least one step. /// calculation has moved forwards at least one step.
/// </remarks> /// </remarks>
public void DetermineStatus(int iterationNumber, Vector<double> solutionVector, Vector<double> sourceVector, Vector<double> residualVector) public void DetermineStatus(int iterationNumber, Vector solutionVector, Vector sourceVector, Vector residualVector)
{ {
if (iterationNumber < 0) if (iterationNumber < 0)
{ {
@ -156,7 +155,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium
} }
/// <summary> /// <summary>
/// Resets the <see cref="IIterationStopCriterium{T}"/> to the pre-calculation state. /// Resets the <see cref="IIterationStopCriterium"/> to the pre-calculation state.
/// </summary> /// </summary>
public void ResetToPrecalculationState() public void ResetToPrecalculationState()
{ {
@ -166,7 +165,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium
/// <summary> /// <summary>
/// Gets the <see cref="StopLevel"/>which indicates what sort of stop criterium this /// Gets the <see cref="StopLevel"/>which indicates what sort of stop criterium this
/// <see cref="IIterationStopCriterium{T}"/> monitors. /// <see cref="IIterationStopCriterium"/> monitors.
/// </summary> /// </summary>
/// <value>Returns <see cref="CalculationFailure"/>.</value> /// <value>Returns <see cref="CalculationFailure"/>.</value>
public StopLevel StopLevel public StopLevel StopLevel
@ -182,7 +181,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium
/// Clones the current <see cref="FailureStopCriterium"/> and its settings. /// Clones the current <see cref="FailureStopCriterium"/> and its settings.
/// </summary> /// </summary>
/// <returns>A new instance of the <see cref="FailureStopCriterium"/> class.</returns> /// <returns>A new instance of the <see cref="FailureStopCriterium"/> class.</returns>
public IIterationStopCriterium<double> Clone() public IIterationStopCriterium Clone()
{ {
return new FailureStopCriterium(); return new FailureStopCriterium();
} }

80
src/Numerics/LinearAlgebra/Double/Solvers/StopCriterium/IIterationStopCriterium.cs

@ -0,0 +1,80 @@
// <copyright file="IIterationStopCriterium.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
// Copyright (c) 2009-2010 Math.NET
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium
{
using System;
using Generic.Solvers.Status;
using Generic.Solvers.StopCriterium;
/// <summary>
/// The base interface for classes that provide stop criteria for iterative calculations.
/// </summary>
public interface IIterationStopCriterium
#if !SILVERLIGHT
: ICloneable
#endif
{
/// <summary>
/// Determines the status of the iterative calculation based on the stop criteria stored
/// by the current <see cref="IIterationStopCriterium"/>. Status is set to <c>Status</c> field of current object.
/// </summary>
/// <param name="iterationNumber">The number of iterations that have passed so far.</param>
/// <param name="solutionVector">The vector containing the current solution values.</param>
/// <param name="sourceVector">The right hand side vector.</param>
/// <param name="residualVector">The vector containing the current residual vectors.</param>
/// <remarks>
/// The individual stop criteria may internally track the progress of the calculation based
/// on the invocation of this method. Therefore this method should only be called if the
/// calculation has moved forwards at least one step.
/// </remarks>
void DetermineStatus(int iterationNumber, Vector solutionVector, Vector sourceVector, Vector residualVector);
/// <summary>
/// Gets the current calculation status.
/// </summary>
/// <remarks><see langword="null" /> is not a legal value. Status should be set in <see cref="DetermineStatus"/> implementation.</remarks>
ICalculationStatus Status { get; }
/// <summary>
/// Resets the <see cref="IIterationStopCriterium"/> to the pre-calculation state.
/// </summary>
/// <remarks>To implementers: Invoking this method should not clear the user defined
/// property values, only the state that is used to track the progress of the
/// calculation.</remarks>
void ResetToPrecalculationState();
/// <summary>
/// Gets the <see cref="StopLevel"/> which indicates what sort of stop criterium this
/// <see cref="IIterationStopCriterium"/> monitors.
/// </summary>
StopLevel StopLevel { get; }
#if SILVERLIGHT
IIterationStopCriterium Clone();
#endif
}
}

9
src/Numerics/LinearAlgebra/Double/Solvers/StopCriterium/IterationCountStopCriterium.cs

@ -32,15 +32,14 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium
{ {
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using Generic;
using Generic.Solvers.Status; using Generic.Solvers.Status;
using Generic.Solvers.StopCriterium; using Generic.Solvers.StopCriterium;
/// <summary> /// <summary>
/// Defines an <see cref="IIterationStopCriterium{T}"/> that monitors the numbers of iteration /// Defines an <see cref="IIterationStopCriterium"/> that monitors the numbers of iteration
/// steps as stop criterium. /// steps as stop criterium.
/// </summary> /// </summary>
public sealed class IterationCountStopCriterium : IIterationStopCriterium<double> public sealed class IterationCountStopCriterium : IIterationStopCriterium
{ {
/// <summary> /// <summary>
/// The default value for the maximum number of iterations the process is allowed /// The default value for the maximum number of iterations the process is allowed
@ -131,7 +130,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium
/// on the invocation of this method. Therefore this method should only be called if the /// on the invocation of this method. Therefore this method should only be called if the
/// calculation has moved forwards at least one step. /// calculation has moved forwards at least one step.
/// </remarks> /// </remarks>
public void DetermineStatus(int iterationNumber, Vector<double> solutionVector, Vector<double> sourceVector, Vector<double> residualVector) public void DetermineStatus(int iterationNumber, Vector solutionVector, Vector sourceVector, Vector residualVector)
{ {
if (iterationNumber < 0) if (iterationNumber < 0)
{ {
@ -208,7 +207,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium
/// Clones the current <see cref="IterationCountStopCriterium"/> and its settings. /// Clones the current <see cref="IterationCountStopCriterium"/> and its settings.
/// </summary> /// </summary>
/// <returns>A new instance of the <see cref="IterationCountStopCriterium"/> class.</returns> /// <returns>A new instance of the <see cref="IterationCountStopCriterium"/> class.</returns>
public IIterationStopCriterium<double> Clone() public IIterationStopCriterium Clone()
{ {
return new IterationCountStopCriterium(_maximumNumberOfIterations); return new IterationCountStopCriterium(_maximumNumberOfIterations);
} }

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

@ -32,15 +32,14 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium
{ {
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using Generic;
using Generic.Solvers.Status; using Generic.Solvers.Status;
using Generic.Solvers.StopCriterium; using Generic.Solvers.StopCriterium;
using Properties; using Properties;
/// <summary> /// <summary>
/// Defines an <see cref="IIterationStopCriterium{T}"/> that monitors residuals as stop criterium. /// Defines an <see cref="IIterationStopCriterium"/> that monitors residuals as stop criterium.
/// </summary> /// </summary>
public sealed class ResidualStopCriterium : IIterationStopCriterium<double> public sealed class ResidualStopCriterium : IIterationStopCriterium
{ {
/// <summary> /// <summary>
/// The default value for the maximum value of the residual. /// The default value for the maximum value of the residual.
@ -212,7 +211,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium
/// <summary> /// <summary>
/// Determines the status of the iterative calculation based on the stop criteria stored /// Determines the status of the iterative calculation based on the stop criteria stored
/// by the current <see cref="IIterationStopCriterium{T}"/>. Result is set into <c>Status</c> field. /// by the current <see cref="IIterationStopCriterium"/>. Result is set into <c>Status</c> field.
/// </summary> /// </summary>
/// <param name="iterationNumber">The number of iterations that have passed so far.</param> /// <param name="iterationNumber">The number of iterations that have passed so far.</param>
/// <param name="solutionVector">The vector containing the current solution values.</param> /// <param name="solutionVector">The vector containing the current solution values.</param>
@ -223,7 +222,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium
/// on the invocation of this method. Therefore this method should only be called if the /// on the invocation of this method. Therefore this method should only be called if the
/// calculation has moved forwards at least one step. /// calculation has moved forwards at least one step.
/// </remarks> /// </remarks>
public void DetermineStatus(int iterationNumber, Vector<double> solutionVector, Vector<double> sourceVector, Vector<double> residualVector) public void DetermineStatus(int iterationNumber, Vector solutionVector, Vector sourceVector, Vector residualVector)
{ {
if (iterationNumber < 0) if (iterationNumber < 0)
{ {
@ -363,7 +362,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium
} }
/// <summary> /// <summary>
/// Resets the <see cref="IIterationStopCriterium{T}"/> to the pre-calculation state. /// Resets the <see cref="IIterationStopCriterium"/> to the pre-calculation state.
/// </summary> /// </summary>
public void ResetToPrecalculationState() public void ResetToPrecalculationState()
{ {
@ -374,7 +373,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium
/// <summary> /// <summary>
/// Gets the <see cref="StopLevel"/> which indicates what sort of stop criterium this /// Gets the <see cref="StopLevel"/> which indicates what sort of stop criterium this
/// <see cref="IIterationStopCriterium{T}"/> monitors. /// <see cref="IIterationStopCriterium"/> monitors.
/// </summary> /// </summary>
/// <value>Returns <see cref="StopLevel"/>.</value> /// <value>Returns <see cref="StopLevel"/>.</value>
public StopLevel StopLevel public StopLevel StopLevel
@ -390,7 +389,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium
/// Clones the current <see cref="ResidualStopCriterium"/> and its settings. /// Clones the current <see cref="ResidualStopCriterium"/> and its settings.
/// </summary> /// </summary>
/// <returns>A new instance of the <see cref="ResidualStopCriterium"/> class.</returns> /// <returns>A new instance of the <see cref="ResidualStopCriterium"/> class.</returns>
public IIterationStopCriterium<double> Clone() public IIterationStopCriterium Clone()
{ {
return new ResidualStopCriterium(_maximum, _minimumIterationsBelowMaximum); return new ResidualStopCriterium(_maximum, _minimumIterationsBelowMaximum);
} }

11
src/Numerics/LinearAlgebra/Generic/Solvers/StopCriterium/StopLevel.cs

@ -27,29 +27,28 @@
namespace MathNet.Numerics.LinearAlgebra.Generic.Solvers.StopCriterium namespace MathNet.Numerics.LinearAlgebra.Generic.Solvers.StopCriterium
{ {
/// <summary> /// <summary>
/// Indicates what an <see cref="IIterationStopCriterium{T}"/> monitors for stop criteria. /// Iteration stop criteria.
/// </summary> /// </summary>
public enum StopLevel public enum StopLevel
{ {
/// <summary> /// <summary>
/// The <see cref="IIterationStopCriterium{T}"/> monitors calculation failures in the /// Monitor calculation failures in the iterative calculation.
/// iterative calculation.
/// </summary> /// </summary>
CalculationFailure, CalculationFailure,
/// <summary> /// <summary>
/// The <see cref="IIterationStopCriterium{T}"/> monitors the calculation for signs of divergence. /// Monitor the calculation for signs of divergence.
/// </summary> /// </summary>
Divergence, Divergence,
/// <summary> /// <summary>
/// The <see cref="IIterationStopCriterium{T}"/> guards the calculation against unlimited continuation /// Guard the calculation against unlimited continuation
/// by monitoring user specified limits, e.g. the maximum number of iterations. /// by monitoring user specified limits, e.g. the maximum number of iterations.
/// </summary> /// </summary>
StoppedWithoutConvergence, StoppedWithoutConvergence,
/// <summary> /// <summary>
/// The <see cref="IIterationStopCriterium{T}"/> monitors the calculation for convergence, usually /// Monitor the calculation for convergence, usually
/// based on the residuals of the calculation. /// based on the residuals of the calculation.
/// </summary> /// </summary>
Convergence Convergence

96
src/Numerics/LinearAlgebra/Single/Solvers/IIterativeSolver.cs

@ -0,0 +1,96 @@
// <copyright file="IIterativeSolver.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
//
// Copyright (c) 2009-2010 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
{
using Generic.Solvers.Status;
/// <summary>
/// Defines the interface for <see cref="IIterativeSolver"/> classes that solve the matrix equation Ax = b in
/// an iterative manner.
/// </summary>
public interface IIterativeSolver
{
/// <summary>
/// Stops the solve process.
/// </summary>
/// <remarks>
/// Note that it may take an indetermined amount of time for the solver to actually stop the process.
/// </remarks>
void StopSolve();
/// <summary>
/// Sets the <see cref="IIterator"/> that will be used to track the iterative process.
/// </summary>
/// <param name="iterator">The iterator.</param>
void SetIterator(IIterator iterator);
/// <summary>
/// Gets the status of the iteration once the calculation is finished.
/// </summary>
ICalculationStatus 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.
/// </summary>
/// <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 Solve(Matrix matrix, Vector vector);
/// <summary>
/// Solves the matrix equation Ax = b, where A is the coefficient matrix, b is the
/// solution vector and x is the unknown vector.
/// </summary>
/// <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 matrix, Vector input, Vector result);
/// <summary>
/// Solves the matrix equation AX = B, where A is the coefficient matrix, B is the
/// solution matrix and X is the unknown matrix.
/// </summary>
/// <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 Solve(Matrix matrix, Matrix input);
/// <summary>
/// Solves the matrix equation AX = B, where A is the coefficient matrix, B is the
/// solution matrix and X is the unknown matrix.
/// </summary>
/// <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 matrix, Matrix input, Matrix result);
}
}

71
src/Numerics/LinearAlgebra/Single/Solvers/IIterativeSolverSetup.cs

@ -0,0 +1,71 @@
// <copyright file="IIterativeSolverSetup.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
//
// Copyright (c) 2009-2010 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
{
using System;
/// <summary>
/// Defines the interface for objects that can create an iterative solver with
/// specific settings. This interface is used to pass iterative solver creation
/// setup information around.
/// </summary>
public interface IIterativeSolverSetup
{
/// <summary>
/// Gets the type of the solver that will be created by this setup object.
/// </summary>
Type SolverType { get; }
/// <summary>
/// Gets type of preconditioner, if any, that will be created by this setup object.
/// </summary>
Type PreconditionerType { get; }
/// <summary>
/// Creates a fully functional iterative solver with the default settings
/// given by this setup.
/// </summary>
/// <returns>A new <see cref="IIterativeSolver"/>.</returns>
IIterativeSolver CreateNew();
/// <summary>
/// Gets the relative speed of the solver.
/// </summary>
/// <value>Returns a value between 0 and 1, inclusive.</value>
double SolutionSpeed { get; }
/// <summary>
/// Gets the relative reliability of the solver.
/// </summary>
/// <value>Returns a value between 0 and 1 inclusive.</value>
double Reliability { get; }
}
}

108
src/Numerics/LinearAlgebra/Single/Solvers/IIterator.cs

@ -0,0 +1,108 @@
// <copyright file="IIterator.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
//
// Copyright (c) 2009-2010 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
{
using System;
using Generic.Solvers.Status;
using StopCriterium;
/// <summary>
/// Defines the base interface for iterators that help control an iterative calculation.
/// </summary>
public interface IIterator
#if !SILVERLIGHT
: ICloneable
#endif
{
/// <summary>
/// Adds an <see cref="IIterationStopCriterium"/> to the internal collection of stop-criteria. Only a
/// single stop criterium of each type can be stored.
/// </summary>
/// <param name="stopCriterium">The stop criterium to add.</param>
/// <exception cref="ArgumentNullException">Thrown if <paramref name="stopCriterium"/> is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">Thrown if <paramref name="stopCriterium"/> is of the same type as an already stored criterium.</exception>
void Add(IIterationStopCriterium stopCriterium);
/// <summary>
/// Removes the <see cref="IIterationStopCriterium"/> from the internal collection.
/// </summary>
/// <param name="stopCriterium">The stop criterium that must be removed.</param>
void Remove(IIterationStopCriterium stopCriterium);
/// <summary>
/// Indicates if the specific stop criterium is stored by the <see cref="IIterator"/>.
/// </summary>
/// <param name="stopCriterium">The stop criterium.</param>
/// <returns><c>true</c> if the <see cref="IIterator"/> contains the stop criterium; otherwise <c>false</c>.</returns>
bool Contains(IIterationStopCriterium stopCriterium);
/// <summary>
/// Indicates to the iterator that the iterative process has been cancelled.
/// </summary>
/// <remarks>Does not reset the stop-criteria.</remarks>
void IterationCancelled();
/// <summary>
/// Determines the status of the iterative calculation based on the stop criteria stored
/// by the current <see cref="IIterator"/>. Status is set to <c>Status</c> field of current object.
/// </summary>
/// <param name="iterationNumber">The number of iterations that have passed so far.</param>
/// <param name="solutionVector">The vector containing the current solution values.</param>
/// <param name="sourceVector">The right hand side vector.</param>
/// <param name="residualVector">The vector containing the current residual vectors.</param>
/// <remarks>
/// The individual iterators may internally track the progress of the calculation based
/// on the invocation of this method. Therefore this method should only be called if the
/// calculation has moved forwards at least one step.
/// </remarks>
void DetermineStatus(int iterationNumber, Vector solutionVector, Vector sourceVector, Vector residualVector);
/// <summary>
/// Gets the current calculation status.
/// </summary>
/// <remarks><see langword="null" /> is not a legal value. Status should be set in <see cref="DetermineStatus"/> implementation.</remarks>.
ICalculationStatus Status { get; }
/// <summary>
/// Resets the <see cref="IIterator"/> to the pre-calculation state.
/// </summary>
/// <remarks>
/// Note to implementers: Invoking this method should not clear the user defined
/// property values, only the state that is used to track the progress of the
/// calculation.
/// </remarks>
void ResetToPrecalculationState();
#if SILVERLIGHT
IIterator Clone();
#endif
}
}

117
src/Numerics/LinearAlgebra/Single/Solvers/Iterative/BiCgStab.cs

@ -31,9 +31,6 @@
namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
{ {
using System; using System;
using Generic;
using Generic.Solvers;
using Generic.Solvers.Preconditioners;
using Generic.Solvers.Status; using Generic.Solvers.Status;
using Preconditioners; using Preconditioners;
using Properties; using Properties;
@ -67,7 +64,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
/// solver. /// solver.
/// </para> /// </para>
/// </remarks> /// </remarks>
public sealed class BiCgStab : IIterativeSolver<float> public sealed class BiCgStab : IIterativeSolver
{ {
/// <summary> /// <summary>
/// The status used if there is no status, i.e. the solver hasn't run yet and there is no /// The status used if there is no status, i.e. the solver hasn't run yet and there is no
@ -79,12 +76,12 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
/// The preconditioner that will be used. Can be set to <see langword="null" />, in which case the default /// The preconditioner that will be used. Can be set to <see langword="null" />, in which case the default
/// pre-conditioner will be used. /// pre-conditioner will be used.
/// </summary> /// </summary>
private IPreConditioner<float> _preconditioner; private IPreConditioner _preconditioner;
/// <summary> /// <summary>
/// The iterative process controller. /// The iterative process controller.
/// </summary> /// </summary>
private IIterator<float> _iterator; private IIterator _iterator;
/// <summary> /// <summary>
/// Indicates if the user has stopped the solver. /// Indicates if the user has stopped the solver.
@ -95,7 +92,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
/// Initializes a new instance of the <see cref="BiCgStab"/> class. /// Initializes a new instance of the <see cref="BiCgStab"/> class.
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// When using this constructor the solver will use the <see cref="IIterator{T}"/> with /// When using this constructor the solver will use the <see cref="IIterator"/> with
/// the standard settings and a default preconditioner. /// the standard settings and a default preconditioner.
/// </remarks> /// </remarks>
public BiCgStab() : this(null, null) public BiCgStab() : this(null, null)
@ -110,18 +107,18 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
/// When using this constructor the solver will use a default preconditioner. /// When using this constructor the solver will use a default preconditioner.
/// </para> /// </para>
/// <para> /// <para>
/// The main advantages of using a user defined <see cref="IIterator{T}"/> are: /// The main advantages of using a user defined <see cref="IIterator"/> are:
/// <list type="number"> /// <list type="number">
/// <item>It is possible to set the desired convergence limits.</item> /// <item>It is possible to set the desired convergence limits.</item>
/// <item> /// <item>
/// It is possible to check the reason for which the solver finished /// It is possible to check the reason for which the solver finished
/// the iterative procedure by calling the <see cref="IIterator{T}.Status"/> property. /// the iterative procedure by calling the <see cref="IIterator.Status"/> property.
/// </item> /// </item>
/// </list> /// </list>
/// </para> /// </para>
/// </remarks> /// </remarks>
/// <param name="iterator">The <see cref="IIterator{T}"/> that will be used to monitor the iterative process. </param> /// <param name="iterator">The <see cref="IIterator"/> that will be used to monitor the iterative process. </param>
public BiCgStab(IIterator<float> iterator) : this(null, iterator) public BiCgStab(IIterator iterator) : this(null, iterator)
{ {
} }
@ -129,11 +126,11 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
/// Initializes a new instance of the <see cref="BiCgStab"/> class. /// Initializes a new instance of the <see cref="BiCgStab"/> class.
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// When using this constructor the solver will use the <see cref="IIterator{T}"/> with /// When using this constructor the solver will use the <see cref="IIterator"/> with
/// the standard settings. /// the standard settings.
/// </remarks> /// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation.</param> /// <param name="preconditioner">The <see cref="IPreConditioner"/> that will be used to precondition the matrix equation.</param>
public BiCgStab(IPreConditioner<float> preconditioner) : this(preconditioner, null) public BiCgStab(IPreConditioner preconditioner) : this(preconditioner, null)
{ {
} }
@ -142,38 +139,38 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// <para> /// <para>
/// The main advantages of using a user defined <see cref="IIterator{T}"/> are: /// The main advantages of using a user defined <see cref="IIterator"/> are:
/// <list type="number"> /// <list type="number">
/// <item>It is possible to set the desired convergence limits.</item> /// <item>It is possible to set the desired convergence limits.</item>
/// <item> /// <item>
/// It is possible to check the reason for which the solver finished /// It is possible to check the reason for which the solver finished
/// the iterative procedure by calling the <see cref="IIterator{T}.Status"/> property. /// the iterative procedure by calling the <see cref="IIterator.Status"/> property.
/// </item> /// </item>
/// </list> /// </list>
/// </para> /// </para>
/// </remarks> /// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation. </param> /// <param name="preconditioner">The <see cref="IPreConditioner"/> that will be used to precondition the matrix equation. </param>
/// <param name="iterator">The <see cref="IIterator{T}"/> that will be used to monitor the iterative process. </param> /// <param name="iterator">The <see cref="IIterator"/> that will be used to monitor the iterative process. </param>
public BiCgStab(IPreConditioner<float> preconditioner, IIterator<float> iterator) public BiCgStab(IPreConditioner preconditioner, IIterator iterator)
{ {
_iterator = iterator; _iterator = iterator;
_preconditioner = preconditioner; _preconditioner = preconditioner;
} }
/// <summary> /// <summary>
/// Sets the <see cref="IPreConditioner{T}"/> that will be used to precondition the iterative process. /// Sets the <see cref="IPreConditioner"/> that will be used to precondition the iterative process.
/// </summary> /// </summary>
/// <param name="preconditioner">The preconditioner.</param> /// <param name="preconditioner">The preconditioner.</param>
public void SetPreconditioner(IPreConditioner<float> preconditioner) public void SetPreconditioner(IPreConditioner preconditioner)
{ {
_preconditioner = preconditioner; _preconditioner = preconditioner;
} }
/// <summary> /// <summary>
/// Sets the <see cref="IIterator{T}"/> that will be used to track the iterative process. /// Sets the <see cref="IIterator"/> that will be used to track the iterative process.
/// </summary> /// </summary>
/// <param name="iterator">The iterator.</param> /// <param name="iterator">The iterator.</param>
public void SetIterator(IIterator<float> iterator) public void SetIterator(IIterator iterator)
{ {
_iterator = iterator; _iterator = iterator;
} }
@ -204,17 +201,17 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
/// Solves the matrix equation Ax = b, where A is the coefficient matrix, b is the /// Solves the matrix equation Ax = b, where A is the coefficient matrix, b is the
/// solution vector and x is the unknown vector. /// solution vector and x is the unknown vector.
/// </summary> /// </summary>
/// <param name="matrix">The coefficient <see cref="Matrix{T}"/>, <c>A</c>.</param> /// <param name="matrix">The coefficient <see cref="Matrix"/>, <c>A</c>.</param>
/// <param name="vector">The solution <see cref="Vector{T}"/>, <c>b</c>.</param> /// <param name="vector">The solution <see cref="Vector"/>, <c>b</c>.</param>
/// <returns>The result <see cref="Vector{T}"/>, <c>x</c>.</returns> /// <returns>The result <see cref="Vector"/>, <c>x</c>.</returns>
public Vector<float> Solve(Matrix<float> matrix, Vector<float> vector) public Vector Solve(Matrix matrix, Vector vector)
{ {
if (vector == null) if (vector == null)
{ {
throw new ArgumentNullException(); throw new ArgumentNullException();
} }
Vector<float> result = new DenseVector(matrix.RowCount); Vector result = new DenseVector(matrix.RowCount);
Solve(matrix, vector, result); Solve(matrix, vector, result);
return result; return result;
} }
@ -223,10 +220,10 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
/// Solves the matrix equation Ax = b, where A is the coefficient matrix, b is the /// Solves the matrix equation Ax = b, where A is the coefficient matrix, b is the
/// solution vector and x is the unknown vector. /// solution vector and x is the unknown vector.
/// </summary> /// </summary>
/// <param name="matrix">The coefficient <see cref="Matrix{T}"/>, <c>A</c>.</param> /// <param name="matrix">The coefficient <see cref="Matrix"/>, <c>A</c>.</param>
/// <param name="input">The solution <see cref="Vector{T}"/>, <c>b</c>.</param> /// <param name="input">The solution <see cref="Vector"/>, <c>b</c>.</param>
/// <param name="result">The result <see cref="Vector{T}"/>, <c>x</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 matrix, Vector input, Vector result)
{ {
// If we were stopped before, we are no longer // If we were stopped before, we are no longer
// We're doing this at the start of the method to ensure // We're doing this at the start of the method to ensure
@ -281,7 +278,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
// Compute r_0 = b - Ax_0 for some initial guess x_0 // Compute r_0 = b - Ax_0 for some initial guess x_0
// In this case we take x_0 = vector // In this case we take x_0 = vector
// This is basically a SAXPY so it could be made a lot faster // This is basically a SAXPY so it could be made a lot faster
Vector<float> residuals = new DenseVector(matrix.RowCount); Vector residuals = new DenseVector(matrix.RowCount);
CalculateTrueResidual(matrix, residuals, result, input); CalculateTrueResidual(matrix, residuals, result, input);
// Choose r~ (for example, r~ = r_0) // Choose r~ (for example, r~ = r_0)
@ -290,13 +287,13 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
// create seven temporary vectors needed to hold temporary // create seven temporary vectors needed to hold temporary
// coefficients. All vectors are mangled in each iteration. // coefficients. All vectors are mangled in each iteration.
// These are defined here to prevent stressing the garbage collector // These are defined here to prevent stressing the garbage collector
Vector<float> vecP = new DenseVector(residuals.Count); Vector vecP = new DenseVector(residuals.Count);
Vector<float> vecPdash = new DenseVector(residuals.Count); Vector vecPdash = new DenseVector(residuals.Count);
Vector<float> nu = new DenseVector(residuals.Count); Vector nu = new DenseVector(residuals.Count);
Vector<float> vecS = new DenseVector(residuals.Count); Vector vecS = new DenseVector(residuals.Count);
Vector<float> vecSdash = new DenseVector(residuals.Count); Vector vecSdash = new DenseVector(residuals.Count);
Vector<float> temp = new DenseVector(residuals.Count); Vector temp = new DenseVector(residuals.Count);
Vector<float> temp2 = new DenseVector(residuals.Count); Vector temp2 = new DenseVector(residuals.Count);
// create some temporary float variables that are needed // create some temporary float variables that are needed
// to hold values in between iterations // to hold values in between iterations
@ -428,13 +425,13 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
} }
/// <summary> /// <summary>
/// Calculates the true residual of the matrix equation Ax = b according to: residual = b - Ax /// Calculates the <c>true</c> residual of the matrix equation Ax = b according to: residual = b - Ax
/// </summary> /// </summary>
/// <param name="matrix">Instance of the <see cref="Matrix{T}"/> A.</param> /// <param name="matrix">Instance of the <see cref="Matrix"/> A.</param>
/// <param name="residual">Residual values in <see cref="Vector{T}"/>.</param> /// <param name="residual">Residual values in <see cref="Vector"/>.</param>
/// <param name="x">Instance of the <see cref="Vector{T}"/> x.</param> /// <param name="x">Instance of the <see cref="Vector"/> x.</param>
/// <param name="b">Instance of the <see cref="Vector{T}"/> b.</param> /// <param name="b">Instance of the <see cref="Vector"/> b.</param>
private static void CalculateTrueResidual(Matrix<float> matrix, Vector<float> residual, Vector<float> x, Vector<float> b) private static void CalculateTrueResidual(Matrix matrix, Vector residual, Vector x, Vector b)
{ {
// -Ax = residual // -Ax = residual
matrix.Multiply(x, residual); matrix.Multiply(x, residual);
@ -450,11 +447,11 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
/// Determine if calculation should continue /// Determine if calculation should continue
/// </summary> /// </summary>
/// <param name="iterationNumber">Number of iterations passed</param> /// <param name="iterationNumber">Number of iterations passed</param>
/// <param name="result">Result <see cref="Vector{T}"/>.</param> /// <param name="result">Result <see cref="Vector"/>.</param>
/// <param name="source">Source <see cref="Vector{T}"/>.</param> /// <param name="source">Source <see cref="Vector"/>.</param>
/// <param name="residuals">Residual <see cref="Vector{T}"/>.</param> /// <param name="residuals">Residual <see cref="Vector"/>.</param>
/// <returns><c>true</c> if continue, otherwise <c>false</c></returns> /// <returns><c>true</c> if continue, otherwise <c>false</c></returns>
private bool ShouldContinue(int iterationNumber, Vector<float> result, Vector<float> source, Vector<float> residuals) private bool ShouldContinue(int iterationNumber, Vector result, Vector source, Vector residuals)
{ {
if (_hasBeenStopped) if (_hasBeenStopped)
{ {
@ -475,10 +472,10 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
/// Solves the matrix equation AX = B, where A is the coefficient matrix, B is the /// Solves the matrix equation AX = B, where A is the coefficient matrix, B is the
/// solution matrix and X is the unknown matrix. /// solution matrix and X is the unknown matrix.
/// </summary> /// </summary>
/// <param name="matrix">The coefficient <see cref="Matrix{T}"/>, <c>A</c>.</param> /// <param name="matrix">The coefficient <see cref="Matrix"/>, <c>A</c>.</param>
/// <param name="input">The solution <see cref="Matrix{T}"/>, <c>B</c>.</param> /// <param name="input">The solution <see cref="Matrix"/>, <c>B</c>.</param>
/// <returns>The result <see cref="Matrix{T}"/>, <c>X</c>.</returns> /// <returns>The result <see cref="Matrix"/>, <c>X</c>.</returns>
public Matrix<float> Solve(Matrix<float> matrix, Matrix<float> input) public Matrix Solve(Matrix matrix, Matrix input)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -490,7 +487,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
throw new ArgumentNullException("input"); throw new ArgumentNullException("input");
} }
var result = matrix.CreateMatrix(input.RowCount, input.ColumnCount); var result = (Matrix)matrix.CreateMatrix(input.RowCount, input.ColumnCount);
Solve(matrix, input, result); Solve(matrix, input, result);
return result; return result;
} }
@ -499,10 +496,10 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
/// Solves the matrix equation AX = B, where A is the coefficient matrix, B is the /// Solves the matrix equation AX = B, where A is the coefficient matrix, B is the
/// solution matrix and X is the unknown matrix. /// solution matrix and X is the unknown matrix.
/// </summary> /// </summary>
/// <param name="matrix">The coefficient <see cref="Matrix{T}"/>, <c>A</c>.</param> /// <param name="matrix">The coefficient <see cref="Matrix"/>, <c>A</c>.</param>
/// <param name="input">The solution <see cref="Matrix{T}"/>, <c>B</c>.</param> /// <param name="input">The solution <see cref="Matrix"/>, <c>B</c>.</param>
/// <param name="result">The result <see cref="Matrix{T}"/>, <c>X</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 matrix, Matrix input, Matrix result)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -526,7 +523,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
for (var column = 0; column < input.ColumnCount; column++) for (var column = 0; column < input.ColumnCount; column++)
{ {
var solution = Solve(matrix, input.Column(column)); var solution = Solve(matrix, (Vector)input.Column(column));
foreach (var element in solution.GetIndexedEnumerator()) foreach (var element in solution.GetIndexedEnumerator())
{ {
result.At(element.Key, column, element.Value); result.At(element.Key, column, element.Value);

76
src/Numerics/LinearAlgebra/Single/Solvers/Iterative/CompositeSolver.cs

@ -35,8 +35,6 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using Generic;
using Generic.Solvers;
using Generic.Solvers.Status; using Generic.Solvers.Status;
using Properties; using Properties;
@ -55,7 +53,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
/// Note that if an iterator is passed to this solver it will be used for all the sub-solvers. /// Note that if an iterator is passed to this solver it will be used for all the sub-solvers.
/// </para> /// </para>
/// </remarks> /// </remarks>
public sealed class CompositeSolver : IIterativeSolver<float> public sealed class CompositeSolver : IIterativeSolver
{ {
#region Internal class - DoubleComparer #region Internal class - DoubleComparer
/// <summary> /// <summary>
@ -96,19 +94,19 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
private static readonly ICalculationStatus RunningStatus = new CalculationRunning(); private static readonly ICalculationStatus RunningStatus = new CalculationRunning();
#if SILVERLIGHT #if SILVERLIGHT
private static readonly Dictionary<double, List<IIterativeSolverSetup<float>>> SolverSetups = new Dictionary<double, List<IIterativeSolverSetup<float>>>(); private static readonly Dictionary<double, List<IIterativeSolverSetup>> SolverSetups = new Dictionary<double, List<IIterativeSolverSetup>>();
#else #else
/// <summary> /// <summary>
/// The collection of iterative solver setups. Stored based on the /// The collection of iterative solver setups. Stored based on the
/// ratio between the relative speed and relative accuracy. /// ratio between the relative speed and relative accuracy.
/// </summary> /// </summary>
private static readonly SortedList<double, List<IIterativeSolverSetup<float>>> SolverSetups = new SortedList<double, List<IIterativeSolverSetup<float>>>(new DoubleComparer()); private static readonly SortedList<double, List<IIterativeSolverSetup>> SolverSetups = new SortedList<double, List<IIterativeSolverSetup>>(new DoubleComparer());
#endif #endif
#region Solver information loading methods #region Solver information loading methods
/// <summary> /// <summary>
/// Loads all the available <see cref="IIterativeSolverSetup{T}"/> objects from the MathNet.Numerics assembly. /// Loads all the available <see cref="IIterativeSolverSetup"/> objects from the MathNet.Numerics assembly.
/// </summary> /// </summary>
public static void LoadSolverInformation() public static void LoadSolverInformation()
{ {
@ -116,16 +114,16 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
} }
/// <summary> /// <summary>
/// Loads the available <see cref="IIterativeSolverSetup{T}"/> objects from the MathNet.Numerics assembly. /// Loads the available <see cref="IIterativeSolverSetup"/> objects from the MathNet.Numerics assembly.
/// </summary> /// </summary>
/// <param name="typesToExclude">The <see cref="IIterativeSolver{T}"/> types that should not be loaded.</param> /// <param name="typesToExclude">The <see cref="IIterativeSolver"/> types that should not be loaded.</param>
public static void LoadSolverInformation(Type[] typesToExclude) public static void LoadSolverInformation(Type[] typesToExclude)
{ {
LoadSolverInformationFromAssembly(Assembly.GetExecutingAssembly(), typesToExclude); LoadSolverInformationFromAssembly(Assembly.GetExecutingAssembly(), typesToExclude);
} }
/// <summary> /// <summary>
/// Loads the available <see cref="IIterativeSolverSetup{T}"/> objects from the assembly specified by the file location. /// Loads the available <see cref="IIterativeSolverSetup"/> objects from the assembly specified by the file location.
/// </summary> /// </summary>
/// <param name="assemblyLocation">The fully qualified path to the assembly.</param> /// <param name="assemblyLocation">The fully qualified path to the assembly.</param>
public static void LoadSolverInformationFromAssembly(string assemblyLocation) public static void LoadSolverInformationFromAssembly(string assemblyLocation)
@ -134,10 +132,10 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
} }
/// <summary> /// <summary>
/// Loads the available <see cref="IIterativeSolverSetup{T}"/> objects from the assembly specified by the file location. /// Loads the available <see cref="IIterativeSolverSetup"/> objects from the assembly specified by the file location.
/// </summary> /// </summary>
/// <param name="assemblyLocation">The fully qualified path to the assembly.</param> /// <param name="assemblyLocation">The fully qualified path to the assembly.</param>
/// <param name="typesToExclude">The <see cref="IIterativeSolver{T}"/> types that should not be loaded. </param> /// <param name="typesToExclude">The <see cref="IIterativeSolver"/> types that should not be loaded. </param>
public static void LoadSolverInformationFromAssembly(string assemblyLocation, params Type[] typesToExclude) public static void LoadSolverInformationFromAssembly(string assemblyLocation, params Type[] typesToExclude)
{ {
if (assemblyLocation == null) if (assemblyLocation == null)
@ -172,7 +170,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
} }
/// <summary> /// <summary>
/// Loads the available <see cref="IIterativeSolverSetup{T}"/> objects from the assembly specified by the assembly name. /// Loads the available <see cref="IIterativeSolverSetup"/> objects from the assembly specified by the assembly name.
/// </summary> /// </summary>
/// <param name="assemblyName">The <see cref="AssemblyName"/> of the assembly that should be searched for setup objects. </param> /// <param name="assemblyName">The <see cref="AssemblyName"/> of the assembly that should be searched for setup objects. </param>
public static void LoadSolverInformationFromAssembly(AssemblyName assemblyName) public static void LoadSolverInformationFromAssembly(AssemblyName assemblyName)
@ -181,10 +179,10 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
} }
/// <summary> /// <summary>
/// Loads the available <see cref="IIterativeSolverSetup{T}"/> objects from the assembly specified by the assembly name. /// Loads the available <see cref="IIterativeSolverSetup"/> objects from the assembly specified by the assembly name.
/// </summary> /// </summary>
/// <param name="assemblyName">The <see cref="AssemblyName"/> of the assembly that should be searched for setup objects.</param> /// <param name="assemblyName">The <see cref="AssemblyName"/> of the assembly that should be searched for setup objects.</param>
/// <param name="typesToExclude">The <see cref="IIterativeSolver{T}"/> types that should not be loaded.</param> /// <param name="typesToExclude">The <see cref="IIterativeSolver"/> types that should not be loaded.</param>
public static void LoadSolverInformationFromAssembly(AssemblyName assemblyName, params Type[] typesToExclude) public static void LoadSolverInformationFromAssembly(AssemblyName assemblyName, params Type[] typesToExclude)
{ {
if (assemblyName == null) if (assemblyName == null)
@ -204,7 +202,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
} }
/// <summary> /// <summary>
/// Loads the available <see cref="IIterativeSolverSetup{T}"/> objects from the assembly specified by the type. /// Loads the available <see cref="IIterativeSolverSetup"/> objects from the assembly specified by the type.
/// </summary> /// </summary>
/// <param name="typeInAssembly">The type in the assembly which should be searched for setup objects.</param> /// <param name="typeInAssembly">The type in the assembly which should be searched for setup objects.</param>
public static void LoadSolverInformationFromAssembly(Type typeInAssembly) public static void LoadSolverInformationFromAssembly(Type typeInAssembly)
@ -213,10 +211,10 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
} }
/// <summary> /// <summary>
/// Loads the available <see cref="IIterativeSolverSetup{T}"/> objects from the assembly specified by the type. /// Loads the available <see cref="IIterativeSolverSetup"/> objects from the assembly specified by the type.
/// </summary> /// </summary>
/// <param name="typeInAssembly">The type in the assembly which should be searched for setup objects.</param> /// <param name="typeInAssembly">The type in the assembly which should be searched for setup objects.</param>
/// <param name="typesToExclude">The <see cref="IIterativeSolver{T}"/> types that should not be loaded.</param> /// <param name="typesToExclude">The <see cref="IIterativeSolver"/> types that should not be loaded.</param>
public static void LoadSolverInformationFromAssembly(Type typeInAssembly, params Type[] typesToExclude) public static void LoadSolverInformationFromAssembly(Type typeInAssembly, params Type[] typesToExclude)
{ {
if (typeInAssembly == null) if (typeInAssembly == null)
@ -228,7 +226,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
} }
/// <summary> /// <summary>
/// Loads the available <see cref="IIterativeSolverSetup{T}"/> objects from the specified assembly. /// Loads the available <see cref="IIterativeSolverSetup"/> objects from the specified assembly.
/// </summary> /// </summary>
/// <param name="assembly">The assembly which will be searched for setup objects.</param> /// <param name="assembly">The assembly which will be searched for setup objects.</param>
public static void LoadSolverInformationFromAssembly(Assembly assembly) public static void LoadSolverInformationFromAssembly(Assembly assembly)
@ -237,10 +235,10 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
} }
/// <summary> /// <summary>
/// Loads the available <see cref="IIterativeSolverSetup{T}"/> objects from the specified assembly. /// Loads the available <see cref="IIterativeSolverSetup"/> objects from the specified assembly.
/// </summary> /// </summary>
/// <param name="assembly">The assembly which will be searched for setup objects.</param> /// <param name="assembly">The assembly which will be searched for setup objects.</param>
/// <param name="typesToExclude">The <see cref="IIterativeSolver{T}"/> types that should not be loaded.</param> /// <param name="typesToExclude">The <see cref="IIterativeSolver"/> types that should not be loaded.</param>
public static void LoadSolverInformationFromAssembly(Assembly assembly, params Type[] typesToExclude) public static void LoadSolverInformationFromAssembly(Assembly assembly, params Type[] typesToExclude)
{ {
if (assembly == null) if (assembly == null)
@ -265,18 +263,18 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
{ {
interfaceTypes.Clear(); interfaceTypes.Clear();
interfaceTypes.AddRange(type.GetInterfaces()); interfaceTypes.AddRange(type.GetInterfaces());
if (!interfaceTypes.Any(match => typeof(IIterativeSolverSetup<double>).IsAssignableFrom(match))) if (!interfaceTypes.Any(match => typeof(IIterativeSolverSetup).IsAssignableFrom(match)))
{ {
continue; continue;
} }
// See if we actually want this type of iterative solver // See if we actually want this type of iterative solver
IIterativeSolverSetup<float> setup; IIterativeSolverSetup setup;
try try
{ {
// If something goes wrong we just ignore it and move on with the next type. // If something goes wrong we just ignore it and move on with the next type.
// There should probably be a log somewhere indicating that something went wrong? // There should probably be a log somewhere indicating that something went wrong?
setup = (IIterativeSolverSetup<float>)Activator.CreateInstance(type); setup = (IIterativeSolverSetup)Activator.CreateInstance(type);
} }
catch (ArgumentException) catch (ArgumentException)
{ {
@ -317,7 +315,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
var ratio = setup.SolutionSpeed / setup.Reliability; var ratio = setup.SolutionSpeed / setup.Reliability;
if (!SolverSetups.ContainsKey(ratio)) if (!SolverSetups.ContainsKey(ratio))
{ {
SolverSetups.Add(ratio, new List<IIterativeSolverSetup<float>>()); SolverSetups.Add(ratio, new List<IIterativeSolverSetup>());
} }
var list = SolverSetups[ratio]; var list = SolverSetups[ratio];
@ -330,7 +328,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
/// <summary> /// <summary>
/// The collection of solvers that will be used to /// The collection of solvers that will be used to
/// </summary> /// </summary>
private readonly List<IIterativeSolver<float>> _solvers = new List<IIterativeSolver<float>>(); private readonly List<IIterativeSolver> _solvers = new List<IIterativeSolver>();
/// <summary> /// <summary>
/// The status of the calculation. /// The status of the calculation.
@ -340,7 +338,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
/// <summary> /// <summary>
/// The iterator that is used to control the iteration process. /// The iterator that is used to control the iteration process.
/// </summary> /// </summary>
private IIterator<float> _iterator; private IIterator _iterator;
/// <summary> /// <summary>
/// A flag indicating if the solver has been stopped or not. /// A flag indicating if the solver has been stopped or not.
@ -351,7 +349,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
/// The solver that is currently running. Reference is used to be able to stop the /// The solver that is currently running. Reference is used to be able to stop the
/// solver if the user cancels the solve process. /// solver if the user cancels the solve process.
/// </summary> /// </summary>
private IIterativeSolver<float> _currentSolver; private IIterativeSolver _currentSolver;
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="CompositeSolver"/> class with the default iterator. /// Initializes a new instance of the <see cref="CompositeSolver"/> class with the default iterator.
@ -364,16 +362,16 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
/// Initializes a new instance of the <see cref="CompositeSolver"/> class with the specified iterator. /// Initializes a new instance of the <see cref="CompositeSolver"/> class with the specified iterator.
/// </summary> /// </summary>
/// <param name="iterator">The iterator that will be used to control the iteration process. </param> /// <param name="iterator">The iterator that will be used to control the iteration process. </param>
public CompositeSolver(IIterator<float> iterator) public CompositeSolver(IIterator iterator)
{ {
_iterator = iterator; _iterator = iterator;
} }
/// <summary> /// <summary>
/// Sets the <see cref="IIterator{T}"/> that will be used to track the iterative process. /// Sets the <see cref="IIterator"/> that will be used to track the iterative process.
/// </summary> /// </summary>
/// <param name="iterator">The iterator.</param> /// <param name="iterator">The iterator.</param>
public void SetIterator(IIterator<float> iterator) public void SetIterator(IIterator iterator)
{ {
_iterator = iterator; _iterator = iterator;
} }
@ -411,14 +409,14 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param> /// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="vector">The solution vector, <c>b</c>.</param> /// <param name="vector">The solution vector, <c>b</c>.</param>
/// <returns>The result vector, <c>x</c>.</returns> /// <returns>The result vector, <c>x</c>.</returns>
public Vector<float> Solve(Matrix<float> matrix, Vector<float> vector) public Vector Solve(Matrix matrix, Vector vector)
{ {
if (vector == null) if (vector == null)
{ {
throw new ArgumentNullException(); throw new ArgumentNullException();
} }
Vector<float> result = new DenseVector(matrix.RowCount); Vector result = new DenseVector(matrix.RowCount);
Solve(matrix, vector, result); Solve(matrix, vector, result);
return result; return result;
} }
@ -430,7 +428,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param> /// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution vector, <c>b</c></param> /// <param name="input">The solution vector, <c>b</c></param>
/// <param name="result">The result vector, <c>x</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 matrix, Vector input, Vector result)
{ {
// If we were stopped before, we are no longer // If we were stopped before, we are no longer
// We're doing this at the start of the method to ensure // We're doing this at the start of the method to ensure
@ -480,8 +478,8 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
// Create a copy of the solution and result vectors so we can use them // Create a copy of the solution and result vectors so we can use them
// later on // later on
var internalInput = input.Clone(); var internalInput = (Vector)input.Clone();
var internalResult = result.Clone(); var internalResult = (Vector)result.Clone();
foreach (var solver in _solvers.TakeWhile(solver => !_hasBeenStopped)) foreach (var solver in _solvers.TakeWhile(solver => !_hasBeenStopped))
{ {
@ -572,7 +570,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param> /// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution matrix, <c>B</c>.</param> /// <param name="input">The solution matrix, <c>B</c>.</param>
/// <returns>The result matrix, <c>X</c>.</returns> /// <returns>The result matrix, <c>X</c>.</returns>
public Matrix<float> Solve(Matrix<float> matrix, Matrix<float> input) public Matrix Solve(Matrix matrix, Matrix input)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -584,7 +582,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
throw new ArgumentNullException("input"); throw new ArgumentNullException("input");
} }
var result = matrix.CreateMatrix(input.RowCount, input.ColumnCount); var result = (Matrix)matrix.CreateMatrix(input.RowCount, input.ColumnCount);
Solve(matrix, input, result); Solve(matrix, input, result);
return result; return result;
} }
@ -596,7 +594,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param> /// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution matrix, <c>B</c>.</param> /// <param name="input">The solution matrix, <c>B</c>.</param>
/// <param name="result">The result matrix, <c>X</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 matrix, Matrix input, Matrix result)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -620,7 +618,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
for (var column = 0; column < input.ColumnCount; column++) for (var column = 0; column < input.ColumnCount; column++)
{ {
var solution = Solve(matrix, input.Column(column)); var solution = Solve(matrix, (Vector)input.Column(column));
foreach (var element in solution.GetIndexedEnumerator()) foreach (var element in solution.GetIndexedEnumerator())
{ {
result.At(element.Key, column, element.Value); result.At(element.Key, column, element.Value);

107
src/Numerics/LinearAlgebra/Single/Solvers/Iterative/GpBiCg.cs

@ -31,9 +31,6 @@
namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
{ {
using System; using System;
using Generic;
using Generic.Solvers;
using Generic.Solvers.Preconditioners;
using Generic.Solvers.Status; using Generic.Solvers.Status;
using Preconditioners; using Preconditioners;
using Properties; using Properties;
@ -65,7 +62,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
/// solver. /// solver.
/// </para> /// </para>
/// </remarks> /// </remarks>
public sealed class GpBiCg : IIterativeSolver<float> public sealed class GpBiCg : IIterativeSolver
{ {
/// <summary> /// <summary>
/// The status used if there is no status, i.e. the solver hasn't run yet and there is no /// The status used if there is no status, i.e. the solver hasn't run yet and there is no
@ -77,12 +74,12 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
/// The preconditioner that will be used. Can be set to <c>null</c>, in which case the default /// The preconditioner that will be used. Can be set to <c>null</c>, in which case the default
/// pre-conditioner will be used. /// pre-conditioner will be used.
/// </summary> /// </summary>
private IPreConditioner<float> _preconditioner; private IPreConditioner _preconditioner;
/// <summary> /// <summary>
/// The iterative process controller. /// The iterative process controller.
/// </summary> /// </summary>
private IIterator<float> _iterator; private IIterator _iterator;
/// <summary> /// <summary>
/// Indicates the number of <c>BiCGStab</c> steps should be taken /// Indicates the number of <c>BiCGStab</c> steps should be taken
@ -105,7 +102,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
/// Initializes a new instance of the <see cref="GpBiCg"/> class. /// Initializes a new instance of the <see cref="GpBiCg"/> class.
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// When using this constructor the solver will use the <see cref="IIterator{T}"/> with /// When using this constructor the solver will use the <see cref="IIterator"/> with
/// the standard settings and a default preconditioner. /// the standard settings and a default preconditioner.
/// </remarks> /// </remarks>
public GpBiCg() : this(null, null) public GpBiCg() : this(null, null)
@ -120,18 +117,18 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
/// When using this constructor the solver will use a default preconditioner. /// When using this constructor the solver will use a default preconditioner.
/// </para> /// </para>
/// <para> /// <para>
/// The main advantages of using a user defined <see cref="IIterator{T}"/> are: /// The main advantages of using a user defined <see cref="IIterator"/> are:
/// <list type="number"> /// <list type="number">
/// <item>It is possible to set the desired convergence limits.</item> /// <item>It is possible to set the desired convergence limits.</item>
/// <item> /// <item>
/// It is possible to check the reason for which the solver finished /// It is possible to check the reason for which the solver finished
/// the iterative procedure by calling the <see cref="IIterator{T}.Status"/> property. /// the iterative procedure by calling the <see cref="IIterator.Status"/> property.
/// </item> /// </item>
/// </list> /// </list>
/// </para> /// </para>
/// </remarks> /// </remarks>
/// <param name="iterator">The <see cref="IIterator{T}"/> that will be used to monitor the iterative process.</param> /// <param name="iterator">The <see cref="IIterator"/> that will be used to monitor the iterative process.</param>
public GpBiCg(IIterator<float> iterator) : this(null, iterator) public GpBiCg(IIterator iterator) : this(null, iterator)
{ {
} }
@ -139,11 +136,11 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
/// Initializes a new instance of the <see cref="GpBiCg"/> class. /// Initializes a new instance of the <see cref="GpBiCg"/> class.
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// When using this constructor the solver will use the <see cref="IIterator{T}"/> with /// When using this constructor the solver will use the <see cref="IIterator"/> with
/// the standard settings. /// the standard settings.
/// </remarks> /// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation.</param> /// <param name="preconditioner">The <see cref="IPreConditioner"/> that will be used to precondition the matrix equation.</param>
public GpBiCg(IPreConditioner<float> preconditioner) : this(preconditioner, null) public GpBiCg(IPreConditioner preconditioner) : this(preconditioner, null)
{ {
} }
@ -152,19 +149,19 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// <para> /// <para>
/// The main advantages of using a user defined <see cref="IIterator{T}"/> are: /// The main advantages of using a user defined <see cref="IIterator"/> are:
/// <list type="number"> /// <list type="number">
/// <item>It is possible to set the desired convergence limits.</item> /// <item>It is possible to set the desired convergence limits.</item>
/// <item> /// <item>
/// It is possible to check the reason for which the solver finished /// It is possible to check the reason for which the solver finished
/// the iterative procedure by calling the <see cref="IIterator{T}.Status"/> property. /// the iterative procedure by calling the <see cref="IIterator.Status"/> property.
/// </item> /// </item>
/// </list> /// </list>
/// </para> /// </para>
/// </remarks> /// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation.</param> /// <param name="preconditioner">The <see cref="IPreConditioner"/> that will be used to precondition the matrix equation.</param>
/// <param name="iterator">The <see cref="IIterator{T}"/> that will be used to monitor the iterative process.</param> /// <param name="iterator">The <see cref="IIterator"/> that will be used to monitor the iterative process.</param>
public GpBiCg(IPreConditioner<float> preconditioner, IIterator<float> iterator) public GpBiCg(IPreConditioner preconditioner, IIterator iterator)
{ {
_iterator = iterator; _iterator = iterator;
_preconditioner = preconditioner; _preconditioner = preconditioner;
@ -215,19 +212,19 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
} }
/// <summary> /// <summary>
/// Sets the <see cref="IPreConditioner{T}"/> that will be used to precondition the iterative process. /// Sets the <see cref="IPreConditioner"/> that will be used to precondition the iterative process.
/// </summary> /// </summary>
/// <param name="preconditioner">The preconditioner.</param> /// <param name="preconditioner">The preconditioner.</param>
public void SetPreconditioner(IPreConditioner<float> preconditioner) public void SetPreconditioner(IPreConditioner preconditioner)
{ {
_preconditioner = preconditioner; _preconditioner = preconditioner;
} }
/// <summary> /// <summary>
/// Sets the <see cref="IIterator{T}"/> that will be used to track the iterative process. /// Sets the <see cref="IIterator"/> that will be used to track the iterative process.
/// </summary> /// </summary>
/// <param name="iterator">The iterator.</param> /// <param name="iterator">The iterator.</param>
public void SetIterator(IIterator<float> iterator) public void SetIterator(IIterator iterator)
{ {
_iterator = iterator; _iterator = iterator;
} }
@ -262,14 +259,14 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param> /// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="vector">The solution vector, <c>b</c>.</param> /// <param name="vector">The solution vector, <c>b</c>.</param>
/// <returns>The result vector, <c>x</c>.</returns> /// <returns>The result vector, <c>x</c>.</returns>
public Vector<float> Solve(Matrix<float> matrix, Vector<float> vector) public Vector Solve(Matrix matrix, Vector vector)
{ {
if (vector == null) if (vector == null)
{ {
throw new ArgumentNullException(); throw new ArgumentNullException();
} }
Vector<float> result = new DenseVector(matrix.RowCount); Vector result = new DenseVector(matrix.RowCount);
Solve(matrix, vector, result); Solve(matrix, vector, result);
return result; return result;
} }
@ -281,7 +278,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param> /// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution vector, <c>b</c></param> /// <param name="input">The solution vector, <c>b</c></param>
/// <param name="result">The result vector, <c>x</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 matrix, Vector input, Vector result)
{ {
// If we were stopped before, we are no longer // If we were stopped before, we are no longer
// We're doing this at the start of the method to ensure // We're doing this at the start of the method to ensure
@ -335,11 +332,11 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
// x_0 is initial guess // x_0 is initial guess
// Take x_0 = 0 // Take x_0 = 0
Vector<float> xtemp = new DenseVector(input.Count); Vector xtemp = new DenseVector(input.Count);
// r_0 = b - Ax_0 // r_0 = b - Ax_0
// This is basically a SAXPY so it could be made a lot faster // This is basically a SAXPY so it could be made a lot faster
Vector<float> residuals = new DenseVector(matrix.RowCount); Vector residuals = new DenseVector(matrix.RowCount);
CalculateTrueResidual(matrix, residuals, xtemp, input); CalculateTrueResidual(matrix, residuals, xtemp, input);
// Define the temporary scalars // Define the temporary scalars
@ -348,26 +345,26 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
// Define the temporary vectors // Define the temporary vectors
// rDash_0 = r_0 // rDash_0 = r_0
Vector<float> rdash = new DenseVector(residuals); Vector rdash = new DenseVector(residuals);
// t_-1 = 0 // t_-1 = 0
Vector<float> t = new DenseVector(residuals.Count); Vector t = new DenseVector(residuals.Count);
Vector<float> t0 = new DenseVector(residuals.Count); Vector t0 = new DenseVector(residuals.Count);
// w_-1 = 0 // w_-1 = 0
Vector<float> w = new DenseVector(residuals.Count); Vector w = new DenseVector(residuals.Count);
// Define the remaining temporary vectors // Define the remaining temporary vectors
Vector<float> c = new DenseVector(residuals.Count); Vector c = new DenseVector(residuals.Count);
Vector<float> p = new DenseVector(residuals.Count); Vector p = new DenseVector(residuals.Count);
Vector<float> s = new DenseVector(residuals.Count); Vector s = new DenseVector(residuals.Count);
Vector<float> u = new DenseVector(residuals.Count); Vector u = new DenseVector(residuals.Count);
Vector<float> y = new DenseVector(residuals.Count); Vector y = new DenseVector(residuals.Count);
Vector<float> z = new DenseVector(residuals.Count); Vector z = new DenseVector(residuals.Count);
Vector<float> temp = new DenseVector(residuals.Count); Vector temp = new DenseVector(residuals.Count);
Vector<float> temp2 = new DenseVector(residuals.Count); Vector temp2 = new DenseVector(residuals.Count);
Vector<float> temp3 = new DenseVector(residuals.Count); Vector temp3 = new DenseVector(residuals.Count);
// for (k = 0, 1, .... ) // for (k = 0, 1, .... )
var iterationNumber = 0; var iterationNumber = 0;
@ -524,13 +521,13 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
} }
/// <summary> /// <summary>
/// Calculates the true residual of the matrix equation Ax = b according to: residual = b - Ax /// Calculates the <c>true</c> residual of the matrix equation Ax = b according to: residual = b - Ax
/// </summary> /// </summary>
/// <param name="matrix">Instance of the <see cref="Matrix{T}"/> A.</param> /// <param name="matrix">Instance of the <see cref="Matrix"/> A.</param>
/// <param name="residual">Residual values in <see cref="Vector{T}"/>.</param> /// <param name="residual">Residual values in <see cref="Vector"/>.</param>
/// <param name="x">Instance of the <see cref="Vector{T}"/> x.</param> /// <param name="x">Instance of the <see cref="Vector"/> x.</param>
/// <param name="b">Instance of the <see cref="Vector{T}"/> b.</param> /// <param name="b">Instance of the <see cref="Vector"/> b.</param>
private static void CalculateTrueResidual(Matrix<float> matrix, Vector<float> residual, Vector<float> x, Vector<float> b) private static void CalculateTrueResidual(Matrix matrix, Vector residual, Vector x, Vector b)
{ {
// -Ax = residual // -Ax = residual
matrix.Multiply(x, residual); matrix.Multiply(x, residual);
@ -544,11 +541,11 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
/// Determine if calculation should continue /// Determine if calculation should continue
/// </summary> /// </summary>
/// <param name="iterationNumber">Number of iterations passed</param> /// <param name="iterationNumber">Number of iterations passed</param>
/// <param name="result">Result <see cref="Vector{T}"/>.</param> /// <param name="result">Result <see cref="Vector"/>.</param>
/// <param name="source">Source <see cref="Vector{T}"/>.</param> /// <param name="source">Source <see cref="Vector"/>.</param>
/// <param name="residuals">Residual <see cref="Vector{T}"/>.</param> /// <param name="residuals">Residual <see cref="Vector"/>.</param>
/// <returns><c>true</c> if continue, otherwise <c>false</c></returns> /// <returns><c>true</c> if continue, otherwise <c>false</c></returns>
private bool ShouldContinue(int iterationNumber, Vector<float> result, Vector<float> source, Vector<float> residuals) private bool ShouldContinue(int iterationNumber, Vector result, Vector source, Vector residuals)
{ {
if (_hasBeenStopped) if (_hasBeenStopped)
{ {
@ -589,7 +586,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param> /// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution matrix, <c>B</c>.</param> /// <param name="input">The solution matrix, <c>B</c>.</param>
/// <returns>The result matrix, <c>X</c>.</returns> /// <returns>The result matrix, <c>X</c>.</returns>
public Matrix<float> Solve(Matrix<float> matrix, Matrix<float> input) public Matrix Solve(Matrix matrix, Matrix input)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -601,7 +598,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
throw new ArgumentNullException("input"); throw new ArgumentNullException("input");
} }
var result = matrix.CreateMatrix(input.RowCount, input.ColumnCount); var result = (Matrix)matrix.CreateMatrix(input.RowCount, input.ColumnCount);
Solve(matrix, input, result); Solve(matrix, input, result);
return result; return result;
} }
@ -613,7 +610,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param> /// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution matrix, <c>B</c>.</param> /// <param name="input">The solution matrix, <c>B</c>.</param>
/// <param name="result">The result matrix, <c>X</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 matrix, Matrix input, Matrix result)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -637,7 +634,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
for (var column = 0; column < input.ColumnCount; column++) for (var column = 0; column < input.ColumnCount; column++)
{ {
var solution = Solve(matrix, input.Column(column)); var solution = Solve(matrix, (Vector)input.Column(column));
foreach (var element in solution.GetIndexedEnumerator()) foreach (var element in solution.GetIndexedEnumerator())
{ {
result.At(element.Key, column, element.Value); result.At(element.Key, column, element.Value);

119
src/Numerics/LinearAlgebra/Single/Solvers/Iterative/MlkBiCgStab.cs

@ -34,10 +34,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using Distributions; using Distributions;
using Generic;
using Generic.Factorization; using Generic.Factorization;
using Generic.Solvers;
using Generic.Solvers.Preconditioners;
using Generic.Solvers.Status; using Generic.Solvers.Status;
using Preconditioners; using Preconditioners;
using Properties; using Properties;
@ -65,7 +62,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
/// solver. /// solver.
/// </para> /// </para>
/// </remarks> /// </remarks>
public sealed class MlkBiCgStab : IIterativeSolver<float> public sealed class MlkBiCgStab : IIterativeSolver
{ {
/// <summary> /// <summary>
/// The default number of starting vectors. /// The default number of starting vectors.
@ -82,17 +79,17 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
/// The preconditioner that will be used. Can be set to <see langword="null" />, in which case the default /// The preconditioner that will be used. Can be set to <see langword="null" />, in which case the default
/// pre-conditioner will be used. /// pre-conditioner will be used.
/// </summary> /// </summary>
private IPreConditioner<float> _preconditioner; private IPreConditioner _preconditioner;
/// <summary> /// <summary>
/// The iterative process controller. /// The iterative process controller.
/// </summary> /// </summary>
private IIterator<float> _iterator; private IIterator _iterator;
/// <summary> /// <summary>
/// The collection of starting vectors which are used as the basis for the Krylov sub-space. /// The collection of starting vectors which are used as the basis for the Krylov sub-space.
/// </summary> /// </summary>
private IList<Vector<float>> _startingVectors; private IList<Vector> _startingVectors;
/// <summary> /// <summary>
/// The number of starting vectors used by the algorithm /// The number of starting vectors used by the algorithm
@ -108,7 +105,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
/// Initializes a new instance of the <see cref="MlkBiCgStab"/> class. /// Initializes a new instance of the <see cref="MlkBiCgStab"/> class.
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// When using this constructor the solver will use the <see cref="IIterator{T}"/> with /// When using this constructor the solver will use the <see cref="IIterator"/> with
/// the standard settings and a default preconditioner. /// the standard settings and a default preconditioner.
/// </remarks> /// </remarks>
public MlkBiCgStab() : this(null, null) public MlkBiCgStab() : this(null, null)
@ -123,18 +120,18 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
/// When using this constructor the solver will use a default preconditioner. /// When using this constructor the solver will use a default preconditioner.
/// </para> /// </para>
/// <para> /// <para>
/// The main advantages of using a user defined <see cref="IIterator{T}"/> are: /// The main advantages of using a user defined <see cref="IIterator"/> are:
/// <list type="number"> /// <list type="number">
/// <item>It is possible to set the desired convergence limits.</item> /// <item>It is possible to set the desired convergence limits.</item>
/// <item> /// <item>
/// It is possible to check the reason for which the solver finished /// It is possible to check the reason for which the solver finished
/// the iterative procedure by calling the <see cref="IIterator{T}.Status"/> property. /// the iterative procedure by calling the <see cref="IIterator.Status"/> property.
/// </item> /// </item>
/// </list> /// </list>
/// </para> /// </para>
/// </remarks> /// </remarks>
/// <param name="iterator">The <see cref="IIterator{T}"/> that will be used to monitor the iterative process.</param> /// <param name="iterator">The <see cref="IIterator"/> that will be used to monitor the iterative process.</param>
public MlkBiCgStab(IIterator<float> iterator) : this(null, iterator) public MlkBiCgStab(IIterator iterator) : this(null, iterator)
{ {
} }
@ -142,11 +139,11 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
/// Initializes a new instance of the <see cref="MlkBiCgStab"/> class. /// Initializes a new instance of the <see cref="MlkBiCgStab"/> class.
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// When using this constructor the solver will use the <see cref="IIterator{T}"/> with /// When using this constructor the solver will use the <see cref="IIterator"/> with
/// the standard settings. /// the standard settings.
/// </remarks> /// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation.</param> /// <param name="preconditioner">The <see cref="IPreConditioner"/> that will be used to precondition the matrix equation.</param>
public MlkBiCgStab(IPreConditioner<float> preconditioner) : this(preconditioner, null) public MlkBiCgStab(IPreConditioner preconditioner) : this(preconditioner, null)
{ {
} }
@ -155,19 +152,19 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// <para> /// <para>
/// The main advantages of using a user defined <see cref="IIterator{T}"/> are: /// The main advantages of using a user defined <see cref="IIterator"/> are:
/// <list type="number"> /// <list type="number">
/// <item>It is possible to set the desired convergence limits.</item> /// <item>It is possible to set the desired convergence limits.</item>
/// <item> /// <item>
/// It is possible to check the reason for which the solver finished /// It is possible to check the reason for which the solver finished
/// the iterative procedure by calling the <see cref="IIterator{T}.Status"/> property. /// the iterative procedure by calling the <see cref="IIterator.Status"/> property.
/// </item> /// </item>
/// </list> /// </list>
/// </para> /// </para>
/// </remarks> /// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation.</param> /// <param name="preconditioner">The <see cref="IPreConditioner"/> that will be used to precondition the matrix equation.</param>
/// <param name="iterator">The <see cref="IIterator{T}"/> that will be used to monitor the iterative process.</param> /// <param name="iterator">The <see cref="IIterator"/> that will be used to monitor the iterative process.</param>
public MlkBiCgStab(IPreConditioner<float> preconditioner, IIterator<float> iterator) public MlkBiCgStab(IPreConditioner preconditioner, IIterator iterator)
{ {
_iterator = iterator; _iterator = iterator;
_preconditioner = preconditioner; _preconditioner = preconditioner;
@ -209,19 +206,19 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
} }
/// <summary> /// <summary>
/// Sets the <see cref="IPreConditioner{T}"/> that will be used to precondition the iterative process. /// Sets the <see cref="IPreConditioner"/> that will be used to precondition the iterative process.
/// </summary> /// </summary>
/// <param name="preconditioner">The preconditioner.</param> /// <param name="preconditioner">The preconditioner.</param>
public void SetPreconditioner(IPreConditioner<float> preconditioner) public void SetPreconditioner(IPreConditioner preconditioner)
{ {
_preconditioner = preconditioner; _preconditioner = preconditioner;
} }
/// <summary> /// <summary>
/// Sets the <see cref="IIterator{T}"/> that will be used to track the iterative process. /// Sets the <see cref="IIterator"/> that will be used to track the iterative process.
/// </summary> /// </summary>
/// <param name="iterator">The iterator.</param> /// <param name="iterator">The iterator.</param>
public void SetIterator(IIterator<float> iterator) public void SetIterator(IIterator iterator)
{ {
_iterator = iterator; _iterator = iterator;
} }
@ -230,7 +227,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
/// Gets or sets a series of orthonormal vectors which will be used as basis for the /// Gets or sets a series of orthonormal vectors which will be used as basis for the
/// Krylov sub-space. /// Krylov sub-space.
/// </summary> /// </summary>
public IList<Vector<float>> StartingVectors public IList<Vector> StartingVectors
{ {
[DebuggerStepThrough] [DebuggerStepThrough]
get get
@ -282,14 +279,14 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param> /// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="vector">The solution vector, <c>b</c>.</param> /// <param name="vector">The solution vector, <c>b</c>.</param>
/// <returns>The result vector, <c>x</c>.</returns> /// <returns>The result vector, <c>x</c>.</returns>
public Vector<float> Solve(Matrix<float> matrix, Vector<float> vector) public Vector Solve(Matrix matrix, Vector vector)
{ {
if (vector == null) if (vector == null)
{ {
throw new ArgumentNullException(); throw new ArgumentNullException();
} }
Vector<float> result = new DenseVector(matrix.RowCount); Vector result = new DenseVector(matrix.RowCount);
Solve(matrix, vector, result); Solve(matrix, vector, result);
return result; return result;
} }
@ -301,7 +298,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param> /// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution vector, <c>b</c></param> /// <param name="input">The solution vector, <c>b</c></param>
/// <param name="result">The result vector, <c>x</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 matrix, Vector input, Vector result)
{ {
// If we were stopped before, we are no longer // If we were stopped before, we are no longer
// We're doing this at the start of the method to ensure // We're doing this at the start of the method to ensure
@ -355,7 +352,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
// Choose an initial guess x_0 // Choose an initial guess x_0
// Take x_0 = 0 // Take x_0 = 0
Vector<float> xtemp = new DenseVector(input.Count); Vector xtemp = new DenseVector(input.Count);
// Choose k vectors q_1, q_2, ..., q_k // Choose k vectors q_1, q_2, ..., q_k
// Build a new set if: // Build a new set if:
@ -384,24 +381,24 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
// r_0 = b - Ax_0 // r_0 = b - Ax_0
// This is basically a SAXPY so it could be made a lot faster // This is basically a SAXPY so it could be made a lot faster
Vector<float> residuals = new DenseVector(matrix.RowCount); Vector residuals = new DenseVector(matrix.RowCount);
CalculateTrueResidual(matrix, residuals, xtemp, input); CalculateTrueResidual(matrix, residuals, xtemp, input);
// Define the temporary scalars // Define the temporary scalars
var c = new float[k]; var c = new float[k];
// Define the temporary vectors // Define the temporary vectors
Vector<float> gtemp = new DenseVector(residuals.Count); Vector gtemp = new DenseVector(residuals.Count);
Vector<float> u = new DenseVector(residuals.Count); Vector u = new DenseVector(residuals.Count);
Vector<float> utemp = new DenseVector(residuals.Count); Vector utemp = new DenseVector(residuals.Count);
Vector<float> temp = new DenseVector(residuals.Count); Vector temp = new DenseVector(residuals.Count);
Vector<float> temp1 = new DenseVector(residuals.Count); Vector temp1 = new DenseVector(residuals.Count);
Vector<float> temp2 = new DenseVector(residuals.Count); Vector temp2 = new DenseVector(residuals.Count);
Vector<float> zd = new DenseVector(residuals.Count); Vector zd = new DenseVector(residuals.Count);
Vector<float> zg = new DenseVector(residuals.Count); Vector zg = new DenseVector(residuals.Count);
Vector<float> zw = new DenseVector(residuals.Count); Vector zw = new DenseVector(residuals.Count);
var d = CreateVectorArray(_startingVectors.Count, residuals.Count); var d = CreateVectorArray(_startingVectors.Count, residuals.Count);
@ -645,7 +642,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
/// the <paramref name="numberOfVariables"/> is smaller than /// the <paramref name="numberOfVariables"/> is smaller than
/// the <paramref name="maximumNumberOfStartingVectors"/>. /// the <paramref name="maximumNumberOfStartingVectors"/>.
/// </returns> /// </returns>
private static IList<Vector<float>> CreateStartingVectors(int maximumNumberOfStartingVectors, int numberOfVariables) private static IList<Vector> CreateStartingVectors(int maximumNumberOfStartingVectors, int numberOfVariables)
{ {
// Create no more starting vectors than the size of the problem - 1 // Create no more starting vectors than the size of the problem - 1
// Get random values and then orthogonalize them with // Get random values and then orthogonalize them with
@ -656,7 +653,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
// mean = 0 and sd = 1 // mean = 0 and sd = 1
var distribution = new Normal(); var distribution = new Normal();
Matrix<float> matrix = new DenseMatrix(numberOfVariables, count); Matrix matrix = new DenseMatrix(numberOfVariables, count);
for (var i = 0; i < matrix.ColumnCount; i++) for (var i = 0; i < matrix.ColumnCount; i++)
{ {
var samples = new float[matrix.RowCount]; var samples = new float[matrix.RowCount];
@ -674,27 +671,27 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
var orthogonalMatrix = gs.Q; var orthogonalMatrix = gs.Q;
// Now transfer this to vectors // Now transfer this to vectors
var result = new List<Vector<float>>(); var result = new List<Vector>();
for (var i = 0; i < orthogonalMatrix.ColumnCount; i++) for (var i = 0; i < orthogonalMatrix.ColumnCount; i++)
{ {
result.Add(orthogonalMatrix.Column(i)); result.Add((Vector)orthogonalMatrix.Column(i));
// Normalize the result vector // Normalize the result vector
result[i].Multiply(1 / (float)result[i].Norm(2), result[i]); result[i].Multiply(1 / result[i].Norm(2), result[i]);
} }
return result; return result;
} }
/// <summary> /// <summary>
/// Create random vecrors array /// Create random vectors array
/// </summary> /// </summary>
/// <param name="arraySize">Number of vectors</param> /// <param name="arraySize">Number of vectors</param>
/// <param name="vectorSize">Size of each vector</param> /// <param name="vectorSize">Size of each vector</param>
/// <returns>Array of random vectors</returns> /// <returns>Array of random vectors</returns>
private static Vector<float>[] CreateVectorArray(int arraySize, int vectorSize) private static Vector[] CreateVectorArray(int arraySize, int vectorSize)
{ {
var result = new Vector<float>[arraySize]; var result = new Vector[arraySize];
for (var i = 0; i < result.Length; i++) for (var i = 0; i < result.Length; i++)
{ {
result[i] = new DenseVector(vectorSize); result[i] = new DenseVector(vectorSize);
@ -704,13 +701,13 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
} }
/// <summary> /// <summary>
/// Calculates the true residual of the matrix equation Ax = b according to: residual = b - Ax /// Calculates the <c>true</c> residual of the matrix equation Ax = b according to: residual = b - Ax
/// </summary> /// </summary>
/// <param name="matrix">Source <see cref="Matrix{T}"/>A.</param> /// <param name="matrix">Source <see cref="Matrix"/>A.</param>
/// <param name="residual">Residual <see cref="Vector{T}"/> data.</param> /// <param name="residual">Residual <see cref="Vector"/> data.</param>
/// <param name="x">x <see cref="Vector{T}"/> data.</param> /// <param name="x">x <see cref="Vector"/> data.</param>
/// <param name="b">b <see cref="Vector{T}"/> data.</param> /// <param name="b">b <see cref="Vector"/> data.</param>
private static void CalculateTrueResidual(Matrix<float> matrix, Vector<float> residual, Vector<float> x, Vector<float> b) private static void CalculateTrueResidual(Matrix matrix, Vector residual, Vector x, Vector b)
{ {
// -Ax = residual // -Ax = residual
matrix.Multiply(x, residual); matrix.Multiply(x, residual);
@ -724,11 +721,11 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
/// Determine if calculation should continue /// Determine if calculation should continue
/// </summary> /// </summary>
/// <param name="iterationNumber">Number of iterations passed</param> /// <param name="iterationNumber">Number of iterations passed</param>
/// <param name="result">Result <see cref="Vector{T}"/>.</param> /// <param name="result">Result <see cref="Vector"/>.</param>
/// <param name="source">Source <see cref="Vector{T}"/>.</param> /// <param name="source">Source <see cref="Vector"/>.</param>
/// <param name="residuals">Residual <see cref="Vector{T}"/>.</param> /// <param name="residuals">Residual <see cref="Vector"/>.</param>
/// <returns><c>true</c> if continue, otherwise <c>false</c></returns> /// <returns><c>true</c> if continue, otherwise <c>false</c></returns>
private bool ShouldContinue(int iterationNumber, Vector<float> result, Vector<float> source, Vector<float> residuals) private bool ShouldContinue(int iterationNumber, Vector result, Vector source, Vector residuals)
{ {
if (_hasBeenStopped) if (_hasBeenStopped)
{ {
@ -752,7 +749,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param> /// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution matrix, <c>B</c>.</param> /// <param name="input">The solution matrix, <c>B</c>.</param>
/// <returns>The result matrix, <c>X</c>.</returns> /// <returns>The result matrix, <c>X</c>.</returns>
public Matrix<float> Solve(Matrix<float> matrix, Matrix<float> input) public Matrix Solve(Matrix matrix, Matrix input)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -764,7 +761,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
throw new ArgumentNullException("input"); throw new ArgumentNullException("input");
} }
var result = matrix.CreateMatrix(input.RowCount, input.ColumnCount); var result = (Matrix)matrix.CreateMatrix(input.RowCount, input.ColumnCount);
Solve(matrix, input, result); Solve(matrix, input, result);
return result; return result;
} }
@ -776,7 +773,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param> /// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution matrix, <c>B</c>.</param> /// <param name="input">The solution matrix, <c>B</c>.</param>
/// <param name="result">The result matrix, <c>X</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 matrix, Matrix input, Matrix result)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -800,7 +797,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
for (var column = 0; column < input.ColumnCount; column++) for (var column = 0; column < input.ColumnCount; column++)
{ {
var solution = Solve(matrix, input.Column(column)); var solution = Solve(matrix, (Vector)input.Column(column));
foreach (var element in solution.GetIndexedEnumerator()) foreach (var element in solution.GetIndexedEnumerator())
{ {
result.At(element.Key, column, element.Value); result.At(element.Key, column, element.Value);

81
src/Numerics/LinearAlgebra/Single/Solvers/Iterative/TFQMR.cs

@ -31,9 +31,6 @@
namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
{ {
using System; using System;
using Generic;
using Generic.Solvers;
using Generic.Solvers.Preconditioners;
using Generic.Solvers.Status; using Generic.Solvers.Status;
using Preconditioners; using Preconditioners;
using Properties; using Properties;
@ -55,7 +52,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
/// solver. /// solver.
/// </para> /// </para>
/// </remarks> /// </remarks>
public sealed class TFQMR : IIterativeSolver<float> public sealed class TFQMR : IIterativeSolver
{ {
/// <summary> /// <summary>
/// The status used if there is no status, i.e. the solver hasn't run yet and there is no /// The status used if there is no status, i.e. the solver hasn't run yet and there is no
@ -67,12 +64,12 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
/// The preconditioner that will be used. Can be set to <see langword="null" />, in which case the default /// The preconditioner that will be used. Can be set to <see langword="null" />, in which case the default
/// pre-conditioner will be used. /// pre-conditioner will be used.
/// </summary> /// </summary>
private IPreConditioner<float> _preconditioner; private IPreConditioner _preconditioner;
/// <summary> /// <summary>
/// The iterative process controller. /// The iterative process controller.
/// </summary> /// </summary>
private IIterator<float> _iterator; private IIterator _iterator;
/// <summary> /// <summary>
/// Indicates if the user has stopped the solver. /// Indicates if the user has stopped the solver.
@ -83,7 +80,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
/// Initializes a new instance of the <see cref="TFQMR"/> class. /// Initializes a new instance of the <see cref="TFQMR"/> class.
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// When using this constructor the solver will use the <see cref="IIterator{T}"/> with /// When using this constructor the solver will use the <see cref="IIterator"/> with
/// the standard settings and a default preconditioner. /// the standard settings and a default preconditioner.
/// </remarks> /// </remarks>
public TFQMR() : this(null, null) public TFQMR() : this(null, null)
@ -98,18 +95,18 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
/// When using this constructor the solver will use a default preconditioner. /// When using this constructor the solver will use a default preconditioner.
/// </para> /// </para>
/// <para> /// <para>
/// The main advantages of using a user defined <see cref="IIterator{T}"/> are: /// The main advantages of using a user defined <see cref="IIterator"/> are:
/// <list type="number"> /// <list type="number">
/// <item>It is possible to set the desired convergence limits.</item> /// <item>It is possible to set the desired convergence limits.</item>
/// <item> /// <item>
/// It is possible to check the reason for which the solver finished /// It is possible to check the reason for which the solver finished
/// the iterative procedure by calling the <see cref="IIterator{T}.Status"/> property. /// the iterative procedure by calling the <see cref="IIterator.Status"/> property.
/// </item> /// </item>
/// </list> /// </list>
/// </para> /// </para>
/// </remarks> /// </remarks>
/// <param name="iterator">The <see cref="IIterator{T}"/> that will be used to monitor the iterative process.</param> /// <param name="iterator">The <see cref="IIterator"/> that will be used to monitor the iterative process.</param>
public TFQMR(IIterator<float> iterator) : this(null, iterator) public TFQMR(IIterator iterator) : this(null, iterator)
{ {
} }
@ -117,11 +114,11 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
/// Initializes a new instance of the <see cref="TFQMR"/> class. /// Initializes a new instance of the <see cref="TFQMR"/> class.
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// When using this constructor the solver will use the <see cref="IIterator{T}"/> with /// When using this constructor the solver will use the <see cref="IIterator"/> with
/// the standard settings. /// the standard settings.
/// </remarks> /// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation.</param> /// <param name="preconditioner">The <see cref="IPreConditioner"/> that will be used to precondition the matrix equation.</param>
public TFQMR(IPreConditioner<float> preconditioner) : this(preconditioner, null) public TFQMR(IPreConditioner preconditioner) : this(preconditioner, null)
{ {
} }
@ -130,38 +127,38 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// <para> /// <para>
/// The main advantages of using a user defined <see cref="IIterator{T}"/> are: /// The main advantages of using a user defined <see cref="IIterator"/> are:
/// <list type="number"> /// <list type="number">
/// <item>It is possible to set the desired convergence limits.</item> /// <item>It is possible to set the desired convergence limits.</item>
/// <item> /// <item>
/// It is possible to check the reason for which the solver finished /// It is possible to check the reason for which the solver finished
/// the iterative procedure by calling the <see cref="IIterator{T}.Status"/> property. /// the iterative procedure by calling the <see cref="IIterator.Status"/> property.
/// </item> /// </item>
/// </list> /// </list>
/// </para> /// </para>
/// </remarks> /// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation.</param> /// <param name="preconditioner">The <see cref="IPreConditioner"/> that will be used to precondition the matrix equation.</param>
/// <param name="iterator">The <see cref="IIterator{T}"/> that will be used to monitor the iterative process.</param> /// <param name="iterator">The <see cref="IIterator"/> that will be used to monitor the iterative process.</param>
public TFQMR(IPreConditioner<float> preconditioner, IIterator<float> iterator) public TFQMR(IPreConditioner preconditioner, IIterator iterator)
{ {
_iterator = iterator; _iterator = iterator;
_preconditioner = preconditioner; _preconditioner = preconditioner;
} }
/// <summary> /// <summary>
/// Sets the <see cref="IPreConditioner{T}"/> that will be used to precondition the iterative process. /// Sets the <see cref="IPreConditioner"/> that will be used to precondition the iterative process.
/// </summary> /// </summary>
/// <param name="preconditioner">The preconditioner.</param> /// <param name="preconditioner">The preconditioner.</param>
public void SetPreconditioner(IPreConditioner<float> preconditioner) public void SetPreconditioner(IPreConditioner preconditioner)
{ {
_preconditioner = preconditioner; _preconditioner = preconditioner;
} }
/// <summary> /// <summary>
/// Sets the <see cref="IIterator{T}"/> that will be used to track the iterative process. /// Sets the <see cref="IIterator"/> that will be used to track the iterative process.
/// </summary> /// </summary>
/// <param name="iterator">The iterator.</param> /// <param name="iterator">The iterator.</param>
public void SetIterator(IIterator<float> iterator) public void SetIterator(IIterator iterator)
{ {
_iterator = iterator; _iterator = iterator;
} }
@ -195,14 +192,14 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param> /// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="vector">The solution vector, <c>b</c>.</param> /// <param name="vector">The solution vector, <c>b</c>.</param>
/// <returns>The result vector, <c>x</c>.</returns> /// <returns>The result vector, <c>x</c>.</returns>
public Vector<float> Solve(Matrix<float> matrix, Vector<float> vector) public Vector Solve(Matrix matrix, Vector vector)
{ {
if (vector == null) if (vector == null)
{ {
throw new ArgumentNullException(); throw new ArgumentNullException();
} }
Vector<float> result = new DenseVector(matrix.RowCount); Vector result = new DenseVector(matrix.RowCount);
Solve(matrix, vector, result); Solve(matrix, vector, result);
return result; return result;
} }
@ -214,7 +211,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param> /// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution vector, <c>b</c></param> /// <param name="input">The solution vector, <c>b</c></param>
/// <param name="result">The result vector, <c>x</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 matrix, Vector input, Vector result)
{ {
// If we were stopped before, we are no longer // If we were stopped before, we are no longer
// We're doing this at the start of the method to ensure // We're doing this at the start of the method to ensure
@ -285,7 +282,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
var temp2 = new DenseVector(input.Count); var temp2 = new DenseVector(input.Count);
// Initialize // Initialize
var startNorm = (float)input.Norm(2); var startNorm = input.Norm(2);
// Define the scalars // Define the scalars
float alpha = 0; float alpha = 0;
@ -351,7 +348,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
yinternal.Add(temp, d); yinternal.Add(temp, d);
// theta = ||pseudoResiduals||_2 / tau // theta = ||pseudoResiduals||_2 / tau
theta = (float)pseudoResiduals.Norm(2) / tau; theta = pseudoResiduals.Norm(2) / tau;
var c = 1 / (float)Math.Sqrt(1 + (theta * theta)); var c = 1 / (float)Math.Sqrt(1 + (theta * theta));
// tau = tau * theta * c // tau = tau * theta * c
@ -426,13 +423,13 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
} }
/// <summary> /// <summary>
/// Calculates the true residual of the matrix equation Ax = b according to: residual = b - Ax /// Calculates the <c>true</c> residual of the matrix equation Ax = b according to: residual = b - Ax
/// </summary> /// </summary>
/// <param name="matrix">Instance of the <see cref="Matrix{T}"/> A.</param> /// <param name="matrix">Instance of the <see cref="Matrix"/> A.</param>
/// <param name="residual">Residual values in <see cref="Vector{T}"/>.</param> /// <param name="residual">Residual values in <see cref="Vector"/>.</param>
/// <param name="x">Instance of the <see cref="Vector{T}"/> x.</param> /// <param name="x">Instance of the <see cref="Vector"/> x.</param>
/// <param name="b">Instance of the <see cref="Vector{T}"/> b.</param> /// <param name="b">Instance of the <see cref="Vector"/> b.</param>
private static void CalculateTrueResidual(Matrix<float> matrix, Vector<float> residual, Vector<float> x, Vector<float> b) private static void CalculateTrueResidual(Matrix matrix, Vector residual, Vector x, Vector b)
{ {
// -Ax = residual // -Ax = residual
matrix.Multiply(x, residual); matrix.Multiply(x, residual);
@ -446,11 +443,11 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
/// Determine if calculation should continue /// Determine if calculation should continue
/// </summary> /// </summary>
/// <param name="iterationNumber">Number of iterations passed</param> /// <param name="iterationNumber">Number of iterations passed</param>
/// <param name="result">Result <see cref="Vector{T}"/>.</param> /// <param name="result">Result <see cref="Vector"/>.</param>
/// <param name="source">Source <see cref="Vector{T}"/>.</param> /// <param name="source">Source <see cref="Vector"/>.</param>
/// <param name="residuals">Residual <see cref="Vector{T}"/>.</param> /// <param name="residuals">Residual <see cref="Vector"/>.</param>
/// <returns><c>true</c> if continue, otherwise <c>false</c></returns> /// <returns><c>true</c> if continue, otherwise <c>false</c></returns>
private bool ShouldContinue(int iterationNumber, Vector<float> result, Vector<float> source, Vector<float> residuals) private bool ShouldContinue(int iterationNumber, Vector result, Vector source, Vector residuals)
{ {
if (_hasBeenStopped) if (_hasBeenStopped)
{ {
@ -484,7 +481,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param> /// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution matrix, <c>B</c>.</param> /// <param name="input">The solution matrix, <c>B</c>.</param>
/// <returns>The result matrix, <c>X</c>.</returns> /// <returns>The result matrix, <c>X</c>.</returns>
public Matrix<float> Solve(Matrix<float> matrix, Matrix<float> input) public Matrix Solve(Matrix matrix, Matrix input)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -496,7 +493,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
throw new ArgumentNullException("input"); throw new ArgumentNullException("input");
} }
var result = matrix.CreateMatrix(input.RowCount, input.ColumnCount); var result = (Matrix)matrix.CreateMatrix(input.RowCount, input.ColumnCount);
Solve(matrix, input, result); Solve(matrix, input, result);
return result; return result;
} }
@ -508,7 +505,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param> /// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution matrix, <c>B</c>.</param> /// <param name="input">The solution matrix, <c>B</c>.</param>
/// <param name="result">The result matrix, <c>X</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 matrix, Matrix input, Matrix result)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -532,7 +529,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative
for (var column = 0; column < input.ColumnCount; column++) for (var column = 0; column < input.ColumnCount; column++)
{ {
var solution = Solve(matrix, input.Column(column)); var solution = Solve(matrix, (Vector)input.Column(column));
foreach (var element in solution.GetIndexedEnumerator()) foreach (var element in solution.GetIndexedEnumerator())
{ {
result.At(element.Key, column, element.Value); result.At(element.Key, column, element.Value);

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

@ -33,17 +33,14 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using Generic;
using Generic.Solvers;
using Generic.Solvers.Status; using Generic.Solvers.Status;
using Generic.Solvers.StopCriterium;
using Properties; using Properties;
using StopCriterium; using StopCriterium;
/// <summary> /// <summary>
/// An iterator that is used to check if an iterative calculation should continue or stop. /// An iterator that is used to check if an iterative calculation should continue or stop.
/// </summary> /// </summary>
public sealed class Iterator : IIterator<float> public sealed class Iterator : IIterator
{ {
/// <summary> /// <summary>
/// The default status for the iterator. /// The default status for the iterator.
@ -51,10 +48,10 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
private static readonly ICalculationStatus DefaultStatus = new CalculationIndetermined(); private static readonly ICalculationStatus DefaultStatus = new CalculationIndetermined();
/// <summary> /// <summary>
/// Creates a default iterator with all the <see cref="IIterationStopCriterium{T}"/> objects. /// Creates a default iterator with all the <see cref="IIterationStopCriterium"/> objects.
/// </summary> /// </summary>
/// <returns>A new <see cref="IIterator{T}"/> object.</returns> /// <returns>A new <see cref="IIterator"/> object.</returns>
public static IIterator<float> CreateDefault() public static IIterator CreateDefault()
{ {
var iterator = new Iterator(); var iterator = new Iterator();
iterator.Add(new FailureStopCriterium()); iterator.Add(new FailureStopCriterium());
@ -69,7 +66,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
/// The collection that holds all the stop criteria and the flag indicating if they should be added /// The collection that holds all the stop criteria and the flag indicating if they should be added
/// to the child iterators. /// to the child iterators.
/// </summary> /// </summary>
private readonly Dictionary<Type, IIterationStopCriterium<float>> _stopCriterias = new Dictionary<Type, IIterationStopCriterium<float>>(); private readonly Dictionary<Type, IIterationStopCriterium> _stopCriterias = new Dictionary<Type, IIterationStopCriterium>();
/// <summary> /// <summary>
/// The status of the iterator. /// The status of the iterator.
@ -96,7 +93,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
/// of the stop criteria will be passed on to child iterators. /// of the stop criteria will be passed on to child iterators.
/// </param> /// </param>
/// <exception cref="ArgumentException">Thrown if <paramref name="stopCriteria"/> contains multiple stop criteria of the same type.</exception> /// <exception cref="ArgumentException">Thrown if <paramref name="stopCriteria"/> contains multiple stop criteria of the same type.</exception>
public Iterator(IEnumerable<IIterationStopCriterium<float>> stopCriteria) public Iterator(IEnumerable<IIterationStopCriterium> stopCriteria)
{ {
// Add the stop criteria // Add the stop criteria
if (stopCriteria == null) if (stopCriteria == null)
@ -111,7 +108,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
} }
/// <summary> /// <summary>
/// Adds an <see cref="IIterationStopCriterium{T}"/> to the internal collection of stop-criteria. Only a /// Adds an <see cref="IIterationStopCriterium"/> to the internal collection of stop-criteria. Only a
/// single stop criterium of each type can be stored. /// single stop criterium of each type can be stored.
/// </summary> /// </summary>
/// <param name="stopCriterium">The stop criterium to add.</param> /// <param name="stopCriterium">The stop criterium to add.</param>
@ -120,7 +117,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
/// Thrown if <paramref name="stopCriterium"/> is of the same type as an already /// Thrown if <paramref name="stopCriterium"/> is of the same type as an already
/// stored criterium. /// stored criterium.
/// </exception> /// </exception>
public void Add(IIterationStopCriterium<float> stopCriterium) public void Add(IIterationStopCriterium stopCriterium)
{ {
if (stopCriterium == null) if (stopCriterium == null)
{ {
@ -137,10 +134,10 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
} }
/// <summary> /// <summary>
/// Removes the <see cref="IIterationStopCriterium{T}"/> from the internal collection. /// Removes the <see cref="IIterationStopCriterium"/> from the internal collection.
/// </summary> /// </summary>
/// <param name="stopCriterium">The stop criterium that must be removed.</param> /// <param name="stopCriterium">The stop criterium that must be removed.</param>
public void Remove(IIterationStopCriterium<float> stopCriterium) public void Remove(IIterationStopCriterium stopCriterium)
{ {
if (stopCriterium == null) if (stopCriterium == null)
{ {
@ -157,11 +154,11 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
} }
/// <summary> /// <summary>
/// Indicates if the specific stop criterium is stored by the <see cref="IIterator{T}"/>. /// Indicates if the specific stop criterium is stored by the <see cref="IIterator"/>.
/// </summary> /// </summary>
/// <param name="stopCriterium">The stop criterium.</param> /// <param name="stopCriterium">The stop criterium.</param>
/// <returns><c>true</c> if the <see cref="IIterator{T}"/> contains the stop criterium; otherwise <c>false</c>.</returns> /// <returns><c>true</c> if the <see cref="IIterator"/> contains the stop criterium; otherwise <c>false</c>.</returns>
public bool Contains(IIterationStopCriterium<float> stopCriterium) public bool Contains(IIterationStopCriterium stopCriterium)
{ {
return stopCriterium != null && _stopCriterias.ContainsKey(stopCriterium.GetType()); return stopCriterium != null && _stopCriterias.ContainsKey(stopCriterium.GetType());
} }
@ -182,7 +179,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
/// Gets an <c>IEnumerator</c> that enumerates over all the stored stop criteria. /// Gets an <c>IEnumerator</c> that enumerates over all the stored stop criteria.
/// </summary> /// </summary>
/// <remarks>Used for testing only.</remarks> /// <remarks>Used for testing only.</remarks>
internal IEnumerator<IIterationStopCriterium<float>> StoredStopCriteria internal IEnumerator<IIterationStopCriterium> StoredStopCriteria
{ {
get get
{ {
@ -204,7 +201,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
/// <summary> /// <summary>
/// Determines the status of the iterative calculation based on the stop criteria stored /// Determines the status of the iterative calculation based on the stop criteria stored
/// by the current <see cref="IIterator{T}"/>. Result is set into <c>Status</c> field. /// by the current <see cref="IIterator"/>. Result is set into <c>Status</c> field.
/// </summary> /// </summary>
/// <param name="iterationNumber">The number of iterations that have passed so far.</param> /// <param name="iterationNumber">The number of iterations that have passed so far.</param>
/// <param name="solutionVector">The vector containing the current solution values.</param> /// <param name="solutionVector">The vector containing the current solution values.</param>
@ -215,7 +212,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
/// on the invocation of this method. Therefore this method should only be called if the /// on the invocation of this method. Therefore this method should only be called if the
/// calculation has moved forwards at least one step. /// calculation has moved forwards at least one step.
/// </remarks> /// </remarks>
public void DetermineStatus(int iterationNumber, Vector<float> solutionVector, Vector<float> sourceVector, Vector<float> residualVector) public void DetermineStatus(int iterationNumber, Vector solutionVector, Vector sourceVector, Vector residualVector)
{ {
if (_stopCriterias.Count == 0) if (_stopCriterias.Count == 0)
{ {
@ -287,7 +284,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
} }
/// <summary> /// <summary>
/// Resets the <see cref="IIterator{T}"/> to the pre-calculation state. /// Resets the <see cref="IIterator"/> to the pre-calculation state.
/// </summary> /// </summary>
public void ResetToPrecalculationState() public void ResetToPrecalculationState()
{ {
@ -308,9 +305,9 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers
/// Creates a deep clone of the current iterator. /// Creates a deep clone of the current iterator.
/// </summary> /// </summary>
/// <returns>The deep clone of the current iterator.</returns> /// <returns>The deep clone of the current iterator.</returns>
public IIterator<float> Clone() public IIterator Clone()
{ {
var stopCriteria = _stopCriterias.Select(pair => pair.Value).Select(stopCriterium => (IIterationStopCriterium<float>)stopCriterium.Clone()).ToList(); var stopCriteria = _stopCriterias.Select(pair => pair.Value).Select(stopCriterium => (IIterationStopCriterium)stopCriterium.Clone()).ToList();
return new Iterator(stopCriteria); return new Iterator(stopCriteria);
} }

14
src/Numerics/LinearAlgebra/Single/Solvers/Preconditioners/Diagonal.cs

@ -31,15 +31,13 @@
namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Preconditioners namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Preconditioners
{ {
using System; using System;
using Generic;
using Generic.Solvers.Preconditioners;
using Properties; using Properties;
/// <summary> /// <summary>
/// A diagonal preconditioner. The preconditioner uses the inverse /// A diagonal preconditioner. The preconditioner uses the inverse
/// of the matrix diagonal as preconditioning values. /// of the matrix diagonal as preconditioning values.
/// </summary> /// </summary>
public sealed class Diagonal : IPreConditioner<float> public sealed class Diagonal : IPreConditioner
{ {
/// <summary> /// <summary>
/// The inverse of the matrix diagonal. /// The inverse of the matrix diagonal.
@ -65,10 +63,10 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Preconditioners
/// Initializes the preconditioner and loads the internal data structures. /// Initializes the preconditioner and loads the internal data structures.
/// </summary> /// </summary>
/// <param name="matrix"> /// <param name="matrix">
/// The <see cref="Matrix{T}"/> upon which this preconditioner is based.</param> /// The <see cref="Matrix"/> upon which this preconditioner is based.</param>
/// <exception cref="ArgumentNullException">If <paramref name="matrix"/> is <see langword="null" />. </exception> /// <exception cref="ArgumentNullException">If <paramref name="matrix"/> is <see langword="null" />. </exception>
/// <exception cref="ArgumentException">If <paramref name="matrix"/> is not a square matrix.</exception> /// <exception cref="ArgumentException">If <paramref name="matrix"/> is not a square matrix.</exception>
public void Initialize(Matrix<float> matrix) public void Initialize(Matrix matrix)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -92,7 +90,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Preconditioners
/// </summary> /// </summary>
/// <param name="rhs">The right hand side vector.</param> /// <param name="rhs">The right hand side vector.</param>
/// <returns>The left hand side vector.</returns> /// <returns>The left hand side vector.</returns>
public Vector<float> Approximate(Vector<float> rhs) public Vector Approximate(Vector rhs)
{ {
if (rhs == null) if (rhs == null)
{ {
@ -109,7 +107,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Preconditioners
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "rhs"); throw new ArgumentException(Resources.ArgumentVectorsSameLength, "rhs");
} }
Vector<float> result = new DenseVector(rhs.Count); Vector result = new DenseVector(rhs.Count);
Approximate(rhs, result); Approximate(rhs, result);
return result; return result;
} }
@ -119,7 +117,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Preconditioners
/// </summary> /// </summary>
/// <param name="rhs">The right hand side vector.</param> /// <param name="rhs">The right hand side vector.</param>
/// <param name="lhs">The left hand side vector. Also known as the result vector.</param> /// <param name="lhs">The left hand side vector. Also known as the result vector.</param>
public void Approximate(Vector<float> rhs, Vector<float> lhs) public void Approximate(Vector rhs, Vector lhs)
{ {
if (rhs == null) if (rhs == null)
{ {

73
src/Numerics/LinearAlgebra/Single/Solvers/Preconditioners/IPreConditioner.cs

@ -0,0 +1,73 @@
// <copyright file="IPreConditioner.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
//
// Copyright (c) 2009-2010 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Preconditioners
{
/// <summary>
/// The base interface for preconditioner classes.
/// </summary>
/// <remarks>
/// <para>
/// Preconditioners are used by iterative solvers to improve the convergence
/// speed of the solving process. Increase in convergence speed
/// is related to the number of iterations necessary to get a converged solution.
/// So while in general the use of a preconditioner means that the iterative
/// solver will perform fewer iterations it does not guarantee that the actual
/// solution time decreases given that some preconditioners can be expensive to
/// setup and run.
/// </para>
/// <para>
/// Note that in general changes to the matrix will invalidate the preconditioner
/// if the changes occur after creating the preconditioner.
/// </para>
/// </remarks>
public interface IPreConditioner
{
/// <summary>
/// Initializes the preconditioner and loads the internal data structures.
/// </summary>
/// <param name="matrix">The matrix on which the preconditioner is based.</param>
void Initialize(Matrix matrix);
/// <summary>
/// Approximates the solution to the matrix equation <b>Mx = b</b>.
/// </summary>
/// <param name="rhs">The right hand side vector.</param>
/// <returns>The left hand side vector.</returns>
Vector Approximate(Vector rhs);
/// <summary>
/// Approximates the solution to the matrix equation <b>Mx = b</b>.
/// </summary>
/// <param name="rhs">The right hand side vector.</param>
/// <param name="lhs">The left hand side vector. Also known as the result vector.</param>
void Approximate(Vector rhs, Vector lhs);
}
}

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

@ -32,8 +32,6 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Preconditioners
{ {
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Generic;
using Generic.Solvers.Preconditioners;
using Properties; using Properties;
/// <summary> /// <summary>
@ -53,7 +51,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Preconditioners
/// pp. 20 - 28 <br/> /// pp. 20 - 28 <br/>
/// Algorithm is described in Section 2, page 22 /// Algorithm is described in Section 2, page 22
/// </remarks> /// </remarks>
public sealed class Ilutp : IPreConditioner<float> public sealed class Ilutp : IPreConditioner
{ {
/// <summary> /// <summary>
/// The default fill level. /// The default fill level.
@ -257,9 +255,9 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Preconditioners
/// This method is used for debugging purposes only and should normally not be used. /// This method is used for debugging purposes only and should normally not be used.
/// </remarks> /// </remarks>
/// <returns>A new matrix containing the upper triagonal elements.</returns> /// <returns>A new matrix containing the upper triagonal elements.</returns>
internal Matrix<float> UpperTriangle() internal Matrix UpperTriangle()
{ {
return _upper.Clone(); return (Matrix)_upper.Clone();
} }
/// <summary> /// <summary>
@ -269,9 +267,9 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Preconditioners
/// This method is used for debugging purposes only and should normally not be used. /// This method is used for debugging purposes only and should normally not be used.
/// </remarks> /// </remarks>
/// <returns>A new matrix containing the lower triagonal elements.</returns> /// <returns>A new matrix containing the lower triagonal elements.</returns>
internal Matrix<float> LowerTriangle() internal Matrix LowerTriangle()
{ {
return _lower.Clone(); return (Matrix)_lower.Clone();
} }
/// <summary> /// <summary>
@ -297,13 +295,13 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Preconditioners
/// Initializes the preconditioner and loads the internal data structures. /// Initializes the preconditioner and loads the internal data structures.
/// </summary> /// </summary>
/// <param name="matrix"> /// <param name="matrix">
/// The <see cref="Matrix{T}"/> upon which this preconditioner is based. Note that the /// The <see cref="Matrix"/> upon which this preconditioner is based. Note that the
/// method takes a general matrix type. However internally the data is stored /// method takes a general matrix type. However internally the data is stored
/// as a sparse matrix. Therefore it is not recommended to pass a dense matrix. /// as a sparse matrix. Therefore it is not recommended to pass a dense matrix.
/// </param> /// </param>
/// <exception cref="ArgumentNullException"> If <paramref name="matrix"/> is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException"> If <paramref name="matrix"/> is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If <paramref name="matrix"/> is not a square matrix.</exception> /// <exception cref="ArgumentException">If <paramref name="matrix"/> is not a square matrix.</exception>
public void Initialize(Matrix<float> matrix) public void Initialize(Matrix matrix)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -375,8 +373,8 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Preconditioners
_pivots[i] = i; _pivots[i] = i;
} }
Vector<float> workVector = new DenseVector(sparseMatrix.RowCount); Vector workVector = new DenseVector(sparseMatrix.RowCount);
Vector<float> rowVector = new DenseVector(sparseMatrix.ColumnCount); Vector rowVector = new DenseVector(sparseMatrix.ColumnCount);
var indexSorting = new int[sparseMatrix.RowCount]; var indexSorting = new int[sparseMatrix.RowCount];
// spaceLeft = lfilNnz * nnz(A) // spaceLeft = lfilNnz * nnz(A)
@ -531,8 +529,8 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Preconditioners
/// <summary> /// <summary>
/// Pivot elements in the <paramref name="row"/> according to internal pivot array /// Pivot elements in the <paramref name="row"/> according to internal pivot array
/// </summary> /// </summary>
/// <param name="row">Row <see cref="Vector{T}"/> to pivot in</param> /// <param name="row">Row <see cref="Vector"/> to pivot in</param>
private void PivotRow(Vector<float> row) private void PivotRow(Vector row)
{ {
var knownPivots = new Dictionary<int, int>(); var knownPivots = new Dictionary<int, int>();
@ -579,12 +577,12 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Preconditioners
} }
/// <summary> /// <summary>
/// Swap columns in the <see cref="Matrix{T}"/> /// Swap columns in the <see cref="Matrix"/>
/// </summary> /// </summary>
/// <param name="matrix">Source <see cref="Matrix{T}"/>.</param> /// <param name="matrix">Source <see cref="Matrix"/>.</param>
/// <param name="firstColumn">First column index to swap</param> /// <param name="firstColumn">First column index to swap</param>
/// <param name="secondColumn">Second column index to swap</param> /// <param name="secondColumn">Second column index to swap</param>
private static void SwapColumns(Matrix<float> matrix, int firstColumn, int secondColumn) private static void SwapColumns(Matrix matrix, int firstColumn, int secondColumn)
{ {
for (var i = 0; i < matrix.RowCount; i++) for (var i = 0; i < matrix.RowCount; i++)
{ {
@ -600,8 +598,8 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Preconditioners
/// <param name="lowerBound">Start sort form</param> /// <param name="lowerBound">Start sort form</param>
/// <param name="upperBound">Sort till upper bound</param> /// <param name="upperBound">Sort till upper bound</param>
/// <param name="sortedIndices">Array with sorted vector indicies</param> /// <param name="sortedIndices">Array with sorted vector indicies</param>
/// <param name="values">Source <see cref="Vector{T}"/></param> /// <param name="values">Source <see cref="Vector"/></param>
private static void FindLargestItems(int lowerBound, int upperBound, int[] sortedIndices, Vector<float> values) private static void FindLargestItems(int lowerBound, int upperBound, int[] sortedIndices, Vector values)
{ {
// Copy the indices for the values into the array // Copy the indices for the values into the array
for (var i = 0; i < upperBound + 1 - lowerBound; i++) for (var i = 0; i < upperBound + 1 - lowerBound; i++)
@ -626,7 +624,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Preconditioners
/// </summary> /// </summary>
/// <param name="rhs">The right hand side vector.</param> /// <param name="rhs">The right hand side vector.</param>
/// <returns>The left hand side vector.</returns> /// <returns>The left hand side vector.</returns>
public Vector<float> Approximate(Vector<float> rhs) public Vector Approximate(Vector rhs)
{ {
if (rhs == null) if (rhs == null)
{ {
@ -643,7 +641,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Preconditioners
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "rhs"); throw new ArgumentException(Resources.ArgumentVectorsSameLength, "rhs");
} }
Vector<float> result = new DenseVector(rhs.Count); Vector result = new DenseVector(rhs.Count);
Approximate(rhs, result); Approximate(rhs, result);
return result; return result;
} }
@ -653,7 +651,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Preconditioners
/// </summary> /// </summary>
/// <param name="rhs">The right hand side vector.</param> /// <param name="rhs">The right hand side vector.</param>
/// <param name="lhs">The left hand side vector. Also known as the result vector.</param> /// <param name="lhs">The left hand side vector. Also known as the result vector.</param>
public void Approximate(Vector<float> rhs, Vector<float> lhs) public void Approximate(Vector rhs, Vector lhs)
{ {
if (rhs == null) if (rhs == null)
{ {
@ -678,7 +676,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Preconditioners
// Solve equation here // Solve equation here
// Pivot(vector, result); // Pivot(vector, result);
// Solve L*Y = B(piv,:) // Solve L*Y = B(piv,:)
Vector<float> rowValues = new DenseVector(_lower.RowCount); Vector rowValues = new DenseVector(_lower.RowCount);
for (var i = 0; i < _lower.RowCount; i++) for (var i = 0; i < _lower.RowCount; i++)
{ {
_lower.Row(i, rowValues); _lower.Row(i, rowValues);
@ -708,17 +706,17 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Preconditioners
// We have a column pivot so we only need to pivot the // We have a column pivot so we only need to pivot the
// end result not the incoming right hand side vector // end result not the incoming right hand side vector
var temp = lhs.Clone(); var temp = (Vector)lhs.Clone();
Pivot(temp, lhs); Pivot(temp, lhs);
} }
/// <summary> /// <summary>
/// Pivot elements in <see cref="Vector{T}"/> accoring to internal pivot array /// Pivot elements in <see cref="Vector"/> according to internal pivot array
/// </summary> /// </summary>
/// <param name="vector">Source <see cref="Vector{T}"/>.</param> /// <param name="vector">Source <see cref="Vector"/>.</param>
/// <param name="result">Result <see cref="Vector{T}"/> after pivoting.</param> /// <param name="result">Result <see cref="Vector"/> after pivoting.</param>
private void Pivot(Vector<float> vector, Vector<float> result) private void Pivot(Vector vector, Vector result)
{ {
for (var i = 0; i < _pivots.Length; i++) for (var i = 0; i < _pivots.Length; i++)
{ {

36
src/Numerics/LinearAlgebra/Single/Solvers/Preconditioners/IlutpElementSorter.cs

@ -30,8 +30,6 @@
namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Preconditioners namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Preconditioners
{ {
using Generic;
/// <summary> /// <summary>
/// An element sort algorithm for the <see cref="Ilutp"/> class. /// An element sort algorithm for the <see cref="Ilutp"/> class.
/// </summary> /// </summary>
@ -48,8 +46,8 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Preconditioners
/// <param name="lowerBound">The starting index.</param> /// <param name="lowerBound">The starting index.</param>
/// <param name="upperBound">The stopping index.</param> /// <param name="upperBound">The stopping index.</param>
/// <param name="sortedIndices">An array that will contain the sorted indices once the algorithm finishes.</param> /// <param name="sortedIndices">An array that will contain the sorted indices once the algorithm finishes.</param>
/// <param name="values">The <see cref="Vector{T}"/> that contains the values that need to be sorted.</param> /// <param name="values">The <see cref="Vector"/> that contains the values that need to be sorted.</param>
public static void SortDoubleIndicesDecreasing(int lowerBound, int upperBound, int[] sortedIndices, Vector<float> values) public static void SortDoubleIndicesDecreasing(int lowerBound, int upperBound, int[] sortedIndices, Vector values)
{ {
// Move all the indices that we're interested in to the beginning of the // Move all the indices that we're interested in to the beginning of the
// array. Ignore the rest of the indices. // array. Ignore the rest of the indices.
@ -74,8 +72,8 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Preconditioners
/// <param name="lowerBound">The starting index.</param> /// <param name="lowerBound">The starting index.</param>
/// <param name="upperBound">The stopping index.</param> /// <param name="upperBound">The stopping index.</param>
/// <param name="sortedIndices">An array that will contain the sorted indices once the algorithm finishes.</param> /// <param name="sortedIndices">An array that will contain the sorted indices once the algorithm finishes.</param>
/// <param name="values">The <see cref="Vector{T}"/> that contains the values that need to be sorted.</param> /// <param name="values">The <see cref="Vector"/> that contains the values that need to be sorted.</param>
private static void HeapSortDoublesIndices(int lowerBound, int upperBound, int[] sortedIndices, Vector<float> values) private static void HeapSortDoublesIndices(int lowerBound, int upperBound, int[] sortedIndices, Vector values)
{ {
var start = ((upperBound - lowerBound + 1) / 2) - 1 + lowerBound; var start = ((upperBound - lowerBound + 1) / 2) - 1 + lowerBound;
var end = (upperBound - lowerBound + 1) - 1 + lowerBound; var end = (upperBound - lowerBound + 1) - 1 + lowerBound;
@ -94,10 +92,10 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Preconditioners
/// Build heap for double indicies /// Build heap for double indicies
/// </summary> /// </summary>
/// <param name="start">Root position</param> /// <param name="start">Root position</param>
/// <param name="count">Lenght of <paramref name="values"/></param> /// <param name="count">Length of <paramref name="values"/></param>
/// <param name="sortedIndices">Indicies of <paramref name="values"/></param> /// <param name="sortedIndices">Indicies of <paramref name="values"/></param>
/// <param name="values">Target <see cref="Vector{T}"/></param> /// <param name="values">Target <see cref="Vector"/></param>
private static void BuildDoubleIndexHeap(int start, int count, int[] sortedIndices, Vector<float> values) private static void BuildDoubleIndexHeap(int start, int count, int[] sortedIndices, Vector values)
{ {
while (start >= 0) while (start >= 0)
{ {
@ -110,17 +108,16 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Preconditioners
/// Sift double indicies /// Sift double indicies
/// </summary> /// </summary>
/// <param name="sortedIndices">Indicies of <paramref name="values"/></param> /// <param name="sortedIndices">Indicies of <paramref name="values"/></param>
/// <param name="values">Target <see cref="Vector{T}"/></param> /// <param name="values">Target <see cref="Vector"/></param>
/// <param name="begin">Root position</param> /// <param name="begin">Root position</param>
/// <param name="count">Lenght of <paramref name="values"/></param> /// <param name="count">Length of <paramref name="values"/></param>
private static void SiftDoubleIndices(int[] sortedIndices, Vector<float> values, int begin, int count) private static void SiftDoubleIndices(int[] sortedIndices, Vector values, int begin, int count)
{ {
var root = begin; var root = begin;
int child;
while (root * 2 < count) while (root * 2 < count)
{ {
child = root * 2; var child = root * 2;
if ((child < count - 1) && (values[sortedIndices[child]] > values[sortedIndices[child + 1]])) if ((child < count - 1) && (values[sortedIndices[child]] > values[sortedIndices[child + 1]]))
{ {
child += 1; child += 1;
@ -170,7 +167,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Preconditioners
/// </summary> /// </summary>
/// <param name="values">Target values array</param> /// <param name="values">Target values array</param>
/// <param name="start">Root position</param> /// <param name="start">Root position</param>
/// <param name="count">Lenght of <paramref name="values"/></param> /// <param name="count">Length of <paramref name="values"/></param>
private static void BuildHeap(int[] values, int start, int count) private static void BuildHeap(int[] values, int start, int count)
{ {
while (start >= 0) while (start >= 0)
@ -185,15 +182,14 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Preconditioners
/// </summary> /// </summary>
/// <param name="values">Target value array</param> /// <param name="values">Target value array</param>
/// <param name="start">Root position</param> /// <param name="start">Root position</param>
/// <param name="count">Lenght of <paramref name="values"/></param> /// <param name="count">Length of <paramref name="values"/></param>
private static void Sift(int[] values, int start, int count) private static void Sift(int[] values, int start, int count)
{ {
var root = start; var root = start;
int child;
while (root * 2 < count) while (root * 2 < count)
{ {
child = root * 2; var child = root * 2;
if ((child < count - 1) && (values[child] > values[child + 1])) if ((child < count - 1) && (values[child] > values[child + 1]))
{ {
child += 1; child += 1;
@ -215,8 +211,8 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Preconditioners
/// Exchange values in array /// Exchange values in array
/// </summary> /// </summary>
/// <param name="values">Target values array</param> /// <param name="values">Target values array</param>
/// <param name="first">First value to exchanghe</param> /// <param name="first">First value to exchange</param>
/// <param name="second">Second value to exchanghe</param> /// <param name="second">Second value to exchange</param>
private static void Exchange(int[] values, int first, int second) private static void Exchange(int[] values, int first, int second)
{ {
var t = values[first]; var t = values[first];

18
src/Numerics/LinearAlgebra/Single/Solvers/Preconditioners/IncompleteLU.cs

@ -31,8 +31,6 @@
namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Preconditioners namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Preconditioners
{ {
using System; using System;
using Generic;
using Generic.Solvers.Preconditioners;
using Properties; using Properties;
/// <summary> /// <summary>
@ -44,7 +42,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Preconditioners
/// Yousef Saad <br/> /// Yousef Saad <br/>
/// Algorithm is described in Chapter 10, section 10.3.2, page 275 <br/> /// Algorithm is described in Chapter 10, section 10.3.2, page 275 <br/>
/// </remarks> /// </remarks>
public sealed class IncompleteLU : IPreConditioner<float> public sealed class IncompleteLU : IPreConditioner
{ {
/// <summary> /// <summary>
/// The matrix holding the lower (L) and upper (U) matrices. The /// The matrix holding the lower (L) and upper (U) matrices. The
@ -56,7 +54,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Preconditioners
/// Returns the upper triagonal matrix that was created during the LU decomposition. /// Returns the upper triagonal matrix that was created during the LU decomposition.
/// </summary> /// </summary>
/// <returns>A new matrix containing the upper triagonal elements.</returns> /// <returns>A new matrix containing the upper triagonal elements.</returns>
internal Matrix<float> UpperTriangle() internal Matrix UpperTriangle()
{ {
var result = new SparseMatrix(_decompositionLU.RowCount); var result = new SparseMatrix(_decompositionLU.RowCount);
for (var i = 0; i < _decompositionLU.RowCount; i++) for (var i = 0; i < _decompositionLU.RowCount; i++)
@ -74,7 +72,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Preconditioners
/// Returns the lower triagonal matrix that was created during the LU decomposition. /// Returns the lower triagonal matrix that was created during the LU decomposition.
/// </summary> /// </summary>
/// <returns>A new matrix containing the lower triagonal elements.</returns> /// <returns>A new matrix containing the lower triagonal elements.</returns>
internal Matrix<float> LowerTriangle() internal Matrix LowerTriangle()
{ {
var result = new SparseMatrix(_decompositionLU.RowCount); var result = new SparseMatrix(_decompositionLU.RowCount);
for (var i = 0; i < _decompositionLU.RowCount; i++) for (var i = 0; i < _decompositionLU.RowCount; i++)
@ -101,7 +99,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Preconditioners
/// <param name="matrix">The matrix upon which the preconditioner is based. </param> /// <param name="matrix">The matrix upon which the preconditioner is based. </param>
/// <exception cref="ArgumentNullException">If <paramref name="matrix"/> is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If <paramref name="matrix"/> is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If <paramref name="matrix"/> is not a square matrix.</exception> /// <exception cref="ArgumentException">If <paramref name="matrix"/> is not a square matrix.</exception>
public void Initialize(Matrix<float> matrix) public void Initialize(Matrix matrix)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -163,7 +161,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Preconditioners
/// </summary> /// </summary>
/// <param name="rhs">The right hand side vector.</param> /// <param name="rhs">The right hand side vector.</param>
/// <returns>The left hand side vector.</returns> /// <returns>The left hand side vector.</returns>
public Vector<float> Approximate(Vector<float> rhs) public Vector Approximate(Vector rhs)
{ {
if (rhs == null) if (rhs == null)
{ {
@ -180,7 +178,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Preconditioners
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "rhs"); throw new ArgumentException(Resources.ArgumentVectorsSameLength, "rhs");
} }
Vector<float> result = new DenseVector(rhs.Count); Vector result = new DenseVector(rhs.Count);
Approximate(rhs, result); Approximate(rhs, result);
return result; return result;
} }
@ -190,7 +188,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Preconditioners
/// </summary> /// </summary>
/// <param name="rhs">The right hand side vector.</param> /// <param name="rhs">The right hand side vector.</param>
/// <param name="lhs">The left hand side vector. Also known as the result vector.</param> /// <param name="lhs">The left hand side vector. Also known as the result vector.</param>
public void Approximate(Vector<float> rhs, Vector<float> lhs) public void Approximate(Vector rhs, Vector lhs)
{ {
if (rhs == null) if (rhs == null)
{ {
@ -220,7 +218,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Preconditioners
// z_i = l_ii^-1 * (y_i - SUM_(j<i) l_ij * z_j) // z_i = l_ii^-1 * (y_i - SUM_(j<i) l_ij * z_j)
// } // }
// NOTE: l_ii should be 1 because u_ii has to be the value // NOTE: l_ii should be 1 because u_ii has to be the value
Vector<float> rowValues = new DenseVector(_decompositionLU.RowCount); Vector rowValues = new DenseVector(_decompositionLU.RowCount);
for (var i = 0; i < _decompositionLU.RowCount; i++) for (var i = 0; i < _decompositionLU.RowCount; i++)
{ {
// Clear the rowValues // Clear the rowValues

15
src/Numerics/LinearAlgebra/Single/Solvers/Preconditioners/UnitPreconditioner.cs

@ -31,17 +31,14 @@
namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Preconditioners namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Preconditioners
{ {
using System; using System;
using Generic;
using Generic.Solvers;
using Generic.Solvers.Preconditioners;
using Properties; using Properties;
/// <summary> /// <summary>
/// A unit preconditioner. This preconditioner does not actually do anything /// A unit preconditioner. This preconditioner does not actually do anything
/// it is only used when running an <see cref="IIterativeSolver{T}"/> without /// it is only used when running an <see cref="IIterativeSolver"/> without
/// a preconditioner. /// a preconditioner.
/// </summary> /// </summary>
internal sealed class UnitPreconditioner : IPreConditioner<float> internal sealed class UnitPreconditioner : IPreConditioner
{ {
/// <summary> /// <summary>
/// The coefficient matrix on which this preconditioner operates. /// The coefficient matrix on which this preconditioner operates.
@ -57,7 +54,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Preconditioners
/// </param> /// </param>
/// <exception cref="ArgumentNullException">If <paramref name="matrix"/> is <see langword="null"/>. </exception> /// <exception cref="ArgumentNullException">If <paramref name="matrix"/> is <see langword="null"/>. </exception>
/// <exception cref="ArgumentException">If <paramref name="matrix"/> is not a square matrix.</exception> /// <exception cref="ArgumentException">If <paramref name="matrix"/> is not a square matrix.</exception>
public void Initialize(Matrix<float> matrix) public void Initialize(Matrix matrix)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -90,7 +87,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Preconditioners
/// If the size of <paramref name="rhs"/> is different the number of rows of the coefficient matrix. /// If the size of <paramref name="rhs"/> is different the number of rows of the coefficient matrix.
/// </para> /// </para>
/// </exception> /// </exception>
public void Approximate(Vector<float> rhs, Vector<float> lhs) public void Approximate(Vector rhs, Vector lhs)
{ {
if (rhs == null) if (rhs == null)
{ {
@ -119,7 +116,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Preconditioners
/// <exception cref="ArgumentException"> /// <exception cref="ArgumentException">
/// If the size of <paramref name="rhs"/> is different the number of rows of the coefficient matrix. /// If the size of <paramref name="rhs"/> is different the number of rows of the coefficient matrix.
/// </exception> /// </exception>
public Vector<float> Approximate(Vector<float> rhs) public Vector Approximate(Vector rhs)
{ {
if (rhs == null) if (rhs == null)
{ {
@ -131,7 +128,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Preconditioners
throw new ArgumentException(Resources.ArgumentMatrixDimensions); throw new ArgumentException(Resources.ArgumentMatrixDimensions);
} }
Vector<float> result = new DenseVector(rhs.Count); Vector result = new DenseVector(rhs.Count);
Approximate(rhs, result); Approximate(rhs, result);
return result; return result;
} }

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

@ -32,14 +32,13 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.StopCriterium
{ {
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using Generic;
using Generic.Solvers.Status; using Generic.Solvers.Status;
using Generic.Solvers.StopCriterium; using Generic.Solvers.StopCriterium;
/// <summary> /// <summary>
/// Monitors an iterative calculation for signs of divergence. /// Monitors an iterative calculation for signs of divergence.
/// </summary> /// </summary>
public sealed class DivergenceStopCriterium : IIterationStopCriterium<float> public sealed class DivergenceStopCriterium : IIterationStopCriterium
{ {
/// <summary> /// <summary>
/// Default value for the maximum relative increase that the /// Default value for the maximum relative increase that the
@ -207,7 +206,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.StopCriterium
/// <summary> /// <summary>
/// Determines the status of the iterative calculation based on the stop criteria stored /// Determines the status of the iterative calculation based on the stop criteria stored
/// by the current <see cref="IIterationStopCriterium{T}"/>. Result is set into <c>Status</c> field. /// by the current <see cref="IIterationStopCriterium"/>. Result is set into <c>Status</c> field.
/// </summary> /// </summary>
/// <param name="iterationNumber">The number of iterations that have passed so far.</param> /// <param name="iterationNumber">The number of iterations that have passed so far.</param>
/// <param name="solutionVector">The vector containing the current solution values.</param> /// <param name="solutionVector">The vector containing the current solution values.</param>
@ -218,7 +217,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.StopCriterium
/// on the invocation of this method. Therefore this method should only be called if the /// on the invocation of this method. Therefore this method should only be called if the
/// calculation has moved forwards at least one step. /// calculation has moved forwards at least one step.
/// </remarks> /// </remarks>
public void DetermineStatus(int iterationNumber, Vector<float> solutionVector, Vector<float> sourceVector, Vector<float> residualVector) public void DetermineStatus(int iterationNumber, Vector solutionVector, Vector sourceVector, Vector residualVector)
{ {
if (iterationNumber < 0) if (iterationNumber < 0)
{ {
@ -301,7 +300,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.StopCriterium
} }
/// <summary> /// <summary>
/// Gets required history lenght /// Gets required history Length
/// </summary> /// </summary>
private int RequiredHistoryLength private int RequiredHistoryLength
{ {
@ -347,7 +346,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.StopCriterium
} }
/// <summary> /// <summary>
/// Resets the <see cref="IIterationStopCriterium{T}"/> to the pre-calculation state. /// Resets the <see cref="IIterationStopCriterium"/> to the pre-calculation state.
/// </summary> /// </summary>
public void ResetToPrecalculationState() public void ResetToPrecalculationState()
{ {
@ -358,7 +357,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.StopCriterium
/// <summary> /// <summary>
/// Gets the <see cref="StopLevel"/> which indicates what sort of stop criterium this /// Gets the <see cref="StopLevel"/> which indicates what sort of stop criterium this
/// <see cref="IIterationStopCriterium{T}"/> monitors. /// <see cref="IIterationStopCriterium"/> monitors.
/// </summary> /// </summary>
/// <value>Returns <see cref="Generic.Solvers.StopCriterium.StopLevel.Divergence"/>.</value> /// <value>Returns <see cref="Generic.Solvers.StopCriterium.StopLevel.Divergence"/>.</value>
public StopLevel StopLevel public StopLevel StopLevel
@ -374,7 +373,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.StopCriterium
/// Clones the current <see cref="DivergenceStopCriterium"/> and its settings. /// Clones the current <see cref="DivergenceStopCriterium"/> and its settings.
/// </summary> /// </summary>
/// <returns>A new instance of the <see cref="DivergenceStopCriterium"/> class.</returns> /// <returns>A new instance of the <see cref="DivergenceStopCriterium"/> class.</returns>
public IIterationStopCriterium<float> Clone() public IIterationStopCriterium Clone()
{ {
return new DivergenceStopCriterium(_maximumRelativeIncrease, _minimumNumberOfIterations); return new DivergenceStopCriterium(_maximumRelativeIncrease, _minimumNumberOfIterations);
} }

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

@ -32,15 +32,14 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.StopCriterium
{ {
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using Generic;
using Generic.Solvers.Status; using Generic.Solvers.Status;
using Generic.Solvers.StopCriterium; using Generic.Solvers.StopCriterium;
using Properties; using Properties;
/// <summary> /// <summary>
/// Defines an <see cref="IIterationStopCriterium{T}"/> that monitors residuals for NaN's. /// Defines an <see cref="IIterationStopCriterium"/> that monitors residuals for NaN's.
/// </summary> /// </summary>
public sealed class FailureStopCriterium : IIterationStopCriterium<float> public sealed class FailureStopCriterium : IIterationStopCriterium
{ {
/// <summary> /// <summary>
/// Defines the default last iteration number. Set to -1 because iterations normally /// Defines the default last iteration number. Set to -1 because iterations normally
@ -65,7 +64,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.StopCriterium
/// <summary> /// <summary>
/// Determines the status of the iterative calculation based on the stop criteria stored /// Determines the status of the iterative calculation based on the stop criteria stored
/// by the current <see cref="IIterationStopCriterium{T}"/>. Result is set into <c>Status</c> field. /// by the current <see cref="IIterationStopCriterium"/>. Result is set into <c>Status</c> field.
/// </summary> /// </summary>
/// <param name="iterationNumber">The number of iterations that have passed so far.</param> /// <param name="iterationNumber">The number of iterations that have passed so far.</param>
/// <param name="solutionVector">The vector containing the current solution values.</param> /// <param name="solutionVector">The vector containing the current solution values.</param>
@ -76,7 +75,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.StopCriterium
/// on the invocation of this method. Therefore this method should only be called if the /// on the invocation of this method. Therefore this method should only be called if the
/// calculation has moved forwards at least one step. /// calculation has moved forwards at least one step.
/// </remarks> /// </remarks>
public void DetermineStatus(int iterationNumber, Vector<float> solutionVector, Vector<float> sourceVector, Vector<float> residualVector) public void DetermineStatus(int iterationNumber, Vector solutionVector, Vector sourceVector, Vector residualVector)
{ {
if (iterationNumber < 0) if (iterationNumber < 0)
{ {
@ -156,7 +155,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.StopCriterium
} }
/// <summary> /// <summary>
/// Resets the <see cref="IIterationStopCriterium{T}"/> to the pre-calculation state. /// Resets the <see cref="IIterationStopCriterium"/> to the pre-calculation state.
/// </summary> /// </summary>
public void ResetToPrecalculationState() public void ResetToPrecalculationState()
{ {
@ -166,7 +165,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.StopCriterium
/// <summary> /// <summary>
/// Gets the <see cref="StopLevel"/>which indicates what sort of stop criterium this /// Gets the <see cref="StopLevel"/>which indicates what sort of stop criterium this
/// <see cref="IIterationStopCriterium{T}"/> monitors. /// <see cref="IIterationStopCriterium"/> monitors.
/// </summary> /// </summary>
/// <value>Returns <see cref="CalculationFailure"/>.</value> /// <value>Returns <see cref="CalculationFailure"/>.</value>
public StopLevel StopLevel public StopLevel StopLevel
@ -182,7 +181,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.StopCriterium
/// Clones the current <see cref="FailureStopCriterium"/> and its settings. /// Clones the current <see cref="FailureStopCriterium"/> and its settings.
/// </summary> /// </summary>
/// <returns>A new instance of the <see cref="FailureStopCriterium"/> class.</returns> /// <returns>A new instance of the <see cref="FailureStopCriterium"/> class.</returns>
public IIterationStopCriterium<float> Clone() public IIterationStopCriterium Clone()
{ {
return new FailureStopCriterium(); return new FailureStopCriterium();
} }

80
src/Numerics/LinearAlgebra/Single/Solvers/StopCriterium/IIterationStopCriterium.cs

@ -0,0 +1,80 @@
// <copyright file="IIterationStopCriterium.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
// Copyright (c) 2009-2010 Math.NET
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.StopCriterium
{
using System;
using Generic.Solvers.Status;
using Generic.Solvers.StopCriterium;
/// <summary>
/// The base interface for classes that provide stop criteria for iterative calculations.
/// </summary>
public interface IIterationStopCriterium
#if !SILVERLIGHT
: ICloneable
#endif
{
/// <summary>
/// Determines the status of the iterative calculation based on the stop criteria stored
/// by the current <see cref="IIterationStopCriterium"/>. Status is set to <c>Status</c> field of current object.
/// </summary>
/// <param name="iterationNumber">The number of iterations that have passed so far.</param>
/// <param name="solutionVector">The vector containing the current solution values.</param>
/// <param name="sourceVector">The right hand side vector.</param>
/// <param name="residualVector">The vector containing the current residual vectors.</param>
/// <remarks>
/// The individual stop criteria may internally track the progress of the calculation based
/// on the invocation of this method. Therefore this method should only be called if the
/// calculation has moved forwards at least one step.
/// </remarks>
void DetermineStatus(int iterationNumber, Vector solutionVector, Vector sourceVector, Vector residualVector);
/// <summary>
/// Gets the current calculation status.
/// </summary>
/// <remarks><see langword="null" /> is not a legal value. Status should be set in <see cref="DetermineStatus"/> implementation.</remarks>
ICalculationStatus Status { get; }
/// <summary>
/// Resets the <see cref="IIterationStopCriterium"/> to the pre-calculation state.
/// </summary>
/// <remarks>To implementers: Invoking this method should not clear the user defined
/// property values, only the state that is used to track the progress of the
/// calculation.</remarks>
void ResetToPrecalculationState();
/// <summary>
/// Gets the <see cref="StopLevel"/> which indicates what sort of stop criterium this
/// <see cref="IIterationStopCriterium"/> monitors.
/// </summary>
StopLevel StopLevel { get; }
#if SILVERLIGHT
IIterationStopCriterium Clone();
#endif
}
}

9
src/Numerics/LinearAlgebra/Single/Solvers/StopCriterium/IterationCountStopCriterium.cs

@ -32,15 +32,14 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.StopCriterium
{ {
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using Generic;
using Generic.Solvers.Status; using Generic.Solvers.Status;
using Generic.Solvers.StopCriterium; using Generic.Solvers.StopCriterium;
/// <summary> /// <summary>
/// Defines an <see cref="IIterationStopCriterium{T}"/> that monitors the numbers of iteration /// Defines an <see cref="IIterationStopCriterium"/> that monitors the numbers of iteration
/// steps as stop criterium. /// steps as stop criterium.
/// </summary> /// </summary>
public sealed class IterationCountStopCriterium : IIterationStopCriterium<float> public sealed class IterationCountStopCriterium : IIterationStopCriterium
{ {
/// <summary> /// <summary>
/// The default value for the maximum number of iterations the process is allowed /// The default value for the maximum number of iterations the process is allowed
@ -131,7 +130,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.StopCriterium
/// on the invocation of this method. Therefore this method should only be called if the /// on the invocation of this method. Therefore this method should only be called if the
/// calculation has moved forwards at least one step. /// calculation has moved forwards at least one step.
/// </remarks> /// </remarks>
public void DetermineStatus(int iterationNumber, Vector<float> solutionVector, Vector<float> sourceVector, Vector<float> residualVector) public void DetermineStatus(int iterationNumber, Vector solutionVector, Vector sourceVector, Vector residualVector)
{ {
if (iterationNumber < 0) if (iterationNumber < 0)
{ {
@ -208,7 +207,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.StopCriterium
/// Clones the current <see cref="IterationCountStopCriterium"/> and its settings. /// Clones the current <see cref="IterationCountStopCriterium"/> and its settings.
/// </summary> /// </summary>
/// <returns>A new instance of the <see cref="IterationCountStopCriterium"/> class.</returns> /// <returns>A new instance of the <see cref="IterationCountStopCriterium"/> class.</returns>
public IIterationStopCriterium<float> Clone() public IIterationStopCriterium Clone()
{ {
return new IterationCountStopCriterium(_maximumNumberOfIterations); return new IterationCountStopCriterium(_maximumNumberOfIterations);
} }

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

@ -32,15 +32,14 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.StopCriterium
{ {
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using Generic;
using Generic.Solvers.Status; using Generic.Solvers.Status;
using Generic.Solvers.StopCriterium; using Generic.Solvers.StopCriterium;
using Properties; using Properties;
/// <summary> /// <summary>
/// Defines an <see cref="IIterationStopCriterium{T}"/> that monitors residuals as stop criterium. /// Defines an <see cref="IIterationStopCriterium"/> that monitors residuals as stop criterium.
/// </summary> /// </summary>
public sealed class ResidualStopCriterium : IIterationStopCriterium<float> public sealed class ResidualStopCriterium : IIterationStopCriterium
{ {
/// <summary> /// <summary>
/// The default value for the maximum value of the residual. /// The default value for the maximum value of the residual.
@ -212,7 +211,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.StopCriterium
/// <summary> /// <summary>
/// Determines the status of the iterative calculation based on the stop criteria stored /// Determines the status of the iterative calculation based on the stop criteria stored
/// by the current <see cref="IIterationStopCriterium{T}"/>. Result is set into <c>Status</c> field. /// by the current <see cref="IIterationStopCriterium"/>. Result is set into <c>Status</c> field.
/// </summary> /// </summary>
/// <param name="iterationNumber">The number of iterations that have passed so far.</param> /// <param name="iterationNumber">The number of iterations that have passed so far.</param>
/// <param name="solutionVector">The vector containing the current solution values.</param> /// <param name="solutionVector">The vector containing the current solution values.</param>
@ -223,7 +222,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.StopCriterium
/// on the invocation of this method. Therefore this method should only be called if the /// on the invocation of this method. Therefore this method should only be called if the
/// calculation has moved forwards at least one step. /// calculation has moved forwards at least one step.
/// </remarks> /// </remarks>
public void DetermineStatus(int iterationNumber, Vector<float> solutionVector, Vector<float> sourceVector, Vector<float> residualVector) public void DetermineStatus(int iterationNumber, Vector solutionVector, Vector sourceVector, Vector residualVector)
{ {
if (iterationNumber < 0) if (iterationNumber < 0)
{ {
@ -363,7 +362,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.StopCriterium
} }
/// <summary> /// <summary>
/// Resets the <see cref="IIterationStopCriterium{T}"/> to the pre-calculation state. /// Resets the <see cref="IIterationStopCriterium"/> to the pre-calculation state.
/// </summary> /// </summary>
public void ResetToPrecalculationState() public void ResetToPrecalculationState()
{ {
@ -374,7 +373,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.StopCriterium
/// <summary> /// <summary>
/// Gets the <see cref="StopLevel"/> which indicates what sort of stop criterium this /// Gets the <see cref="StopLevel"/> which indicates what sort of stop criterium this
/// <see cref="IIterationStopCriterium{T}"/> monitors. /// <see cref="IIterationStopCriterium"/> monitors.
/// </summary> /// </summary>
/// <value>Returns <see cref="StopLevel"/>.</value> /// <value>Returns <see cref="StopLevel"/>.</value>
public StopLevel StopLevel public StopLevel StopLevel
@ -390,7 +389,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.StopCriterium
/// Clones the current <see cref="ResidualStopCriterium"/> and its settings. /// Clones the current <see cref="ResidualStopCriterium"/> and its settings.
/// </summary> /// </summary>
/// <returns>A new instance of the <see cref="ResidualStopCriterium"/> class.</returns> /// <returns>A new instance of the <see cref="ResidualStopCriterium"/> class.</returns>
public IIterationStopCriterium<float> Clone() public IIterationStopCriterium Clone()
{ {
return new ResidualStopCriterium(_maximum, _minimumIterationsBelowMaximum); return new ResidualStopCriterium(_maximum, _minimumIterationsBelowMaximum);
} }

25
src/Numerics/Numerics.csproj

@ -172,6 +172,11 @@
<Compile Include="LinearAlgebra\Complex32\Factorization\Svd.cs" /> <Compile Include="LinearAlgebra\Complex32\Factorization\Svd.cs" />
<Compile Include="LinearAlgebra\Complex32\IO\MatlabReader.cs" /> <Compile Include="LinearAlgebra\Complex32\IO\MatlabReader.cs" />
<Compile Include="LinearAlgebra\Complex32\Matrix.cs" /> <Compile Include="LinearAlgebra\Complex32\Matrix.cs" />
<Compile Include="LinearAlgebra\Complex32\Solvers\IIterativeSolver.cs" />
<Compile Include="LinearAlgebra\Complex32\Solvers\IIterativeSolverSetup.cs" />
<Compile Include="LinearAlgebra\Complex32\Solvers\IIterator.cs" />
<Compile Include="LinearAlgebra\Complex32\Solvers\Preconditioners\IPreConditioner.cs" />
<Compile Include="LinearAlgebra\Complex32\Solvers\StopCriterium\IIterationStopCriterium.cs" />
<Compile Include="LinearAlgebra\Complex32\SparseMatrix.cs" /> <Compile Include="LinearAlgebra\Complex32\SparseMatrix.cs" />
<Compile Include="LinearAlgebra\Complex32\Vector.cs" /> <Compile Include="LinearAlgebra\Complex32\Vector.cs" />
<Compile Include="LinearAlgebra\Complex\DenseMatrix.cs" /> <Compile Include="LinearAlgebra\Complex\DenseMatrix.cs" />
@ -187,6 +192,11 @@
<Compile Include="LinearAlgebra\Complex\Factorization\Svd.cs" /> <Compile Include="LinearAlgebra\Complex\Factorization\Svd.cs" />
<Compile Include="LinearAlgebra\Complex\IO\MatlabReader.cs" /> <Compile Include="LinearAlgebra\Complex\IO\MatlabReader.cs" />
<Compile Include="LinearAlgebra\Complex\Matrix.cs" /> <Compile Include="LinearAlgebra\Complex\Matrix.cs" />
<Compile Include="LinearAlgebra\Complex\Solvers\IIterativeSolver.cs" />
<Compile Include="LinearAlgebra\Complex\Solvers\IIterativeSolverSetup.cs" />
<Compile Include="LinearAlgebra\Complex\Solvers\IIterator.cs" />
<Compile Include="LinearAlgebra\Complex\Solvers\Preconditioners\IPreConditioner.cs" />
<Compile Include="LinearAlgebra\Complex\Solvers\StopCriterium\IIterationStopCriterium.cs" />
<Compile Include="LinearAlgebra\Complex\SparseMatrix.cs" /> <Compile Include="LinearAlgebra\Complex\SparseMatrix.cs" />
<Compile Include="LinearAlgebra\Complex\Vector.cs" /> <Compile Include="LinearAlgebra\Complex\Vector.cs" />
<Compile Include="LinearAlgebra\Double\Factorization\Cholesky.cs" /> <Compile Include="LinearAlgebra\Double\Factorization\Cholesky.cs" />
@ -198,6 +208,11 @@
<Compile Include="LinearAlgebra\Double\Factorization\Svd.cs" /> <Compile Include="LinearAlgebra\Double\Factorization\Svd.cs" />
<Compile Include="LinearAlgebra\Double\Factorization\LU.cs" /> <Compile Include="LinearAlgebra\Double\Factorization\LU.cs" />
<Compile Include="LinearAlgebra\Double\Matrix.cs" /> <Compile Include="LinearAlgebra\Double\Matrix.cs" />
<Compile Include="LinearAlgebra\Double\Solvers\IIterativeSolver.cs" />
<Compile Include="LinearAlgebra\Double\Solvers\IIterativeSolverSetup.cs" />
<Compile Include="LinearAlgebra\Double\Solvers\IIterator.cs" />
<Compile Include="LinearAlgebra\Double\Solvers\Preconditioners\IPreConditioner.cs" />
<Compile Include="LinearAlgebra\Double\Solvers\StopCriterium\IIterationStopCriterium.cs" />
<Compile Include="LinearAlgebra\Double\SparseMatrix.cs" /> <Compile Include="LinearAlgebra\Double\SparseMatrix.cs" />
<Compile Include="LinearAlgebra\Double\Vector.cs" /> <Compile Include="LinearAlgebra\Double\Vector.cs" />
<Compile Include="LinearAlgebra\Generic\Common.cs" /> <Compile Include="LinearAlgebra\Generic\Common.cs" />
@ -300,6 +315,9 @@
<Compile Include="LinearAlgebra\Single\IO\DelimitedReader.cs" /> <Compile Include="LinearAlgebra\Single\IO\DelimitedReader.cs" />
<Compile Include="LinearAlgebra\Single\IO\MatlabReader.cs" /> <Compile Include="LinearAlgebra\Single\IO\MatlabReader.cs" />
<Compile Include="LinearAlgebra\Single\Matrix.cs" /> <Compile Include="LinearAlgebra\Single\Matrix.cs" />
<Compile Include="LinearAlgebra\Single\Solvers\IIterativeSolver.cs" />
<Compile Include="LinearAlgebra\Single\Solvers\IIterativeSolverSetup.cs" />
<Compile Include="LinearAlgebra\Single\Solvers\IIterator.cs" />
<Compile Include="LinearAlgebra\Single\Solvers\Iterative\BiCgStab.cs" /> <Compile Include="LinearAlgebra\Single\Solvers\Iterative\BiCgStab.cs" />
<Compile Include="LinearAlgebra\Single\Solvers\Iterative\CompositeSolver.cs" /> <Compile Include="LinearAlgebra\Single\Solvers\Iterative\CompositeSolver.cs" />
<Compile Include="LinearAlgebra\Single\Solvers\Iterative\GpBiCg.cs" /> <Compile Include="LinearAlgebra\Single\Solvers\Iterative\GpBiCg.cs" />
@ -310,9 +328,11 @@
<Compile Include="LinearAlgebra\Single\Solvers\Preconditioners\Ilutp.cs" /> <Compile Include="LinearAlgebra\Single\Solvers\Preconditioners\Ilutp.cs" />
<Compile Include="LinearAlgebra\Single\Solvers\Preconditioners\IlutpElementSorter.cs" /> <Compile Include="LinearAlgebra\Single\Solvers\Preconditioners\IlutpElementSorter.cs" />
<Compile Include="LinearAlgebra\Single\Solvers\Preconditioners\IncompleteLU.cs" /> <Compile Include="LinearAlgebra\Single\Solvers\Preconditioners\IncompleteLU.cs" />
<Compile Include="LinearAlgebra\Single\Solvers\Preconditioners\IPreConditioner.cs" />
<Compile Include="LinearAlgebra\Single\Solvers\Preconditioners\UnitPreconditioner.cs" /> <Compile Include="LinearAlgebra\Single\Solvers\Preconditioners\UnitPreconditioner.cs" />
<Compile Include="LinearAlgebra\Single\Solvers\StopCriterium\DivergenceStopCriterium.cs" /> <Compile Include="LinearAlgebra\Single\Solvers\StopCriterium\DivergenceStopCriterium.cs" />
<Compile Include="LinearAlgebra\Single\Solvers\StopCriterium\FailureStopCriterium.cs" /> <Compile Include="LinearAlgebra\Single\Solvers\StopCriterium\FailureStopCriterium.cs" />
<Compile Include="LinearAlgebra\Single\Solvers\StopCriterium\IIterationStopCriterium.cs" />
<Compile Include="LinearAlgebra\Single\Solvers\StopCriterium\IterationCountStopCriterium.cs" /> <Compile Include="LinearAlgebra\Single\Solvers\StopCriterium\IterationCountStopCriterium.cs" />
<Compile Include="LinearAlgebra\Single\Solvers\StopCriterium\ResidualStopCriterium.cs" /> <Compile Include="LinearAlgebra\Single\Solvers\StopCriterium\ResidualStopCriterium.cs" />
<Compile Include="LinearAlgebra\Single\SparseMatrix.cs" /> <Compile Include="LinearAlgebra\Single\SparseMatrix.cs" />
@ -335,9 +355,6 @@
<Compile Include="LinearAlgebra\IO\Matlab\MatlabFile.cs" /> <Compile Include="LinearAlgebra\IO\Matlab\MatlabFile.cs" />
<Compile Include="LinearAlgebra\IO\Matlab\MatlabParser.cs" /> <Compile Include="LinearAlgebra\IO\Matlab\MatlabParser.cs" />
<Compile Include="LinearAlgebra\Generic\ISolver.cs" /> <Compile Include="LinearAlgebra\Generic\ISolver.cs" />
<Compile Include="LinearAlgebra\Generic\Solvers\IIterativeSolver.cs" />
<Compile Include="LinearAlgebra\Generic\Solvers\IIterativeSolverSetup.cs" />
<Compile Include="LinearAlgebra\Generic\Solvers\IIterator.cs" />
<Compile Include="LinearAlgebra\Double\Solvers\Iterative\BiCgStab.cs" /> <Compile Include="LinearAlgebra\Double\Solvers\Iterative\BiCgStab.cs" />
<Compile Include="LinearAlgebra\Double\Solvers\Iterative\CompositeSolver.cs" /> <Compile Include="LinearAlgebra\Double\Solvers\Iterative\CompositeSolver.cs" />
<Compile Include="LinearAlgebra\Double\Solvers\Iterative\GpBiCg.cs" /> <Compile Include="LinearAlgebra\Double\Solvers\Iterative\GpBiCg.cs" />
@ -350,7 +367,6 @@
<Compile Include="LinearAlgebra\Double\Solvers\Preconditioners\IncompleteLU.cs"> <Compile Include="LinearAlgebra\Double\Solvers\Preconditioners\IncompleteLU.cs">
<SubType>Code</SubType> <SubType>Code</SubType>
</Compile> </Compile>
<Compile Include="LinearAlgebra\Generic\Solvers\Preconditioners\IPreConditioner.cs" />
<Compile Include="LinearAlgebra\Double\Solvers\Preconditioners\UnitPreconditioner.cs" /> <Compile Include="LinearAlgebra\Double\Solvers\Preconditioners\UnitPreconditioner.cs" />
<Compile Include="LinearAlgebra\Generic\Solvers\Status\CalculationCancelled.cs" /> <Compile Include="LinearAlgebra\Generic\Solvers\Status\CalculationCancelled.cs" />
<Compile Include="LinearAlgebra\Generic\Solvers\Status\CalculationConverged.cs" /> <Compile Include="LinearAlgebra\Generic\Solvers\Status\CalculationConverged.cs" />
@ -362,7 +378,6 @@
<Compile Include="LinearAlgebra\Generic\Solvers\Status\ICalculationStatus.cs" /> <Compile Include="LinearAlgebra\Generic\Solvers\Status\ICalculationStatus.cs" />
<Compile Include="LinearAlgebra\Double\Solvers\StopCriterium\DivergenceStopCriterium.cs" /> <Compile Include="LinearAlgebra\Double\Solvers\StopCriterium\DivergenceStopCriterium.cs" />
<Compile Include="LinearAlgebra\Double\Solvers\StopCriterium\FailureStopCriterium.cs" /> <Compile Include="LinearAlgebra\Double\Solvers\StopCriterium\FailureStopCriterium.cs" />
<Compile Include="LinearAlgebra\Generic\Solvers\StopCriterium\IIterationStopCriterium.cs" />
<Compile Include="LinearAlgebra\Double\Solvers\StopCriterium\IterationCountStopCriterium.cs" /> <Compile Include="LinearAlgebra\Double\Solvers\StopCriterium\IterationCountStopCriterium.cs" />
<Compile Include="LinearAlgebra\Double\Solvers\StopCriterium\ResidualStopCriterium.cs" /> <Compile Include="LinearAlgebra\Double\Solvers\StopCriterium\ResidualStopCriterium.cs" />
<Compile Include="LinearAlgebra\Generic\Solvers\StopCriterium\StopLevel.cs" /> <Compile Include="LinearAlgebra\Generic\Solvers\StopCriterium\StopLevel.cs" />

75
src/Silverlight/Silverlight.csproj

@ -348,6 +348,15 @@
<Compile Include="..\Numerics\LinearAlgebra\Complex32\Matrix.cs"> <Compile Include="..\Numerics\LinearAlgebra\Complex32\Matrix.cs">
<Link>LinearAlgebra\Complex32\Matrix.cs</Link> <Link>LinearAlgebra\Complex32\Matrix.cs</Link>
</Compile> </Compile>
<Compile Include="..\Numerics\LinearAlgebra\Complex32\Solvers\IIterativeSolver.cs">
<Link>LinearAlgebra\Complex32\Solvers\IIterativeSolver.cs</Link>
</Compile>
<Compile Include="..\Numerics\LinearAlgebra\Complex32\Solvers\IIterativeSolverSetup.cs">
<Link>LinearAlgebra\Complex32\Solvers\IIterativeSolverSetup.cs</Link>
</Compile>
<Compile Include="..\Numerics\LinearAlgebra\Complex32\Solvers\IIterator.cs">
<Link>LinearAlgebra\Complex32\Solvers\IIterator.cs</Link>
</Compile>
<Compile Include="..\Numerics\LinearAlgebra\Complex32\Solvers\Iterative\BiCgStab.cs"> <Compile Include="..\Numerics\LinearAlgebra\Complex32\Solvers\Iterative\BiCgStab.cs">
<Link>LinearAlgebra\Complex32\Solvers\Iterative\BiCgStab.cs</Link> <Link>LinearAlgebra\Complex32\Solvers\Iterative\BiCgStab.cs</Link>
</Compile> </Compile>
@ -378,6 +387,9 @@
<Compile Include="..\Numerics\LinearAlgebra\Complex32\Solvers\Preconditioners\IncompleteLU.cs"> <Compile Include="..\Numerics\LinearAlgebra\Complex32\Solvers\Preconditioners\IncompleteLU.cs">
<Link>LinearAlgebra\Complex32\Solvers\Preconditioners\IncompleteLU.cs</Link> <Link>LinearAlgebra\Complex32\Solvers\Preconditioners\IncompleteLU.cs</Link>
</Compile> </Compile>
<Compile Include="..\Numerics\LinearAlgebra\Complex32\Solvers\Preconditioners\IPreConditioner.cs">
<Link>LinearAlgebra\Complex32\Solvers\Preconditioners\IPreConditioner.cs</Link>
</Compile>
<Compile Include="..\Numerics\LinearAlgebra\Complex32\Solvers\Preconditioners\UnitPreconditioner.cs"> <Compile Include="..\Numerics\LinearAlgebra\Complex32\Solvers\Preconditioners\UnitPreconditioner.cs">
<Link>LinearAlgebra\Complex32\Solvers\Preconditioners\UnitPreconditioner.cs</Link> <Link>LinearAlgebra\Complex32\Solvers\Preconditioners\UnitPreconditioner.cs</Link>
</Compile> </Compile>
@ -387,6 +399,9 @@
<Compile Include="..\Numerics\LinearAlgebra\Complex32\Solvers\StopCriterium\FailureStopCriterium.cs"> <Compile Include="..\Numerics\LinearAlgebra\Complex32\Solvers\StopCriterium\FailureStopCriterium.cs">
<Link>LinearAlgebra\Complex32\Solvers\StopCriterium\FailureStopCriterium.cs</Link> <Link>LinearAlgebra\Complex32\Solvers\StopCriterium\FailureStopCriterium.cs</Link>
</Compile> </Compile>
<Compile Include="..\Numerics\LinearAlgebra\Complex32\Solvers\StopCriterium\IIterationStopCriterium.cs">
<Link>LinearAlgebra\Complex32\Solvers\StopCriterium\IIterationStopCriterium.cs</Link>
</Compile>
<Compile Include="..\Numerics\LinearAlgebra\Complex32\Solvers\StopCriterium\IterationCountStopCriterium.cs"> <Compile Include="..\Numerics\LinearAlgebra\Complex32\Solvers\StopCriterium\IterationCountStopCriterium.cs">
<Link>LinearAlgebra\Complex32\Solvers\StopCriterium\IterationCountStopCriterium.cs</Link> <Link>LinearAlgebra\Complex32\Solvers\StopCriterium\IterationCountStopCriterium.cs</Link>
</Compile> </Compile>
@ -468,6 +483,15 @@
<Compile Include="..\Numerics\LinearAlgebra\Complex\Matrix.cs"> <Compile Include="..\Numerics\LinearAlgebra\Complex\Matrix.cs">
<Link>LinearAlgebra\Complex\Matrix.cs</Link> <Link>LinearAlgebra\Complex\Matrix.cs</Link>
</Compile> </Compile>
<Compile Include="..\Numerics\LinearAlgebra\Complex\Solvers\IIterativeSolver.cs">
<Link>LinearAlgebra\Complex\Solvers\IIterativeSolver.cs</Link>
</Compile>
<Compile Include="..\Numerics\LinearAlgebra\Complex\Solvers\IIterativeSolverSetup.cs">
<Link>LinearAlgebra\Complex\Solvers\IIterativeSolverSetup.cs</Link>
</Compile>
<Compile Include="..\Numerics\LinearAlgebra\Complex\Solvers\IIterator.cs">
<Link>LinearAlgebra\Complex\Solvers\IIterator.cs</Link>
</Compile>
<Compile Include="..\Numerics\LinearAlgebra\Complex\Solvers\Iterative\BiCgStab.cs"> <Compile Include="..\Numerics\LinearAlgebra\Complex\Solvers\Iterative\BiCgStab.cs">
<Link>LinearAlgebra\Complex\Solvers\Iterative\BiCgStab.cs</Link> <Link>LinearAlgebra\Complex\Solvers\Iterative\BiCgStab.cs</Link>
</Compile> </Compile>
@ -498,6 +522,9 @@
<Compile Include="..\Numerics\LinearAlgebra\Complex\Solvers\Preconditioners\IncompleteLU.cs"> <Compile Include="..\Numerics\LinearAlgebra\Complex\Solvers\Preconditioners\IncompleteLU.cs">
<Link>LinearAlgebra\Complex\Solvers\Preconditioners\IncompleteLU.cs</Link> <Link>LinearAlgebra\Complex\Solvers\Preconditioners\IncompleteLU.cs</Link>
</Compile> </Compile>
<Compile Include="..\Numerics\LinearAlgebra\Complex\Solvers\Preconditioners\IPreConditioner.cs">
<Link>LinearAlgebra\Complex\Solvers\Preconditioners\IPreConditioner.cs</Link>
</Compile>
<Compile Include="..\Numerics\LinearAlgebra\Complex\Solvers\Preconditioners\UnitPreconditioner.cs"> <Compile Include="..\Numerics\LinearAlgebra\Complex\Solvers\Preconditioners\UnitPreconditioner.cs">
<Link>LinearAlgebra\Complex\Solvers\Preconditioners\UnitPreconditioner.cs</Link> <Link>LinearAlgebra\Complex\Solvers\Preconditioners\UnitPreconditioner.cs</Link>
</Compile> </Compile>
@ -507,6 +534,9 @@
<Compile Include="..\Numerics\LinearAlgebra\Complex\Solvers\StopCriterium\FailureStopCriterium.cs"> <Compile Include="..\Numerics\LinearAlgebra\Complex\Solvers\StopCriterium\FailureStopCriterium.cs">
<Link>LinearAlgebra\Complex\Solvers\StopCriterium\FailureStopCriterium.cs</Link> <Link>LinearAlgebra\Complex\Solvers\StopCriterium\FailureStopCriterium.cs</Link>
</Compile> </Compile>
<Compile Include="..\Numerics\LinearAlgebra\Complex\Solvers\StopCriterium\IIterationStopCriterium.cs">
<Link>LinearAlgebra\Complex\Solvers\StopCriterium\IIterationStopCriterium.cs</Link>
</Compile>
<Compile Include="..\Numerics\LinearAlgebra\Complex\Solvers\StopCriterium\IterationCountStopCriterium.cs"> <Compile Include="..\Numerics\LinearAlgebra\Complex\Solvers\StopCriterium\IterationCountStopCriterium.cs">
<Link>LinearAlgebra\Complex\Solvers\StopCriterium\IterationCountStopCriterium.cs</Link> <Link>LinearAlgebra\Complex\Solvers\StopCriterium\IterationCountStopCriterium.cs</Link>
</Compile> </Compile>
@ -588,6 +618,15 @@
<Compile Include="..\Numerics\LinearAlgebra\Double\Matrix.cs"> <Compile Include="..\Numerics\LinearAlgebra\Double\Matrix.cs">
<Link>LinearAlgebra\Double\Matrix.cs</Link> <Link>LinearAlgebra\Double\Matrix.cs</Link>
</Compile> </Compile>
<Compile Include="..\Numerics\LinearAlgebra\Double\Solvers\IIterativeSolver.cs">
<Link>LinearAlgebra\Double\Solvers\IIterativeSolver.cs</Link>
</Compile>
<Compile Include="..\Numerics\LinearAlgebra\Double\Solvers\IIterativeSolverSetup.cs">
<Link>LinearAlgebra\Double\Solvers\IIterativeSolverSetup.cs</Link>
</Compile>
<Compile Include="..\Numerics\LinearAlgebra\Double\Solvers\IIterator.cs">
<Link>LinearAlgebra\Double\Solvers\IIterator.cs</Link>
</Compile>
<Compile Include="..\Numerics\LinearAlgebra\Double\Solvers\Iterative\BiCgStab.cs"> <Compile Include="..\Numerics\LinearAlgebra\Double\Solvers\Iterative\BiCgStab.cs">
<Link>LinearAlgebra\Double\Solvers\Iterative\BiCgStab.cs</Link> <Link>LinearAlgebra\Double\Solvers\Iterative\BiCgStab.cs</Link>
</Compile> </Compile>
@ -618,6 +657,9 @@
<Compile Include="..\Numerics\LinearAlgebra\Double\Solvers\Preconditioners\IncompleteLU.cs"> <Compile Include="..\Numerics\LinearAlgebra\Double\Solvers\Preconditioners\IncompleteLU.cs">
<Link>LinearAlgebra\Double\Solvers\Preconditioners\IncompleteLU.cs</Link> <Link>LinearAlgebra\Double\Solvers\Preconditioners\IncompleteLU.cs</Link>
</Compile> </Compile>
<Compile Include="..\Numerics\LinearAlgebra\Double\Solvers\Preconditioners\IPreConditioner.cs">
<Link>LinearAlgebra\Double\Solvers\Preconditioners\IPreConditioner.cs</Link>
</Compile>
<Compile Include="..\Numerics\LinearAlgebra\Double\Solvers\Preconditioners\UnitPreconditioner.cs"> <Compile Include="..\Numerics\LinearAlgebra\Double\Solvers\Preconditioners\UnitPreconditioner.cs">
<Link>LinearAlgebra\Double\Solvers\Preconditioners\UnitPreconditioner.cs</Link> <Link>LinearAlgebra\Double\Solvers\Preconditioners\UnitPreconditioner.cs</Link>
</Compile> </Compile>
@ -627,6 +669,9 @@
<Compile Include="..\Numerics\LinearAlgebra\Double\Solvers\StopCriterium\FailureStopCriterium.cs"> <Compile Include="..\Numerics\LinearAlgebra\Double\Solvers\StopCriterium\FailureStopCriterium.cs">
<Link>LinearAlgebra\Double\Solvers\StopCriterium\FailureStopCriterium.cs</Link> <Link>LinearAlgebra\Double\Solvers\StopCriterium\FailureStopCriterium.cs</Link>
</Compile> </Compile>
<Compile Include="..\Numerics\LinearAlgebra\Double\Solvers\StopCriterium\IIterationStopCriterium.cs">
<Link>LinearAlgebra\Double\Solvers\StopCriterium\IIterationStopCriterium.cs</Link>
</Compile>
<Compile Include="..\Numerics\LinearAlgebra\Double\Solvers\StopCriterium\IterationCountStopCriterium.cs"> <Compile Include="..\Numerics\LinearAlgebra\Double\Solvers\StopCriterium\IterationCountStopCriterium.cs">
<Link>LinearAlgebra\Double\Solvers\StopCriterium\IterationCountStopCriterium.cs</Link> <Link>LinearAlgebra\Double\Solvers\StopCriterium\IterationCountStopCriterium.cs</Link>
</Compile> </Compile>
@ -717,6 +762,15 @@
<Compile Include="..\Numerics\LinearAlgebra\Single\Matrix.cs"> <Compile Include="..\Numerics\LinearAlgebra\Single\Matrix.cs">
<Link>LinearAlgebra\Single\Matrix.cs</Link> <Link>LinearAlgebra\Single\Matrix.cs</Link>
</Compile> </Compile>
<Compile Include="..\Numerics\LinearAlgebra\Single\Solvers\IIterativeSolver.cs">
<Link>LinearAlgebra\Single\Solvers\IIterativeSolver.cs</Link>
</Compile>
<Compile Include="..\Numerics\LinearAlgebra\Single\Solvers\IIterativeSolverSetup.cs">
<Link>LinearAlgebra\Single\Solvers\IIterativeSolverSetup.cs</Link>
</Compile>
<Compile Include="..\Numerics\LinearAlgebra\Single\Solvers\IIterator.cs">
<Link>LinearAlgebra\Single\Solvers\IIterator.cs</Link>
</Compile>
<Compile Include="..\Numerics\LinearAlgebra\Single\Solvers\Iterative\BiCgStab.cs"> <Compile Include="..\Numerics\LinearAlgebra\Single\Solvers\Iterative\BiCgStab.cs">
<Link>LinearAlgebra\Single\Solvers\Iterative\BiCgStab.cs</Link> <Link>LinearAlgebra\Single\Solvers\Iterative\BiCgStab.cs</Link>
</Compile> </Compile>
@ -747,6 +801,9 @@
<Compile Include="..\Numerics\LinearAlgebra\Single\Solvers\Preconditioners\IncompleteLU.cs"> <Compile Include="..\Numerics\LinearAlgebra\Single\Solvers\Preconditioners\IncompleteLU.cs">
<Link>LinearAlgebra\Single\Solvers\Preconditioners\IncompleteLU.cs</Link> <Link>LinearAlgebra\Single\Solvers\Preconditioners\IncompleteLU.cs</Link>
</Compile> </Compile>
<Compile Include="..\Numerics\LinearAlgebra\Single\Solvers\Preconditioners\IPreConditioner.cs">
<Link>LinearAlgebra\Single\Solvers\Preconditioners\IPreConditioner.cs</Link>
</Compile>
<Compile Include="..\Numerics\LinearAlgebra\Single\Solvers\Preconditioners\UnitPreconditioner.cs"> <Compile Include="..\Numerics\LinearAlgebra\Single\Solvers\Preconditioners\UnitPreconditioner.cs">
<Link>LinearAlgebra\Single\Solvers\Preconditioners\UnitPreconditioner.cs</Link> <Link>LinearAlgebra\Single\Solvers\Preconditioners\UnitPreconditioner.cs</Link>
</Compile> </Compile>
@ -756,6 +813,9 @@
<Compile Include="..\Numerics\LinearAlgebra\Single\Solvers\StopCriterium\FailureStopCriterium.cs"> <Compile Include="..\Numerics\LinearAlgebra\Single\Solvers\StopCriterium\FailureStopCriterium.cs">
<Link>LinearAlgebra\Single\Solvers\StopCriterium\FailureStopCriterium.cs</Link> <Link>LinearAlgebra\Single\Solvers\StopCriterium\FailureStopCriterium.cs</Link>
</Compile> </Compile>
<Compile Include="..\Numerics\LinearAlgebra\Single\Solvers\StopCriterium\IIterationStopCriterium.cs">
<Link>LinearAlgebra\Single\Solvers\StopCriterium\IIterationStopCriterium.cs</Link>
</Compile>
<Compile Include="..\Numerics\LinearAlgebra\Single\Solvers\StopCriterium\IterationCountStopCriterium.cs"> <Compile Include="..\Numerics\LinearAlgebra\Single\Solvers\StopCriterium\IterationCountStopCriterium.cs">
<Link>LinearAlgebra\Single\Solvers\StopCriterium\IterationCountStopCriterium.cs</Link> <Link>LinearAlgebra\Single\Solvers\StopCriterium\IterationCountStopCriterium.cs</Link>
</Compile> </Compile>
@ -792,18 +852,6 @@
<Compile Include="..\Numerics\LinearAlgebra\Generic\Matrix.cs"> <Compile Include="..\Numerics\LinearAlgebra\Generic\Matrix.cs">
<Link>LinearAlgebra\Generic\Matrix.cs</Link> <Link>LinearAlgebra\Generic\Matrix.cs</Link>
</Compile> </Compile>
<Compile Include="..\Numerics\LinearAlgebra\Generic\Solvers\IIterativeSolver.cs">
<Link>LinearAlgebra\Generic\Solvers\IIterativeSolver.cs</Link>
</Compile>
<Compile Include="..\Numerics\LinearAlgebra\Generic\Solvers\IIterativeSolverSetup.cs">
<Link>LinearAlgebra\Generic\Solvers\IIterativeSolverSetup.cs</Link>
</Compile>
<Compile Include="..\Numerics\LinearAlgebra\Generic\Solvers\IIterator.cs">
<Link>LinearAlgebra\Generic\Solvers\IIterator.cs</Link>
</Compile>
<Compile Include="..\Numerics\LinearAlgebra\Generic\Solvers\Preconditioners\IPreConditioner.cs">
<Link>LinearAlgebra\Generic\Solvers\Preconditioners\IPreConditioner.cs</Link>
</Compile>
<Compile Include="..\Numerics\LinearAlgebra\Generic\Solvers\Status\CalculationCancelled.cs"> <Compile Include="..\Numerics\LinearAlgebra\Generic\Solvers\Status\CalculationCancelled.cs">
<Link>LinearAlgebra\Generic\Solvers\Status\CalculationCancelled.cs</Link> <Link>LinearAlgebra\Generic\Solvers\Status\CalculationCancelled.cs</Link>
</Compile> </Compile>
@ -828,9 +876,6 @@
<Compile Include="..\Numerics\LinearAlgebra\Generic\Solvers\Status\ICalculationStatus.cs"> <Compile Include="..\Numerics\LinearAlgebra\Generic\Solvers\Status\ICalculationStatus.cs">
<Link>LinearAlgebra\Generic\Solvers\Status\ICalculationStatus.cs</Link> <Link>LinearAlgebra\Generic\Solvers\Status\ICalculationStatus.cs</Link>
</Compile> </Compile>
<Compile Include="..\Numerics\LinearAlgebra\Generic\Solvers\StopCriterium\IIterationStopCriterium.cs">
<Link>LinearAlgebra\Generic\Solvers\StopCriterium\IIterationStopCriterium.cs</Link>
</Compile>
<Compile Include="..\Numerics\LinearAlgebra\Generic\Solvers\StopCriterium\StopLevel.cs"> <Compile Include="..\Numerics\LinearAlgebra\Generic\Solvers\StopCriterium\StopLevel.cs">
<Link>LinearAlgebra\Generic\Solvers\StopCriterium\StopLevel.cs</Link> <Link>LinearAlgebra\Generic\Solvers\StopCriterium\StopLevel.cs</Link>
</Compile> </Compile>

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

@ -7,7 +7,6 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Iterativ
using LinearAlgebra.Complex.Solvers.StopCriterium; using LinearAlgebra.Complex.Solvers.StopCriterium;
using LinearAlgebra.Generic; using LinearAlgebra.Generic;
using LinearAlgebra.Generic.Solvers.Status; using LinearAlgebra.Generic.Solvers.Status;
using LinearAlgebra.Generic.Solvers.StopCriterium;
using MbUnit.Framework; using MbUnit.Framework;
[TestFixture] [TestFixture]
@ -21,7 +20,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Iterativ
public void SolveWideMatrix() public void SolveWideMatrix()
{ {
var matrix = new SparseMatrix(2, 3); var matrix = new SparseMatrix(2, 3);
Vector<Complex> input = new DenseVector(2); Vector input = new DenseVector(2);
var solver = new BiCgStab(); var solver = new BiCgStab();
solver.Solve(matrix, input); solver.Solve(matrix, input);
@ -32,7 +31,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Iterativ
public void SolveLongMatrix() public void SolveLongMatrix()
{ {
var matrix = new SparseMatrix(3, 2); var matrix = new SparseMatrix(3, 2);
Vector<Complex> input = new DenseVector(3); Vector input = new DenseVector(3);
var solver = new BiCgStab(); var solver = new BiCgStab();
solver.Solve(matrix, input); solver.Solve(matrix, input);
@ -43,13 +42,13 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Iterativ
public void SolveUnitMatrixAndBackMultiply() public void SolveUnitMatrixAndBackMultiply()
{ {
// Create the identity matrix // Create the identity matrix
Matrix<Complex> matrix = SparseMatrix.Identity(100); Matrix matrix = SparseMatrix.Identity(100);
// Create the y vector // Create the y vector
Vector<Complex> y = new DenseVector(matrix.RowCount, Complex.One); Vector y = new DenseVector(matrix.RowCount, Complex.One);
// Create an iteration monitor which will keep track of iterative convergence // Create an iteration monitor which will keep track of iterative convergence
var monitor = new Iterator(new IIterationStopCriterium<Complex>[] var monitor = new Iterator(new IIterationStopCriterium[]
{ {
new IterationCountStopCriterium(MaximumIterations), new IterationCountStopCriterium(MaximumIterations),
new ResidualStopCriterium(ConvergenceBoundary), new ResidualStopCriterium(ConvergenceBoundary),
@ -83,16 +82,16 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Iterativ
public void SolveScaledUnitMatrixAndBackMultiply() public void SolveScaledUnitMatrixAndBackMultiply()
{ {
// Create the identity matrix // Create the identity matrix
Matrix<Complex> matrix = SparseMatrix.Identity(100); Matrix matrix = SparseMatrix.Identity(100);
// Scale it with a funny number // Scale it with a funny number
matrix.Multiply(new Complex(System.Math.PI, System.Math.PI), matrix); matrix.Multiply(new Complex(System.Math.PI, System.Math.PI), matrix);
// Create the y vector // Create the y vector
Vector<Complex> y = new DenseVector(matrix.RowCount, Complex.One); Vector y = new DenseVector(matrix.RowCount, Complex.One);
// Create an iteration monitor which will keep track of iterative convergence // Create an iteration monitor which will keep track of iterative convergence
var monitor = new Iterator(new IIterationStopCriterium<Complex>[] var monitor = new Iterator(new IIterationStopCriterium[]
{ {
new IterationCountStopCriterium(MaximumIterations), new IterationCountStopCriterium(MaximumIterations),
new ResidualStopCriterium(ConvergenceBoundary), new ResidualStopCriterium(ConvergenceBoundary),
@ -165,10 +164,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Iterativ
} }
// Create the y vector // Create the y vector
Vector<Complex> y = new DenseVector(matrix.RowCount, Complex.One); Vector y = new DenseVector(matrix.RowCount, Complex.One);
// Create an iteration monitor which will keep track of iterative convergence // Create an iteration monitor which will keep track of iterative convergence
var monitor = new Iterator(new IIterationStopCriterium<Complex>[] var monitor = new Iterator(new IIterationStopCriterium[]
{ {
new IterationCountStopCriterium(MaximumIterations), new IterationCountStopCriterium(MaximumIterations),
new ResidualStopCriterium(ConvergenceBoundary), new ResidualStopCriterium(ConvergenceBoundary),
@ -205,10 +204,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Iterativ
[MultipleAsserts] [MultipleAsserts]
public void CanSolveForRandomVector(int order) public void CanSolveForRandomVector(int order)
{ {
var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); var matrixA = (Matrix)MatrixLoader.GenerateRandomDenseMatrix(order, order);
var vectorb = MatrixLoader.GenerateRandomDenseVector(order); var vectorb = (Vector)MatrixLoader.GenerateRandomDenseVector(order);
var monitor = new Iterator(new IIterationStopCriterium<Complex>[] var monitor = new Iterator(new IIterationStopCriterium[]
{ {
new IterationCountStopCriterium(1000), new IterationCountStopCriterium(1000),
new ResidualStopCriterium(1e-10), new ResidualStopCriterium(1e-10),
@ -236,10 +235,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Iterativ
[MultipleAsserts] [MultipleAsserts]
public void CanSolveForRandomMatrix(int order) public void CanSolveForRandomMatrix(int order)
{ {
var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); var matrixA = (Matrix)MatrixLoader.GenerateRandomDenseMatrix(order, order);
var matrixB = MatrixLoader.GenerateRandomDenseMatrix(order, order); var matrixB = (Matrix)MatrixLoader.GenerateRandomDenseMatrix(order, order);
var monitor = new Iterator(new IIterationStopCriterium<Complex>[] var monitor = new Iterator(new IIterationStopCriterium[]
{ {
new IterationCountStopCriterium(1000), new IterationCountStopCriterium(1000),
new ResidualStopCriterium(1e-10), new ResidualStopCriterium(1e-10),

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

@ -21,7 +21,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Iterativ
public void SolveWideMatrix() public void SolveWideMatrix()
{ {
var matrix = new SparseMatrix(2, 3); var matrix = new SparseMatrix(2, 3);
Vector<Complex> input = new DenseVector(2); Vector input = new DenseVector(2);
var solver = new GpBiCg(); var solver = new GpBiCg();
solver.Solve(matrix, input); solver.Solve(matrix, input);
@ -32,7 +32,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Iterativ
public void SolveLongMatrix() public void SolveLongMatrix()
{ {
var matrix = new SparseMatrix(3, 2); var matrix = new SparseMatrix(3, 2);
Vector<Complex> input = new DenseVector(3); Vector input = new DenseVector(3);
var solver = new GpBiCg(); var solver = new GpBiCg();
solver.Solve(matrix, input); solver.Solve(matrix, input);
@ -43,13 +43,13 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Iterativ
public void SolveUnitMatrixAndBackMultiply() public void SolveUnitMatrixAndBackMultiply()
{ {
// Create the identity matrix // Create the identity matrix
Matrix<Complex> matrix = SparseMatrix.Identity(100); Matrix matrix = SparseMatrix.Identity(100);
// Create the y vector // Create the y vector
Vector<Complex> y = new DenseVector(matrix.RowCount, 1); Vector y = new DenseVector(matrix.RowCount, 1);
// Create an iteration monitor which will keep track of iterative convergence // Create an iteration monitor which will keep track of iterative convergence
var monitor = new Iterator(new IIterationStopCriterium<Complex>[] var monitor = new Iterator(new IIterationStopCriterium[]
{ {
new IterationCountStopCriterium(MaximumIterations), new IterationCountStopCriterium(MaximumIterations),
new ResidualStopCriterium(ConvergenceBoundary), new ResidualStopCriterium(ConvergenceBoundary),
@ -83,16 +83,16 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Iterativ
public void SolveScaledUnitMatrixAndBackMultiply() public void SolveScaledUnitMatrixAndBackMultiply()
{ {
// Create the identity matrix // Create the identity matrix
Matrix<Complex> matrix = SparseMatrix.Identity(100); Matrix matrix = SparseMatrix.Identity(100);
// Scale it with a funny number // Scale it with a funny number
matrix.Multiply(System.Math.PI, matrix); matrix.Multiply(System.Math.PI, matrix);
// Create the y vector // Create the y vector
Vector<Complex> y = new DenseVector(matrix.RowCount, 1); Vector y = new DenseVector(matrix.RowCount, 1);
// Create an iteration monitor which will keep track of iterative convergence // Create an iteration monitor which will keep track of iterative convergence
var monitor = new Iterator(new IIterationStopCriterium<Complex>[] var monitor = new Iterator(new IIterationStopCriterium[]
{ {
new IterationCountStopCriterium(MaximumIterations), new IterationCountStopCriterium(MaximumIterations),
new ResidualStopCriterium(ConvergenceBoundary), new ResidualStopCriterium(ConvergenceBoundary),
@ -166,10 +166,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Iterativ
} }
// Create the y vector // Create the y vector
Vector<Complex> y = new DenseVector(matrix.RowCount, 1); Vector y = new DenseVector(matrix.RowCount, 1);
// Create an iteration monitor which will keep track of iterative convergence // Create an iteration monitor which will keep track of iterative convergence
var monitor = new Iterator(new IIterationStopCriterium<Complex>[] var monitor = new Iterator(new IIterationStopCriterium[]
{ {
new IterationCountStopCriterium(MaximumIterations), new IterationCountStopCriterium(MaximumIterations),
new ResidualStopCriterium(ConvergenceBoundary), new ResidualStopCriterium(ConvergenceBoundary),
@ -207,10 +207,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Iterativ
[MultipleAsserts] [MultipleAsserts]
public void CanSolveForRandomVector(int order) public void CanSolveForRandomVector(int order)
{ {
var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); var matrixA = (Matrix)MatrixLoader.GenerateRandomDenseMatrix(order, order);
var vectorb = MatrixLoader.GenerateRandomDenseVector(order); var vectorb = (Vector)MatrixLoader.GenerateRandomDenseVector(order);
var monitor = new Iterator(new IIterationStopCriterium<Complex>[] var monitor = new Iterator(new IIterationStopCriterium[]
{ {
new IterationCountStopCriterium(1000), new IterationCountStopCriterium(1000),
new ResidualStopCriterium(1e-10), new ResidualStopCriterium(1e-10),
@ -238,10 +238,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Iterativ
[MultipleAsserts] [MultipleAsserts]
public void CanSolveForRandomMatrix(int order) public void CanSolveForRandomMatrix(int order)
{ {
var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); var matrixA = (Matrix)MatrixLoader.GenerateRandomDenseMatrix(order, order);
var matrixB = MatrixLoader.GenerateRandomDenseMatrix(order, order); var matrixB = (Matrix)MatrixLoader.GenerateRandomDenseMatrix(order, order);
var monitor = new Iterator(new IIterationStopCriterium<Complex>[] var monitor = new Iterator(new IIterationStopCriterium[]
{ {
new IterationCountStopCriterium(1000), new IterationCountStopCriterium(1000),
new ResidualStopCriterium(1e-10), new ResidualStopCriterium(1e-10),

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

@ -21,7 +21,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Iterativ
public void SolveWideMatrix() public void SolveWideMatrix()
{ {
var matrix = new SparseMatrix(2, 3); var matrix = new SparseMatrix(2, 3);
Vector<Complex> input = new DenseVector(2); Vector input = new DenseVector(2);
var solver = new MlkBiCgStab(); var solver = new MlkBiCgStab();
solver.Solve(matrix, input); solver.Solve(matrix, input);
@ -32,7 +32,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Iterativ
public void SolveLongMatrix() public void SolveLongMatrix()
{ {
var matrix = new SparseMatrix(3, 2); var matrix = new SparseMatrix(3, 2);
Vector<Complex> input = new DenseVector(3); Vector input = new DenseVector(3);
var solver = new MlkBiCgStab(); var solver = new MlkBiCgStab();
solver.Solve(matrix, input); solver.Solve(matrix, input);
@ -43,13 +43,13 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Iterativ
public void SolveUnitMatrixAndBackMultiply() public void SolveUnitMatrixAndBackMultiply()
{ {
// Create the identity matrix // Create the identity matrix
Matrix<Complex> matrix = SparseMatrix.Identity(100); Matrix matrix = SparseMatrix.Identity(100);
// Create the y vector // Create the y vector
Vector<Complex> y = new DenseVector(matrix.RowCount, 1); Vector y = new DenseVector(matrix.RowCount, 1);
// Create an iteration monitor which will keep track of iterative convergence // Create an iteration monitor which will keep track of iterative convergence
var monitor = new Iterator(new IIterationStopCriterium<Complex>[] var monitor = new Iterator(new IIterationStopCriterium[]
{ {
new IterationCountStopCriterium(MaximumIterations), new IterationCountStopCriterium(MaximumIterations),
new ResidualStopCriterium(ConvergenceBoundary), new ResidualStopCriterium(ConvergenceBoundary),
@ -84,16 +84,16 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Iterativ
public void SolveScaledUnitMatrixAndBackMultiply() public void SolveScaledUnitMatrixAndBackMultiply()
{ {
// Create the identity matrix // Create the identity matrix
Matrix<Complex> matrix = SparseMatrix.Identity(100); Matrix matrix = SparseMatrix.Identity(100);
// Scale it with a funny number // Scale it with a funny number
matrix.Multiply(System.Math.PI, matrix); matrix.Multiply(System.Math.PI, matrix);
// Create the y vector // Create the y vector
Vector<Complex> y = new DenseVector(matrix.RowCount, 1); Vector y = new DenseVector(matrix.RowCount, 1);
// Create an iteration monitor which will keep track of iterative convergence // Create an iteration monitor which will keep track of iterative convergence
var monitor = new Iterator(new IIterationStopCriterium<Complex>[] var monitor = new Iterator(new IIterationStopCriterium[]
{ {
new IterationCountStopCriterium(MaximumIterations), new IterationCountStopCriterium(MaximumIterations),
new ResidualStopCriterium(ConvergenceBoundary), new ResidualStopCriterium(ConvergenceBoundary),
@ -165,10 +165,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Iterativ
} }
// Create the y vector // Create the y vector
Vector<Complex> y = new DenseVector(matrix.RowCount, 1); Vector y = new DenseVector(matrix.RowCount, 1);
// Create an iteration monitor which will keep track of iterative convergence // Create an iteration monitor which will keep track of iterative convergence
var monitor = new Iterator(new IIterationStopCriterium<Complex>[] var monitor = new Iterator(new IIterationStopCriterium[]
{ {
new IterationCountStopCriterium(MaximumIterations), new IterationCountStopCriterium(MaximumIterations),
new ResidualStopCriterium(ConvergenceBoundary), new ResidualStopCriterium(ConvergenceBoundary),
@ -204,10 +204,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Iterativ
[MultipleAsserts] [MultipleAsserts]
public void CanSolveForRandomVector(int order) public void CanSolveForRandomVector(int order)
{ {
var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); var matrixA = (Matrix)MatrixLoader.GenerateRandomDenseMatrix(order, order);
var vectorb = MatrixLoader.GenerateRandomDenseVector(order); var vectorb = (Vector)MatrixLoader.GenerateRandomDenseVector(order);
var monitor = new Iterator(new IIterationStopCriterium<Complex>[] var monitor = new Iterator(new IIterationStopCriterium[]
{ {
new IterationCountStopCriterium(1000), new IterationCountStopCriterium(1000),
new ResidualStopCriterium(1e-10), new ResidualStopCriterium(1e-10),
@ -234,10 +234,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Iterativ
[MultipleAsserts] [MultipleAsserts]
public void CanSolveForRandomMatrix(int order) public void CanSolveForRandomMatrix(int order)
{ {
var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); var matrixA = (Matrix)MatrixLoader.GenerateRandomDenseMatrix(order, order);
var matrixB = MatrixLoader.GenerateRandomDenseMatrix(order, order); var matrixB = (Matrix)MatrixLoader.GenerateRandomDenseMatrix(order, order);
var monitor = new Iterator(new IIterationStopCriterium<Complex>[] var monitor = new Iterator(new IIterationStopCriterium[]
{ {
new IterationCountStopCriterium(1000), new IterationCountStopCriterium(1000),
new ResidualStopCriterium(1e-10), new ResidualStopCriterium(1e-10),

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

@ -1,13 +1,10 @@
namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Iterative namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Iterative
{ {
using System.Numerics;
using LinearAlgebra.Complex; using LinearAlgebra.Complex;
using LinearAlgebra.Complex.Solvers; using LinearAlgebra.Complex.Solvers;
using LinearAlgebra.Complex.Solvers.Iterative; using LinearAlgebra.Complex.Solvers.Iterative;
using LinearAlgebra.Complex.Solvers.StopCriterium; using LinearAlgebra.Complex.Solvers.StopCriterium;
using LinearAlgebra.Generic;
using LinearAlgebra.Generic.Solvers.Status; using LinearAlgebra.Generic.Solvers.Status;
using LinearAlgebra.Generic.Solvers.StopCriterium;
using MbUnit.Framework; using MbUnit.Framework;
[TestFixture] [TestFixture]
@ -21,7 +18,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Iterativ
public void SolveWideMatrix() public void SolveWideMatrix()
{ {
var matrix = new SparseMatrix(2, 3); var matrix = new SparseMatrix(2, 3);
Vector<Complex> input = new DenseVector(2); Vector input = new DenseVector(2);
var solver = new TFQMR(); var solver = new TFQMR();
solver.Solve(matrix, input); solver.Solve(matrix, input);
@ -32,7 +29,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Iterativ
public void SolveLongMatrix() public void SolveLongMatrix()
{ {
var matrix = new SparseMatrix(3, 2); var matrix = new SparseMatrix(3, 2);
Vector<Complex> input = new DenseVector(3); Vector input = new DenseVector(3);
var solver = new TFQMR(); var solver = new TFQMR();
solver.Solve(matrix, input); solver.Solve(matrix, input);
@ -43,13 +40,13 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Iterativ
public void SolveUnitMatrixAndBackMultiply() public void SolveUnitMatrixAndBackMultiply()
{ {
// Create the identity matrix // Create the identity matrix
Matrix<Complex> matrix = SparseMatrix.Identity(100); Matrix matrix = SparseMatrix.Identity(100);
// Create the y vector // Create the y vector
Vector<Complex> y = new DenseVector(matrix.RowCount, 1); Vector y = new DenseVector(matrix.RowCount, 1);
// Create an iteration monitor which will keep track of iterative convergence // Create an iteration monitor which will keep track of iterative convergence
var monitor = new Iterator(new IIterationStopCriterium<Complex>[] var monitor = new Iterator(new IIterationStopCriterium[]
{ {
new IterationCountStopCriterium(MaximumIterations), new IterationCountStopCriterium(MaximumIterations),
new ResidualStopCriterium(ConvergenceBoundary), new ResidualStopCriterium(ConvergenceBoundary),
@ -84,16 +81,16 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Iterativ
public void SolveScaledUnitMatrixAndBackMultiply() public void SolveScaledUnitMatrixAndBackMultiply()
{ {
// Create the identity matrix // Create the identity matrix
Matrix<Complex> matrix = SparseMatrix.Identity(100); Matrix matrix = SparseMatrix.Identity(100);
// Scale it with a funny number // Scale it with a funny number
matrix.Multiply(System.Math.PI, matrix); matrix.Multiply(System.Math.PI, matrix);
// Create the y vector // Create the y vector
Vector<Complex> y = new DenseVector(matrix.RowCount, 1); Vector y = new DenseVector(matrix.RowCount, 1);
// Create an iteration monitor which will keep track of iterative convergence // Create an iteration monitor which will keep track of iterative convergence
var monitor = new Iterator(new IIterationStopCriterium<Complex>[] var monitor = new Iterator(new IIterationStopCriterium[]
{ {
new IterationCountStopCriterium(MaximumIterations), new IterationCountStopCriterium(MaximumIterations),
new ResidualStopCriterium(ConvergenceBoundary), new ResidualStopCriterium(ConvergenceBoundary),
@ -165,10 +162,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Iterativ
} }
// Create the y vector // Create the y vector
Vector<Complex> y = new DenseVector(matrix.RowCount, 1); Vector y = new DenseVector(matrix.RowCount, 1);
// Create an iteration monitor which will keep track of iterative convergence // Create an iteration monitor which will keep track of iterative convergence
var monitor = new Iterator(new IIterationStopCriterium<Complex>[] var monitor = new Iterator(new IIterationStopCriterium[]
{ {
new IterationCountStopCriterium(MaximumIterations), new IterationCountStopCriterium(MaximumIterations),
new ResidualStopCriterium(ConvergenceBoundary), new ResidualStopCriterium(ConvergenceBoundary),
@ -205,10 +202,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Iterativ
[MultipleAsserts] [MultipleAsserts]
public void CanSolveForRandomVector(int order) public void CanSolveForRandomVector(int order)
{ {
var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); var matrixA = (Matrix)MatrixLoader.GenerateRandomDenseMatrix(order, order);
var vectorb = MatrixLoader.GenerateRandomDenseVector(order); var vectorb = (Vector)MatrixLoader.GenerateRandomDenseVector(order);
var monitor = new Iterator(new IIterationStopCriterium<Complex>[] var monitor = new Iterator(new IIterationStopCriterium[]
{ {
new IterationCountStopCriterium(1000), new IterationCountStopCriterium(1000),
new ResidualStopCriterium(1e-10), new ResidualStopCriterium(1e-10),
@ -236,10 +233,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Iterativ
[MultipleAsserts] [MultipleAsserts]
public void CanSolveForRandomMatrix(int order) public void CanSolveForRandomMatrix(int order)
{ {
var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); var matrixA = (Matrix)MatrixLoader.GenerateRandomDenseMatrix(order, order);
var matrixB = MatrixLoader.GenerateRandomDenseMatrix(order, order); var matrixB = (Matrix)MatrixLoader.GenerateRandomDenseMatrix(order, order);
var monitor = new Iterator(new IIterationStopCriterium<Complex>[] var monitor = new Iterator(new IIterationStopCriterium[]
{ {
new IterationCountStopCriterium(1000), new IterationCountStopCriterium(1000),
new ResidualStopCriterium(1e-10), new ResidualStopCriterium(1e-10),

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

@ -26,7 +26,7 @@
[MultipleAsserts] [MultipleAsserts]
public void CreateWithEmptyCollection() public void CreateWithEmptyCollection()
{ {
var iterator = new Iterator(new IIterationStopCriterium<Complex>[] { }); var iterator = new Iterator(new IIterationStopCriterium[] { });
Assert.IsNotNull(iterator, "Should have an iterator"); Assert.IsNotNull(iterator, "Should have an iterator");
Assert.AreEqual(0, iterator.NumberOfCriteria, "There shouldn't be any criteria"); Assert.AreEqual(0, iterator.NumberOfCriteria, "There shouldn't be any criteria");
} }
@ -35,7 +35,7 @@
[MultipleAsserts] [MultipleAsserts]
public void CreateWithCollectionWithNulls() public void CreateWithCollectionWithNulls()
{ {
var iterator = new Iterator(new IIterationStopCriterium<Complex>[] { null, null }); var iterator = new Iterator(new IIterationStopCriterium[] { null, null });
Assert.IsNotNull(iterator, "Should have an iterator"); Assert.IsNotNull(iterator, "Should have an iterator");
Assert.AreEqual(0, iterator.NumberOfCriteria, "There shouldn't be any criteria"); Assert.AreEqual(0, iterator.NumberOfCriteria, "There shouldn't be any criteria");
} }
@ -44,7 +44,7 @@
[ExpectedArgumentException] [ExpectedArgumentException]
public void CreateWithDuplicates() public void CreateWithDuplicates()
{ {
new Iterator(new IIterationStopCriterium<Complex>[] new Iterator(new IIterationStopCriterium[]
{ {
new FailureStopCriterium(), new FailureStopCriterium(),
new FailureStopCriterium() new FailureStopCriterium()
@ -55,7 +55,7 @@
[MultipleAsserts] [MultipleAsserts]
public void CreateWithCollection() public void CreateWithCollection()
{ {
var criteria = new List<IIterationStopCriterium<Complex>> var criteria = new List<IIterationStopCriterium>
{ {
new FailureStopCriterium(), new FailureStopCriterium(),
new DivergenceStopCriterium(), new DivergenceStopCriterium(),
@ -98,7 +98,7 @@
[MultipleAsserts] [MultipleAsserts]
public void Add() public void Add()
{ {
var criteria = new List<IIterationStopCriterium<Complex>> var criteria = new List<IIterationStopCriterium>
{ {
new FailureStopCriterium(), new FailureStopCriterium(),
new DivergenceStopCriterium(), new DivergenceStopCriterium(),
@ -128,7 +128,7 @@
[ExpectedArgumentNullException] [ExpectedArgumentNullException]
public void RemoveWithNullStopCriterium() public void RemoveWithNullStopCriterium()
{ {
var criteria = new List<IIterationStopCriterium<Complex>> var criteria = new List<IIterationStopCriterium>
{ {
new FailureStopCriterium(), new FailureStopCriterium(),
new DivergenceStopCriterium(), new DivergenceStopCriterium(),
@ -145,7 +145,7 @@
[MultipleAsserts] [MultipleAsserts]
public void RemoveWithNonExistingStopCriterium() public void RemoveWithNonExistingStopCriterium()
{ {
var criteria = new List<IIterationStopCriterium<Complex>> var criteria = new List<IIterationStopCriterium>
{ {
new FailureStopCriterium(), new FailureStopCriterium(),
new DivergenceStopCriterium(), new DivergenceStopCriterium(),
@ -162,7 +162,7 @@
[MultipleAsserts] [MultipleAsserts]
public void Remove() public void Remove()
{ {
var criteria = new List<IIterationStopCriterium<Complex>> var criteria = new List<IIterationStopCriterium>
{ {
new FailureStopCriterium(), new FailureStopCriterium(),
new DivergenceStopCriterium(), new DivergenceStopCriterium(),
@ -194,7 +194,7 @@
[ExpectedException(typeof(ArgumentOutOfRangeException))] [ExpectedException(typeof(ArgumentOutOfRangeException))]
public void DetermineStatusWithNegativeIterationNumber() public void DetermineStatusWithNegativeIterationNumber()
{ {
var criteria = new List<IIterationStopCriterium<Complex>> var criteria = new List<IIterationStopCriterium>
{ {
new FailureStopCriterium(), new FailureStopCriterium(),
new DivergenceStopCriterium(), new DivergenceStopCriterium(),
@ -213,7 +213,7 @@
[ExpectedArgumentNullException] [ExpectedArgumentNullException]
public void DetermineStatusWithNullSolutionVector() public void DetermineStatusWithNullSolutionVector()
{ {
var criteria = new List<IIterationStopCriterium<Complex>> var criteria = new List<IIterationStopCriterium>
{ {
new FailureStopCriterium(), new FailureStopCriterium(),
new DivergenceStopCriterium(), new DivergenceStopCriterium(),
@ -232,7 +232,7 @@
[ExpectedArgumentNullException] [ExpectedArgumentNullException]
public void DetermineStatusWithNullSourceVector() public void DetermineStatusWithNullSourceVector()
{ {
var criteria = new List<IIterationStopCriterium<Complex>> var criteria = new List<IIterationStopCriterium>
{ {
new FailureStopCriterium(), new FailureStopCriterium(),
new DivergenceStopCriterium(), new DivergenceStopCriterium(),
@ -251,7 +251,7 @@
[ExpectedArgumentNullException] [ExpectedArgumentNullException]
public void DetermineStatusWithNullResidualVector() public void DetermineStatusWithNullResidualVector()
{ {
var criteria = new List<IIterationStopCriterium<Complex>> var criteria = new List<IIterationStopCriterium>
{ {
new FailureStopCriterium(), new FailureStopCriterium(),
new DivergenceStopCriterium(), new DivergenceStopCriterium(),
@ -270,7 +270,7 @@
[MultipleAsserts] [MultipleAsserts]
public void DetermineStatus() public void DetermineStatus()
{ {
var criteria = new List<IIterationStopCriterium<Complex>> var criteria = new List<IIterationStopCriterium>
{ {
new FailureStopCriterium(), new FailureStopCriterium(),
new DivergenceStopCriterium(), new DivergenceStopCriterium(),
@ -298,7 +298,7 @@
[MultipleAsserts] [MultipleAsserts]
public void ResetToPrecalculationState() public void ResetToPrecalculationState()
{ {
var criteria = new List<IIterationStopCriterium<Complex>> var criteria = new List<IIterationStopCriterium>
{ {
new FailureStopCriterium(), new FailureStopCriterium(),
new DivergenceStopCriterium(), new DivergenceStopCriterium(),
@ -325,7 +325,7 @@
[MultipleAsserts] [MultipleAsserts]
public void Clone() public void Clone()
{ {
var criteria = new List<IIterationStopCriterium<Complex>> var criteria = new List<IIterationStopCriterium>
{ {
new FailureStopCriterium(), new FailureStopCriterium(),
new DivergenceStopCriterium(), new DivergenceStopCriterium(),

9
src/UnitTests/LinearAlgebraTests/Complex/Solvers/Preconditioners/DiagonalTest.cs

@ -1,27 +1,24 @@
namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Preconditioners namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Preconditioners
{ {
using System.Numerics;
using LinearAlgebra.Complex; using LinearAlgebra.Complex;
using LinearAlgebra.Complex.Solvers.Preconditioners; using LinearAlgebra.Complex.Solvers.Preconditioners;
using LinearAlgebra.Generic;
using LinearAlgebra.Generic.Solvers.Preconditioners;
using MbUnit.Framework; using MbUnit.Framework;
[TestFixture] [TestFixture]
public sealed class DiagonalTest : PreconditionerTest public sealed class DiagonalTest : PreconditionerTest
{ {
internal override IPreConditioner<Complex> CreatePreconditioner() internal override IPreConditioner CreatePreconditioner()
{ {
return new Diagonal(); return new Diagonal();
} }
protected override void CheckResult(IPreConditioner<Complex> preconditioner, SparseMatrix matrix, Vector<Complex> vector, Vector<Complex> result) protected override void CheckResult(IPreConditioner preconditioner, SparseMatrix matrix, Vector vector, Vector result)
{ {
Assert.AreEqual(typeof(Diagonal), preconditioner.GetType(), "#01"); Assert.AreEqual(typeof(Diagonal), preconditioner.GetType(), "#01");
// Compute M * result = product // Compute M * result = product
// compare vector and product. Should be equal // compare vector and product. Should be equal
Vector<Complex> product = new DenseVector(result.Count); Vector product = new DenseVector(result.Count);
matrix.Multiply(result, product); matrix.Multiply(result, product);
for (var i = 0; i < product.Count; i++) for (var i = 0; i < product.Count; i++)

15
src/UnitTests/LinearAlgebraTests/Complex/Solvers/Preconditioners/IlutpTest.cs

@ -1,12 +1,9 @@
namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Preconditioners namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Preconditioners
{ {
using System; using System;
using System.Numerics;
using System.Reflection; using System.Reflection;
using LinearAlgebra.Complex; using LinearAlgebra.Complex;
using LinearAlgebra.Complex.Solvers.Preconditioners; using LinearAlgebra.Complex.Solvers.Preconditioners;
using LinearAlgebra.Generic;
using LinearAlgebra.Generic.Solvers.Preconditioners;
using MbUnit.Framework; using MbUnit.Framework;
[TestFixture] [TestFixture]
@ -74,7 +71,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Precondi
return result; return result;
} }
internal override IPreConditioner<Complex> CreatePreconditioner() internal override IPreConditioner CreatePreconditioner()
{ {
_pivotTolerance = 0; _pivotTolerance = 0;
_dropTolerance = 0.0; _dropTolerance = 0.0;
@ -82,13 +79,13 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Precondi
return InternalCreatePreconditioner(); return InternalCreatePreconditioner();
} }
protected override void CheckResult(IPreConditioner<Complex> preconditioner, SparseMatrix matrix, Vector<Complex> vector, Vector<Complex> result) protected override void CheckResult(IPreConditioner preconditioner, SparseMatrix matrix, Vector vector, Vector result)
{ {
Assert.AreEqual(typeof(Ilutp), preconditioner.GetType(), "#01"); Assert.AreEqual(typeof(Ilutp), preconditioner.GetType(), "#01");
// Compute M * result = product // Compute M * result = product
// compare vector and product. Should be equal // compare vector and product. Should be equal
Vector<Complex> product = new DenseVector(result.Count); Vector product = new DenseVector(result.Count);
matrix.Multiply(result, product); matrix.Multiply(result, product);
for (var i = 0; i < product.Count; i++) for (var i = 0; i < product.Count; i++)
{ {
@ -112,7 +109,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Precondi
_fillLevel = 100; _fillLevel = 100;
var preconditioner = CreatePreconditioner(); var preconditioner = CreatePreconditioner();
preconditioner.Initialize(newMatrix); preconditioner.Initialize(newMatrix);
Vector<Complex> result = new DenseVector(vector.Count); Vector result = new DenseVector(vector.Count);
preconditioner.Approximate(vector, result); preconditioner.Approximate(vector, result);
CheckResult(preconditioner, newMatrix, vector, result); CheckResult(preconditioner, newMatrix, vector, result);
} }
@ -131,7 +128,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Precondi
_fillLevel = 100; _fillLevel = 100;
var preconditioner = CreatePreconditioner(); var preconditioner = CreatePreconditioner();
preconditioner.Initialize(newMatrix); preconditioner.Initialize(newMatrix);
Vector<Complex> result = new DenseVector(vector.Count); Vector result = new DenseVector(vector.Count);
preconditioner.Approximate(vector, result); preconditioner.Approximate(vector, result);
CheckResult(preconditioner, newMatrix, vector, result); CheckResult(preconditioner, newMatrix, vector, result);
} }
@ -246,7 +243,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Precondi
FillLevel = 10 FillLevel = 10
}; };
preconditioner.Initialize(newMatrix); preconditioner.Initialize(newMatrix);
Vector<Complex> result = new DenseVector(vector.Count); Vector result = new DenseVector(vector.Count);
preconditioner.Approximate(vector, result); preconditioner.Approximate(vector, result);
CheckResult(preconditioner, newMatrix, vector, result); CheckResult(preconditioner, newMatrix, vector, result);
} }

17
src/UnitTests/LinearAlgebraTests/Complex/Solvers/Preconditioners/IncompleteLUTest.cs

@ -1,12 +1,9 @@
namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Preconditioners namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Preconditioners
{ {
using System; using System;
using System.Numerics;
using System.Reflection; using System.Reflection;
using LinearAlgebra.Complex; using LinearAlgebra.Complex;
using LinearAlgebra.Complex.Solvers.Preconditioners; using LinearAlgebra.Complex.Solvers.Preconditioners;
using LinearAlgebra.Generic;
using LinearAlgebra.Generic.Solvers.Preconditioners;
using MbUnit.Framework; using MbUnit.Framework;
[TestFixture] [TestFixture]
@ -25,28 +22,28 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Precondi
return (T)obj; return (T)obj;
} }
private static Matrix<Complex> GetUpperTriangle(IncompleteLU ilu) private static Matrix GetUpperTriangle(IncompleteLU ilu)
{ {
return GetMethod<Matrix<Complex>>(ilu, "UpperTriangle"); return GetMethod<Matrix>(ilu, "UpperTriangle");
} }
private static Matrix<Complex> GetLowerTriangle(IncompleteLU ilu) private static Matrix GetLowerTriangle(IncompleteLU ilu)
{ {
return GetMethod<Matrix<Complex>>(ilu, "LowerTriangle"); return GetMethod<Matrix>(ilu, "LowerTriangle");
} }
internal override IPreConditioner<Complex> CreatePreconditioner() internal override IPreConditioner CreatePreconditioner()
{ {
return new IncompleteLU(); return new IncompleteLU();
} }
protected override void CheckResult(IPreConditioner<Complex> preconditioner, SparseMatrix matrix, Vector<Complex> vector, Vector<Complex> result) protected override void CheckResult(IPreConditioner preconditioner, SparseMatrix matrix, Vector vector, Vector result)
{ {
Assert.AreEqual(typeof(IncompleteLU), preconditioner.GetType(), "#01"); Assert.AreEqual(typeof(IncompleteLU), preconditioner.GetType(), "#01");
// Compute M * result = product // Compute M * result = product
// compare vector and product. Should be equal // compare vector and product. Should be equal
Vector<Complex> product = new DenseVector(result.Count); Vector product = new DenseVector(result.Count);
matrix.Multiply(result, product); matrix.Multiply(result, product);
for (var i = 0; i < product.Count; i++) for (var i = 0; i < product.Count; i++)

18
src/UnitTests/LinearAlgebraTests/Complex/Solvers/Preconditioners/PreConditionerTest.cs

@ -2,8 +2,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Precondi
{ {
using System.Numerics; using System.Numerics;
using LinearAlgebra.Complex; using LinearAlgebra.Complex;
using LinearAlgebra.Complex.Solvers.Preconditioners;
using LinearAlgebra.Generic; using LinearAlgebra.Generic;
using LinearAlgebra.Generic.Solvers.Preconditioners;
using MbUnit.Framework; using MbUnit.Framework;
public abstract class PreconditionerTest public abstract class PreconditionerTest
@ -21,9 +21,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Precondi
return matrix; return matrix;
} }
protected Vector<Complex> CreateStandardBcVector(int size) protected Vector CreateStandardBcVector(int size)
{ {
Vector<Complex> vector = new DenseVector(size); Vector vector = new DenseVector(size);
for (var i = 0; i < size; i++) for (var i = 0; i < size; i++)
{ {
vector[i] = i + 1; vector[i] = i + 1;
@ -32,9 +32,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Precondi
return vector; return vector;
} }
internal abstract IPreConditioner<Complex> CreatePreconditioner(); internal abstract IPreConditioner CreatePreconditioner();
protected abstract void CheckResult(IPreConditioner<Complex> preconditioner, SparseMatrix matrix, Vector<Complex> vector, Vector<Complex> result); protected abstract void CheckResult(IPreConditioner preconditioner, SparseMatrix matrix, Vector vector, Vector result);
[Test] [Test]
[MultipleAsserts] [MultipleAsserts]
@ -64,7 +64,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Precondi
var preconditioner = CreatePreconditioner(); var preconditioner = CreatePreconditioner();
preconditioner.Initialize(newMatrix); preconditioner.Initialize(newMatrix);
Vector<Complex> result = new DenseVector(vector.Count); Vector result = new DenseVector(vector.Count);
preconditioner.Approximate(vector, result); preconditioner.Approximate(vector, result);
CheckResult(preconditioner, newMatrix, vector, result); CheckResult(preconditioner, newMatrix, vector, result);
@ -81,7 +81,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Precondi
var preconditioner = CreatePreconditioner(); var preconditioner = CreatePreconditioner();
preconditioner.Initialize(newMatrix); preconditioner.Initialize(newMatrix);
Vector<Complex> result = new DenseVector(vector.Count + 10); Vector result = new DenseVector(vector.Count + 10);
preconditioner.Approximate(vector, result); preconditioner.Approximate(vector, result);
} }
@ -96,7 +96,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Precondi
var preconditioner = CreatePreconditioner(); var preconditioner = CreatePreconditioner();
preconditioner.Initialize(newMatrix); preconditioner.Initialize(newMatrix);
Vector<Complex> result = new DenseVector(vector.Count + 10); Vector result = new DenseVector(vector.Count + 10);
preconditioner.Approximate(null, result); preconditioner.Approximate(null, result);
} }
@ -111,7 +111,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Precondi
var preconditioner = CreatePreconditioner(); var preconditioner = CreatePreconditioner();
preconditioner.Initialize(newMatrix); preconditioner.Initialize(newMatrix);
Vector<Complex> result = null; Vector result = null;
preconditioner.Approximate(vector, result); preconditioner.Approximate(vector, result);
} }

7
src/UnitTests/LinearAlgebraTests/Complex/Solvers/Preconditioners/UnitPreconditionerTest.cs

@ -1,21 +1,18 @@
namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Preconditioners namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Solvers.Preconditioners
{ {
using System.Numerics;
using LinearAlgebra.Complex; using LinearAlgebra.Complex;
using LinearAlgebra.Complex.Solvers.Preconditioners; using LinearAlgebra.Complex.Solvers.Preconditioners;
using LinearAlgebra.Generic;
using LinearAlgebra.Generic.Solvers.Preconditioners;
using MbUnit.Framework; using MbUnit.Framework;
[TestFixture] [TestFixture]
public sealed class UnitPreconditionerTest : PreconditionerTest public sealed class UnitPreconditionerTest : PreconditionerTest
{ {
internal override IPreConditioner<Complex> CreatePreconditioner() internal override IPreConditioner CreatePreconditioner()
{ {
return new UnitPreconditioner(); return new UnitPreconditioner();
} }
protected override void CheckResult(IPreConditioner<Complex> preconditioner, SparseMatrix matrix, Vector<Complex> vector, Vector<Complex> result) protected override void CheckResult(IPreConditioner preconditioner, SparseMatrix matrix, Vector vector, Vector result)
{ {
Assert.AreEqual(typeof(UnitPreconditioner), preconditioner.GetType(), "#01"); Assert.AreEqual(typeof(UnitPreconditioner), preconditioner.GetType(), "#01");

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

@ -22,7 +22,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.Iterat
public void SolveWideMatrix() public void SolveWideMatrix()
{ {
var matrix = new SparseMatrix(2, 3); var matrix = new SparseMatrix(2, 3);
Vector<Complex32> input = new DenseVector(2); Vector input = new DenseVector(2);
var solver = new BiCgStab(); var solver = new BiCgStab();
solver.Solve(matrix, input); solver.Solve(matrix, input);
@ -33,7 +33,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.Iterat
public void SolveLongMatrix() public void SolveLongMatrix()
{ {
var matrix = new SparseMatrix(3, 2); var matrix = new SparseMatrix(3, 2);
Vector<Complex32> input = new DenseVector(3); Vector input = new DenseVector(3);
var solver = new BiCgStab(); var solver = new BiCgStab();
solver.Solve(matrix, input); solver.Solve(matrix, input);
@ -44,13 +44,13 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.Iterat
public void SolveUnitMatrixAndBackMultiply() public void SolveUnitMatrixAndBackMultiply()
{ {
// Create the identity matrix // Create the identity matrix
Matrix<Complex32> matrix = SparseMatrix.Identity(100); Matrix matrix = SparseMatrix.Identity(100);
// Create the y vector // Create the y vector
Vector<Complex32> y = new DenseVector(matrix.RowCount, Complex32.One); Vector y = new DenseVector(matrix.RowCount, Complex32.One);
// Create an iteration monitor which will keep track of iterative convergence // Create an iteration monitor which will keep track of iterative convergence
var monitor = new Iterator(new IIterationStopCriterium<Complex32>[] var monitor = new Iterator(new IIterationStopCriterium[]
{ {
new IterationCountStopCriterium(MaximumIterations), new IterationCountStopCriterium(MaximumIterations),
new ResidualStopCriterium(ConvergenceBoundary), new ResidualStopCriterium(ConvergenceBoundary),
@ -84,16 +84,16 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.Iterat
public void SolveScaledUnitMatrixAndBackMultiply() public void SolveScaledUnitMatrixAndBackMultiply()
{ {
// Create the identity matrix // Create the identity matrix
Matrix<Complex32> matrix = SparseMatrix.Identity(100); Matrix matrix = SparseMatrix.Identity(100);
// Scale it with a funny number // Scale it with a funny number
matrix.Multiply(new Complex32((float)Math.PI, (float)Math.PI), matrix); matrix.Multiply(new Complex32((float)Math.PI, (float)Math.PI), matrix);
// Create the y vector // Create the y vector
Vector<Complex32> y = new DenseVector(matrix.RowCount, Complex32.One); Vector y = new DenseVector(matrix.RowCount, Complex32.One);
// Create an iteration monitor which will keep track of iterative convergence // Create an iteration monitor which will keep track of iterative convergence
var monitor = new Iterator(new IIterationStopCriterium<Complex32>[] var monitor = new Iterator(new IIterationStopCriterium[]
{ {
new IterationCountStopCriterium(MaximumIterations), new IterationCountStopCriterium(MaximumIterations),
new ResidualStopCriterium(ConvergenceBoundary), new ResidualStopCriterium(ConvergenceBoundary),
@ -166,10 +166,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.Iterat
} }
// Create the y vector // Create the y vector
Vector<Complex32> y = new DenseVector(matrix.RowCount, Complex32.One); Vector y = new DenseVector(matrix.RowCount, Complex32.One);
// Create an iteration monitor which will keep track of iterative convergence // Create an iteration monitor which will keep track of iterative convergence
var monitor = new Iterator(new IIterationStopCriterium<Complex32>[] var monitor = new Iterator(new IIterationStopCriterium[]
{ {
new IterationCountStopCriterium(MaximumIterations), new IterationCountStopCriterium(MaximumIterations),
new ResidualStopCriterium(ConvergenceBoundary), new ResidualStopCriterium(ConvergenceBoundary),
@ -205,10 +205,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.Iterat
{ {
for (var iteration = 5; iteration > 3; iteration--) for (var iteration = 5; iteration > 3; iteration--)
{ {
var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); var matrixA = (Matrix)MatrixLoader.GenerateRandomDenseMatrix(order, order);
var vectorb = MatrixLoader.GenerateRandomDenseVector(order); var vectorb = (Vector)MatrixLoader.GenerateRandomDenseVector(order);
var monitor = new Iterator(new IIterationStopCriterium<Complex32>[] var monitor = new Iterator(new IIterationStopCriterium[]
{ {
new IterationCountStopCriterium(1000), new IterationCountStopCriterium(1000),
new ResidualStopCriterium((float)Math.Pow(1.0/10.0, iteration)), new ResidualStopCriterium((float)Math.Pow(1.0/10.0, iteration)),
@ -245,10 +245,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Solvers.Iterat
{ {
for (var iteration = 5; iteration > 3; iteration--) for (var iteration = 5; iteration > 3; iteration--)
{ {
var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); var matrixA = (Matrix)MatrixLoader.GenerateRandomDenseMatrix(order, order);
var matrixB = MatrixLoader.GenerateRandomDenseMatrix(order, order); var matrixB = (Matrix)MatrixLoader.GenerateRandomDenseMatrix(order, order);
var monitor = new Iterator(new IIterationStopCriterium<Complex32>[] var monitor = new Iterator(new IIterationStopCriterium[]
{ {
new IterationCountStopCriterium(1000), new IterationCountStopCriterium(1000),
new ResidualStopCriterium((float)Math.Pow(1.0 / 10.0, iteration)) new ResidualStopCriterium((float)Math.Pow(1.0 / 10.0, iteration))

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save