Browse Source

andriy's conversion to a generic matrix

la-knuth
Marcus Cuda 16 years ago
parent
commit
cbd321574f
  1. 8
      src/FSharp/DenseMatrix.fs
  2. 6
      src/FSharp/Main.fs
  3. 43
      src/FSharp/Matrix.fs
  4. 8
      src/FSharp/SparseMatrix.fs
  5. 42
      src/FSharp/Vector.fs
  6. 4
      src/FSharpExamples/Apply.fs
  7. 5
      src/FSharpUnitTests/FsUnit.fs
  8. 25
      src/FSharpUnitTests/Program.fs
  9. 180
      src/Numerics/LinearAlgebra/Double/DenseMatrix.cs
  10. 155
      src/Numerics/LinearAlgebra/Double/DenseVector.cs
  11. 283
      src/Numerics/LinearAlgebra/Double/DiagonalMatrix.cs
  12. 47
      src/Numerics/LinearAlgebra/Double/Factorization/DenseCholesky.cs
  13. 48
      src/Numerics/LinearAlgebra/Double/Factorization/DenseLU.cs
  14. 47
      src/Numerics/LinearAlgebra/Double/Factorization/DenseQR.cs
  15. 48
      src/Numerics/LinearAlgebra/Double/Factorization/DenseSvd.cs
  16. 21
      src/Numerics/LinearAlgebra/Double/Factorization/ExtensionMethods.cs
  17. 49
      src/Numerics/LinearAlgebra/Double/Factorization/GramSchmidt.cs
  18. 51
      src/Numerics/LinearAlgebra/Double/Factorization/SparseCholesky.cs
  19. 50
      src/Numerics/LinearAlgebra/Double/Factorization/SparseLU.cs
  20. 53
      src/Numerics/LinearAlgebra/Double/Factorization/SparseQR.cs
  21. 62
      src/Numerics/LinearAlgebra/Double/Factorization/SparseSvd.cs
  22. 84
      src/Numerics/LinearAlgebra/Double/Factorization/UserCholesky.cs
  23. 50
      src/Numerics/LinearAlgebra/Double/Factorization/UserLU.cs
  24. 53
      src/Numerics/LinearAlgebra/Double/Factorization/UserQR.cs
  25. 62
      src/Numerics/LinearAlgebra/Double/Factorization/UserSvd.cs
  26. 5
      src/Numerics/LinearAlgebra/Double/IO/DelimitedReader.cs
  27. 7
      src/Numerics/LinearAlgebra/Double/IO/DelimitedWriter.cs
  28. 7
      src/Numerics/LinearAlgebra/Double/IO/Matlab/MatlabFile.cs
  29. 11
      src/Numerics/LinearAlgebra/Double/IO/Matlab/MatlabParser.cs
  30. 13
      src/Numerics/LinearAlgebra/Double/IO/MatlabReader.cs
  31. 13
      src/Numerics/LinearAlgebra/Double/IO/MatrixReader.cs
  32. 30
      src/Numerics/LinearAlgebra/Double/IO/MatrixWriter.cs
  33. 113
      src/Numerics/LinearAlgebra/Double/Solvers/Iterative/BiCgStab.cs
  34. 70
      src/Numerics/LinearAlgebra/Double/Solvers/Iterative/CompositeSolver.cs
  35. 101
      src/Numerics/LinearAlgebra/Double/Solvers/Iterative/GpBiCg.cs
  36. 107
      src/Numerics/LinearAlgebra/Double/Solvers/Iterative/MlkBiCgStab.cs
  37. 73
      src/Numerics/LinearAlgebra/Double/Solvers/Iterative/TFQMR.cs
  38. 43
      src/Numerics/LinearAlgebra/Double/Solvers/Iterator.cs
  39. 14
      src/Numerics/LinearAlgebra/Double/Solvers/Preconditioners/Diagonal.cs
  40. 46
      src/Numerics/LinearAlgebra/Double/Solvers/Preconditioners/Ilutp.cs
  41. 18
      src/Numerics/LinearAlgebra/Double/Solvers/Preconditioners/IlutpElementSorter.cs
  42. 18
      src/Numerics/LinearAlgebra/Double/Solvers/Preconditioners/IncompleteLU.cs
  43. 15
      src/Numerics/LinearAlgebra/Double/Solvers/Preconditioners/UnitPreconditioner.cs
  44. 18
      src/Numerics/LinearAlgebra/Double/Solvers/StopCriterium/DivergenceStopCriterium.cs
  45. 18
      src/Numerics/LinearAlgebra/Double/Solvers/StopCriterium/FailureStopCriterium.cs
  46. 12
      src/Numerics/LinearAlgebra/Double/Solvers/StopCriterium/IterationCountStopCriterium.cs
  47. 18
      src/Numerics/LinearAlgebra/Double/Solvers/StopCriterium/ResidualStopCriterium.cs
  48. 267
      src/Numerics/LinearAlgebra/Double/SparseMatrix.cs
  49. 213
      src/Numerics/LinearAlgebra/Double/SparseVector.cs
  50. 82
      src/Numerics/LinearAlgebra/Generic/Factorization/Cholesky.cs
  51. 91
      src/Numerics/LinearAlgebra/Generic/Factorization/LU.cs
  52. 88
      src/Numerics/LinearAlgebra/Generic/Factorization/QR.cs
  53. 118
      src/Numerics/LinearAlgebra/Generic/Factorization/Svd.cs
  54. 28
      src/Numerics/LinearAlgebra/Generic/ISolver.cs
  55. 259
      src/Numerics/LinearAlgebra/Generic/Matrix.Arithmetic.cs
  56. 317
      src/Numerics/LinearAlgebra/Generic/Matrix.cs
  57. 21
      src/Numerics/LinearAlgebra/Generic/Solvers/IIterativeSolver.cs
  58. 10
      src/Numerics/LinearAlgebra/Generic/Solvers/IIterativeSolverSetup.cs
  59. 29
      src/Numerics/LinearAlgebra/Generic/Solvers/IIterator.cs
  60. 14
      src/Numerics/LinearAlgebra/Generic/Solvers/Preconditioners/IPreConditioner.cs
  61. 2
      src/Numerics/LinearAlgebra/Generic/Solvers/Status/CalculationCancelled.cs
  62. 2
      src/Numerics/LinearAlgebra/Generic/Solvers/Status/CalculationConverged.cs
  63. 2
      src/Numerics/LinearAlgebra/Generic/Solvers/Status/CalculationDiverged.cs
  64. 2
      src/Numerics/LinearAlgebra/Generic/Solvers/Status/CalculationFailure.cs
  65. 2
      src/Numerics/LinearAlgebra/Generic/Solvers/Status/CalculationIndetermined.cs
  66. 2
      src/Numerics/LinearAlgebra/Generic/Solvers/Status/CalculationRunning.cs
  67. 2
      src/Numerics/LinearAlgebra/Generic/Solvers/Status/CalculationStoppedWithoutConvergence.cs
  68. 2
      src/Numerics/LinearAlgebra/Generic/Solvers/Status/ICalculationStatus.cs
  69. 17
      src/Numerics/LinearAlgebra/Generic/Solvers/StopCriterium/IIterationStopCriterium.cs
  70. 4
      src/Numerics/LinearAlgebra/Generic/Solvers/StopCriterium/StopLevel.cs
  71. 370
      src/Numerics/LinearAlgebra/Generic/Vector.cs
  72. 44
      src/Numerics/Numerics.csproj
  73. 130
      src/Silverlight/Silverlight.csproj
  74. 11
      src/UnitTests/LinearAlgebraTests/Double/DenseMatrixTests.cs
  75. 13
      src/UnitTests/LinearAlgebraTests/Double/DenseVectorTests.cs
  76. 13
      src/UnitTests/LinearAlgebraTests/Double/DiagonalMatrixTests.cs
  77. 9
      src/UnitTests/LinearAlgebraTests/Double/LinearAlgebraProviderTests.cs
  78. 27
      src/UnitTests/LinearAlgebraTests/Double/MatrixLoader.cs
  79. 221
      src/UnitTests/LinearAlgebraTests/Double/MatrixTests.Arithmetic.cs
  80. 320
      src/UnitTests/LinearAlgebraTests/Double/MatrixTests.cs
  81. 28
      src/UnitTests/LinearAlgebraTests/Double/Solvers/Iterative/BiCgStabTest.cs
  82. 28
      src/UnitTests/LinearAlgebraTests/Double/Solvers/Iterative/GpBiCgTest.cs
  83. 28
      src/UnitTests/LinearAlgebraTests/Double/Solvers/Iterative/MlkBiCgStabTest.cs
  84. 28
      src/UnitTests/LinearAlgebraTests/Double/Solvers/Iterative/TFQMRTest.cs
  85. 33
      src/UnitTests/LinearAlgebraTests/Double/Solvers/IteratorTest.cs
  86. 8
      src/UnitTests/LinearAlgebraTests/Double/Solvers/Preconditioners/DiagonalTest.cs
  87. 14
      src/UnitTests/LinearAlgebraTests/Double/Solvers/Preconditioners/IlutpTest.cs
  88. 18
      src/UnitTests/LinearAlgebraTests/Double/Solvers/Preconditioners/IncompleteLUTest.cs
  89. 19
      src/UnitTests/LinearAlgebraTests/Double/Solvers/Preconditioners/PreConditionerTest.cs
  90. 6
      src/UnitTests/LinearAlgebraTests/Double/Solvers/Preconditioners/UnitPreconditionerTest.cs
  91. 2
      src/UnitTests/LinearAlgebraTests/Double/Solvers/StopCriterium/DivergenceStopCriteriumTest.cs
  92. 2
      src/UnitTests/LinearAlgebraTests/Double/Solvers/StopCriterium/FailureStopCriteriumTest.cs
  93. 2
      src/UnitTests/LinearAlgebraTests/Double/Solvers/StopCriterium/IterationCountStopCriteriumTest.cs
  94. 2
      src/UnitTests/LinearAlgebraTests/Double/Solvers/StopCriterium/ResidualStopCriteriumTest.cs
  95. 11
      src/UnitTests/LinearAlgebraTests/Double/SparseMatrixTests.cs
  96. 15
      src/UnitTests/LinearAlgebraTests/Double/SparseVectorTest.cs
  97. 110
      src/UnitTests/LinearAlgebraTests/Double/UserDefinedMatrixTests.cs
  98. 141
      src/UnitTests/LinearAlgebraTests/Double/UserDefinedVectorTests.cs
  99. 45
      src/UnitTests/LinearAlgebraTests/Double/VectorTests.Arithmetic.cs
  100. 10
      src/UnitTests/LinearAlgebraTests/Double/VectorTests.cs

8
src/FSharp/DenseMatrix.fs

@ -30,8 +30,8 @@
// </copyright> // </copyright>
namespace MathNet.Numerics.LinearAlgebra.Double namespace MathNet.Numerics.LinearAlgebra.Double
open MathNet.Numerics.LinearAlgebra open MathNet.Numerics.LinearAlgebra
open MathNet.Numerics.LinearAlgebra.Generic
/// A module which implements functional dense vector operations. /// A module which implements functional dense vector operations.
module DenseMatrix = module DenseMatrix =
@ -81,7 +81,7 @@ module DenseMatrix =
A A
/// Create a square matrix with the vector elements on the diagonal. /// Create a square matrix with the vector elements on the diagonal.
let inline diag (v: #Vector) = let inline diag (v: #Vector<float>) =
let n = v.Count let n = v.Count
let A = new DenseMatrix(n,n) let A = new DenseMatrix(n,n)
for i=0 to n-1 do for i=0 to n-1 do
@ -89,13 +89,13 @@ module DenseMatrix =
A A
/// Initialize a matrix by calling a construction function for every row. /// Initialize a matrix by calling a construction function for every row.
let inline initRow (n: int) (m: int) (f: int -> #Vector) = let inline initRow (n: int) (m: int) (f: int -> #Vector<float>) =
let A = new DenseMatrix(n,m) let A = new DenseMatrix(n,m)
for i=0 to n-1 do A.SetRow(i, f i) for i=0 to n-1 do A.SetRow(i, f i)
A A
/// Initialize a matrix by calling a construction function for every column. /// Initialize a matrix by calling a construction function for every column.
let inline initCol (n: int) (m: int) (f: int -> #Vector) = let inline initCol (n: int) (m: int) (f: int -> #Vector<float>) =
let A = new DenseMatrix(n,m) let A = new DenseMatrix(n,m)
for i=0 to m-1 do A.SetColumn(i, f i) for i=0 to m-1 do A.SetColumn(i, f i)
A A

6
src/FSharp/Main.fs

@ -31,12 +31,12 @@
namespace MathNet.Numerics namespace MathNet.Numerics
open MathNet.Numerics.LinearAlgebra.Double open MathNet.Numerics.LinearAlgebra.Double
open MathNet.Numerics.LinearAlgebra.Generic
/// A module which implements some F# utility functions. /// A module which implements some F# utility functions.
module FSharp = module FSharp =
/// Construct a dense matrix from a list of floating point numbers. /// Construct a dense matrix from a list of floating point numbers.
let inline matrix (lst: list<list<float>>) = DenseMatrix.ofList lst :> Matrix let inline matrix (lst: list<list<float>>) = DenseMatrix.ofList lst :> Matrix<float>
/// Construct a dense vector from a list of floating point numbers. /// Construct a dense vector from a list of floating point numbers.
let inline vector (lst: list<float>) = DenseVector.ofList lst :> Vector let inline vector (lst: list<float>) = DenseVector.ofList lst :> Vector<float>

43
src/FSharp/Matrix.fs

@ -31,12 +31,13 @@
namespace MathNet.Numerics.LinearAlgebra.Double namespace MathNet.Numerics.LinearAlgebra.Double
open MathNet.Numerics.LinearAlgebra.Double open MathNet.Numerics.LinearAlgebra.Double
open MathNet.Numerics.LinearAlgebra.Generic
/// A module which implements functional matrix operations. /// A module which implements functional matrix operations.
module Matrix = module Matrix =
/// Fold a function over all matrix elements. /// Fold a function over all matrix elements.
let inline fold (f: 'a -> float -> 'a) (acc0: 'a) (A: #Matrix) = let inline fold (f: 'a -> float -> 'a) (acc0: 'a) (A: #Matrix<float>) =
let n = A.RowCount let n = A.RowCount
let m = A.ColumnCount let m = A.ColumnCount
let mutable acc = acc0 let mutable acc = acc0
@ -46,7 +47,7 @@ module Matrix =
acc acc
/// Fold a matrix by applying a given function to all matrix elements. /// Fold a matrix by applying a given function to all matrix elements.
let inline foldi (f: int -> int -> 'a -> float -> 'a) (acc0: 'a) (A: #Matrix) = let inline foldi (f: int -> int -> 'a -> float -> 'a) (acc0: 'a) (A: #Matrix<float>) =
let n = A.RowCount let n = A.RowCount
let m = A.ColumnCount let m = A.ColumnCount
let mutable acc = acc0 let mutable acc = acc0
@ -56,13 +57,13 @@ module Matrix =
acc acc
/// Create a 2D array from a matrix. /// Create a 2D array from a matrix.
let inline toArray2 (A: #Matrix) = let inline toArray2 (A: #Matrix<float>) =
let n = A.RowCount let n = A.RowCount
let m = A.ColumnCount let m = A.ColumnCount
Array2D.init n m (fun i j -> (A.Item(i,j))) Array2D.init n m (fun i j -> (A.Item(i,j)))
/// Checks whether a predicate holds for all elements of a matrix. /// Checks whether a predicate holds for all elements of a matrix.
let inline forall (p: float -> bool) (A: #Matrix) = let inline forall (p: float -> bool) (A: #Matrix<float>) =
let mutable b = true let mutable b = true
let mutable i = 0 let mutable i = 0
let mutable j = 0 let mutable j = 0
@ -73,7 +74,7 @@ module Matrix =
b b
/// Chechks whether a predicate holds for at least one element of a matrix. /// Chechks whether a predicate holds for at least one element of a matrix.
let inline exists (p: float -> bool) (A: #Matrix) = let inline exists (p: float -> bool) (A: #Matrix<float>) =
let mutable b = false let mutable b = false
let mutable i = 0 let mutable i = 0
let mutable j = 0 let mutable j = 0
@ -84,7 +85,7 @@ module Matrix =
b b
/// Checks whether a position dependent predicate holds for all elements of a matrix. /// Checks whether a position dependent predicate holds for all elements of a matrix.
let inline foralli (p: int -> int -> float -> bool) (A: #Matrix) = let inline foralli (p: int -> int -> float -> bool) (A: #Matrix<float>) =
let mutable b = true let mutable b = true
let mutable i = 0 let mutable i = 0
let mutable j = 0 let mutable j = 0
@ -95,7 +96,7 @@ module Matrix =
b b
/// Checks whether a position dependent predicate holds for at least one element of a matrix. /// Checks whether a position dependent predicate holds for at least one element of a matrix.
let inline existsi (p: int -> int -> float -> bool) (A: #Matrix) = let inline existsi (p: int -> int -> float -> bool) (A: #Matrix<float>) =
let mutable b = false let mutable b = false
let mutable i = 0 let mutable i = 0
let mutable j = 0 let mutable j = 0
@ -106,7 +107,7 @@ module Matrix =
b b
/// Map every matrix element using the given function. /// Map every matrix element using the given function.
let inline map (f: float -> float) (A: #Matrix) = let inline map (f: float -> float) (A: #Matrix<float>) =
let N = A.RowCount let N = A.RowCount
let M = A.ColumnCount let M = A.ColumnCount
let C = A.Clone() let C = A.Clone()
@ -116,7 +117,7 @@ module Matrix =
C C
/// Map every matrix element using the given position dependent function. /// Map every matrix element using the given position dependent function.
let inline mapi (f: int -> int -> float -> float) (A: #Matrix) = let inline mapi (f: int -> int -> float -> float) (A: #Matrix<float>) =
let N = A.RowCount let N = A.RowCount
let M = A.ColumnCount let M = A.ColumnCount
let C = A.Clone() let C = A.Clone()
@ -126,25 +127,25 @@ module Matrix =
C C
/// In-place assignment. /// In-place assignment.
let inline inplaceAssign (f: int -> int -> float) (A: #Matrix) = let inline inplaceAssign (f: int -> int -> float) (A: #Matrix<float>) =
for i=0 to A.RowCount-1 do for i=0 to A.RowCount-1 do
for j=0 to A.ColumnCount-1 do for j=0 to A.ColumnCount-1 do
A.Item(i,j) <- f i j A.Item(i,j) <- f i j
/// In-place map of every matrix element using a position dependent function. /// In-place map of every matrix element using a position dependent function.
let inline inplaceMapi (f: int -> int -> float -> float) (A: #Matrix) = let inline inplaceMapi (f: int -> int -> float -> float) (A: #Matrix<float>) =
for i=0 to A.RowCount-1 do for i=0 to A.RowCount-1 do
for j=0 to A.ColumnCount-1 do for j=0 to A.ColumnCount-1 do
A.Item(i,j) <- f i j (A.Item(i,j)) A.Item(i,j) <- f i j (A.Item(i,j))
/// Creates a sequence that iterates the non-zero entries in the matrix. /// Creates a sequence that iterates the non-zero entries in the matrix.
let inline nonZeroEntries (A: #Matrix) = let inline nonZeroEntries (A: #Matrix<float>) =
seq { for i in 0 .. A.RowCount-1 do seq { for i in 0 .. A.RowCount-1 do
for j in 0 .. A.ColumnCount-1 do for j in 0 .. A.ColumnCount-1 do
if A.Item(i,j) <> 0.0 then yield (i,j, A.Item(i,j)) } if A.Item(i,j) <> 0.0 then yield (i,j, A.Item(i,j)) }
/// Returns the sum of all elements of a matrix. /// Returns the sum of all elements of a matrix.
let inline sum (A: #Matrix) = let inline sum (A: #Matrix<float>) =
let mutable f = 0.0 let mutable f = 0.0
for i=0 to A.RowCount-1 do for i=0 to A.RowCount-1 do
for j=0 to A.ColumnCount-1 do for j=0 to A.ColumnCount-1 do
@ -152,49 +153,49 @@ module Matrix =
f f
/// Iterates over all elements of a matrix. /// Iterates over all elements of a matrix.
let inline iter (f: float -> unit) (A: #Matrix) = let inline iter (f: float -> unit) (A: #Matrix<float>) =
for i=0 to A.RowCount-1 do for i=0 to A.RowCount-1 do
for j=0 to A.ColumnCount-1 do for j=0 to A.ColumnCount-1 do
f (A.Item(i,j)) f (A.Item(i,j))
() ()
/// Iterates over all elements of a matrix using the element indices. /// Iterates over all elements of a matrix using the element indices.
let inline iteri (f: int -> int -> float -> unit) (A: #Matrix) = let inline iteri (f: int -> int -> float -> unit) (A: #Matrix<float>) =
for i=0 to A.RowCount-1 do for i=0 to A.RowCount-1 do
for j=0 to A.ColumnCount-1 do for j=0 to A.ColumnCount-1 do
f i j (A.Item(i,j)) f i j (A.Item(i,j))
() ()
/// Fold one column. /// Fold one column.
let inline foldCol (f: 'a -> float -> 'a) acc (A: #Matrix) k = let inline foldCol (f: 'a -> float -> 'a) acc (A: #Matrix<float>) k =
let mutable macc = acc let mutable macc = acc
for i=0 to A.RowCount-1 do for i=0 to A.RowCount-1 do
macc <- f macc (A.Item(i,k)) macc <- f macc (A.Item(i,k))
macc macc
/// Fold one row. /// Fold one row.
let inline foldRow (f: 'a -> float -> 'a) acc (A: #Matrix) k = let inline foldRow (f: 'a -> float -> 'a) acc (A: #Matrix<float>) k =
let mutable macc = acc let mutable macc = acc
for i=0 to A.ColumnCount-1 do for i=0 to A.ColumnCount-1 do
macc <- f macc (A.Item(k,i)) macc <- f macc (A.Item(k,i))
macc macc
/// Fold all columns into one row vector. /// Fold all columns into one row vector.
let inline foldByCol (f: float -> float -> float) acc (A: #Matrix) = let inline foldByCol (f: float -> float -> float) acc (A: #Matrix<float>) =
let v = new DenseVector(A.ColumnCount) let v = new DenseVector(A.ColumnCount)
for k=0 to A.ColumnCount-1 do for k=0 to A.ColumnCount-1 do
let mutable macc = acc let mutable macc = acc
for i=0 to A.RowCount-1 do for i=0 to A.RowCount-1 do
macc <- f macc (A.Item(i,k)) macc <- f macc (A.Item(i,k))
v.[k] <- macc v.[k] <- macc
v :> Vector v :> Vector<float>
/// Fold all rows into one column vector. /// Fold all rows into one column vector.
let inline foldByRow (f: float -> float -> float) acc (A: #Matrix) = let inline foldByRow (f: float -> float -> float) acc (A: #Matrix<float>) =
let v = new DenseVector(A.RowCount) let v = new DenseVector(A.RowCount)
for k=0 to A.RowCount-1 do for k=0 to A.RowCount-1 do
let mutable macc = acc let mutable macc = acc
for i=0 to A.ColumnCount-1 do for i=0 to A.ColumnCount-1 do
macc <- f macc (A.Item(k,i)) macc <- f macc (A.Item(k,i))
v.[k] <- macc v.[k] <- macc
v :> Vector v :> Vector<float>

8
src/FSharp/SparseMatrix.fs

@ -31,7 +31,7 @@
namespace MathNet.Numerics.LinearAlgebra.Double namespace MathNet.Numerics.LinearAlgebra.Double
open MathNet.Numerics.LinearAlgebra open MathNet.Numerics.LinearAlgebra
open MathNet.Numerics.LinearAlgebra.Generic
/// A module which implements functional sparse vector operations. /// A module which implements functional sparse vector operations.
module SparseMatrix = module SparseMatrix =
@ -55,7 +55,7 @@ module SparseMatrix =
A A
/// Create a square matrix with the vector elements on the diagonal. /// Create a square matrix with the vector elements on the diagonal.
let inline diag (v: #Vector) = let inline diag (v: #Vector<float>) =
let n = v.Count let n = v.Count
let A = new Double.SparseMatrix(n,n) let A = new Double.SparseMatrix(n,n)
for i=0 to n-1 do for i=0 to n-1 do
@ -63,13 +63,13 @@ module SparseMatrix =
A A
/// Initialize a matrix by calling a construction function for every row. /// Initialize a matrix by calling a construction function for every row.
let inline initRow (n: int) (m: int) (f: int -> #Vector) = let inline initRow (n: int) (m: int) (f: int -> #Vector<float>) =
let A = new Double.SparseMatrix(n,m) let A = new Double.SparseMatrix(n,m)
for i=0 to n-1 do A.SetRow(i, f i) for i=0 to n-1 do A.SetRow(i, f i)
A A
/// Initialize a matrix by calling a construction function for every column. /// Initialize a matrix by calling a construction function for every column.
let inline initCol (n: int) (m: int) (f: int -> #Vector) = let inline initCol (n: int) (m: int) (f: int -> #Vector<float>) =
let A = new Double.SparseMatrix(n,m) let A = new Double.SparseMatrix(n,m)
for i=0 to n-1 do A.SetColumn(i, f i) for i=0 to n-1 do A.SetColumn(i, f i)
A A

42
src/FSharp/Vector.fs

@ -31,77 +31,77 @@
namespace MathNet.Numerics.LinearAlgebra.Double namespace MathNet.Numerics.LinearAlgebra.Double
open MathNet.Numerics.LinearAlgebra open MathNet.Numerics.LinearAlgebra
open MathNet.Numerics.LinearAlgebra.Generic
/// A module which implements functional vector operations. /// A module which implements functional vector operations.
module Vector = module Vector =
/// Transform a vector into an array. /// Transform a vector into an array.
let inline toArray (v: #Vector) = let inline toArray (v: #Vector<float>) =
let n = v.Count let n = v.Count
Array.init n (fun i -> v.Item(i)) Array.init n (fun i -> v.Item(i))
/// Transform a vector into an array. /// Transform a vector into an array.
let inline toList (v: #Vector) = let inline toList (v: #Vector<float>) =
let n = v.Count let n = v.Count
List.init n (fun i -> v.Item(i)) List.init n (fun i -> v.Item(i))
/// In-place mutation by applying a function to every element of the vector. /// In-place mutation by applying a function to every element of the vector.
let inline mapInPlace (f: float -> float) (v: #Vector) = let inline mapInPlace (f: float -> float) (v: #Vector<float>) =
for i=0 to v.Count-1 do for i=0 to v.Count-1 do
v.Item(i) <- f (v.Item(i)) v.Item(i) <- f (v.Item(i))
() ()
/// In-place mutation by applying a function to every element of the vector. /// In-place mutation by applying a function to every element of the vector.
let inline mapiInPlace (f: int -> float -> float) (v: #Vector) = let inline mapiInPlace (f: int -> float -> float) (v: #Vector<float>) =
for i=0 to v.Count-1 do for i=0 to v.Count-1 do
v.Item(i) <- f i (v.Item(i)) v.Item(i) <- f i (v.Item(i))
() ()
/// In-place vector addition. /// In-place vector addition.
let inline addInPlace (v: #Vector) (w: #Vector) = v.Add(w, v) let inline addInPlace (v: #Vector<float>) (w: #Vector<float>) = v.Add(w, v)
/// In place vector subtraction. /// In place vector subtraction.
let inline subInPlace (v: #Vector) (w: #Vector) = v.Subtract(w, v) let inline subInPlace (v: #Vector<float>) (w: #Vector<float>) = v.Subtract(w, v)
/// Functional map operator for vectors. /// Functional map operator for vectors.
/// <include file='../../../../FSharpExamples/DenseVector.xml' path='example'/> /// <include file='../../../../FSharpExamples/DenseVector.xml' path='example'/>
let inline map f (v: #Vector) = let inline map f (v: #Vector<float>) =
let w = v.Clone() let w = v.Clone()
mapInPlace (fun x -> f x) w mapInPlace (fun x -> f x) w
w w
/// Applies a function to all elements of the vector. /// Applies a function to all elements of the vector.
let inline iter (f: float -> unit) (v: #Vector) = let inline iter (f: float -> unit) (v: #Vector<float>) =
for i=0 to v.Count-1 do for i=0 to v.Count-1 do
f (v.Item i) f (v.Item i)
/// Applies a function to all elements of the vector. /// Applies a function to all elements of the vector.
let inline iteri (f: int -> float -> unit) (v: #Vector) = let inline iteri (f: int -> float -> unit) (v: #Vector<float>) =
for i=0 to v.Count-1 do for i=0 to v.Count-1 do
f i (v.Item i) f i (v.Item i)
/// Maps a vector to a new vector by applying a function to every element. /// Maps a vector to a new vector by applying a function to every element.
let inline mapi (f: int -> float -> float) (v: #Vector) = let inline mapi (f: int -> float -> float) (v: #Vector<float>) =
let w = v.Clone() let w = v.Clone()
mapiInPlace f w mapiInPlace f w
w w
/// Fold all entries of a vector. /// Fold all entries of a vector.
let inline fold (f: 'a -> float -> 'a) (acc0: 'a) (v: #Vector) = let inline fold (f: 'a -> float -> 'a) (acc0: 'a) (v: #Vector<float>) =
let mutable acc = acc0 let mutable acc = acc0
for i=0 to v.Count-1 do for i=0 to v.Count-1 do
acc <- f acc (v.Item(i)) acc <- f acc (v.Item(i))
acc acc
/// Fold all entries of a vector using a position dependent folding function. /// Fold all entries of a vector using a position dependent folding function.
let inline foldi (f: int -> 'a -> float -> 'a) (acc0: 'a) (v: #Vector) = let inline foldi (f: int -> 'a -> float -> 'a) (acc0: 'a) (v: #Vector<float>) =
let mutable acc = acc0 let mutable acc = acc0
for i=0 to v.Count-1 do for i=0 to v.Count-1 do
acc <- f i acc (v.Item(i)) acc <- f i acc (v.Item(i))
acc acc
/// Checks whether a predicate is satisfied for every element in the vector. /// Checks whether a predicate is satisfied for every element in the vector.
let inline forall (p: float -> bool) (v: #Vector) = let inline forall (p: float -> bool) (v: #Vector<float>) =
let mutable b = true let mutable b = true
let mutable i = 0 let mutable i = 0
while b && i < v.Count do while b && i < v.Count do
@ -110,7 +110,7 @@ module Vector =
b b
/// Checks whether there is an entry in the vector that satisfies a given predicate. /// Checks whether there is an entry in the vector that satisfies a given predicate.
let inline exists (p: float -> bool) (v: #Vector) = let inline exists (p: float -> bool) (v: #Vector<float>) =
let mutable b = false let mutable b = false
let mutable i = 0 let mutable i = 0
while not(b) && i < v.Count do while not(b) && i < v.Count do
@ -119,7 +119,7 @@ module Vector =
b b
/// Checks whether a predicate is true for all entries in a vector. /// Checks whether a predicate is true for all entries in a vector.
let inline foralli (p: int -> float -> bool) (v: #Vector) = let inline foralli (p: int -> float -> bool) (v: #Vector<float>) =
let mutable b = true let mutable b = true
let mutable i = 0 let mutable i = 0
while b && i < v.Count do while b && i < v.Count do
@ -128,7 +128,7 @@ module Vector =
b b
/// Checks whether there is an entry in the vector that satisfies a given position dependent predicate. /// Checks whether there is an entry in the vector that satisfies a given position dependent predicate.
let inline existsi (p: int -> float -> bool) (v: #Vector) = let inline existsi (p: int -> float -> bool) (v: #Vector<float>) =
let mutable b = false let mutable b = false
let mutable i = 0 let mutable i = 0
while not(b) && i < v.Count do while not(b) && i < v.Count do
@ -137,7 +137,7 @@ module Vector =
b b
/// Scans a vector; like fold but returns the intermediate result. /// Scans a vector; like fold but returns the intermediate result.
let inline scan (f: float -> float -> float) (v: #Vector) = let inline scan (f: float -> float -> float) (v: #Vector<float>) =
let w = v.Clone() let w = v.Clone()
let mutable p = v.Item(0) let mutable p = v.Item(0)
for i=1 to v.Count-1 do for i=1 to v.Count-1 do
@ -146,7 +146,7 @@ module Vector =
w w
/// Scans a vector; like fold but returns the intermediate result. /// Scans a vector; like fold but returns the intermediate result.
let inline scanBack (f: float -> float -> float) (v: #Vector) = let inline scanBack (f: float -> float -> float) (v: #Vector<float>) =
let w = v.Clone() let w = v.Clone()
let mutable p = v.Item(v.Count-1) let mutable p = v.Item(v.Count-1)
for i=2 to v.Count do for i=2 to v.Count do
@ -155,14 +155,14 @@ module Vector =
w w
/// Reduces a vector: the result of this function will be f(...f(f(v[0],v[1]), v[2]),..., v[n]). /// Reduces a vector: the result of this function will be f(...f(f(v[0],v[1]), v[2]),..., v[n]).
let inline reduce (f: float -> float -> float) (v: #Vector) = let inline reduce (f: float -> float -> float) (v: #Vector<float>) =
let mutable p = v.Item(0) let mutable p = v.Item(0)
for i=1 to v.Count-1 do for i=1 to v.Count-1 do
p <- f p (v.Item(i)) p <- f p (v.Item(i))
p p
/// Reduces a vector: the result of this function will be f(v[1], ..., f(v[n-2], f(v[n-1],v[n]))...). /// Reduces a vector: the result of this function will be f(v[1], ..., f(v[n-2], f(v[n-1],v[n]))...).
let inline reduceBack (f: float -> float -> float) (v: #Vector) = let inline reduceBack (f: float -> float -> float) (v: #Vector<float>) =
let mutable p = v.Item(v.Count-1) let mutable p = v.Item(v.Count-1)
for i=2 to v.Count do for i=2 to v.Count do
p <- f (v.Item(v.Count - i)) p p <- f (v.Item(v.Count - i)) p

4
src/FSharpExamples/Apply.fs

@ -30,7 +30,7 @@ module MathNet.Numerics.FSharp.Examples.Apply
open System.Numerics open System.Numerics
open MathNet.Numerics open MathNet.Numerics
open MathNet.Numerics.LinearAlgebra.Double open MathNet.Numerics.LinearAlgebra.Double
open MathNet.Numerics.LinearAlgebra.Generic
/// Flag to specify wether we want pretty printing or tab separated output. /// Flag to specify wether we want pretty printing or tab separated output.
let prettyPrint = false let prettyPrint = false
@ -61,7 +61,7 @@ let FunctionList : (string * (float -> float) * (float -> float)) [] =
/// A vector with random entries. /// A vector with random entries.
let w = let w =
let rnd = new Random.MersenneTwister() let rnd = new Random.MersenneTwister()
(new DenseVector(Array.init N (fun _ -> rnd.NextDouble() * 10.0))) :> Vector (new DenseVector(Array.init N (fun _ -> rnd.NextDouble() * 10.0))) :> Vector<float>
/// A stopwatch to time the execution. /// A stopwatch to time the execution.
let sw = new System.Diagnostics.Stopwatch() let sw = new System.Diagnostics.Stopwatch()

5
src/FSharpUnitTests/FsUnit.fs

@ -29,6 +29,7 @@ namespace FsUnit
open MathNet.Numerics open MathNet.Numerics
open MathNet.Numerics.LinearAlgebra.Double open MathNet.Numerics.LinearAlgebra.Double
open MathNet.Numerics.LinearAlgebra.Generic
type Result = type Result =
| Pass | Pass
@ -174,7 +175,7 @@ module SpecOps =
else Fail (sprintf "Expected: %A\nActual: %A" expected actual)) else Fail (sprintf "Expected: %A\nActual: %A" expected actual))
(sprintf "NOT Expected: %A\nActual: %A" expected actual) (sprintf "NOT Expected: %A\nActual: %A" expected actual)
let approximately_vector_equal (places : int) (expected: #Vector) (actual: #Vector) = let approximately_vector_equal (places : int) (expected: #Vector<float>) (actual: #Vector<float>) =
make (fun () -> make (fun () ->
let mutable f = true let mutable f = true
for i=0 to expected.Count-1 do for i=0 to expected.Count-1 do
@ -184,7 +185,7 @@ module SpecOps =
else Fail (sprintf "Expected: %A\nActual: %A" expected actual)) else Fail (sprintf "Expected: %A\nActual: %A" expected actual))
(sprintf "NOT Expected: %A\nActual: %A" expected actual) (sprintf "NOT Expected: %A\nActual: %A" expected actual)
let approximately_matrix_equal (places : int) (expected: #Matrix) (actual: #Matrix) = let approximately_matrix_equal (places : int) (expected: #Matrix<float>) (actual: #Matrix<float>) =
make (fun () -> make (fun () ->
let mutable f = true let mutable f = true
for i=0 to expected.RowCount-1 do for i=0 to expected.RowCount-1 do

25
src/FSharpUnitTests/Program.fs

@ -1,6 +1,7 @@
open FsUnit open FsUnit
open MathNet.Numerics.FSharp open MathNet.Numerics.FSharp
open MathNet.Numerics.LinearAlgebra.Double open MathNet.Numerics.LinearAlgebra.Double
open MathNet.Numerics.LinearAlgebra.Generic
/// Unit tests for the dense vector type. /// Unit tests for the dense vector type.
let DenseVectorTests = let DenseVectorTests =
@ -29,13 +30,13 @@ let DenseVectorTests =
let SparseVectorTests = let SparseVectorTests =
/// A small uniform vector. /// A small uniform vector.
let smallv = new DenseVector( [|0.0;0.3;0.0;0.0;0.0|] ) :> Vector let smallv = new DenseVector( [|0.0;0.3;0.0;0.0;0.0|] ) :> Vector<float>
specs "SparseVector" [ specs "SparseVector" [
spec "SparseVector.ofList" spec "SparseVector.ofList"
((SparseVector.ofList 5 [ (1,0.3) ] :> Vector) |> should equal smallv) ((SparseVector.ofList 5 [ (1,0.3) ] :> Vector<float>) |> should equal smallv)
spec "SparseVector.ofSeq" spec "SparseVector.ofSeq"
((SparseVector.ofSeq 5 (List.toSeq [ (1,0.3) ]) :> Vector) |> should equal smallv) ((SparseVector.ofSeq 5 (List.toSeq [ (1,0.3) ]) :> Vector<float>) |> should equal smallv)
] ]
@ -43,10 +44,10 @@ let SparseVectorTests =
let VectorTests = let VectorTests =
/// A small uniform vector. /// A small uniform vector.
let smallv = new DenseVector( [|0.3;0.3;0.3;0.3;0.3|] ) :> Vector let smallv = new DenseVector( [|0.3;0.3;0.3;0.3;0.3|] ) :> Vector<float>
/// A large vector with increasingly large entries /// A large vector with increasingly large entries
let largev = new DenseVector( Array.init 100 (fun i -> float i / 100.0) ) :> Vector let largev = new DenseVector( Array.init 100 (fun i -> float i / 100.0) ) :> Vector<float>
specs "Vector" [ specs "Vector" [
spec "Vector.toArray" spec "Vector.toArray"
@ -86,9 +87,9 @@ let VectorTests =
spec "Vector.existsi" spec "Vector.existsi"
(Vector.existsi (fun i x -> x = 0.3 && i = 2) smallv |> should equal true) (Vector.existsi (fun i x -> x = 0.3 && i = 2) smallv |> should equal true)
spec "Vector.scan" spec "Vector.scan"
(Vector.scan (fun acc x -> acc + x) smallv |> should approximately_vector_equal 14 (new DenseVector( [|0.3;0.6;0.9;1.2;1.5|] ) :> Vector) ) (Vector.scan (fun acc x -> acc + x) smallv |> should approximately_vector_equal 14 (new DenseVector( [|0.3;0.6;0.9;1.2;1.5|] ) :> Vector<float>) )
spec "Vector.scanBack" spec "Vector.scanBack"
(Vector.scanBack (fun x acc -> acc + x) smallv |> should approximately_vector_equal 14 (new DenseVector( [|1.5;1.2;0.9;0.6;0.3|] ) :> Vector) ) (Vector.scanBack (fun x acc -> acc + x) smallv |> should approximately_vector_equal 14 (new DenseVector( [|1.5;1.2;0.9;0.6;0.3|] ) :> Vector<float>) )
spec "Vector.reduce_left" spec "Vector.reduce_left"
(Vector.reduce (fun acc x -> acc ** x) smallv |> should approximately_equal 14 0.990295218585507) (Vector.reduce (fun acc x -> acc ** x) smallv |> should approximately_equal 14 0.990295218585507)
spec "Vector.reduce_right" spec "Vector.reduce_right"
@ -141,9 +142,9 @@ let MatrixTests =
spec "Matrix.foldRow" spec "Matrix.foldRow"
(Matrix.foldRow (+) 0.0 largeM 0 |> should equal 4950.0) (Matrix.foldRow (+) 0.0 largeM 0 |> should equal 4950.0)
spec "Matrix.foldByCol" spec "Matrix.foldByCol"
(Matrix.foldByCol (+) 0.0 smallM |> should equal (DenseVector.ofList [0.6;0.6] :> Vector)) (Matrix.foldByCol (+) 0.0 smallM |> should equal (DenseVector.ofList [0.6;0.6] :> Vector<float>))
spec "Matrix.foldByRow" spec "Matrix.foldByRow"
(Matrix.foldByRow (+) 0.0 smallM |> should equal (DenseVector.ofList [0.6;0.6] :> Vector)) (Matrix.foldByRow (+) 0.0 smallM |> should equal (DenseVector.ofList [0.6;0.6] :> Vector<float>))
] ]
@ -183,13 +184,13 @@ let DenseMatrixTests =
let SparseMatrixTests = let SparseMatrixTests =
/// A small uniform vector. /// A small uniform vector.
let smallM = DenseMatrix.init 4 4 (fun i j -> if i = 1 && j = 2 then 1.0 else 0.0) :> Matrix let smallM = DenseMatrix.init 4 4 (fun i j -> if i = 1 && j = 2 then 1.0 else 0.0) :> Matrix<float>
specs "SparseMatrix" [ specs "SparseMatrix" [
spec "SparseMatrix.ofList" spec "SparseMatrix.ofList"
((SparseMatrix.ofList 4 4 [(1,2,1.0)] :> Matrix) |> should equal smallM) ((SparseMatrix.ofList 4 4 [(1,2,1.0)] :> Matrix<float>) |> should equal smallM)
spec "SparseMatrix.ofSeq" spec "SparseMatrix.ofSeq"
((SparseMatrix.ofSeq 4 4 (Seq.ofList [(1,2,1.0)]) :> Matrix) |> should equal smallM) ((SparseMatrix.ofSeq 4 4 (Seq.ofList [(1,2,1.0)]) :> Matrix<float>) |> should equal smallM)
spec "SparseMatrix.constDiag" spec "SparseMatrix.constDiag"
(SparseMatrix.constDiag 100 2.0 |> should equal (2.0 * (SparseMatrix.Identity 100))) (SparseMatrix.constDiag 100 2.0 |> should equal (2.0 * (SparseMatrix.Identity 100)))
spec "SparseMatrix.diag" spec "SparseMatrix.diag"

180
src/Numerics/LinearAlgebra/Double/DenseMatrix.cs

@ -27,12 +27,18 @@
namespace MathNet.Numerics.LinearAlgebra.Double namespace MathNet.Numerics.LinearAlgebra.Double
{ {
using System; using System;
using System.Text;
using Distributions;
using Factorization;
using Generic;
using Generic.Factorization;
using Properties; using Properties;
using Threading;
/// <summary> /// <summary>
/// A Matrix class with dense storage. The underlying storage is a one dimensional array in column-major order. /// A Matrix class with dense storage. The underlying storage is a one dimensional array in column-major order.
/// </summary> /// </summary>
public class DenseMatrix : Matrix public class DenseMatrix : Matrix<double>
{ {
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="DenseMatrix"/> class. This matrix is square with a given size. /// Initializes a new instance of the <see cref="DenseMatrix"/> class. This matrix is square with a given size.
@ -137,19 +143,19 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns> /// <returns>
/// A <c>DenseMatrix</c> with the given dimensions. /// A <c>DenseMatrix</c> with the given dimensions.
/// </returns> /// </returns>
public override Matrix CreateMatrix(int numberOfRows, int numberOfColumns) public override Matrix<double> CreateMatrix(int numberOfRows, int numberOfColumns)
{ {
return new DenseMatrix(numberOfRows, numberOfColumns); return new DenseMatrix(numberOfRows, numberOfColumns);
} }
/// <summary> /// <summary>
/// Creates a <see cref="Vector"/> with a the given dimension. /// Creates a <see cref="Vector{T}"/> with a the given dimension.
/// </summary> /// </summary>
/// <param name="size">The size of the vector.</param> /// <param name="size">The size of the vector.</param>
/// <returns> /// <returns>
/// A <see cref="Vector"/> with the given dimension. /// A <see cref="Vector{T}"/> with the given dimension.
/// </returns> /// </returns>
public override Vector CreateVector(int size) public override Vector<double> CreateVector(int size)
{ {
return new DenseVector(size); return new DenseVector(size);
} }
@ -200,7 +206,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// Returns the transpose of this matrix. /// Returns the transpose of this matrix.
/// </summary> /// </summary>
/// <returns>The transpose of this matrix.</returns> /// <returns>The transpose of this matrix.</returns>
public override Matrix Transpose() public override Matrix<double> Transpose()
{ {
var ret = new DenseMatrix(ColumnCount, RowCount); var ret = new DenseMatrix(ColumnCount, RowCount);
for (var j = 0; j < ColumnCount; j++) for (var j = 0; j < ColumnCount; j++)
@ -278,7 +284,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="other">The matrix to add to this matrix.</param> /// <param name="other">The matrix to add to this matrix.</param>
/// <exception cref="ArgumentNullException">If the other matrix is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the other matrix is <see langword="null" />.</exception>
/// <exception cref="ArgumentOutOfRangeException">If the two matrices don't have the same dimensions.</exception> /// <exception cref="ArgumentOutOfRangeException">If the two matrices don't have the same dimensions.</exception>
public override void Add(Matrix other) public override void Add(Matrix<double> other)
{ {
var m = other as DenseMatrix; var m = other as DenseMatrix;
if (m == null) if (m == null)
@ -318,7 +324,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="other">The matrix to subtract.</param> /// <param name="other">The matrix to subtract.</param>
/// <exception cref="ArgumentNullException">If the other matrix is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the other matrix is <see langword="null" />.</exception>
/// <exception cref="ArgumentOutOfRangeException">If the two matrices don't have the same dimensions.</exception> /// <exception cref="ArgumentOutOfRangeException">If the two matrices don't have the same dimensions.</exception>
public override void Subtract(Matrix other) public override void Subtract(Matrix<double> other)
{ {
var m = other as DenseMatrix; var m = other as DenseMatrix;
if (m == null) if (m == null)
@ -370,7 +376,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentNullException">If the result matrix is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the result matrix is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If <strong>this.Columns != other.Rows</strong>.</exception> /// <exception cref="ArgumentException">If <strong>this.Columns != other.Rows</strong>.</exception>
/// <exception cref="ArgumentException">If the result matrix's dimensions are not the this.Rows x other.Columns.</exception> /// <exception cref="ArgumentException">If the result matrix's dimensions are not the this.Rows x other.Columns.</exception>
public override void Multiply(Matrix other, Matrix result) public override void Multiply(Matrix<double> other, Matrix<double> result)
{ {
if (other == null) if (other == null)
{ {
@ -419,7 +425,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentException">If <strong>this.Columns != other.Rows</strong>.</exception> /// <exception cref="ArgumentException">If <strong>this.Columns != other.Rows</strong>.</exception>
/// <exception cref="ArgumentNullException">If the other matrix is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the other matrix is <see langword="null" />.</exception>
/// <returns>The result of multiplication.</returns> /// <returns>The result of multiplication.</returns>
public override Matrix Multiply(Matrix other) public override Matrix<double> Multiply(Matrix<double> other)
{ {
if (other == null) if (other == null)
{ {
@ -451,7 +457,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentNullException">If the result matrix is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the result matrix is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If <strong>this.Columns != other.Rows</strong>.</exception> /// <exception cref="ArgumentException">If <strong>this.Columns != other.Rows</strong>.</exception>
/// <exception cref="ArgumentException">If the result matrix's dimensions are not the this.Rows x other.Columns.</exception> /// <exception cref="ArgumentException">If the result matrix's dimensions are not the this.Rows x other.Columns.</exception>
public override void TransposeAndMultiply(Matrix other, Matrix result) public override void TransposeAndMultiply(Matrix<double> other, Matrix<double> result)
{ {
var otherDense = other as DenseMatrix; var otherDense = other as DenseMatrix;
var resultDense = result as DenseMatrix; var resultDense = result as DenseMatrix;
@ -493,7 +499,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentException">If <strong>this.Columns != other.Rows</strong>.</exception> /// <exception cref="ArgumentException">If <strong>this.Columns != other.Rows</strong>.</exception>
/// <exception cref="ArgumentNullException">If the other matrix is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the other matrix is <see langword="null" />.</exception>
/// <returns>The result of multiplication.</returns> /// <returns>The result of multiplication.</returns>
public override Matrix TransposeAndMultiply(Matrix other) public override Matrix<double> TransposeAndMultiply(Matrix<double> other)
{ {
var otherDense = other as DenseMatrix; var otherDense = other as DenseMatrix;
if (otherDense == null) if (otherDense == null)
@ -563,5 +569,155 @@ namespace MathNet.Numerics.LinearAlgebra.Double
} }
#endregion #endregion
/// <summary>
/// Negates each element of this matrix.
/// </summary>
public override void Negate()
{
Multiply(-1);
}
/// <summary>
/// Generates matrix with random elements.
/// </summary>
/// <param name="numberOfRows">Number of rows.</param>
/// <param name="numberOfColumns">Number of columns.</param>
/// <param name="distribution">Continuous Random Distribution or Source</param>
/// <returns>
/// An <c>numberOfRows</c>-by-<c>numberOfColumns</c> matrix with elements distributed according to the provided distribution.
/// </returns>
/// <exception cref="ArgumentException">If the parameter <paramref name="numberOfRows"/> is not positive.</exception>
/// <exception cref="ArgumentException">If the parameter <paramref name="numberOfColumns"/> is not positive.</exception>
public override Matrix<double> Random(int numberOfRows, int numberOfColumns, IContinuousDistribution distribution)
{
if (numberOfRows < 1)
{
throw new ArgumentException(Resources.ArgumentMustBePositive, "numberOfRows");
}
if (numberOfColumns < 1)
{
throw new ArgumentException(Resources.ArgumentMustBePositive, "numberOfColumns");
}
var matrix = CreateMatrix(numberOfRows, numberOfColumns);
CommonParallel.For(
0,
ColumnCount,
j =>
{
for (var i = 0; i < matrix.RowCount; i++)
{
matrix[i, j] = distribution.Sample();
}
});
return matrix;
}
/// <summary>
/// Generates matrix with random elements.
/// </summary>
/// <param name="numberOfRows">Number of rows.</param>
/// <param name="numberOfColumns">Number of columns.</param>
/// <param name="distribution">Continuous Random Distribution or Source</param>
/// <returns>
/// An <c>numberOfRows</c>-by-<c>numberOfColumns</c> matrix with elements distributed according to the provided distribution.
/// </returns>
/// <exception cref="ArgumentException">If the parameter <paramref name="numberOfRows"/> is not positive.</exception>
/// <exception cref="ArgumentException">If the parameter <paramref name="numberOfColumns"/> is not positive.</exception>
public override Matrix<double> Random(int numberOfRows, int numberOfColumns, IDiscreteDistribution distribution)
{
if (numberOfRows < 1)
{
throw new ArgumentException(Resources.ArgumentMustBePositive, "numberOfRows");
}
if (numberOfColumns < 1)
{
throw new ArgumentException(Resources.ArgumentMustBePositive, "numberOfColumns");
}
var matrix = CreateMatrix(numberOfRows, numberOfColumns);
CommonParallel.For(
0,
ColumnCount,
j =>
{
for (var i = 0; i < matrix.RowCount; i++)
{
matrix[i, j] = distribution.Sample();
}
});
return matrix;
}
#region Simple arithmetic of type T
/// <summary>
/// Add two values T+T
/// </summary>
/// <param name="val1">Left operand value</param>
/// <param name="val2">Right operand value</param>
/// <returns>Result of addition</returns>
protected sealed override double AddT(double val1, double val2)
{
return val1 + val2;
}
/// <summary>
/// Subtract two values T-T
/// </summary>
/// <param name="val1">Left operand value</param>
/// <param name="val2">Right operand value</param>
/// <returns>Result of subtract</returns>
protected sealed override double SubtractT(double val1, double val2)
{
return val1 - val2;
}
/// <summary>
/// Multiply two values T*T
/// </summary>
/// <param name="val1">Left operand value</param>
/// <param name="val2">Right operand value</param>
/// <returns>Result of multiplication</returns>
protected sealed override double MultiplyT(double val1, double val2)
{
return val1 * val2;
}
/// <summary>
/// Divide two values T/T
/// </summary>
/// <param name="val1">Left operand value</param>
/// <param name="val2">Right operand value</param>
/// <returns>Result of divide</returns>
protected sealed override double DivideT(double val1, double val2)
{
return val1 / val2;
}
/// <summary>
/// Is equal to one?
/// </summary>
/// <param name="val1">Value to check</param>
/// <returns>True if one; otherwise false</returns>
protected sealed override bool IsOneT(double val1)
{
return 1.0.AlmostEqualInDecimalPlaces(val1, 15);
}
/// <summary>
/// Take absolute value
/// </summary>
/// <param name="val1">Source alue</param>
/// <returns>True if one; otherwise false</returns>
protected sealed override double AbsoluteT(double val1)
{
return Math.Abs(val1);
}
#endregion
} }
} }

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

@ -30,7 +30,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.Linq; using System.Linq;
using System.Text;
using Distributions; using Distributions;
using Generic;
using NumberTheory; using NumberTheory;
using Properties; using Properties;
using Threading; using Threading;
@ -38,7 +40,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <summary> /// <summary>
/// A vector using dense storage. /// A vector using dense storage.
/// </summary> /// </summary>
public class DenseVector : Vector public class DenseVector : Vector<double>
{ {
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="DenseVector"/> class with a given size. /// Initializes a new instance of the <see cref="DenseVector"/> class with a given size.
@ -84,7 +86,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="other"> /// <param name="other">
/// The vector to create the new vector from. /// The vector to create the new vector from.
/// </param> /// </param>
public DenseVector(Vector other) public DenseVector(Vector<double> other)
: this(other.Count) : this(other.Count)
{ {
var vector = other as DenseVector; var vector = other as DenseVector;
@ -175,7 +177,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// Create a matrix based on this vector in column form (one single column). /// Create a matrix based on this vector in column form (one single column).
/// </summary> /// </summary>
/// <returns>This vector as a column matrix.</returns> /// <returns>This vector as a column matrix.</returns>
public override Matrix ToColumnMatrix() public override Matrix<double> ToColumnMatrix()
{ {
var matrix = new DenseMatrix(Count, 1); var matrix = new DenseMatrix(Count, 1);
for (var i = 0; i < Data.Length; i++) for (var i = 0; i < Data.Length; i++)
@ -190,7 +192,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// Create a matrix based on this vector in row form (one single row). /// Create a matrix based on this vector in row form (one single row).
/// </summary> /// </summary>
/// <returns>This vector as a row matrix.</returns> /// <returns>This vector as a row matrix.</returns>
public override Matrix ToRowMatrix() public override Matrix<double> ToRowMatrix()
{ {
var matrix = new DenseMatrix(1, Count); var matrix = new DenseMatrix(1, Count);
for (var i = 0; i < Data.Length; i++) for (var i = 0; i < Data.Length; i++)
@ -232,7 +234,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns> /// <returns>
/// A matrix with the given dimensions. /// A matrix with the given dimensions.
/// </returns> /// </returns>
public override Matrix CreateMatrix(int rows, int columns) public override Matrix<double> CreateMatrix(int rows, int columns)
{ {
return new DenseMatrix(rows, columns); return new DenseMatrix(rows, columns);
} }
@ -247,7 +249,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns> /// <returns>
/// The new <c>Vector</c>. /// The new <c>Vector</c>.
/// </returns> /// </returns>
public override Vector CreateVector(int size) public override Vector<double> CreateVector(int size)
{ {
return new DenseVector(size); return new DenseVector(size);
} }
@ -264,7 +266,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentException"> /// <exception cref="ArgumentException">
/// If <paramref name="target"/> is not the same size as this vector. /// If <paramref name="target"/> is not the same size as this vector.
/// </exception> /// </exception>
public override void CopyTo(Vector target) public override void CopyTo(Vector<double> target)
{ {
if (target == null) if (target == null)
{ {
@ -300,7 +302,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// </summary> /// </summary>
/// <param name="scalar">The scalar to add.</param> /// <param name="scalar">The scalar to add.</param>
/// <returns>A copy of the vector with the scalar added.</returns> /// <returns>A copy of the vector with the scalar added.</returns>
public override Vector Add(double scalar) public override Vector<double> Add(double scalar)
{ {
if (scalar == 0.0) if (scalar == 0.0)
{ {
@ -322,7 +324,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="result">The vector to store the result of the addition.</param> /// <param name="result">The vector to store the result of the addition.</param>
/// <exception cref="ArgumentNullException">If the result vector is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the result vector is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If this vector and <paramref name="result"/> are not the same size.</exception> /// <exception cref="ArgumentException">If this vector and <paramref name="result"/> are not the same size.</exception>
public override void Add(double scalar, Vector result) public override void Add(double scalar, Vector<double> result)
{ {
if (result == null) if (result == null)
{ {
@ -355,7 +357,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>A new vector containing the sum of both vectors.</returns> /// <returns>A new vector containing the sum of both vectors.</returns>
/// <exception cref="ArgumentNullException">If the other vector is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the other vector is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If this vector and <paramref name="other"/> are not the same size.</exception> /// <exception cref="ArgumentException">If this vector and <paramref name="other"/> are not the same size.</exception>
public override Vector Add(Vector other) public override Vector<double> Add(Vector<double> other)
{ {
if (other == null) if (other == null)
{ {
@ -388,7 +390,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentNullException">If the result vector is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the result vector is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If this vector and <paramref name="other"/> are not the same size.</exception> /// <exception cref="ArgumentException">If this vector and <paramref name="other"/> are not the same size.</exception>
/// <exception cref="ArgumentException">If this vector and <paramref name="result"/> are not the same size.</exception> /// <exception cref="ArgumentException">If this vector and <paramref name="result"/> are not the same size.</exception>
public override void Add(Vector other, Vector result) public override void Add(Vector<double> other, Vector<double> result)
{ {
if (result == null) if (result == null)
{ {
@ -436,7 +438,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="rightSide">The vector to get the values from.</param> /// <param name="rightSide">The vector to get the values from.</param>
/// <returns>A vector containing a the same values as <paramref name="rightSide"/>.</returns> /// <returns>A vector containing a the same values as <paramref name="rightSide"/>.</returns>
/// <exception cref="ArgumentNullException">If <paramref name="rightSide"/> is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If <paramref name="rightSide"/> is <see langword="null" />.</exception>
public static Vector operator +(DenseVector rightSide) public static Vector<double> operator +(DenseVector rightSide)
{ {
if (rightSide == null) if (rightSide == null)
{ {
@ -454,7 +456,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>The result of the addition.</returns> /// <returns>The result of the addition.</returns>
/// <exception cref="ArgumentException">If <paramref name="leftSide"/> and <paramref name="rightSide"/> are not the same size.</exception> /// <exception cref="ArgumentException">If <paramref name="leftSide"/> and <paramref name="rightSide"/> are not the same size.</exception>
/// <exception cref="ArgumentNullException">If <paramref name="leftSide"/> or <paramref name="rightSide"/> is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If <paramref name="leftSide"/> or <paramref name="rightSide"/> is <see langword="null" />.</exception>
public static Vector operator +(DenseVector leftSide, DenseVector rightSide) public static Vector<double> operator +(DenseVector leftSide, DenseVector rightSide)
{ {
if (rightSide == null) if (rightSide == null)
{ {
@ -479,7 +481,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// </summary> /// </summary>
/// <param name="scalar">The scalar to subtract.</param> /// <param name="scalar">The scalar to subtract.</param>
/// <returns>A new vector containing the subtraction of this vector and the scalar.</returns> /// <returns>A new vector containing the subtraction of this vector and the scalar.</returns>
public override Vector Subtract(double scalar) public override Vector<double> Subtract(double scalar)
{ {
if (scalar == 0.0) if (scalar == 0.0)
{ {
@ -501,7 +503,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="result">The vector to store the result of the subtraction.</param> /// <param name="result">The vector to store the result of the subtraction.</param>
/// <exception cref="ArgumentNullException">If the result vector is <see langword="null"/>.</exception> /// <exception cref="ArgumentNullException">If the result vector is <see langword="null"/>.</exception>
/// <exception cref="ArgumentException">If this vector and <paramref name="result"/> are not the same size.</exception> /// <exception cref="ArgumentException">If this vector and <paramref name="result"/> are not the same size.</exception>
public override void Subtract(double scalar, Vector result) public override void Subtract(double scalar, Vector<double> result)
{ {
if (result == null) if (result == null)
{ {
@ -534,7 +536,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>A new vector containing the subtraction of the the two vectors.</returns> /// <returns>A new vector containing the subtraction of the the two vectors.</returns>
/// <exception cref="ArgumentNullException">If the other vector is <see langword="null"/>.</exception> /// <exception cref="ArgumentNullException">If the other vector is <see langword="null"/>.</exception>
/// <exception cref="ArgumentException">If this vector and <paramref name="other"/> are not the same size.</exception> /// <exception cref="ArgumentException">If this vector and <paramref name="other"/> are not the same size.</exception>
public override Vector Subtract(Vector other) public override Vector<double> Subtract(Vector<double> other)
{ {
if (other == null) if (other == null)
{ {
@ -567,7 +569,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentNullException">If the result vector is <see langword="null"/>.</exception> /// <exception cref="ArgumentNullException">If the result vector is <see langword="null"/>.</exception>
/// <exception cref="ArgumentException">If this vector and <paramref name="other"/> are not the same size.</exception> /// <exception cref="ArgumentException">If this vector and <paramref name="other"/> are not the same size.</exception>
/// <exception cref="ArgumentException">If this vector and <paramref name="result"/> are not the same size.</exception> /// <exception cref="ArgumentException">If this vector and <paramref name="result"/> are not the same size.</exception>
public override void Subtract(Vector other, Vector result) public override void Subtract(Vector<double> other, Vector<double> result)
{ {
if (result == null) if (result == null)
{ {
@ -614,7 +616,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="rightSide">The vector to get the values from.</param> /// <param name="rightSide">The vector to get the values from.</param>
/// <returns>A vector containing the negated values as <paramref name="rightSide"/>.</returns> /// <returns>A vector containing the negated values as <paramref name="rightSide"/>.</returns>
/// <exception cref="ArgumentNullException">If <paramref name="rightSide"/> is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If <paramref name="rightSide"/> is <see langword="null" />.</exception>
public static Vector operator -(DenseVector rightSide) public static Vector<double> operator -(DenseVector rightSide)
{ {
if (rightSide == null) if (rightSide == null)
{ {
@ -632,7 +634,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>The result of the subtraction.</returns> /// <returns>The result of the subtraction.</returns>
/// <exception cref="ArgumentException">If <paramref name="leftSide"/> and <paramref name="rightSide"/> are not the same size.</exception> /// <exception cref="ArgumentException">If <paramref name="leftSide"/> and <paramref name="rightSide"/> are not the same size.</exception>
/// <exception cref="ArgumentNullException">If <paramref name="leftSide"/> or <paramref name="rightSide"/> is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If <paramref name="leftSide"/> or <paramref name="rightSide"/> is <see langword="null" />.</exception>
public static Vector operator -(DenseVector leftSide, DenseVector rightSide) public static Vector<double> operator -(DenseVector leftSide, DenseVector rightSide)
{ {
if (rightSide == null) if (rightSide == null)
{ {
@ -657,7 +659,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// </summary> /// </summary>
/// <returns>The negated vector.</returns> /// <returns>The negated vector.</returns>
/// <remarks>Added as an alternative to the unary negation operator.</remarks> /// <remarks>Added as an alternative to the unary negation operator.</remarks>
public override Vector Negate() public override Vector<double> Negate()
{ {
var result = new DenseVector(Count); var result = new DenseVector(Count);
CommonParallel.For( CommonParallel.For(
@ -673,7 +675,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// </summary> /// </summary>
/// <param name="scalar">The scalar to multiply.</param> /// <param name="scalar">The scalar to multiply.</param>
/// <returns>A new vector that is the multiplication of the vector and the scalar.</returns> /// <returns>A new vector that is the multiplication of the vector and the scalar.</returns>
public override Vector Multiply(double scalar) public override Vector<double> Multiply(double scalar)
{ {
if (scalar == 1.0) if (scalar == 1.0)
{ {
@ -692,7 +694,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>The result of the addition.</returns> /// <returns>The result of the addition.</returns>
/// <exception cref="ArgumentException">If <paramref name="other"/> is not of the same size.</exception> /// <exception cref="ArgumentException">If <paramref name="other"/> is not of the same size.</exception>
/// <exception cref="ArgumentNullException">If <paramref name="other"/> is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If <paramref name="other"/> is <see langword="null" />.</exception>
public override double DotProduct(Vector other) public override double DotProduct(Vector<double> other)
{ {
if (other == null) if (other == null)
{ {
@ -864,7 +866,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <item>If <paramref name="index"/> + <paramref name="length"/> is greater than or equal to the size of the vector.</item> /// <item>If <paramref name="index"/> + <paramref name="length"/> is greater than or equal to the size of the vector.</item>
/// </list></exception> /// </list></exception>
/// <exception cref="ArgumentException">If <paramref name="length"/> is not positive.</exception> /// <exception cref="ArgumentException">If <paramref name="length"/> is not positive.</exception>
public override Vector SubVector(int index, int length) public override Vector<double> SubVector(int index, int length)
{ {
if (index < 0 || index >= Count) if (index < 0 || index >= Count)
{ {
@ -991,7 +993,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>A new vector which is the pointwise multiplication of the two vectors.</returns> /// <returns>A new vector which is the pointwise multiplication of the two vectors.</returns>
/// <exception cref="ArgumentNullException">If the other vector is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the other vector is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If this vector and <paramref name="other"/> are not the same size.</exception> /// <exception cref="ArgumentException">If this vector and <paramref name="other"/> are not the same size.</exception>
public override Vector PointwiseMultiply(Vector other) public override Vector<double> PointwiseMultiply(Vector<double> other)
{ {
if (other == null) if (other == null)
{ {
@ -1027,7 +1029,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentNullException">If the result vector is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the result vector is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If this vector and <paramref name="other"/> are not the same size.</exception> /// <exception cref="ArgumentException">If this vector and <paramref name="other"/> are not the same size.</exception>
/// <exception cref="ArgumentException">If this vector and <paramref name="result"/> are not the same size.</exception> /// <exception cref="ArgumentException">If this vector and <paramref name="result"/> are not the same size.</exception>
public override void PointwiseMultiply(Vector other, Vector result) public override void PointwiseMultiply(Vector<double> other, Vector<double> result)
{ {
if (result == null) if (result == null)
{ {
@ -1078,7 +1080,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>A new vector which is the pointwise division of the two vectors.</returns> /// <returns>A new vector which is the pointwise division of the two vectors.</returns>
/// <exception cref="ArgumentNullException">If the other vector is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the other vector is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If this vector and <paramref name="other"/> are not the same size.</exception> /// <exception cref="ArgumentException">If this vector and <paramref name="other"/> are not the same size.</exception>
public override Vector PointwiseDivide(Vector other) public override Vector<double> PointwiseDivide(Vector<double> other)
{ {
if (other == null) if (other == null)
{ {
@ -1114,7 +1116,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentNullException">If the result vector is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the result vector is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If this vector and <paramref name="other"/> are not the same size.</exception> /// <exception cref="ArgumentException">If this vector and <paramref name="other"/> are not the same size.</exception>
/// <exception cref="ArgumentException">If this vector and <paramref name="result"/> are not the same size.</exception> /// <exception cref="ArgumentException">If this vector and <paramref name="result"/> are not the same size.</exception>
public override void PointwiseDivide(Vector other, Vector result) public override void PointwiseDivide(Vector<double> other, Vector<double> result)
{ {
if (result == null) if (result == null)
{ {
@ -1202,7 +1204,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// to the specified random distribution. /// to the specified random distribution.
/// </returns> /// </returns>
/// <exception cref="ArgumentNullException">If the n vector is non positive<see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the n vector is non positive<see langword="null" />.</exception>
public override Vector Random(int length, IContinuousDistribution randomDistribution) public override Vector<double> Random(int length, IContinuousDistribution randomDistribution)
{ {
if (length < 1) if (length < 1)
{ {
@ -1228,7 +1230,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// to the specified random distribution. /// to the specified random distribution.
/// </returns> /// </returns>
/// <exception cref="ArgumentNullException">If the n vector is non positive<see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the n vector is non positive<see langword="null" />.</exception>
public override Vector Random(int length, IDiscreteDistribution randomDistribution) public override Vector<double> Random(int length, IDiscreteDistribution randomDistribution)
{ {
if (length < 1) if (length < 1)
{ {
@ -1252,7 +1254,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// Matrix M[i,j] = this[i] * v[j]. /// Matrix M[i,j] = this[i] * v[j].
/// </returns> /// </returns>
/// <seealso cref="OuterProduct"/> /// <seealso cref="OuterProduct"/>
public Matrix TensorMultiply(DenseVector v) public Matrix<double> TensorMultiply(DenseVector v)
{ {
return OuterProduct(this, v); return OuterProduct(this, v);
} }
@ -1301,6 +1303,33 @@ namespace MathNet.Numerics.LinearAlgebra.Double
return Math.Pow(sum, 1.0 / p); return Math.Pow(sum, 1.0 / p);
} }
/// <summary>
/// Normalizes this vector to a unit vector with respect to the p-norm.
/// </summary>
/// <param name="p">
/// The p value.
/// </param>
/// <returns>
/// This vector normalized to a unit vector with respect to the p-norm.
/// </returns>
public override Vector<double> Normalize(double p)
{
if (p < 0.0)
{
throw new ArgumentOutOfRangeException("p");
}
var norm = Norm(p);
var clone = Clone();
if (norm == 0.0)
{
return clone;
}
clone.Multiply(1.0 / norm, clone);
return clone;
}
#endregion #endregion
#region Parse Functions #region Parse Functions
@ -1469,5 +1498,71 @@ namespace MathNet.Numerics.LinearAlgebra.Double
{ {
Array.Clear(Data, 0, Data.Length); Array.Clear(Data, 0, Data.Length);
} }
#region Simple arithmetic of type T
/// <summary>
/// Add two values T+T
/// </summary>
/// <param name="val1">Left operand value</param>
/// <param name="val2">Right operand value</param>
/// <returns>Result of addition</returns>
protected sealed override double AddT(double val1, double val2)
{
return val1 + val2;
}
/// <summary>
/// Subtract two values T-T
/// </summary>
/// <param name="val1">Left operand value</param>
/// <param name="val2">Right operand value</param>
/// <returns>Result of subtract</returns>
protected sealed override double SubtractT(double val1, double val2)
{
return val1 - val2;
}
/// <summary>
/// Multiply two values T*T
/// </summary>
/// <param name="val1">Left operand value</param>
/// <param name="val2">Right operand value</param>
/// <returns>Result of multiplication</returns>
protected sealed override double MultiplyT(double val1, double val2)
{
return val1 * val2;
}
/// <summary>
/// Divide two values T/T
/// </summary>
/// <param name="val1">Left operand value</param>
/// <param name="val2">Right operand value</param>
/// <returns>Result of divide</returns>
protected sealed override double DivideT(double val1, double val2)
{
return val1 / val2;
}
/// <summary>
/// Is equal to one?
/// </summary>
/// <param name="val1">Value to check</param>
/// <returns>True if one; otherwise false</returns>
protected sealed override bool IsOneT(double val1)
{
return val1 == 1.0;
}
/// <summary>
/// Take absolute value
/// </summary>
/// <param name="val1">Source alue</param>
/// <returns>True if one; otherwise false</returns>
protected sealed override double AbsoluteT(double val1)
{
return Math.Abs(val1);
}
#endregion
} }
} }

283
src/Numerics/LinearAlgebra/Double/DiagonalMatrix.cs

@ -28,6 +28,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double
{ {
using System; using System;
using System.Linq; using System.Linq;
using System.Text;
using Distributions;
using Generic;
using Properties; using Properties;
using Threading; using Threading;
@ -40,7 +43,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// entries are set. The exception to this is when the off diagonal elements are /// entries are set. The exception to this is when the off diagonal elements are
/// 0.0 or NaN; these settings will cause no change to the diagonal matrix. /// 0.0 or NaN; these settings will cause no change to the diagonal matrix.
/// </remarks> /// </remarks>
public class DiagonalMatrix : Matrix public class DiagonalMatrix : Matrix<double>
{ {
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="DiagonalMatrix"/> class. This matrix is square with a given size. /// Initializes a new instance of the <see cref="DiagonalMatrix"/> class. This matrix is square with a given size.
@ -195,19 +198,19 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns> /// <returns>
/// A <c>DiagonalMatrix</c> with the given dimensions. /// A <c>DiagonalMatrix</c> with the given dimensions.
/// </returns> /// </returns>
public override Matrix CreateMatrix(int numberOfRows, int numberOfColumns) public override Matrix<double> CreateMatrix(int numberOfRows, int numberOfColumns)
{ {
return new DiagonalMatrix(numberOfRows, numberOfColumns); return new DiagonalMatrix(numberOfRows, numberOfColumns);
} }
/// <summary> /// <summary>
/// Creates a <see cref="Vector"/> with a the given dimension. /// Creates a <see cref="Vector{T}"/> with a the given dimension.
/// </summary> /// </summary>
/// <param name="size">The size of the vector.</param> /// <param name="size">The size of the vector.</param>
/// <returns> /// <returns>
/// A <see cref="Vector"/> with the given dimension. /// A <see cref="Vector{T}"/> with the given dimension.
/// </returns> /// </returns>
public override Vector CreateVector(int size) public override Vector<double> CreateVector(int size)
{ {
return new SparseVector(size); return new SparseVector(size);
} }
@ -283,7 +286,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentNullException">If the other matrix is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the other matrix is <see langword="null" />.</exception>
/// <exception cref="ArgumentOutOfRangeException">If the two matrices don't have the same dimensions.</exception> /// <exception cref="ArgumentOutOfRangeException">If the two matrices don't have the same dimensions.</exception>
/// <exception cref="ArgumentException">If <paramref name="other"/> is not <see cref="DiagonalMatrix"/>.</exception> /// <exception cref="ArgumentException">If <paramref name="other"/> is not <see cref="DiagonalMatrix"/>.</exception>
public override void Add(Matrix other) public override void Add(Matrix<double> other)
{ {
if (other == null) if (other == null)
{ {
@ -327,7 +330,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentNullException">If the other matrix is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the other matrix is <see langword="null" />.</exception>
/// <exception cref="ArgumentOutOfRangeException">If the two matrices don't have the same dimensions.</exception> /// <exception cref="ArgumentOutOfRangeException">If the two matrices don't have the same dimensions.</exception>
/// <exception cref="ArgumentException">If <paramref name="other"/> is not <see cref="DiagonalMatrix"/>.</exception> /// <exception cref="ArgumentException">If <paramref name="other"/> is not <see cref="DiagonalMatrix"/>.</exception>
public override void Subtract(Matrix other) public override void Subtract(Matrix<double> other)
{ {
if (other == null) if (other == null)
{ {
@ -390,7 +393,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
} }
/// <summary> /// <summary>
/// Copies the values of the given <see cref="Vector"/> to the diagonal. /// Copies the values of the given <see cref="Vector{T}"/> to the diagonal.
/// </summary> /// </summary>
/// <param name="source">The vector to copy the values from. The length of the vector should be /// <param name="source">The vector to copy the values from. The length of the vector should be
/// Min(Rows, Columns).</param> /// Min(Rows, Columns).</param>
@ -399,7 +402,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// equal Min(Rows, Columns).</exception> /// equal Min(Rows, Columns).</exception>
/// <remarks>For non-square matrices, the elements of <paramref name="source"/> are copied to /// <remarks>For non-square matrices, the elements of <paramref name="source"/> are copied to
/// this[i,i].</remarks> /// this[i,i].</remarks>
public override void SetDiagonal(Vector source) public override void SetDiagonal(Vector<double> source)
{ {
var denseSource = source as DenseVector; var denseSource = source as DenseVector;
if (denseSource == null) if (denseSource == null)
@ -445,7 +448,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentNullException">If the result matrix is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the result matrix is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If <strong>this.Columns != other.Rows</strong>.</exception> /// <exception cref="ArgumentException">If <strong>this.Columns != other.Rows</strong>.</exception>
/// <exception cref="ArgumentException">If the result matrix's dimensions are not the this.Rows x other.Columns.</exception> /// <exception cref="ArgumentException">If the result matrix's dimensions are not the this.Rows x other.Columns.</exception>
public override void Multiply(Matrix other, Matrix result) public override void Multiply(Matrix<double> other, Matrix<double> result)
{ {
if (other == null) if (other == null)
{ {
@ -492,7 +495,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentException">If <strong>this.Columns != other.Rows</strong>.</exception> /// <exception cref="ArgumentException">If <strong>this.Columns != other.Rows</strong>.</exception>
/// <exception cref="ArgumentNullException">If the other matrix is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the other matrix is <see langword="null" />.</exception>
/// <returns>The result of multiplication.</returns> /// <returns>The result of multiplication.</returns>
public override Matrix Multiply(Matrix other) public override Matrix<double> Multiply(Matrix<double> other)
{ {
if (other == null) if (other == null)
{ {
@ -524,7 +527,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentNullException">If <paramref name="result"/> is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If <paramref name="result"/> is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If <strong>result.Count != this.RowCount</strong>.</exception> /// <exception cref="ArgumentException">If <strong>result.Count != this.RowCount</strong>.</exception>
/// <exception cref="ArgumentException">If <strong>this.ColumnCount != <paramref name="rightSide"/>.Count</strong>.</exception> /// <exception cref="ArgumentException">If <strong>this.ColumnCount != <paramref name="rightSide"/>.Count</strong>.</exception>
public override void Multiply(Vector rightSide, Vector result) public override void Multiply(Vector<double> rightSide, Vector<double> result)
{ {
if (rightSide == null) if (rightSide == null)
{ {
@ -574,7 +577,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentNullException">If the result matrix is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the result matrix is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If <strong>result.Count != this.ColumnCount</strong>.</exception> /// <exception cref="ArgumentException">If <strong>result.Count != this.ColumnCount</strong>.</exception>
/// <exception cref="ArgumentException">If <strong>this.RowCount != <paramref name="leftSide"/>.Count</strong>.</exception> /// <exception cref="ArgumentException">If <strong>this.RowCount != <paramref name="leftSide"/>.Count</strong>.</exception>
public override void LeftMultiply(Vector leftSide, Vector result) public override void LeftMultiply(Vector<double> leftSide, Vector<double> result)
{ {
if (leftSide == null) if (leftSide == null)
{ {
@ -635,7 +638,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>The elements of the diagonal.</returns> /// <returns>The elements of the diagonal.</returns>
/// <remarks>For non-square matrices, the method returns Min(Rows, Columns) elements where /// <remarks>For non-square matrices, the method returns Min(Rows, Columns) elements where
/// i == j (i is the row index, and j is the column index).</remarks> /// i == j (i is the row index, and j is the column index).</remarks>
public override Vector Diagonal() public override Vector<double> Diagonal()
{ {
// TODO: Should we return reference to array? In current implementation we return copy of array, so changes in DenseVector will // TODO: Should we return reference to array? In current implementation we return copy of array, so changes in DenseVector will
// not influence onto diagonal elements // not influence onto diagonal elements
@ -651,7 +654,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentNullException">If the result matrix is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the result matrix is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If <strong>this.Columns != other.Rows</strong>.</exception> /// <exception cref="ArgumentException">If <strong>this.Columns != other.Rows</strong>.</exception>
/// <exception cref="ArgumentException">If the result matrix's dimensions are not the this.Rows x other.Columns.</exception> /// <exception cref="ArgumentException">If the result matrix's dimensions are not the this.Rows x other.Columns.</exception>
public override void TransposeAndMultiply(Matrix other, Matrix result) public override void TransposeAndMultiply(Matrix<double> other, Matrix<double> result)
{ {
var otherDiagonal = other as DiagonalMatrix; var otherDiagonal = other as DiagonalMatrix;
var resultDiagonal = result as DiagonalMatrix; var resultDiagonal = result as DiagonalMatrix;
@ -672,7 +675,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentException">If <strong>this.Columns != other.Rows</strong>.</exception> /// <exception cref="ArgumentException">If <strong>this.Columns != other.Rows</strong>.</exception>
/// <exception cref="ArgumentNullException">If the other matrix is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the other matrix is <see langword="null" />.</exception>
/// <returns>The result of multiplication.</returns> /// <returns>The result of multiplication.</returns>
public override Matrix TransposeAndMultiply(Matrix other) public override Matrix<double> TransposeAndMultiply(Matrix<double> other)
{ {
var otherDiagonal = other as DiagonalMatrix; var otherDiagonal = other as DiagonalMatrix;
if (otherDiagonal == null) if (otherDiagonal == null)
@ -732,7 +735,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentException"> /// <exception cref="ArgumentException">
/// If this and the target matrix do not have the same dimensions.. /// If this and the target matrix do not have the same dimensions..
/// </exception> /// </exception>
public override void CopyTo(Matrix target) public override void CopyTo(Matrix<double> target)
{ {
var diagonalTarget = target as DiagonalMatrix; var diagonalTarget = target as DiagonalMatrix;
@ -759,7 +762,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// Returns the transpose of this matrix. /// Returns the transpose of this matrix.
/// </summary> /// </summary>
/// <returns>The transpose of this matrix.</returns> /// <returns>The transpose of this matrix.</returns>
public override Matrix Transpose() public override Matrix<double> Transpose()
{ {
var ret = new DiagonalMatrix(ColumnCount, RowCount); var ret = new DiagonalMatrix(ColumnCount, RowCount);
Buffer.BlockCopy(Data, 0, ret.Data, 0, Data.Length * Constants.SizeOfDouble); Buffer.BlockCopy(Data, 0, ret.Data, 0, Data.Length * Constants.SizeOfDouble);
@ -772,8 +775,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="columnIndex">The column to copy elements from.</param> /// <param name="columnIndex">The column to copy elements from.</param>
/// <param name="rowIndex">The row to start copying from.</param> /// <param name="rowIndex">The row to start copying from.</param>
/// <param name="length">The number of elements to copy.</param> /// <param name="length">The number of elements to copy.</param>
/// <param name="result">The <see cref="Vector"/> to copy the column into.</param> /// <param name="result">The <see cref="Vector{T}"/> to copy the column into.</param>
/// <exception cref="ArgumentNullException">If the result <see cref="Vector"/> is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the result <see cref="Vector{T}"/> is <see langword="null" />.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="columnIndex"/> is negative, /// <exception cref="ArgumentOutOfRangeException">If <paramref name="columnIndex"/> is negative,
/// or greater than or equal to the number of columns.</exception> /// or greater than or equal to the number of columns.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="rowIndex"/> is negative, /// <exception cref="ArgumentOutOfRangeException">If <paramref name="rowIndex"/> is negative,
@ -782,7 +785,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// is greater than or equal to the number of rows.</exception> /// is greater than or equal to the number of rows.</exception>
/// <exception cref="ArgumentException">If <paramref name="length"/> is not positive.</exception> /// <exception cref="ArgumentException">If <paramref name="length"/> is not positive.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <strong>result.Count &lt; length</strong>.</exception> /// <exception cref="ArgumentOutOfRangeException">If <strong>result.Count &lt; length</strong>.</exception>
public override void Column(int columnIndex, int rowIndex, int length, Vector result) public override void Column(int columnIndex, int rowIndex, int length, Vector<double> result)
{ {
if (result == null) if (result == null)
{ {
@ -823,13 +826,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double
} }
/// <summary> /// <summary>
/// Copies the requested row elements into a new <see cref="Vector"/>. /// Copies the requested row elements into a new <see cref="Vector{T}"/>.
/// </summary> /// </summary>
/// <param name="rowIndex">The row to copy elements from.</param> /// <param name="rowIndex">The row to copy elements from.</param>
/// <param name="columnIndex">The column to start copying from.</param> /// <param name="columnIndex">The column to start copying from.</param>
/// <param name="length">The number of elements to copy.</param> /// <param name="length">The number of elements to copy.</param>
/// <param name="result">The <see cref="Vector"/> to copy the column into.</param> /// <param name="result">The <see cref="Vector{T}"/> to copy the column into.</param>
/// <exception cref="ArgumentNullException">If the result <see cref="Vector"/> is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the result <see cref="Vector{T}"/> is <see langword="null" />.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="rowIndex"/> is negative, /// <exception cref="ArgumentOutOfRangeException">If <paramref name="rowIndex"/> is negative,
/// or greater than or equal to the number of columns.</exception> /// or greater than or equal to the number of columns.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="columnIndex"/> is negative, /// <exception cref="ArgumentOutOfRangeException">If <paramref name="columnIndex"/> is negative,
@ -838,7 +841,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// is greater than or equal to the number of rows.</exception> /// is greater than or equal to the number of rows.</exception>
/// <exception cref="ArgumentException">If <paramref name="length"/> is not positive.</exception> /// <exception cref="ArgumentException">If <paramref name="length"/> is not positive.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <strong>result.Count &lt; length</strong>.</exception> /// <exception cref="ArgumentOutOfRangeException">If <strong>result.Count &lt; length</strong>.</exception>
public override void Row(int rowIndex, int columnIndex, int length, Vector result) public override void Row(int rowIndex, int columnIndex, int length, Vector<double> result)
{ {
if (result == null) if (result == null)
{ {
@ -913,10 +916,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double
{ {
var maxSv = double.NegativeInfinity; var maxSv = double.NegativeInfinity;
var minSv = double.PositiveInfinity; var minSv = double.PositiveInfinity;
for (var i = 0; i < Data.Length; i++) foreach (var t in Data)
{ {
maxSv = Math.Max(maxSv, Math.Abs(Data[i])); maxSv = Math.Max(maxSv, Math.Abs(t));
minSv = Math.Min(minSv, Math.Abs(Data[i])); minSv = Math.Min(minSv, Math.Abs(t));
} }
return maxSv / minSv; return maxSv / minSv;
@ -926,7 +929,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentException">If <see cref="DiagonalMatrix"/> is not a square matrix.</exception> /// <exception cref="ArgumentException">If <see cref="DiagonalMatrix"/> is not a square matrix.</exception>
/// <exception cref="ArgumentException">If <see cref="DiagonalMatrix"/> is singular.</exception> /// <exception cref="ArgumentException">If <see cref="DiagonalMatrix"/> is singular.</exception>
/// <returns>The inverse of this matrix.</returns> /// <returns>The inverse of this matrix.</returns>
public override Matrix Inverse() public override Matrix<double> Inverse()
{ {
if (RowCount != ColumnCount) if (RowCount != ColumnCount)
{ {
@ -953,7 +956,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// Returns a new matrix containing the lower triangle of this matrix. /// Returns a new matrix containing the lower triangle of this matrix.
/// </summary> /// </summary>
/// <returns>The lower triangle of this matrix.</returns> /// <returns>The lower triangle of this matrix.</returns>
public override Matrix LowerTriangle() public override Matrix<double> LowerTriangle()
{ {
return Clone(); return Clone();
} }
@ -964,7 +967,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="result">Where to store the lower triangle.</param> /// <param name="result">Where to store the lower triangle.</param>
/// <exception cref="ArgumentNullException">If <paramref name="result"/> is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If <paramref name="result"/> is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If the result matrix's dimensions are not the same as this matrix.</exception> /// <exception cref="ArgumentException">If the result matrix's dimensions are not the same as this matrix.</exception>
public override void LowerTriangle(Matrix result) public override void LowerTriangle(Matrix<double> result)
{ {
if (result == null) if (result == null)
{ {
@ -993,7 +996,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// does not contain the diagonal elements of this matrix. /// does not contain the diagonal elements of this matrix.
/// </summary> /// </summary>
/// <returns>The lower triangle of this matrix.</returns> /// <returns>The lower triangle of this matrix.</returns>
public override Matrix StrictlyLowerTriangle() public override Matrix<double> StrictlyLowerTriangle()
{ {
return new DiagonalMatrix(RowCount, ColumnCount); return new DiagonalMatrix(RowCount, ColumnCount);
} }
@ -1004,7 +1007,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="result">Where to store the lower triangle.</param> /// <param name="result">Where to store the lower triangle.</param>
/// <exception cref="ArgumentNullException">If <paramref name="result"/> is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If <paramref name="result"/> is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If the result matrix's dimensions are not the same as this matrix.</exception> /// <exception cref="ArgumentException">If the result matrix's dimensions are not the same as this matrix.</exception>
public override void StrictlyLowerTriangle(Matrix result) public override void StrictlyLowerTriangle(Matrix<double> result)
{ {
if (result == null) if (result == null)
{ {
@ -1023,7 +1026,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// Returns a new matrix containing the upper triangle of this matrix. /// Returns a new matrix containing the upper triangle of this matrix.
/// </summary> /// </summary>
/// <returns>The upper triangle of this matrix.</returns> /// <returns>The upper triangle of this matrix.</returns>
public override Matrix UpperTriangle() public override Matrix<double> UpperTriangle()
{ {
return Clone(); return Clone();
} }
@ -1034,7 +1037,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="result">Where to store the lower triangle.</param> /// <param name="result">Where to store the lower triangle.</param>
/// <exception cref="ArgumentNullException">If <paramref name="result"/> is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If <paramref name="result"/> is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If the result matrix's dimensions are not the same as this matrix.</exception> /// <exception cref="ArgumentException">If the result matrix's dimensions are not the same as this matrix.</exception>
public override void UpperTriangle(Matrix result) public override void UpperTriangle(Matrix<double> result)
{ {
if (result == null) if (result == null)
{ {
@ -1058,7 +1061,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// does not contain the diagonal elements of this matrix. /// does not contain the diagonal elements of this matrix.
/// </summary> /// </summary>
/// <returns>The upper triangle of this matrix.</returns> /// <returns>The upper triangle of this matrix.</returns>
public override Matrix StrictlyUpperTriangle() public override Matrix<double> StrictlyUpperTriangle()
{ {
return new DiagonalMatrix(RowCount, ColumnCount); return new DiagonalMatrix(RowCount, ColumnCount);
} }
@ -1069,7 +1072,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="result">Where to store the lower triangle.</param> /// <param name="result">Where to store the lower triangle.</param>
/// <exception cref="ArgumentNullException">If <paramref name="result"/> is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If <paramref name="result"/> is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If the result matrix's dimensions are not the same as this matrix.</exception> /// <exception cref="ArgumentException">If the result matrix's dimensions are not the same as this matrix.</exception>
public override void StrictlyUpperTriangle(Matrix result) public override void StrictlyUpperTriangle(Matrix<double> result)
{ {
if (result == null) if (result == null)
{ {
@ -1100,7 +1103,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <item><c>(rowIndex + rowLength) &gt;= Rows</c></item></list></exception> /// <item><c>(rowIndex + rowLength) &gt;= Rows</c></item></list></exception>
/// <exception cref="ArgumentException">If <paramref name="rowLength"/> or <paramref name="columnLength"/> /// <exception cref="ArgumentException">If <paramref name="rowLength"/> or <paramref name="columnLength"/>
/// is not positive.</exception> /// is not positive.</exception>
public override Matrix SubMatrix(int rowIndex, int rowLength, int columnIndex, int columnLength) public override Matrix<double> SubMatrix(int rowIndex, int rowLength, int columnIndex, int columnLength)
{ {
if (rowIndex >= RowCount || rowIndex < 0) if (rowIndex >= RowCount || rowIndex < 0)
{ {
@ -1186,7 +1189,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentNullException">If <paramref name="column "/> is <see langword="null" />. </exception> /// <exception cref="ArgumentNullException">If <paramref name="column "/> is <see langword="null" />. </exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="columnIndex"/> is &lt; zero or &gt; the number of columns.</exception> /// <exception cref="ArgumentOutOfRangeException">If <paramref name="columnIndex"/> is &lt; zero or &gt; the number of columns.</exception>
/// <exception cref="ArgumentException">If the size of <paramref name="column"/> != the number of rows.</exception> /// <exception cref="ArgumentException">If the size of <paramref name="column"/> != the number of rows.</exception>
public override Matrix InsertColumn(int columnIndex, Vector column) public override Matrix<double> InsertColumn(int columnIndex, Vector<double> column)
{ {
if (column == null) if (column == null)
{ {
@ -1229,7 +1232,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentNullException">If <paramref name="row"/> is <see langword="null" />. </exception> /// <exception cref="ArgumentNullException">If <paramref name="row"/> is <see langword="null" />. </exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="rowIndex"/> is &lt; zero or &gt; the number of rows.</exception> /// <exception cref="ArgumentOutOfRangeException">If <paramref name="rowIndex"/> is &lt; zero or &gt; the number of rows.</exception>
/// <exception cref="ArgumentException">If the size of <paramref name="row"/> != the number of columns.</exception> /// <exception cref="ArgumentException">If the size of <paramref name="row"/> != the number of columns.</exception>
public override Matrix InsertRow(int rowIndex, Vector row) public override Matrix<double> InsertRow(int rowIndex, Vector<double> row)
{ {
if (row == null) if (row == null)
{ {
@ -1270,7 +1273,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>The combined <see cref="SparseMatrix"/>.</returns> /// <returns>The combined <see cref="SparseMatrix"/>.</returns>
/// <exception cref="ArgumentNullException">If lower is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If lower is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If <strong>upper.Columns != lower.Columns</strong>.</exception> /// <exception cref="ArgumentException">If <strong>upper.Columns != lower.Columns</strong>.</exception>
public override Matrix Stack(Matrix lower) public override Matrix<double> Stack(Matrix<double> lower)
{ {
if (lower == null) if (lower == null)
{ {
@ -1294,7 +1297,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="result">The combined <see cref="SparseMatrix"/>.</param> /// <param name="result">The combined <see cref="SparseMatrix"/>.</param>
/// <exception cref="ArgumentNullException">If lower is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If lower is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If <strong>upper.Columns != lower.Columns</strong>.</exception> /// <exception cref="ArgumentException">If <strong>upper.Columns != lower.Columns</strong>.</exception>
public override void Stack(Matrix lower, Matrix result) public override void Stack(Matrix<double> lower, Matrix<double> result)
{ {
if (lower == null) if (lower == null)
{ {
@ -1340,7 +1343,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// </summary> /// </summary>
/// <param name="right">The matrix to concatenate.</param> /// <param name="right">The matrix to concatenate.</param>
/// <returns>The combined <see cref="SparseMatrix"/>.</returns> /// <returns>The combined <see cref="SparseMatrix"/>.</returns>
public override Matrix Append(Matrix right) public override Matrix<double> Append(Matrix<double> right)
{ {
if (right == null) if (right == null)
{ {
@ -1362,7 +1365,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// </summary> /// </summary>
/// <param name="right">The matrix to concatenate.</param> /// <param name="right">The matrix to concatenate.</param>
/// <param name="result">The combined <see cref="SparseMatrix"/>.</param> /// <param name="result">The combined <see cref="SparseMatrix"/>.</param>
public override void Append(Matrix right, Matrix result) public override void Append(Matrix<double> right, Matrix<double> result)
{ {
if (right == null) if (right == null)
{ {
@ -1411,7 +1414,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="lower">The lower, right matrix.</param> /// <param name="lower">The lower, right matrix.</param>
/// <exception cref="ArgumentNullException">If lower is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If lower is <see langword="null" />.</exception>
/// <returns>the combined matrix</returns> /// <returns>the combined matrix</returns>
public override Matrix DiagonalStack(Matrix lower) public override Matrix<double> DiagonalStack(Matrix<double> lower)
{ {
if (lower == null) if (lower == null)
{ {
@ -1431,7 +1434,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentNullException">If lower is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If lower is <see langword="null" />.</exception>
/// <exception cref="ArgumentNullException">If the result matrix is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the result matrix is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If the result matrix's dimensions are not (this.Rows + lower.rows) x (this.Columns + lower.Columns).</exception> /// <exception cref="ArgumentException">If the result matrix's dimensions are not (this.Rows + lower.rows) x (this.Columns + lower.Columns).</exception>
public override void DiagonalStack(Matrix lower, Matrix result) public override void DiagonalStack(Matrix<double> lower, Matrix<double> result)
{ {
if (lower == null) if (lower == null)
{ {
@ -1470,7 +1473,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentNullException">If the result matrix is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the result matrix is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If this matrix and <paramref name="other"/> are not the same size.</exception> /// <exception cref="ArgumentException">If this matrix and <paramref name="other"/> are not the same size.</exception>
/// <exception cref="ArgumentException">If this matrix and <paramref name="result"/> are not the same size.</exception> /// <exception cref="ArgumentException">If this matrix and <paramref name="result"/> are not the same size.</exception>
public override void PointwiseMultiply(Matrix other, Matrix result) public override void PointwiseMultiply(Matrix<double> other, Matrix<double> result)
{ {
if (other == null) if (other == null)
{ {
@ -1548,5 +1551,191 @@ namespace MathNet.Numerics.LinearAlgebra.Double
} }
#endregion #endregion
/// <summary>
/// Negates each element of this matrix.
/// </summary>
public override void Negate()
{
Multiply(-1);
}
/// <summary>
/// Generates matrix with random elements.
/// </summary>
/// <param name="numberOfRows">Number of rows.</param>
/// <param name="numberOfColumns">Number of columns.</param>
/// <param name="distribution">Continuous Random Distribution or Source</param>
/// <returns>
/// An <c>numberOfRows</c>-by-<c>numberOfColumns</c> matrix with elements distributed according to the provided distribution.
/// </returns>
/// <exception cref="ArgumentException">If the parameter <paramref name="numberOfRows"/> is not positive.</exception>
/// <exception cref="ArgumentException">If the parameter <paramref name="numberOfColumns"/> is not positive.</exception>
public override Matrix<double> Random(int numberOfRows, int numberOfColumns, IContinuousDistribution distribution)
{
if (numberOfRows < 1)
{
throw new ArgumentException(Resources.ArgumentMustBePositive, "numberOfRows");
}
if (numberOfColumns < 1)
{
throw new ArgumentException(Resources.ArgumentMustBePositive, "numberOfColumns");
}
var matrix = CreateMatrix(numberOfRows, numberOfColumns);
CommonParallel.For(
0,
ColumnCount,
j =>
{
for (var i = 0; i < matrix.RowCount; i++)
{
matrix[i, j] = distribution.Sample();
}
});
return matrix;
}
/// <summary>
/// Generates matrix with random elements.
/// </summary>
/// <param name="numberOfRows">Number of rows.</param>
/// <param name="numberOfColumns">Number of columns.</param>
/// <param name="distribution">Continuous Random Distribution or Source</param>
/// <returns>
/// An <c>numberOfRows</c>-by-<c>numberOfColumns</c> matrix with elements distributed according to the provided distribution.
/// </returns>
/// <exception cref="ArgumentException">If the parameter <paramref name="numberOfRows"/> is not positive.</exception>
/// <exception cref="ArgumentException">If the parameter <paramref name="numberOfColumns"/> is not positive.</exception>
public override Matrix<double> Random(int numberOfRows, int numberOfColumns, IDiscreteDistribution distribution)
{
if (numberOfRows < 1)
{
throw new ArgumentException(Resources.ArgumentMustBePositive, "numberOfRows");
}
if (numberOfColumns < 1)
{
throw new ArgumentException(Resources.ArgumentMustBePositive, "numberOfColumns");
}
var matrix = CreateMatrix(numberOfRows, numberOfColumns);
CommonParallel.For(
0,
ColumnCount,
j =>
{
for (var i = 0; i < matrix.RowCount; i++)
{
matrix[i, j] = distribution.Sample();
}
});
return matrix;
}
/// <summary>
/// Returns a <see cref="System.String"/> that represents this instance.
/// </summary>
/// <param name="format">
/// The format to use.
/// </param>
/// <param name="formatProvider">
/// The format provider to use.
/// </param>
/// <returns>
/// A <see cref="System.String"/> that represents this instance.
/// </returns>
public override string ToString(string format, IFormatProvider formatProvider)
{
var stringBuilder = new StringBuilder();
for (var row = 0; row < RowCount; row++)
{
for (var column = 0; column < ColumnCount; column++)
{
stringBuilder.Append(At(row, column).ToString(format, formatProvider));
if (column != ColumnCount - 1)
{
stringBuilder.Append(formatProvider.GetTextInfo().ListSeparator);
}
}
if (row != RowCount - 1)
{
stringBuilder.Append(Environment.NewLine);
}
}
return stringBuilder.ToString();
}
#region Simple arithmetic of type T
/// <summary>
/// Add two values T+T
/// </summary>
/// <param name="val1">Left operand value</param>
/// <param name="val2">Right operand value</param>
/// <returns>Result of addition</returns>
protected sealed override double AddT(double val1, double val2)
{
return val1 + val2;
}
/// <summary>
/// Subtract two values T-T
/// </summary>
/// <param name="val1">Left operand value</param>
/// <param name="val2">Right operand value</param>
/// <returns>Result of subtract</returns>
protected sealed override double SubtractT(double val1, double val2)
{
return val1 - val2;
}
/// <summary>
/// Multiply two values T*T
/// </summary>
/// <param name="val1">Left operand value</param>
/// <param name="val2">Right operand value</param>
/// <returns>Result of multiplication</returns>
protected sealed override double MultiplyT(double val1, double val2)
{
return val1 * val2;
}
/// <summary>
/// Divide two values T/T
/// </summary>
/// <param name="val1">Left operand value</param>
/// <param name="val2">Right operand value</param>
/// <returns>Result of divide</returns>
protected sealed override double DivideT(double val1, double val2)
{
return val1 / val2;
}
/// <summary>
/// Is equal to one?
/// </summary>
/// <param name="val1">Value to check</param>
/// <returns>True if one; otherwise false</returns>
protected sealed override bool IsOneT(double val1)
{
return 1.0.AlmostEqualInDecimalPlaces(val1, 15);
}
/// <summary>
/// Take absolute value
/// </summary>
/// <param name="val1">Source alue</param>
/// <returns>True if one; otherwise false</returns>
protected sealed override double AbsoluteT(double val1)
{
return Math.Abs(val1);
}
#endregion
} }
} }

47
src/Numerics/LinearAlgebra/Double/Factorization/DenseCholesky.cs

@ -31,6 +31,8 @@
namespace MathNet.Numerics.LinearAlgebra.Double.Factorization namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
{ {
using System; using System;
using Generic;
using Generic.Factorization;
using Properties; using Properties;
/// <summary> /// <summary>
@ -42,7 +44,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// The computation of the Cholesky factorization is done at construction time. If the matrix is not symmetric /// The computation of the Cholesky factorization is done at construction time. If the matrix is not symmetric
/// or positive definite, the constructor will throw an exception. /// or positive definite, the constructor will throw an exception.
/// </remarks> /// </remarks>
public class DenseCholesky : Cholesky public class DenseCholesky : Cholesky<double>
{ {
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="DenseCholesky"/> class. This object will compute the /// Initializes a new instance of the <see cref="DenseCholesky"/> class. This object will compute the
@ -73,9 +75,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <summary> /// <summary>
/// Solves a system of linear equations, <b>AX = B</b>, with A Cholesky factorized. /// Solves a system of linear equations, <b>AX = B</b>, with A Cholesky factorized.
/// </summary> /// </summary>
/// <param name="input">The right hand side <see cref="Matrix"/>, <b>B</b>.</param> /// <param name="input">The right hand side <see cref="Matrix{T}"/>, <b>B</b>.</param>
/// <param name="result">The left hand side <see cref="Matrix"/>, <b>X</b>.</param> /// <param name="result">The left hand side <see cref="Matrix{T}"/>, <b>X</b>.</param>
public override void Solve(Matrix input, Matrix result) public override void Solve(Matrix<double> input, Matrix<double> result)
{ {
// Check for proper arguments. // Check for proper arguments.
if (input == null) if (input == null)
@ -128,8 +130,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// Solves a system of linear equations, <b>Ax = b</b>, with A Cholesky factorized. /// Solves a system of linear equations, <b>Ax = b</b>, with A Cholesky factorized.
/// </summary> /// </summary>
/// <param name="input">The right hand side vector, <b>b</b>.</param> /// <param name="input">The right hand side vector, <b>b</b>.</param>
/// <param name="result">The left hand side <see cref="Matrix"/>, <b>x</b>.</param> /// <param name="result">The left hand side <see cref="Matrix{T}"/>, <b>x</b>.</param>
public override void Solve(Vector input, Vector result) public override void Solve(Vector<double> input, Vector<double> result)
{ {
// Check for proper arguments. // Check for proper arguments.
if (input == null) if (input == null)
@ -172,5 +174,38 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
var dfactor = (DenseMatrix)CholeskyFactor; var dfactor = (DenseMatrix)CholeskyFactor;
Control.LinearAlgebraProvider.CholeskySolveFactored(dfactor.Data, dfactor.RowCount, dresult.Data, dresult.Count, 1); Control.LinearAlgebraProvider.CholeskySolveFactored(dfactor.Data, dfactor.RowCount, dresult.Data, dresult.Count, 1);
} }
#region Simple arithmetic of type T
/// <summary>
/// Multiply two values T*T
/// </summary>
/// <param name="val1">Left operand value</param>
/// <param name="val2">Right operand value</param>
/// <returns>Result of multiplication</returns>
protected sealed override double MultiplyT(double val1, double val2)
{
return val1 * val2;
}
/// <summary>
/// Returns the natural (base e) logarithm of a specified number.
/// </summary>
/// <param name="val1"> A number whose logarithm is to be found</param>
/// <returns>Natural (base e) logarithm </returns>
protected sealed override double LogT(double val1)
{
return Math.Log(val1);
}
/// <summary>
/// Get value of type T equal to one
/// </summary>
/// <returns>One value</returns>
protected sealed override double OneValueT
{
get { return 1.0; }
}
#endregion
} }
} }

48
src/Numerics/LinearAlgebra/Double/Factorization/DenseLU.cs

@ -31,6 +31,8 @@
namespace MathNet.Numerics.LinearAlgebra.Double.Factorization namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
{ {
using System; using System;
using Generic;
using Generic.Factorization;
using Properties; using Properties;
/// <summary> /// <summary>
@ -41,7 +43,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <remarks> /// <remarks>
/// The computation of the LU factorization is done at construction time. /// The computation of the LU factorization is done at construction time.
/// </remarks> /// </remarks>
public class DenseLU : LU public class DenseLU : LU<double>
{ {
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="DenseLU"/> class. This object will compute the /// Initializes a new instance of the <see cref="DenseLU"/> class. This object will compute the
@ -74,9 +76,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <summary> /// <summary>
/// Solves a system of linear equations, <c>AX = B</c>, with A LU factorized. /// Solves a system of linear equations, <c>AX = B</c>, with A LU factorized.
/// </summary> /// </summary>
/// <param name="input">The right hand side <see cref="Matrix"/>, <c>B</c>.</param> /// <param name="input">The right hand side <see cref="Matrix{T}"/>, <c>B</c>.</param>
/// <param name="result">The left hand side <see cref="Matrix"/>, <c>X</c>.</param> /// <param name="result">The left hand side <see cref="Matrix{T}"/>, <c>X</c>.</param>
public override void Solve(Matrix input, Matrix result) public override void Solve(Matrix<double> input, Matrix<double> result)
{ {
// Check for proper arguments. // Check for proper arguments.
if (input == null) if (input == null)
@ -129,8 +131,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// Solves a system of linear equations, <c>Ax = b</c>, with A LU factorized. /// Solves a system of linear equations, <c>Ax = b</c>, with A LU factorized.
/// </summary> /// </summary>
/// <param name="input">The right hand side vector, <c>b</c>.</param> /// <param name="input">The right hand side vector, <c>b</c>.</param>
/// <param name="result">The left hand side <see cref="Matrix"/>, <c>x</c>.</param> /// <param name="result">The left hand side <see cref="Matrix{T}"/>, <c>x</c>.</param>
public override void Solve(Vector input, Vector result) public override void Solve(Vector<double> input, Vector<double> result)
{ {
// Check for proper arguments. // Check for proper arguments.
if (input == null) if (input == null)
@ -178,11 +180,43 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// Returns the inverse of this matrix. The inverse is calculated using LU decomposition. /// Returns the inverse of this matrix. The inverse is calculated using LU decomposition.
/// </summary> /// </summary>
/// <returns>The inverse of this matrix.</returns> /// <returns>The inverse of this matrix.</returns>
public override Matrix Inverse() public override Matrix<double> Inverse()
{ {
var result = (DenseMatrix)Factors.Clone(); var result = (DenseMatrix)Factors.Clone();
Control.LinearAlgebraProvider.LUInverseFactored(result.Data, result.RowCount, Pivots); Control.LinearAlgebraProvider.LUInverseFactored(result.Data, result.RowCount, Pivots);
return result; return result;
} }
#region Simple arithmetic of type T
/// <summary>
/// Multiply two values T*T
/// </summary>
/// <param name="val1">Left operand value</param>
/// <param name="val2">Right operand value</param>
/// <returns>Result of multiplication</returns>
protected sealed override double MultiplyT(double val1, double val2)
{
return val1 * val2;
}
/// <summary>
/// Get value of type T equal to one
/// </summary>
/// <returns>One value</returns>
protected sealed override double OneValueT
{
get { return 1.0; }
}
/// <summary>
/// Get value of type T equal to minus one
/// </summary>
/// <returns>One value</returns>
protected sealed override double MinusOneValueT
{
get { return -1.0; }
}
#endregion
} }
} }

47
src/Numerics/LinearAlgebra/Double/Factorization/DenseQR.cs

@ -31,6 +31,8 @@
namespace MathNet.Numerics.LinearAlgebra.Double.Factorization namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
{ {
using System; using System;
using Generic;
using Generic.Factorization;
using Properties; using Properties;
/// <summary> /// <summary>
@ -42,7 +44,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <remarks> /// <remarks>
/// The computation of the QR decomposition is done at construction time by Householder transformation. /// The computation of the QR decomposition is done at construction time by Householder transformation.
/// </remarks> /// </remarks>
public class DenseQR : QR public class DenseQR : QR<double>
{ {
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="DenseQR"/> class. This object will compute the /// Initializes a new instance of the <see cref="DenseQR"/> class. This object will compute the
@ -71,9 +73,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <summary> /// <summary>
/// Solves a system of linear equations, <b>AX = B</b>, with A QR factorized. /// Solves a system of linear equations, <b>AX = B</b>, with A QR factorized.
/// </summary> /// </summary>
/// <param name="input">The right hand side <see cref="Matrix"/>, <b>B</b>.</param> /// <param name="input">The right hand side <see cref="Matrix{T}"/>, <b>B</b>.</param>
/// <param name="result">The left hand side <see cref="Matrix"/>, <b>X</b>.</param> /// <param name="result">The left hand side <see cref="Matrix{T}"/>, <b>X</b>.</param>
public override void Solve(Matrix input, Matrix result) public override void Solve(Matrix<double> input, Matrix<double> result)
{ {
// Check for proper arguments. // Check for proper arguments.
if (input == null) if (input == null)
@ -123,8 +125,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// Solves a system of linear equations, <b>Ax = b</b>, with A QR factorized. /// Solves a system of linear equations, <b>Ax = b</b>, with A QR factorized.
/// </summary> /// </summary>
/// <param name="input">The right hand side vector, <b>b</b>.</param> /// <param name="input">The right hand side vector, <b>b</b>.</param>
/// <param name="result">The left hand side <see cref="Matrix"/>, <b>x</b>.</param> /// <param name="result">The left hand side <see cref="Matrix{T}"/>, <b>x</b>.</param>
public override void Solve(Vector input, Vector result) public override void Solve(Vector<double> input, Vector<double> result)
{ {
if (input == null) if (input == null)
{ {
@ -163,5 +165,38 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
Control.LinearAlgebraProvider.QRSolveFactored(((DenseMatrix)MatrixQ).Data, ((DenseMatrix)MatrixR).Data, MatrixR.RowCount, MatrixR.ColumnCount, dinput.Data, 1, dresult.Data); Control.LinearAlgebraProvider.QRSolveFactored(((DenseMatrix)MatrixQ).Data, ((DenseMatrix)MatrixR).Data, MatrixR.RowCount, MatrixR.ColumnCount, dinput.Data, 1, dresult.Data);
} }
#region Simple arithmetic of type T
/// <summary>
/// Multiply two values T*T
/// </summary>
/// <param name="val1">Left operand value</param>
/// <param name="val2">Right operand value</param>
/// <returns>Result of multiplication</returns>
protected sealed override double MultiplyT(double val1, double val2)
{
return val1 * val2;
}
/// <summary>
/// Returns the absolute value of a specified number.
/// </summary>
/// <param name="val1"> A number whose absolute is to be found</param>
/// <returns>Absolute value </returns>
protected sealed override double AbsoluteT(double val1)
{
return Math.Abs(val1);
}
/// <summary>
/// Get value of type T equal to one
/// </summary>
/// <returns>One value</returns>
protected sealed override double OneValueT
{
get { return 1.0; }
}
#endregion
} }
} }

48
src/Numerics/LinearAlgebra/Double/Factorization/DenseSvd.cs

@ -30,6 +30,8 @@
namespace MathNet.Numerics.LinearAlgebra.Double.Factorization namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
{ {
using System; using System;
using Generic;
using Generic.Factorization;
using Properties; using Properties;
/// <summary> /// <summary>
@ -46,7 +48,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <remarks> /// <remarks>
/// The computation of the singular value decomposition is done at construction time. /// The computation of the singular value decomposition is done at construction time.
/// </remarks> /// </remarks>
public class DenseSvd : Svd public class DenseSvd : Svd<double>
{ {
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="DenseSvd"/> class. This object will compute the /// Initializes a new instance of the <see cref="DenseSvd"/> class. This object will compute the
@ -74,9 +76,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <summary> /// <summary>
/// Solves a system of linear equations, <b>AX = B</b>, with A SVD factorized. /// Solves a system of linear equations, <b>AX = B</b>, with A SVD factorized.
/// </summary> /// </summary>
/// <param name="input">The right hand side <see cref="Matrix"/>, <b>B</b>.</param> /// <param name="input">The right hand side <see cref="Matrix{T}"/>, <b>B</b>.</param>
/// <param name="result">The left hand side <see cref="Matrix"/>, <b>X</b>.</param> /// <param name="result">The left hand side <see cref="Matrix{T}"/>, <b>X</b>.</param>
public override void Solve(Matrix input, Matrix result) public override void Solve(Matrix<double> input, Matrix<double> result)
{ {
// Check for proper arguments. // Check for proper arguments.
if (input == null) if (input == null)
@ -131,8 +133,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// Solves a system of linear equations, <b>Ax = b</b>, with A SVD factorized. /// Solves a system of linear equations, <b>Ax = b</b>, with A SVD factorized.
/// </summary> /// </summary>
/// <param name="input">The right hand side vector, <b>b</b>.</param> /// <param name="input">The right hand side vector, <b>b</b>.</param>
/// <param name="result">The left hand side <see cref="Matrix"/>, <b>x</b>.</param> /// <param name="result">The left hand side <see cref="Matrix{T}"/>, <b>x</b>.</param>
public override void Solve(Vector input, Vector result) public override void Solve(Vector<double> input, Vector<double> result)
{ {
if (input == null) if (input == null)
{ {
@ -176,5 +178,39 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
Control.LinearAlgebraProvider.SvdSolveFactored(MatrixU.RowCount, MatrixVT.ColumnCount, ((DenseVector)VectorS).Data, ((DenseMatrix)MatrixU).Data, ((DenseMatrix)MatrixVT).Data, dinput.Data, 1, dresult.Data); Control.LinearAlgebraProvider.SvdSolveFactored(MatrixU.RowCount, MatrixVT.ColumnCount, ((DenseVector)VectorS).Data, ((DenseMatrix)MatrixU).Data, ((DenseMatrix)MatrixVT).Data, dinput.Data, 1, dresult.Data);
} }
#region Simple arithmetic of type T
/// <summary>
/// Multiply two values T*T
/// </summary>
/// <param name="val1">Left operand value</param>
/// <param name="val2">Right operand value</param>
/// <returns>Result of multiplication</returns>
protected sealed override double MultiplyT(double val1, double val2)
{
return val1 * val2;
}
/// <summary>
/// Returns the absolute value of a specified number.
/// </summary>
/// <param name="val1"> A number whose absolute is to be found</param>
/// <returns>Absolute value </returns>
protected sealed override double AbsoluteT(double val1)
{
return Math.Abs(val1);
}
/// <summary>
/// Get value of type T equal to one
/// </summary>
/// <returns>One value</returns>
protected sealed override double OneValueT
{
get { return 1.0; }
}
#endregion
} }
} }

21
src/Numerics/LinearAlgebra/Double/Factorization/ExtensionMethods.cs

@ -30,6 +30,9 @@
namespace MathNet.Numerics.LinearAlgebra.Double.Factorization namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
{ {
using Generic;
using Generic.Factorization;
/// <summary> /// <summary>
/// Extension methods which return factorizations for the various matrix classes. /// Extension methods which return factorizations for the various matrix classes.
/// </summary> /// </summary>
@ -40,9 +43,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// </summary> /// </summary>
/// <param name="matrix">The matrix to factor.</param> /// <param name="matrix">The matrix to factor.</param>
/// <returns>The Cholesky decomposition object.</returns> /// <returns>The Cholesky decomposition object.</returns>
public static Cholesky Cholesky(this Matrix matrix) public static Cholesky<double> Cholesky(this Matrix<double> matrix)
{ {
return Factorization.Cholesky.Create(matrix); return Cholesky<double>.Create(matrix);
} }
/// <summary> /// <summary>
@ -50,9 +53,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// </summary> /// </summary>
/// <param name="matrix">The matrix to factor.</param> /// <param name="matrix">The matrix to factor.</param>
/// <returns>The LU decomposition object.</returns> /// <returns>The LU decomposition object.</returns>
public static LU LU(this Matrix matrix) public static LU<double> LU(this Matrix<double> matrix)
{ {
return Factorization.LU.Create(matrix); return LU<double>.Create(matrix);
} }
/// <summary> /// <summary>
@ -60,9 +63,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// </summary> /// </summary>
/// <param name="matrix">The matrix to factor.</param> /// <param name="matrix">The matrix to factor.</param>
/// <returns>The QR decomposition object.</returns> /// <returns>The QR decomposition object.</returns>
public static QR QR(this Matrix matrix) public static QR<double> QR(this Matrix<double> matrix)
{ {
return Factorization.QR.Create(matrix); return QR<double>.Create(matrix);
} }
/// <summary> /// <summary>
@ -70,7 +73,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// </summary> /// </summary>
/// <param name="matrix">The matrix to factor.</param> /// <param name="matrix">The matrix to factor.</param>
/// <returns>The QR decomposition object.</returns> /// <returns>The QR decomposition object.</returns>
public static GramSchmidt GramSchmidt(this Matrix matrix) public static GramSchmidt GramSchmidt(this Matrix<double> matrix)
{ {
// NOTE: There is no factory for GramSchmidt. Use constructor of GramSchmidt class. // NOTE: There is no factory for GramSchmidt. Use constructor of GramSchmidt class.
return new GramSchmidt(matrix); return new GramSchmidt(matrix);
@ -82,9 +85,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <param name="matrix">The matrix to factor.</param> /// <param name="matrix">The matrix to factor.</param>
/// <param name="computeVectors">Compute the singular U and VT vectors or not.</param> /// <param name="computeVectors">Compute the singular U and VT vectors or not.</param>
/// <returns>The QR decomposition object.</returns> /// <returns>The QR decomposition object.</returns>
public static Svd Svd(this Matrix matrix, bool computeVectors) public static Svd<double> Svd(this Matrix<double> matrix, bool computeVectors)
{ {
return Factorization.Svd.Create(matrix, computeVectors); return Svd<double>.Create(matrix, computeVectors);
} }
} }
} }

49
src/Numerics/LinearAlgebra/Double/Factorization/GramSchmidt.cs

@ -31,6 +31,8 @@
namespace MathNet.Numerics.LinearAlgebra.Double.Factorization namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
{ {
using System; using System;
using Generic;
using Generic.Factorization;
using Properties; using Properties;
/// <summary> /// <summary>
@ -40,7 +42,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <remarks> /// <remarks>
/// The computation of the QR decomposition is done at construction time by modified Gram-Schmidt Orthogonalization. /// The computation of the QR decomposition is done at construction time by modified Gram-Schmidt Orthogonalization.
/// </remarks> /// </remarks>
public class GramSchmidt : QR public class GramSchmidt : QR<double>
{ {
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="GramSchmidt"/> class. This object creates an orthogonal matrix /// Initializes a new instance of the <see cref="GramSchmidt"/> class. This object creates an orthogonal matrix
@ -50,7 +52,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <exception cref="ArgumentNullException">If <paramref name="matrix"/> is <c>null</c>.</exception> /// <exception cref="ArgumentNullException">If <paramref name="matrix"/> is <c>null</c>.</exception>
/// <exception cref="ArgumentException">If <paramref name="matrix"/> row count is less then column count</exception> /// <exception cref="ArgumentException">If <paramref name="matrix"/> row count is less then column count</exception>
/// <exception cref="ArgumentException">If <paramref name="matrix"/> is rank deficient</exception> /// <exception cref="ArgumentException">If <paramref name="matrix"/> is rank deficient</exception>
public GramSchmidt(Matrix matrix) public GramSchmidt(Matrix<double> matrix)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -133,9 +135,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <summary> /// <summary>
/// Solves a system of linear equations, <b>AX = B</b>, with A QR factorized. /// Solves a system of linear equations, <b>AX = B</b>, with A QR factorized.
/// </summary> /// </summary>
/// <param name="input">The right hand side <see cref="Matrix"/>, <b>B</b>.</param> /// <param name="input">The right hand side <see cref="Matrix{T}"/>, <b>B</b>.</param>
/// <param name="result">The left hand side <see cref="Matrix"/>, <b>X</b>.</param> /// <param name="result">The left hand side <see cref="Matrix{T}"/>, <b>X</b>.</param>
public override void Solve(Matrix input, Matrix result) public override void Solve(Matrix<double> input, Matrix<double> result)
{ {
// Check for proper arguments. // Check for proper arguments.
if (input == null) if (input == null)
@ -219,8 +221,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// Solves a system of linear equations, <b>Ax = b</b>, with A QR factorized. /// Solves a system of linear equations, <b>Ax = b</b>, with A QR factorized.
/// </summary> /// </summary>
/// <param name="input">The right hand side vector, <b>b</b>.</param> /// <param name="input">The right hand side vector, <b>b</b>.</param>
/// <param name="result">The left hand side <see cref="Matrix"/>, <b>x</b>.</param> /// <param name="result">The left hand side <see cref="Matrix{T}"/>, <b>x</b>.</param>
public override void Solve(Vector input, Vector result) public override void Solve(Vector<double> input, Vector<double> result)
{ {
if (input == null) if (input == null)
{ {
@ -280,5 +282,38 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
result[i] = inputCopy[i]; result[i] = inputCopy[i];
} }
} }
#region Simple arithmetic of type T
/// <summary>
/// Multiply two values T*T
/// </summary>
/// <param name="val1">Left operand value</param>
/// <param name="val2">Right operand value</param>
/// <returns>Result of multiplication</returns>
protected sealed override double MultiplyT(double val1, double val2)
{
return val1 * val2;
}
/// <summary>
/// Returns the absolute value of a specified number.
/// </summary>
/// <param name="val1"> A number whose absolute is to be found</param>
/// <returns>Absolute value </returns>
protected sealed override double AbsoluteT(double val1)
{
return Math.Abs(val1);
}
/// <summary>
/// Get value of type T equal to one
/// </summary>
/// <returns>One value</returns>
protected sealed override double OneValueT
{
get { return 1.0; }
}
#endregion
} }
} }

51
src/Numerics/LinearAlgebra/Double/Factorization/SparseCholesky.cs

@ -31,6 +31,8 @@
namespace MathNet.Numerics.LinearAlgebra.Double.Factorization namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
{ {
using System; using System;
using Generic;
using Generic.Factorization;
using Properties; using Properties;
/// <summary> /// <summary>
@ -42,7 +44,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// The computation of the Cholesky factorization is done at construction time. If the matrix is not symmetric /// The computation of the Cholesky factorization is done at construction time. If the matrix is not symmetric
/// or positive definite, the constructor will throw an exception. /// or positive definite, the constructor will throw an exception.
/// </remarks> /// </remarks>
public class SparseCholesky : Cholesky public class SparseCholesky : Cholesky<double>
{ {
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="SparseCholesky"/> class. This object will compute the /// Initializes a new instance of the <see cref="SparseCholesky"/> class. This object will compute the
@ -52,7 +54,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <exception cref="ArgumentNullException">If <paramref name="matrix"/> is <c>null</c>.</exception> /// <exception cref="ArgumentNullException">If <paramref name="matrix"/> is <c>null</c>.</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>
/// <exception cref="ArgumentException">If <paramref name="matrix"/> is not positive definite.</exception> /// <exception cref="ArgumentException">If <paramref name="matrix"/> is not positive definite.</exception>
public SparseCholesky(Matrix matrix) public SparseCholesky(Matrix<double> matrix)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -96,13 +98,12 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
} }
} }
/// <summary> /// <summary>
/// Solves a system of linear equations, <b>AX = B</b>, with A Cholesky factorized. /// Solves a system of linear equations, <b>AX = B</b>, with A Cholesky factorized.
/// </summary> /// </summary>
/// <param name="input">The right hand side <see cref="Matrix"/>, <b>B</b>.</param> /// <param name="input">The right hand side <see cref="Matrix{T}"/>, <b>B</b>.</param>
/// <param name="result">The left hand side <see cref="Matrix"/>, <b>X</b>.</param> /// <param name="result">The left hand side <see cref="Matrix{T}"/>, <b>X</b>.</param>
public override void Solve(Matrix input, Matrix result) public override void Solve(Matrix<double> input, Matrix<double> result)
{ {
if (input == null) if (input == null)
{ {
@ -166,8 +167,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// Solves a system of linear equations, <b>Ax = b</b>, with A Cholesky factorized. /// Solves a system of linear equations, <b>Ax = b</b>, with A Cholesky factorized.
/// </summary> /// </summary>
/// <param name="input">The right hand side vector, <b>b</b>.</param> /// <param name="input">The right hand side vector, <b>b</b>.</param>
/// <param name="result">The left hand side <see cref="Matrix"/>, <b>x</b>.</param> /// <param name="result">The left hand side <see cref="Matrix{T}"/>, <b>x</b>.</param>
public override void Solve(Vector input, Vector result) public override void Solve(Vector<double> input, Vector<double> result)
{ {
// Check for proper arguments. // Check for proper arguments.
if (input == null) if (input == null)
@ -219,5 +220,39 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
result[i] = sum / CholeskyFactor.At(i, i); result[i] = sum / CholeskyFactor.At(i, i);
} }
} }
#region Simple arithmetic of type T
/// <summary>
/// Multiply two values T*T
/// </summary>
/// <param name="val1">Left operand value</param>
/// <param name="val2">Right operand value</param>
/// <returns>Result of multiplication</returns>
protected sealed override double MultiplyT(double val1, double val2)
{
return val1 * val2;
}
/// <summary>
/// Returns the natural (base e) logarithm of a specified number.
/// </summary>
/// <param name="val1"> A number whose logarithm is to be found</param>
/// <returns>Natural (base e) logarithm </returns>
protected sealed override double LogT(double val1)
{
return Math.Log(val1);
}
/// <summary>
/// Get value of type T equal to one
/// </summary>
/// <returns>One value</returns>
protected sealed override double OneValueT
{
get { return 1.0; }
}
#endregion
} }
} }

50
src/Numerics/LinearAlgebra/Double/Factorization/SparseLU.cs

@ -31,6 +31,8 @@
namespace MathNet.Numerics.LinearAlgebra.Double.Factorization namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
{ {
using System; using System;
using Generic;
using Generic.Factorization;
using Properties; using Properties;
/// <summary> /// <summary>
@ -41,7 +43,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <remarks> /// <remarks>
/// The computation of the LU factorization is done at construction time. /// The computation of the LU factorization is done at construction time.
/// </remarks> /// </remarks>
public class SparseLU : LU public class SparseLU : LU<double>
{ {
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="SparseLU"/> class. This object will compute the /// Initializes a new instance of the <see cref="SparseLU"/> class. This object will compute the
@ -50,7 +52,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <param name="matrix">The matrix to factor.</param> /// <param name="matrix">The matrix to factor.</param>
/// <exception cref="ArgumentNullException">If <paramref name="matrix"/> is <c>null</c>.</exception> /// <exception cref="ArgumentNullException">If <paramref name="matrix"/> is <c>null</c>.</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 SparseLU(Matrix matrix) public SparseLU(Matrix<double> matrix)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -132,9 +134,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <summary> /// <summary>
/// Solves a system of linear equations, <c>AX = B</c>, with A LU factorized. /// Solves a system of linear equations, <c>AX = B</c>, with A LU factorized.
/// </summary> /// </summary>
/// <param name="input">The right hand side <see cref="Matrix"/>, <c>B</c>.</param> /// <param name="input">The right hand side <see cref="Matrix{T}"/>, <c>B</c>.</param>
/// <param name="result">The left hand side <see cref="Matrix"/>, <c>X</c>.</param> /// <param name="result">The left hand side <see cref="Matrix{T}"/>, <c>X</c>.</param>
public override void Solve(Matrix input, Matrix result) public override void Solve(Matrix<double> input, Matrix<double> result)
{ {
// Check for proper arguments. // Check for proper arguments.
if (input == null) if (input == null)
@ -219,8 +221,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// Solves a system of linear equations, <c>Ax = b</c>, with A LU factorized. /// Solves a system of linear equations, <c>Ax = b</c>, with A LU factorized.
/// </summary> /// </summary>
/// <param name="input">The right hand side vector, <c>b</c>.</param> /// <param name="input">The right hand side vector, <c>b</c>.</param>
/// <param name="result">The left hand side <see cref="Matrix"/>, <c>x</c>.</param> /// <param name="result">The left hand side <see cref="Matrix{T}"/>, <c>x</c>.</param>
public override void Solve(Vector input, Vector result) public override void Solve(Vector<double> input, Vector<double> result)
{ {
// Check for proper arguments. // Check for proper arguments.
if (input == null) if (input == null)
@ -285,7 +287,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// Returns the inverse of this matrix. The inverse is calculated using LU decomposition. /// Returns the inverse of this matrix. The inverse is calculated using LU decomposition.
/// </summary> /// </summary>
/// <returns>The inverse of this matrix.</returns> /// <returns>The inverse of this matrix.</returns>
public override Matrix Inverse() public override Matrix<double> Inverse()
{ {
var order = Factors.RowCount; var order = Factors.RowCount;
var inverse = Factors.CreateMatrix(order, order); var inverse = Factors.CreateMatrix(order, order);
@ -296,5 +298,37 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
return Solve(inverse); return Solve(inverse);
} }
#region Simple arithmetic of type T
/// <summary>
/// Multiply two values T*T
/// </summary>
/// <param name="val1">Left operand value</param>
/// <param name="val2">Right operand value</param>
/// <returns>Result of multiplication</returns>
protected sealed override double MultiplyT(double val1, double val2)
{
return val1 * val2;
}
/// <summary>
/// Get value of type T equal to one
/// </summary>
/// <returns>One value</returns>
protected sealed override double OneValueT
{
get { return 1.0; }
}
/// <summary>
/// Get value of type T equal to minus one
/// </summary>
/// <returns>One value</returns>
protected sealed override double MinusOneValueT
{
get { return -1.0; }
}
#endregion
} }
} }

53
src/Numerics/LinearAlgebra/Double/Factorization/SparseQR.cs

@ -32,6 +32,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
{ {
using System; using System;
using System.Linq; using System.Linq;
using Generic;
using Generic.Factorization;
using Properties; using Properties;
/// <summary> /// <summary>
@ -43,7 +45,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <remarks> /// <remarks>
/// The computation of the QR decomposition is done at construction time by Householder transformation. /// The computation of the QR decomposition is done at construction time by Householder transformation.
/// </remarks> /// </remarks>
public class SparseQR : QR public class SparseQR : QR<double>
{ {
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="SparseQR"/> class. This object will compute the /// Initializes a new instance of the <see cref="SparseQR"/> class. This object will compute the
@ -51,7 +53,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// </summary> /// </summary>
/// <param name="matrix">The matrix to factor.</param> /// <param name="matrix">The matrix to factor.</param>
/// <exception cref="ArgumentNullException">If <paramref name="matrix"/> is <c>null</c>.</exception> /// <exception cref="ArgumentNullException">If <paramref name="matrix"/> is <c>null</c>.</exception>
public SparseQR(Matrix matrix) public SparseQR(Matrix<double> matrix)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -93,7 +95,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <param name="rowEnd">The last row</param> /// <param name="rowEnd">The last row</param>
/// <param name="column">Column index</param> /// <param name="column">Column index</param>
/// <returns>Generated vector</returns> /// <returns>Generated vector</returns>
private static double[] GenerateColumn(Matrix a, int rowStart, int rowEnd, int column) private static double[] GenerateColumn(Matrix<double> a, int rowStart, int rowEnd, int column)
{ {
var ru = rowEnd - rowStart + 1; var ru = rowEnd - rowStart + 1;
var u = new double[ru]; var u = new double[ru];
@ -147,7 +149,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <param name="rowEnd">The last row</param> /// <param name="rowEnd">The last row</param>
/// <param name="columnStart">The first column</param> /// <param name="columnStart">The first column</param>
/// <param name="columnEnd">The last column</param> /// <param name="columnEnd">The last column</param>
private static void ComputeQR(double[] u, Matrix a, int rowStart, int rowEnd, int columnStart, int columnEnd) private static void ComputeQR(double[] u, Matrix<double> a, int rowStart, int rowEnd, int columnStart, int columnEnd)
{ {
if (rowEnd < rowStart || columnEnd < columnStart) if (rowEnd < rowStart || columnEnd < columnStart)
{ {
@ -180,9 +182,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <summary> /// <summary>
/// Solves a system of linear equations, <b>AX = B</b>, with A QR factorized. /// Solves a system of linear equations, <b>AX = B</b>, with A QR factorized.
/// </summary> /// </summary>
/// <param name="input">The right hand side <see cref="Matrix"/>, <b>B</b>.</param> /// <param name="input">The right hand side <see cref="Matrix{T}"/>, <b>B</b>.</param>
/// <param name="result">The left hand side <see cref="Matrix"/>, <b>X</b>.</param> /// <param name="result">The left hand side <see cref="Matrix{T}"/>, <b>X</b>.</param>
public override void Solve(Matrix input, Matrix result) public override void Solve(Matrix<double> input, Matrix<double> result)
{ {
// Check for proper arguments. // Check for proper arguments.
if (input == null) if (input == null)
@ -267,8 +269,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// Solves a system of linear equations, <b>Ax = b</b>, with A QR factorized. /// Solves a system of linear equations, <b>Ax = b</b>, with A QR factorized.
/// </summary> /// </summary>
/// <param name="input">The right hand side vector, <b>b</b>.</param> /// <param name="input">The right hand side vector, <b>b</b>.</param>
/// <param name="result">The left hand side <see cref="Matrix"/>, <b>x</b>.</param> /// <param name="result">The left hand side <see cref="Matrix{T}"/>, <b>x</b>.</param>
public override void Solve(Vector input, Vector result) public override void Solve(Vector<double> input, Vector<double> result)
{ {
if (input == null) if (input == null)
{ {
@ -328,5 +330,38 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
result[i] = inputCopy[i]; result[i] = inputCopy[i];
} }
} }
#region Simple arithmetic of type T
/// <summary>
/// Multiply two values T*T
/// </summary>
/// <param name="val1">Left operand value</param>
/// <param name="val2">Right operand value</param>
/// <returns>Result of multiplication</returns>
protected sealed override double MultiplyT(double val1, double val2)
{
return val1 * val2;
}
/// <summary>
/// Returns the absolute value of a specified number.
/// </summary>
/// <param name="val1"> A number whose absolute is to be found</param>
/// <returns>Absolute value </returns>
protected sealed override double AbsoluteT(double val1)
{
return Math.Abs(val1);
}
/// <summary>
/// Get value of type T equal to one
/// </summary>
/// <returns>One value</returns>
protected sealed override double OneValueT
{
get { return 1.0; }
}
#endregion
} }
} }

62
src/Numerics/LinearAlgebra/Double/Factorization/SparseSvd.cs

@ -30,10 +30,12 @@
namespace MathNet.Numerics.LinearAlgebra.Double.Factorization namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
{ {
using System; using System;
using Generic;
using Generic.Factorization;
using Properties; using Properties;
/// <summary> /// <summary>
/// <para>A class which encapsulates the functionality of the singular value decomposition (SVD) for <see cref="Matrix"/>.</para> /// <para>A class which encapsulates the functionality of the singular value decomposition (SVD) for <see cref="Matrix{T}"/>.</para>
/// <para>Suppose M is an m-by-n matrix whose entries are real numbers. /// <para>Suppose M is an m-by-n matrix whose entries are real numbers.
/// Then there exists a factorization of the form M = UΣVT where: /// Then there exists a factorization of the form M = UΣVT where:
/// - U is an m-by-m unitary matrix; /// - U is an m-by-m unitary matrix;
@ -46,7 +48,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <remarks> /// <remarks>
/// The computation of the singular value decomposition is done at construction time. /// The computation of the singular value decomposition is done at construction time.
/// </remarks> /// </remarks>
public class SparseSvd : Svd public class SparseSvd : Svd<double>
{ {
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="SparseSvd"/> class. This object will compute the /// Initializes a new instance of the <see cref="SparseSvd"/> class. This object will compute the
@ -56,7 +58,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <param name="computeVectors">Compute the singular U and VT vectors or not.</param> /// <param name="computeVectors">Compute the singular U and VT vectors or not.</param>
/// <exception cref="ArgumentNullException">If <paramref name="matrix"/> is <b>null</b>.</exception> /// <exception cref="ArgumentNullException">If <paramref name="matrix"/> is <b>null</b>.</exception>
/// <exception cref="ArgumentException">If SVD algorithm failed to converge with matrix <paramref name="matrix"/>.</exception> /// <exception cref="ArgumentException">If SVD algorithm failed to converge with matrix <paramref name="matrix"/>.</exception>
public SparseSvd(Matrix matrix, bool computeVectors) public SparseSvd(Matrix<double> matrix, bool computeVectors)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -603,7 +605,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <param name="rowCount">The number of rows in <paramref name="a"/></param> /// <param name="rowCount">The number of rows in <paramref name="a"/></param>
/// <param name="columnA">Column A index to swap</param> /// <param name="columnA">Column A index to swap</param>
/// <param name="columnB">Column B index to swap</param> /// <param name="columnB">Column B index to swap</param>
private static void Dswap(Matrix a, int rowCount, int columnA, int columnB) private static void Dswap(Matrix<double> a, int rowCount, int columnA, int columnB)
{ {
for (var i = 0; i < rowCount; i++) for (var i = 0; i < rowCount; i++)
{ {
@ -621,7 +623,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <param name="column">Column to scale</param> /// <param name="column">Column to scale</param>
/// <param name="rowStart">Row to scale from</param> /// <param name="rowStart">Row to scale from</param>
/// <param name="z">Scale value</param> /// <param name="z">Scale value</param>
private static void DscalColumn(Matrix a, int rowCount, int column, int rowStart, double z) private static void DscalColumn(Matrix<double> a, int rowCount, int column, int rowStart, double z)
{ {
for (var i = rowStart; i < rowCount; i++) for (var i = rowStart; i < rowCount; i++)
{ {
@ -708,7 +710,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <param name="column">Column index</param> /// <param name="column">Column index</param>
/// <param name="rowStart">Start row index</param> /// <param name="rowStart">Start row index</param>
/// <returns>Norm2 (Euclidean norm) of trhe column</returns> /// <returns>Norm2 (Euclidean norm) of trhe column</returns>
private static double Dnrm2Column(Matrix a, int rowCount, int column, int rowStart) private static double Dnrm2Column(Matrix<double> a, int rowCount, int column, int rowStart)
{ {
double s = 0; double s = 0;
for (var i = rowStart; i < rowCount; i++) for (var i = rowStart; i < rowCount; i++)
@ -745,7 +747,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <param name="columnB">Index of column B</param> /// <param name="columnB">Index of column B</param>
/// <param name="rowStart">Starting row index</param> /// <param name="rowStart">Starting row index</param>
/// <returns>Dot product value</returns> /// <returns>Dot product value</returns>
private static double Ddot(Matrix a, int rowCount, int columnA, int columnB, int rowStart) private static double Ddot(Matrix<double> a, int rowCount, int columnA, int columnB, int rowStart)
{ {
var z = 0.0; var z = 0.0;
for (var i = rowStart; i < rowCount; i++) for (var i = rowStart; i < rowCount; i++)
@ -766,7 +768,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <param name="columnB">Index of column B</param> /// <param name="columnB">Index of column B</param>
/// <param name="c">Scalar "c" value</param> /// <param name="c">Scalar "c" value</param>
/// <param name="s">Scalar "s" value</param> /// <param name="s">Scalar "s" value</param>
private static void Drot(Matrix a, int rowCount, int columnA, int columnB, double c, double s) private static void Drot(Matrix<double> a, int rowCount, int columnA, int columnB, double c, double s)
{ {
for (var i = 0; i < rowCount; i++) for (var i = 0; i < rowCount; i++)
{ {
@ -780,9 +782,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <summary> /// <summary>
/// Solves a system of linear equations, <b>AX = B</b>, with A SVD factorized. /// Solves a system of linear equations, <b>AX = B</b>, with A SVD factorized.
/// </summary> /// </summary>
/// <param name="input">The right hand side <see cref="Matrix"/>, <b>B</b>.</param> /// <param name="input">The right hand side <see cref="Matrix{T}"/>, <b>B</b>.</param>
/// <param name="result">The left hand side <see cref="Matrix"/>, <b>X</b>.</param> /// <param name="result">The left hand side <see cref="Matrix{T}"/>, <b>X</b>.</param>
public override void Solve(Matrix input, Matrix result) public override void Solve(Matrix<double> input, Matrix<double> result)
{ {
// Check for proper arguments. // Check for proper arguments.
if (input == null) if (input == null)
@ -858,8 +860,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// Solves a system of linear equations, <b>Ax = b</b>, with A SVD factorized. /// Solves a system of linear equations, <b>Ax = b</b>, with A SVD factorized.
/// </summary> /// </summary>
/// <param name="input">The right hand side vector, <b>b</b>.</param> /// <param name="input">The right hand side vector, <b>b</b>.</param>
/// <param name="result">The left hand side <see cref="Matrix"/>, <b>x</b>.</param> /// <param name="result">The left hand side <see cref="Matrix{T}"/>, <b>x</b>.</param>
public override void Solve(Vector input, Vector result) public override void Solve(Vector<double> input, Vector<double> result)
{ {
if (input == null) if (input == null)
{ {
@ -919,5 +921,39 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
result[j] = value; result[j] = value;
} }
} }
#region Simple arithmetic of type T
/// <summary>
/// Multiply two values T*T
/// </summary>
/// <param name="val1">Left operand value</param>
/// <param name="val2">Right operand value</param>
/// <returns>Result of multiplication</returns>
protected sealed override double MultiplyT(double val1, double val2)
{
return val1 * val2;
}
/// <summary>
/// Returns the absolute value of a specified number.
/// </summary>
/// <param name="val1"> A number whose absolute is to be found</param>
/// <returns>Absolute value </returns>
protected sealed override double AbsoluteT(double val1)
{
return Math.Abs(val1);
}
/// <summary>
/// Get value of type T equal to one
/// </summary>
/// <returns>One value</returns>
protected sealed override double OneValueT
{
get { return 1.0; }
}
#endregion
} }
} }

84
src/Numerics/LinearAlgebra/Double/Factorization/UserCholesky.cs

@ -31,6 +31,8 @@
namespace MathNet.Numerics.LinearAlgebra.Double.Factorization namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
{ {
using System; using System;
using Generic;
using Generic.Factorization;
using Properties; using Properties;
/// <summary> /// <summary>
@ -42,7 +44,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// The computation of the Cholesky factorization is done at construction time. If the matrix is not symmetric /// The computation of the Cholesky factorization is done at construction time. If the matrix is not symmetric
/// or positive definite, the constructor will throw an exception. /// or positive definite, the constructor will throw an exception.
/// </remarks> /// </remarks>
public class UserCholesky : Cholesky public class UserCholesky : Cholesky<double>
{ {
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="UserCholesky"/> class. This object will compute the /// Initializes a new instance of the <see cref="UserCholesky"/> class. This object will compute the
@ -52,7 +54,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <exception cref="ArgumentNullException">If <paramref name="matrix"/> is <c>null</c>.</exception> /// <exception cref="ArgumentNullException">If <paramref name="matrix"/> is <c>null</c>.</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>
/// <exception cref="ArgumentException">If <paramref name="matrix"/> is not positive definite.</exception> /// <exception cref="ArgumentException">If <paramref name="matrix"/> is not positive definite.</exception>
public UserCholesky(Matrix matrix) public UserCholesky(Matrix<double> matrix)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -96,12 +98,46 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
} }
} }
/// <summary>
/// Gets the determinant of the matrix for which the Cholesky matrix was computed.
/// </summary>
public override double Determinant
{
get
{
var det = 1.0;
for (var j = 0; j < CholeskyFactor.RowCount; j++)
{
det *= CholeskyFactor[j, j] * CholeskyFactor[j, j];
}
return det;
}
}
/// <summary>
/// Gets the log determinant of the matrix for which the Cholesky matrix was computed.
/// </summary>
public override double DeterminantLn
{
get
{
var det = 0.0;
for (var j = 0; j < CholeskyFactor.RowCount; j++)
{
det += 2.0 * Math.Log(CholeskyFactor[j, j]);
}
return det;
}
}
/// <summary> /// <summary>
/// Solves a system of linear equations, <b>AX = B</b>, with A Cholesky factorized. /// Solves a system of linear equations, <b>AX = B</b>, with A Cholesky factorized.
/// </summary> /// </summary>
/// <param name="input">The right hand side <see cref="Matrix"/>, <b>B</b>.</param> /// <param name="input">The right hand side <see cref="Matrix{T}"/>, <b>B</b>.</param>
/// <param name="result">The left hand side <see cref="Matrix"/>, <b>X</b>.</param> /// <param name="result">The left hand side <see cref="Matrix{T}"/>, <b>X</b>.</param>
public override void Solve(Matrix input, Matrix result) public override void Solve(Matrix<double> input, Matrix<double> result)
{ {
if (input == null) if (input == null)
{ {
@ -165,8 +201,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// Solves a system of linear equations, <b>Ax = b</b>, with A Cholesky factorized. /// Solves a system of linear equations, <b>Ax = b</b>, with A Cholesky factorized.
/// </summary> /// </summary>
/// <param name="input">The right hand side vector, <b>b</b>.</param> /// <param name="input">The right hand side vector, <b>b</b>.</param>
/// <param name="result">The left hand side <see cref="Matrix"/>, <b>x</b>.</param> /// <param name="result">The left hand side <see cref="Matrix{T}"/>, <b>x</b>.</param>
public override void Solve(Vector input, Vector result) public override void Solve(Vector<double> input, Vector<double> result)
{ {
// Check for proper arguments. // Check for proper arguments.
if (input == null) if (input == null)
@ -218,5 +254,39 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
result[i] = sum / CholeskyFactor.At(i, i); result[i] = sum / CholeskyFactor.At(i, i);
} }
} }
#region Simple T Mathematics
/// <summary>
/// Multiply two values T*T
/// </summary>
/// <param name="val1">Left operand value</param>
/// <param name="val2">Right operand value</param>
/// <returns>Result of multiplication</returns>
protected sealed override double MultiplyT(double val1, double val2)
{
return val1 * val2;
}
/// <summary>
/// Returns the natural (base e) logarithm of a specified number.
/// </summary>
/// <param name="val1"> A number whose logarithm is to be found</param>
/// <returns>Natural (base e) logarithm </returns>
protected sealed override double LogT(double val1)
{
return Math.Log(val1);
}
/// <summary>
/// Get value of type T equal to one
/// </summary>
/// <returns>One value</returns>
protected sealed override double OneValueT
{
get { return 1.0; }
}
#endregion
} }
} }

50
src/Numerics/LinearAlgebra/Double/Factorization/UserLU.cs

@ -31,6 +31,8 @@
namespace MathNet.Numerics.LinearAlgebra.Double.Factorization namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
{ {
using System; using System;
using Generic;
using Generic.Factorization;
using Properties; using Properties;
/// <summary> /// <summary>
@ -41,7 +43,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <remarks> /// <remarks>
/// The computation of the LU factorization is done at construction time. /// The computation of the LU factorization is done at construction time.
/// </remarks> /// </remarks>
public class UserLU : LU public class UserLU : LU<double>
{ {
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="UserLU"/> class. This object will compute the /// Initializes a new instance of the <see cref="UserLU"/> class. This object will compute the
@ -50,7 +52,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <param name="matrix">The matrix to factor.</param> /// <param name="matrix">The matrix to factor.</param>
/// <exception cref="ArgumentNullException">If <paramref name="matrix"/> is <c>null</c>.</exception> /// <exception cref="ArgumentNullException">If <paramref name="matrix"/> is <c>null</c>.</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 UserLU(Matrix matrix) public UserLU(Matrix<double> matrix)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -132,9 +134,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <summary> /// <summary>
/// Solves a system of linear equations, <c>AX = B</c>, with A LU factorized. /// Solves a system of linear equations, <c>AX = B</c>, with A LU factorized.
/// </summary> /// </summary>
/// <param name="input">The right hand side <see cref="Matrix"/>, <c>B</c>.</param> /// <param name="input">The right hand side <see cref="Matrix{T}"/>, <c>B</c>.</param>
/// <param name="result">The left hand side <see cref="Matrix"/>, <c>X</c>.</param> /// <param name="result">The left hand side <see cref="Matrix{T}"/>, <c>X</c>.</param>
public override void Solve(Matrix input, Matrix result) public override void Solve(Matrix<double> input, Matrix<double> result)
{ {
// Check for proper arguments. // Check for proper arguments.
if (input == null) if (input == null)
@ -219,8 +221,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// Solves a system of linear equations, <c>Ax = b</c>, with A LU factorized. /// Solves a system of linear equations, <c>Ax = b</c>, with A LU factorized.
/// </summary> /// </summary>
/// <param name="input">The right hand side vector, <c>b</c>.</param> /// <param name="input">The right hand side vector, <c>b</c>.</param>
/// <param name="result">The left hand side <see cref="Matrix"/>, <c>x</c>.</param> /// <param name="result">The left hand side <see cref="Matrix{T}"/>, <c>x</c>.</param>
public override void Solve(Vector input, Vector result) public override void Solve(Vector<double> input, Vector<double> result)
{ {
// Check for proper arguments. // Check for proper arguments.
if (input == null) if (input == null)
@ -285,7 +287,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// Returns the inverse of this matrix. The inverse is calculated using LU decomposition. /// Returns the inverse of this matrix. The inverse is calculated using LU decomposition.
/// </summary> /// </summary>
/// <returns>The inverse of this matrix.</returns> /// <returns>The inverse of this matrix.</returns>
public override Matrix Inverse() public override Matrix<double> Inverse()
{ {
var order = Factors.RowCount; var order = Factors.RowCount;
var inverse = Factors.CreateMatrix(order, order); var inverse = Factors.CreateMatrix(order, order);
@ -296,5 +298,37 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
return Solve(inverse); return Solve(inverse);
} }
#region Simple arithmetic of type T
/// <summary>
/// Multiply two values T*T
/// </summary>
/// <param name="val1">Left operand value</param>
/// <param name="val2">Right operand value</param>
/// <returns>Result of multiplication</returns>
protected sealed override double MultiplyT(double val1, double val2)
{
return val1 * val2;
}
/// <summary>
/// Get value of type T equal to one
/// </summary>
/// <returns>One value</returns>
protected sealed override double OneValueT
{
get { return 1.0; }
}
/// <summary>
/// Get value of type T equal to minus one
/// </summary>
/// <returns>One value</returns>
protected sealed override double MinusOneValueT
{
get { return -1.0; }
}
#endregion
} }
} }

53
src/Numerics/LinearAlgebra/Double/Factorization/UserQR.cs

@ -32,6 +32,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
{ {
using System; using System;
using System.Linq; using System.Linq;
using Generic;
using Generic.Factorization;
using Properties; using Properties;
/// <summary> /// <summary>
@ -43,7 +45,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <remarks> /// <remarks>
/// The computation of the QR decomposition is done at construction time by Householder transformation. /// The computation of the QR decomposition is done at construction time by Householder transformation.
/// </remarks> /// </remarks>
public class UserQR : QR public class UserQR : QR<double>
{ {
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="UserQR"/> class. This object will compute the /// Initializes a new instance of the <see cref="UserQR"/> class. This object will compute the
@ -51,7 +53,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// </summary> /// </summary>
/// <param name="matrix">The matrix to factor.</param> /// <param name="matrix">The matrix to factor.</param>
/// <exception cref="ArgumentNullException">If <paramref name="matrix"/> is <c>null</c>.</exception> /// <exception cref="ArgumentNullException">If <paramref name="matrix"/> is <c>null</c>.</exception>
public UserQR(Matrix matrix) public UserQR(Matrix<double> matrix)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -93,7 +95,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <param name="rowEnd">The last row</param> /// <param name="rowEnd">The last row</param>
/// <param name="column">Column index</param> /// <param name="column">Column index</param>
/// <returns>Generated vector</returns> /// <returns>Generated vector</returns>
private static double[] GenerateColumn(Matrix a, int rowStart, int rowEnd, int column) private static double[] GenerateColumn(Matrix<double> a, int rowStart, int rowEnd, int column)
{ {
var ru = rowEnd - rowStart + 1; var ru = rowEnd - rowStart + 1;
var u = new double[ru]; var u = new double[ru];
@ -147,7 +149,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <param name="rowEnd">The last row</param> /// <param name="rowEnd">The last row</param>
/// <param name="columnStart">The first column</param> /// <param name="columnStart">The first column</param>
/// <param name="columnEnd">The last column</param> /// <param name="columnEnd">The last column</param>
private static void ComputeQR(double[] u, Matrix a, int rowStart, int rowEnd, int columnStart, int columnEnd) private static void ComputeQR(double[] u, Matrix<double> a, int rowStart, int rowEnd, int columnStart, int columnEnd)
{ {
if (rowEnd < rowStart || columnEnd < columnStart) if (rowEnd < rowStart || columnEnd < columnStart)
{ {
@ -180,9 +182,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <summary> /// <summary>
/// Solves a system of linear equations, <b>AX = B</b>, with A QR factorized. /// Solves a system of linear equations, <b>AX = B</b>, with A QR factorized.
/// </summary> /// </summary>
/// <param name="input">The right hand side <see cref="Matrix"/>, <b>B</b>.</param> /// <param name="input">The right hand side <see cref="Matrix{T}"/>, <b>B</b>.</param>
/// <param name="result">The left hand side <see cref="Matrix"/>, <b>X</b>.</param> /// <param name="result">The left hand side <see cref="Matrix{T}"/>, <b>X</b>.</param>
public override void Solve(Matrix input, Matrix result) public override void Solve(Matrix<double> input, Matrix<double> result)
{ {
// Check for proper arguments. // Check for proper arguments.
if (input == null) if (input == null)
@ -266,8 +268,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// Solves a system of linear equations, <b>Ax = b</b>, with A QR factorized. /// Solves a system of linear equations, <b>Ax = b</b>, with A QR factorized.
/// </summary> /// </summary>
/// <param name="input">The right hand side vector, <b>b</b>.</param> /// <param name="input">The right hand side vector, <b>b</b>.</param>
/// <param name="result">The left hand side <see cref="Matrix"/>, <b>x</b>.</param> /// <param name="result">The left hand side <see cref="Matrix{T}"/>, <b>x</b>.</param>
public override void Solve(Vector input, Vector result) public override void Solve(Vector<double> input, Vector<double> result)
{ {
if (input == null) if (input == null)
{ {
@ -327,5 +329,38 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
result[i] = inputCopy[i]; result[i] = inputCopy[i];
} }
} }
#region Simple arithmetic of type T
/// <summary>
/// Multiply two values T*T
/// </summary>
/// <param name="val1">Left operand value</param>
/// <param name="val2">Right operand value</param>
/// <returns>Result of multiplication</returns>
protected sealed override double MultiplyT(double val1, double val2)
{
return val1 * val2;
}
/// <summary>
/// Returns the absolute value of a specified number.
/// </summary>
/// <param name="val1"> A number whose absolute is to be found</param>
/// <returns>Absolute value </returns>
protected sealed override double AbsoluteT(double val1)
{
return Math.Abs(val1);
}
/// <summary>
/// Get value of type T equal to one
/// </summary>
/// <returns>One value</returns>
protected sealed override double OneValueT
{
get { return 1.0; }
}
#endregion
} }
} }

62
src/Numerics/LinearAlgebra/Double/Factorization/UserSvd.cs

@ -30,10 +30,12 @@
namespace MathNet.Numerics.LinearAlgebra.Double.Factorization namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
{ {
using System; using System;
using Generic;
using Generic.Factorization;
using Properties; using Properties;
/// <summary> /// <summary>
/// <para>A class which encapsulates the functionality of the singular value decomposition (SVD) for <see cref="Matrix"/>.</para> /// <para>A class which encapsulates the functionality of the singular value decomposition (SVD) for <see cref="Matrix{T}"/>.</para>
/// <para>Suppose M is an m-by-n matrix whose entries are real numbers. /// <para>Suppose M is an m-by-n matrix whose entries are real numbers.
/// Then there exists a factorization of the form M = UΣVT where: /// Then there exists a factorization of the form M = UΣVT where:
/// - U is an m-by-m unitary matrix; /// - U is an m-by-m unitary matrix;
@ -46,7 +48,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <remarks> /// <remarks>
/// The computation of the singular value decomposition is done at construction time. /// The computation of the singular value decomposition is done at construction time.
/// </remarks> /// </remarks>
public class UserSvd : Svd public class UserSvd : Svd<double>
{ {
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="UserSvd"/> class. This object will compute the /// Initializes a new instance of the <see cref="UserSvd"/> class. This object will compute the
@ -56,7 +58,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <param name="computeVectors">Compute the singular U and VT vectors or not.</param> /// <param name="computeVectors">Compute the singular U and VT vectors or not.</param>
/// <exception cref="ArgumentNullException">If <paramref name="matrix"/> is <b>null</b>.</exception> /// <exception cref="ArgumentNullException">If <paramref name="matrix"/> is <b>null</b>.</exception>
/// <exception cref="ArgumentException">If SVD algorithm failed to converge with matrix <paramref name="matrix"/>.</exception> /// <exception cref="ArgumentException">If SVD algorithm failed to converge with matrix <paramref name="matrix"/>.</exception>
public UserSvd(Matrix matrix, bool computeVectors) public UserSvd(Matrix<double> matrix, bool computeVectors)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -603,7 +605,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <param name="rowCount">The number of rows in <paramref name="a"/></param> /// <param name="rowCount">The number of rows in <paramref name="a"/></param>
/// <param name="columnA">Column A index to swap</param> /// <param name="columnA">Column A index to swap</param>
/// <param name="columnB">Column B index to swap</param> /// <param name="columnB">Column B index to swap</param>
private static void Dswap(Matrix a, int rowCount, int columnA, int columnB) private static void Dswap(Matrix<double> a, int rowCount, int columnA, int columnB)
{ {
for (var i = 0; i < rowCount; i++) for (var i = 0; i < rowCount; i++)
{ {
@ -621,7 +623,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <param name="column">Column to scale</param> /// <param name="column">Column to scale</param>
/// <param name="rowStart">Row to scale from</param> /// <param name="rowStart">Row to scale from</param>
/// <param name="z">Scale value</param> /// <param name="z">Scale value</param>
private static void DscalColumn(Matrix a, int rowCount, int column, int rowStart, double z) private static void DscalColumn(Matrix<double> a, int rowCount, int column, int rowStart, double z)
{ {
for (var i = rowStart; i < rowCount; i++) for (var i = rowStart; i < rowCount; i++)
{ {
@ -708,7 +710,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <param name="column">Column index</param> /// <param name="column">Column index</param>
/// <param name="rowStart">Start row index</param> /// <param name="rowStart">Start row index</param>
/// <returns>Norm2 (Euclidean norm) of trhe column</returns> /// <returns>Norm2 (Euclidean norm) of trhe column</returns>
private static double Dnrm2Column(Matrix a, int rowCount, int column, int rowStart) private static double Dnrm2Column(Matrix<double> a, int rowCount, int column, int rowStart)
{ {
double s = 0; double s = 0;
for (var i = rowStart; i < rowCount; i++) for (var i = rowStart; i < rowCount; i++)
@ -745,7 +747,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <param name="columnB">Index of column B</param> /// <param name="columnB">Index of column B</param>
/// <param name="rowStart">Starting row index</param> /// <param name="rowStart">Starting row index</param>
/// <returns>Dot product value</returns> /// <returns>Dot product value</returns>
private static double Ddot(Matrix a, int rowCount, int columnA, int columnB, int rowStart) private static double Ddot(Matrix<double> a, int rowCount, int columnA, int columnB, int rowStart)
{ {
var z = 0.0; var z = 0.0;
for (var i = rowStart; i < rowCount; i++) for (var i = rowStart; i < rowCount; i++)
@ -766,7 +768,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <param name="columnB">Index of column B</param> /// <param name="columnB">Index of column B</param>
/// <param name="c">Scalar "c" value</param> /// <param name="c">Scalar "c" value</param>
/// <param name="s">Scalar "s" value</param> /// <param name="s">Scalar "s" value</param>
private static void Drot(Matrix a, int rowCount, int columnA, int columnB, double c, double s) private static void Drot(Matrix<double> a, int rowCount, int columnA, int columnB, double c, double s)
{ {
for (var i = 0; i < rowCount; i++) for (var i = 0; i < rowCount; i++)
{ {
@ -780,9 +782,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <summary> /// <summary>
/// Solves a system of linear equations, <b>AX = B</b>, with A SVD factorized. /// Solves a system of linear equations, <b>AX = B</b>, with A SVD factorized.
/// </summary> /// </summary>
/// <param name="input">The right hand side <see cref="Matrix"/>, <b>B</b>.</param> /// <param name="input">The right hand side <see cref="Matrix{T}"/>, <b>B</b>.</param>
/// <param name="result">The left hand side <see cref="Matrix"/>, <b>X</b>.</param> /// <param name="result">The left hand side <see cref="Matrix{T}"/>, <b>X</b>.</param>
public override void Solve(Matrix input, Matrix result) public override void Solve(Matrix<double> input, Matrix<double> result)
{ {
// Check for proper arguments. // Check for proper arguments.
if (input == null) if (input == null)
@ -858,8 +860,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// Solves a system of linear equations, <b>Ax = b</b>, with A SVD factorized. /// Solves a system of linear equations, <b>Ax = b</b>, with A SVD factorized.
/// </summary> /// </summary>
/// <param name="input">The right hand side vector, <b>b</b>.</param> /// <param name="input">The right hand side vector, <b>b</b>.</param>
/// <param name="result">The left hand side <see cref="Matrix"/>, <b>x</b>.</param> /// <param name="result">The left hand side <see cref="Matrix{T}"/>, <b>x</b>.</param>
public override void Solve(Vector input, Vector result) public override void Solve(Vector<double> input, Vector<double> result)
{ {
if (input == null) if (input == null)
{ {
@ -919,5 +921,39 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
result[j] = value; result[j] = value;
} }
} }
#region Simple arithmetic of type T
/// <summary>
/// Multiply two values T*T
/// </summary>
/// <param name="val1">Left operand value</param>
/// <param name="val2">Right operand value</param>
/// <returns>Result of multiplication</returns>
protected sealed override double MultiplyT(double val1, double val2)
{
return val1 * val2;
}
/// <summary>
/// Returns the absolute value of a specified number.
/// </summary>
/// <param name="val1"> A number whose absolute is to be found</param>
/// <returns>Absolute value </returns>
protected sealed override double AbsoluteT(double val1)
{
return Math.Abs(val1);
}
/// <summary>
/// Get value of type T equal to one
/// </summary>
/// <returns>One value</returns>
protected sealed override double OneValueT
{
get { return 1.0; }
}
#endregion
} }
} }

5
src/Numerics/LinearAlgebra/Double/IO/DelimitedReader.cs

@ -32,14 +32,15 @@ namespace MathNet.Numerics.LinearAlgebra.Double.IO
using System.IO; using System.IO;
using System.Reflection; using System.Reflection;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using Generic;
/// <summary> /// <summary>
/// Creates a <see cref="Matrix"/> from a delimited text file. If the user does not /// Creates a <see cref="Matrix{T}"/> from a delimited text file. If the user does not
/// specify a delimiter, then any whitespace is used. /// specify a delimiter, then any whitespace is used.
/// </summary> /// </summary>
/// <typeparam name="TMatrix">The type of the matrix to return.</typeparam> /// <typeparam name="TMatrix">The type of the matrix to return.</typeparam>
public class DelimitedReader<TMatrix> : MatrixReader<TMatrix> public class DelimitedReader<TMatrix> : MatrixReader<TMatrix>
where TMatrix : Matrix where TMatrix : Matrix<double>
{ {
/// <summary> /// <summary>
/// Constructor to create matrix instance. /// Constructor to create matrix instance.

7
src/Numerics/LinearAlgebra/Double/IO/DelimitedWriter.cs

@ -32,9 +32,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double.IO
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.IO; using System.IO;
using Generic;
/// <summary> /// <summary>
/// Writes an <see cref="Matrix"/> to delimited text file. If the user does not /// Writes an <see cref="Matrix{T}"/> to delimited text file. If the user does not
/// specify a delimiter, a tab separator is used. /// specify a delimiter, a tab separator is used.
/// </summary> /// </summary>
public class DelimitedWriter : MatrixWriter public class DelimitedWriter : MatrixWriter
@ -115,13 +116,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double.IO
} }
/// <summary> /// <summary>
/// Writes the given <see cref="Matrix"/> to the given <see cref="TextWriter"/>. /// Writes the given <see cref="Matrix{T}"/> to the given <see cref="TextWriter"/>.
/// </summary> /// </summary>
/// <param name="matrix">The matrix to write.</param> /// <param name="matrix">The matrix to write.</param>
/// <param name="writer">The <see cref="TextWriter"/> to write the matrix to.</param> /// <param name="writer">The <see cref="TextWriter"/> to write the matrix to.</param>
/// <param name="format">The format to use on each element.</param> /// <param name="format">The format to use on each element.</param>
/// <exception cref="ArgumentNullException">If either <paramref name="matrix"/> or <paramref name="writer"/> is <c>null</c>.</exception> /// <exception cref="ArgumentNullException">If either <paramref name="matrix"/> or <paramref name="writer"/> is <c>null</c>.</exception>
protected override void DoWriteMatrix(Matrix matrix, TextWriter writer, string format) protected override void DoWriteMatrix(Matrix<double> matrix, TextWriter writer, string format)
{ {
if (matrix == null) if (matrix == null)
{ {

7
src/Numerics/LinearAlgebra/Double/IO/Matlab/MatlabFile.cs

@ -29,6 +29,7 @@
namespace MathNet.Numerics.LinearAlgebra.Double.IO.Matlab namespace MathNet.Numerics.LinearAlgebra.Double.IO.Matlab
{ {
using System.Collections.Generic; using System.Collections.Generic;
using Generic;
/// <summary> /// <summary>
/// Represents a Matlab file /// Represents a Matlab file
@ -38,7 +39,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.IO.Matlab
/// <summary> /// <summary>
/// Matrices in a matlab file stored as 1-D arrays /// Matrices in a matlab file stored as 1-D arrays
/// </summary> /// </summary>
private readonly IDictionary<string, Matrix> _matrices = new SortedList<string, Matrix>(); private readonly IDictionary<string, Matrix<double>> _matrices = new SortedList<string, Matrix<double>>();
/// <summary> /// <summary>
/// Gets or sets the header text. /// Gets or sets the header text.
@ -56,7 +57,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.IO.Matlab
/// Gets the first matrix. /// Gets the first matrix.
/// </summary> /// </summary>
/// <value>The first matrix.</value> /// <value>The first matrix.</value>
public Matrix FirstMatrix public Matrix<double> FirstMatrix
{ {
get get
{ {
@ -73,7 +74,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.IO.Matlab
/// Gets the matrices. /// Gets the matrices.
/// </summary> /// </summary>
/// <value>The matrices.</value> /// <value>The matrices.</value>
public IDictionary<string, Matrix> Matrices public IDictionary<string, Matrix<double>> Matrices
{ {
get { return _matrices; } get { return _matrices; }
} }

11
src/Numerics/LinearAlgebra/Double/IO/Matlab/MatlabParser.cs

@ -31,6 +31,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.IO.Matlab
using System.IO; using System.IO;
using System.Text; using System.Text;
using Common.IO.Matlab; using Common.IO.Matlab;
using Generic;
using Properties; using Properties;
using zlib; using zlib;
@ -296,7 +297,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.IO.Matlab
size = reader.ReadInt32(); size = reader.ReadInt32();
} }
Matrix matrix; Matrix<double> matrix;
switch (arrayClass) switch (arrayClass)
{ {
case ArrayClass.Sparse: case ArrayClass.Sparse:
@ -331,7 +332,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.IO.Matlab
/// <param name="columns">The number of columns.</param> /// <param name="columns">The number of columns.</param>
/// <param name="size">The size of the block.</param> /// <param name="size">The size of the block.</param>
/// <returns>A populated sparse matrix.</returns> /// <returns>A populated sparse matrix.</returns>
private static Matrix PopulateSparseMatrix(BinaryReader reader, int rows, int columns, int size) private static Matrix<double> PopulateSparseMatrix(BinaryReader reader, int rows, int columns, int size)
{ {
// populate the row data array // populate the row data array
var ir = new int[size / 4]; var ir = new int[size / 4];
@ -360,7 +361,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.IO.Matlab
// skip length since we already no it for the number of rows // skip length since we already no it for the number of rows
reader.BaseStream.Seek(4, SeekOrigin.Current); reader.BaseStream.Seek(4, SeekOrigin.Current);
Matrix matrix = new SparseMatrix(rows, columns); Matrix<double> matrix = new SparseMatrix(rows, columns);
var col = 0; var col = 0;
for (var i = 0; i < ir.Length; i++) for (var i = 0; i < ir.Length; i++)
{ {
@ -420,9 +421,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double.IO.Matlab
/// <param name="rows">The number of rows.</param> /// <param name="rows">The number of rows.</param>
/// <param name="columns">The number of columns.</param> /// <param name="columns">The number of columns.</param>
/// <returns>Returns a populated dense matrix.</returns> /// <returns>Returns a populated dense matrix.</returns>
private static Matrix PopulateDenseMatrix(DataType type, BinaryReader reader, int rows, int columns) private static Matrix<double> PopulateDenseMatrix(DataType type, BinaryReader reader, int rows, int columns)
{ {
Matrix matrix = new DenseMatrix(rows, columns); Matrix<double> matrix = new DenseMatrix(rows, columns);
switch (type) switch (type)
{ {
case DataType.Int8: case DataType.Int8:

13
src/Numerics/LinearAlgebra/Double/IO/MatlabReader.cs

@ -31,6 +31,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.IO
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using Generic;
using Matlab; using Matlab;
using Properties; using Properties;
@ -89,7 +90,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.IO
/// If the matrix is stored as a sparse matrix, then a <see cref="SparseMatrix"/> is returned. Otherwise, a <see cref="DenseMatrix"/> /// If the matrix is stored as a sparse matrix, then a <see cref="SparseMatrix"/> is returned. Otherwise, a <see cref="DenseMatrix"/>
/// is returned. /// is returned.
/// </returns> /// </returns>
public Matrix ReadMatrix() public Matrix<double> ReadMatrix()
{ {
return ReadMatrix(null); return ReadMatrix(null);
} }
@ -102,7 +103,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.IO
/// If the matrix is stored as a sparse matrix, then a <see cref="SparseMatrix"/> is returned. Otherwise, a <see cref="DenseMatrix"/> /// If the matrix is stored as a sparse matrix, then a <see cref="SparseMatrix"/> is returned. Otherwise, a <see cref="DenseMatrix"/>
/// is returned. <see langword="null"/> is returned if a matrix with the requests name doesn't exist. /// is returned. <see langword="null"/> is returned if a matrix with the requests name doesn't exist.
/// </returns> /// </returns>
public Matrix ReadMatrix(string matrixName) public Matrix<double> ReadMatrix(string matrixName)
{ {
Stream stream; Stream stream;
if (_filename == null) if (_filename == null)
@ -119,7 +120,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.IO
var parser = new MatlabParser(stream, names); var parser = new MatlabParser(stream, names);
var file = parser.Parse(); var file = parser.Parse();
Matrix matrix = null; Matrix<double> matrix = null;
if (string.IsNullOrEmpty(matrixName)) if (string.IsNullOrEmpty(matrixName))
{ {
matrix = file.FirstMatrix; matrix = file.FirstMatrix;
@ -142,7 +143,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.IO
/// Reads all matrices from the file or stream. /// Reads all matrices from the file or stream.
/// </summary> /// </summary>
/// <returns>All matrices from the file or stream.</returns> /// <returns>All matrices from the file or stream.</returns>
public Matrix[] ReadMatrices() public Matrix<double>[] ReadMatrices()
{ {
return ReadMatrices(new string[] { }); return ReadMatrices(new string[] { });
} }
@ -154,7 +155,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.IO
/// <returns> /// <returns>
/// The named matrices from the file or stream. /// The named matrices from the file or stream.
/// </returns> /// </returns>
public Matrix[] ReadMatrices(IEnumerable<string> names) public Matrix<double>[] ReadMatrices(IEnumerable<string> names)
{ {
Stream stream; Stream stream;
if (_filename == null) if (_filename == null)
@ -170,7 +171,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.IO
var parser = new MatlabParser(stream, names); var parser = new MatlabParser(stream, names);
var file = parser.Parse(); var file = parser.Parse();
var matrices = new Matrix[file.Matrices.Count]; var matrices = new Matrix<double>[file.Matrices.Count];
var i = 0; var i = 0;
foreach (var matrix in file.Matrices.Values) foreach (var matrix in file.Matrices.Values)
{ {

13
src/Numerics/LinearAlgebra/Double/IO/MatrixReader.cs

@ -28,24 +28,25 @@ namespace MathNet.Numerics.LinearAlgebra.Double.IO
{ {
using System; using System;
using System.IO; using System.IO;
using Generic;
using Properties; using Properties;
/// <summary> /// <summary>
/// Base class to read a single <see cref="Matrix"/> from a file or stream. /// Base class to read a single <see cref="Matrix{T}"/> from a file or stream.
/// </summary> /// </summary>
/// <typeparam name="TMatrix">The type of Matrix to return.</typeparam> /// <typeparam name="TMatrix">The type of Matrix to return.</typeparam>
public abstract class MatrixReader<TMatrix> where TMatrix : Matrix public abstract class MatrixReader<TMatrix> where TMatrix : Matrix<double>
{ {
/// <summary> /// <summary>
/// Reads a <see cref="Matrix"/> from a file. /// Reads a <see cref="Matrix{T}"/> from a file.
/// </summary> /// </summary>
/// <param name="file">The file to read the matrix from.</param> /// <param name="file">The file to read the matrix from.</param>
/// <returns>A <see cref="Matrix"/> containing the data from the file. <see langword="null" /> is returned if the file is empty.</returns> /// <returns>A <see cref="Matrix{T}"/> containing the data from the file. <see langword="null" /> is returned if the file is empty.</returns>
/// <exception cref="ArgumentNullException">If <paramref name="file"/> is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If <paramref name="file"/> is <see langword="null" />.</exception>
/// <exception cref="IOException">If the file doesn't exist.</exception> /// <exception cref="IOException">If the file doesn't exist.</exception>
/// <exception cref="FormatException">If a value is not a number or not in a valid format.</exception> /// <exception cref="FormatException">If a value is not a number or not in a valid format.</exception>
/// <exception cref="OverflowException">If a value represents a number less than <see cref="Double.MinValue"/> or greater than <see cref="Double.MaxValue"/>.</exception> /// <exception cref="OverflowException">If a value represents a number less than <see cref="Double.MinValue"/> or greater than <see cref="Double.MaxValue"/>.</exception>
public Matrix ReadMatrix(string file) public Matrix<double> ReadMatrix(string file)
{ {
if (file == null) if (file == null)
{ {
@ -56,7 +57,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.IO
} }
/// <summary> /// <summary>
/// Reads a <see cref="Matrix"/> from a <see cref="Stream"/>. /// Reads a <see cref="Matrix{T}"/> from a <see cref="Stream"/>.
/// </summary> /// </summary>
/// <param name="stream">The <see cref="Stream"/> to read the matrix from.</param> /// <param name="stream">The <see cref="Stream"/> to read the matrix from.</param>
/// <returns>A matrix containing the data from the <see cref="Stream"/>. <see langword="null" /> is returned if the <see cref="Stream"/> is empty.</returns> /// <returns>A matrix containing the data from the <see cref="Stream"/>. <see langword="null" /> is returned if the <see cref="Stream"/> is empty.</returns>

30
src/Numerics/LinearAlgebra/Double/IO/MatrixWriter.cs

@ -31,19 +31,21 @@ using System.IO;
namespace MathNet.Numerics.LinearAlgebra.Double.IO namespace MathNet.Numerics.LinearAlgebra.Double.IO
{ {
using Generic;
/// <summary> /// <summary>
/// Base class to write a single <see cref="Matrix"/> to a file or stream. /// Base class to write a single <see cref="Matrix{T}"/> to a file or stream.
/// </summary> /// </summary>
public abstract class MatrixWriter public abstract class MatrixWriter
{ {
/// <summary> /// <summary>
/// Writes the given <see cref="Matrix"/> to the given file. If the file already exists, /// Writes the given <see cref="Matrix{T}"/> to the given file. If the file already exists,
/// the file will be overwritten. /// the file will be overwritten.
/// </summary> /// </summary>
/// <param name="matrix">The matrix to write.</param> /// <param name="matrix">The matrix to write.</param>
/// <param name="file">The file to write the matrix to.</param> /// <param name="file">The file to write the matrix to.</param>
/// <exception cref="ArgumentNullException">If either <paramref name="matrix"/> or <paramref name="file"/> is <c>null</c>.</exception> /// <exception cref="ArgumentNullException">If either <paramref name="matrix"/> or <paramref name="file"/> is <c>null</c>.</exception>
public void WriteMatrix(Matrix matrix, string file) public void WriteMatrix(Matrix<double> matrix, string file)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -62,14 +64,14 @@ namespace MathNet.Numerics.LinearAlgebra.Double.IO
} }
/// <summary> /// <summary>
/// Writes the given <see cref="Matrix"/> to the given file. If the file already exists, /// Writes the given <see cref="Matrix{T}"/> to the given file. If the file already exists,
/// the file will be overwritten. /// the file will be overwritten.
/// </summary> /// </summary>
/// <param name="matrix">the matrix to write.</param> /// <param name="matrix">the matrix to write.</param>
/// <param name="file">The file to write the matrix to.</param> /// <param name="file">The file to write the matrix to.</param>
/// <param name="format">The format to use on each element.</param> /// <param name="format">The format to use on each element.</param>
/// <exception cref="ArgumentNullException">If either <paramref name="matrix"/> or <paramref name="file"/> is <c>null</c>.</exception> /// <exception cref="ArgumentNullException">If either <paramref name="matrix"/> or <paramref name="file"/> is <c>null</c>.</exception>
public void WriteMatrix(Matrix matrix, string file, string format) public void WriteMatrix(Matrix<double> matrix, string file, string format)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -93,12 +95,12 @@ namespace MathNet.Numerics.LinearAlgebra.Double.IO
} }
/// <summary> /// <summary>
/// Writes the given <see cref="Matrix"/> to the given stream. /// Writes the given <see cref="Matrix{T}"/> to the given stream.
/// </summary> /// </summary>
/// <param name="matrix">The matrix to write.</param> /// <param name="matrix">The matrix to write.</param>
/// <param name="stream">The <see cref="Stream"/> to write the matrix to.</param> /// <param name="stream">The <see cref="Stream"/> to write the matrix to.</param>
/// <exception cref="ArgumentNullException">If either <paramref name="matrix"/> or <paramref name="stream"/> is <c>null</c>.</exception> /// <exception cref="ArgumentNullException">If either <paramref name="matrix"/> or <paramref name="stream"/> is <c>null</c>.</exception>
public void WriteMatrix(Matrix matrix, Stream stream) public void WriteMatrix(Matrix<double> matrix, Stream stream)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -117,13 +119,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double.IO
} }
/// <summary> /// <summary>
/// Writes the given <see cref="Matrix"/> to the given stream. /// Writes the given <see cref="Matrix{T}"/> to the given stream.
/// </summary> /// </summary>
/// <param name="matrix">The <see cref="TextWriter"/> to write.</param> /// <param name="matrix">The <see cref="TextWriter"/> to write.</param>
/// <param name="stream">The <see cref="Stream"/> to write the matrix to.</param> /// <param name="stream">The <see cref="Stream"/> to write the matrix to.</param>
/// <param name="format">The format to use on each element.</param> /// <param name="format">The format to use on each element.</param>
/// <exception cref="ArgumentNullException">If either <paramref name="matrix"/> or <paramref name="stream"/> is <c>null</c>.</exception> /// <exception cref="ArgumentNullException">If either <paramref name="matrix"/> or <paramref name="stream"/> is <c>null</c>.</exception>
public void WriteMatrix(Matrix matrix, Stream stream, string format) public void WriteMatrix(Matrix<double> matrix, Stream stream, string format)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -142,12 +144,12 @@ namespace MathNet.Numerics.LinearAlgebra.Double.IO
} }
/// <summary> /// <summary>
/// Writes the given <see cref="Matrix"/> to the given <see cref="TextWriter"/>. /// Writes the given <see cref="Matrix{T}"/> to the given <see cref="TextWriter"/>.
/// </summary> /// </summary>
/// <param name="matrix">The matrix to write.</param> /// <param name="matrix">The matrix to write.</param>
/// <param name="writer">The <see cref="TextWriter"/> to write the matrix to.</param> /// <param name="writer">The <see cref="TextWriter"/> to write the matrix to.</param>
/// <exception cref="ArgumentNullException">If either <paramref name="matrix"/> or <paramref name="writer"/> is <c>null</c>.</exception> /// <exception cref="ArgumentNullException">If either <paramref name="matrix"/> or <paramref name="writer"/> is <c>null</c>.</exception>
public void WriteMatrix(Matrix matrix, TextWriter writer) public void WriteMatrix(Matrix<double> matrix, TextWriter writer)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -163,13 +165,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double.IO
} }
/// <summary> /// <summary>
/// Writes the given <see cref="Matrix"/> to the given <see cref="TextWriter"/>. /// Writes the given <see cref="Matrix{T}"/> to the given <see cref="TextWriter"/>.
/// </summary> /// </summary>
/// <param name="matrix">The matrix to write.</param> /// <param name="matrix">The matrix to write.</param>
/// <param name="writer">The <see cref="TextWriter"/> to write the matrix to.</param> /// <param name="writer">The <see cref="TextWriter"/> to write the matrix to.</param>
/// <param name="format">The format to use on each element.</param> /// <param name="format">The format to use on each element.</param>
/// <exception cref="ArgumentNullException">If either <paramref name="matrix"/> or <paramref name="writer"/> is <c>null</c>.</exception> /// <exception cref="ArgumentNullException">If either <paramref name="matrix"/> or <paramref name="writer"/> is <c>null</c>.</exception>
public void WriteMatrix(Matrix matrix, TextWriter writer, string format) public void WriteMatrix(Matrix<double> matrix, TextWriter writer, string format)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -190,6 +192,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double.IO
/// <param name="matrix">The matrix to serialize.</param> /// <param name="matrix">The matrix to serialize.</param>
/// <param name="writer">The <see cref="TextWriter"/> to write the matrix to.</param> /// <param name="writer">The <see cref="TextWriter"/> to write the matrix to.</param>
/// <param name="format">The format for the new matrix.</param> /// <param name="format">The format for the new matrix.</param>
protected abstract void DoWriteMatrix(Matrix matrix, TextWriter writer, string format); protected abstract void DoWriteMatrix(Matrix<double> matrix, TextWriter writer, string format);
} }
} }

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

@ -31,9 +31,12 @@
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 Preconditioners; using Preconditioners;
using Properties; using Properties;
using Status;
/// <summary> /// <summary>
/// A Bi-Conjugate Gradient stabilized iterative matrix solver. /// A Bi-Conjugate Gradient stabilized iterative matrix solver.
@ -64,7 +67,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// solver. /// solver.
/// </para> /// </para>
/// </remarks> /// </remarks>
public sealed class BiCgStab : IIterativeSolver public sealed class BiCgStab : IIterativeSolver<double>
{ {
/// <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
@ -76,12 +79,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 _preconditioner; private IPreConditioner<double> _preconditioner;
/// <summary> /// <summary>
/// The iterative process controller. /// The iterative process controller.
/// </summary> /// </summary>
private IIterator _iterator; private IIterator<double> _iterator;
/// <summary> /// <summary>
/// Indicates if the user has stopped the solver. /// Indicates if the user has stopped the solver.
@ -92,7 +95,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"/> with /// When using this constructor the solver will use the <see cref="IIterator{T}"/> 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)
@ -107,18 +110,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"/> are: /// The main advantages of using a user defined <see cref="IIterator{T}"/> 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.Status"/> property. /// the iterative procedure by calling the <see cref="IIterator{T}.Status"/> property.
/// </item> /// </item>
/// </list> /// </list>
/// </para> /// </para>
/// </remarks> /// </remarks>
/// <param name="iterator">The <see cref="IIterator"/> that will be used to monitor the iterative process. </param> /// <param name="iterator">The <see cref="IIterator{T}"/> that will be used to monitor the iterative process. </param>
public BiCgStab(IIterator iterator) : this(null, iterator) public BiCgStab(IIterator<double> iterator) : this(null, iterator)
{ {
} }
@ -126,11 +129,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"/> with /// When using this constructor the solver will use the <see cref="IIterator{T}"/> with
/// the standard settings. /// the standard settings.
/// </remarks> /// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner"/> that will be used to precondition the matrix equation.</param> /// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation.</param>
public BiCgStab(IPreConditioner preconditioner) : this(preconditioner, null) public BiCgStab(IPreConditioner<double> preconditioner) : this(preconditioner, null)
{ {
} }
@ -139,38 +142,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"/> are: /// The main advantages of using a user defined <see cref="IIterator{T}"/> 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.Status"/> property. /// the iterative procedure by calling the <see cref="IIterator{T}.Status"/> property.
/// </item> /// </item>
/// </list> /// </list>
/// </para> /// </para>
/// </remarks> /// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner"/> that will be used to precondition the matrix equation. </param> /// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation. </param>
/// <param name="iterator">The <see cref="IIterator"/> that will be used to monitor the iterative process. </param> /// <param name="iterator">The <see cref="IIterator{T}"/> that will be used to monitor the iterative process. </param>
public BiCgStab(IPreConditioner preconditioner, IIterator iterator) public BiCgStab(IPreConditioner<double> preconditioner, IIterator<double> iterator)
{ {
_iterator = iterator; _iterator = iterator;
_preconditioner = preconditioner; _preconditioner = preconditioner;
} }
/// <summary> /// <summary>
/// Sets the <see cref="IPreConditioner"/> that will be used to precondition the iterative process. /// Sets the <see cref="IPreConditioner{T}"/> 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 preconditioner) public void SetPreconditioner(IPreConditioner<double> preconditioner)
{ {
_preconditioner = preconditioner; _preconditioner = preconditioner;
} }
/// <summary> /// <summary>
/// Sets the <see cref="IIterator"/> that will be used to track the iterative process. /// Sets the <see cref="IIterator{T}"/> 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 iterator) public void SetIterator(IIterator<double> iterator)
{ {
_iterator = iterator; _iterator = iterator;
} }
@ -201,17 +204,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"/>, <c>A</c>.</param> /// <param name="matrix">The coefficient <see cref="Matrix{T}"/>, <c>A</c>.</param>
/// <param name="vector">The solution <see cref="Vector"/>, <c>b</c>.</param> /// <param name="vector">The solution <see cref="Vector{T}"/>, <c>b</c>.</param>
/// <returns>The result <see cref="Vector"/>, <c>x</c>.</returns> /// <returns>The result <see cref="Vector{T}"/>, <c>x</c>.</returns>
public Vector Solve(Matrix matrix, Vector vector) public Vector<double> Solve(Matrix<double> matrix, Vector<double> vector)
{ {
if (vector == null) if (vector == null)
{ {
throw new ArgumentNullException(); throw new ArgumentNullException();
} }
Vector result = new DenseVector(matrix.RowCount); Vector<double> result = new DenseVector(matrix.RowCount);
Solve(matrix, vector, result); Solve(matrix, vector, result);
return result; return result;
} }
@ -220,10 +223,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"/>, <c>A</c>.</param> /// <param name="matrix">The coefficient <see cref="Matrix{T}"/>, <c>A</c>.</param>
/// <param name="input">The solution <see cref="Vector"/>, <c>b</c>.</param> /// <param name="input">The solution <see cref="Vector{T}"/>, <c>b</c>.</param>
/// <param name="result">The result <see cref="Vector"/>, <c>x</c>.</param> /// <param name="result">The result <see cref="Vector{T}"/>, <c>x</c>.</param>
public void Solve(Matrix matrix, Vector input, Vector result) public void Solve(Matrix<double> matrix, Vector<double> input, Vector<double> 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
@ -273,7 +276,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 residuals = new DenseVector(matrix.RowCount); Vector<double> 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)
@ -283,12 +286,12 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
// create five temporary vectors needed to hold temporary // create five 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 vecP = new DenseVector(residuals.Count); Vector<double> vecP = new DenseVector(residuals.Count);
Vector vecPdash = new DenseVector(residuals.Count); Vector<double> vecPdash = new DenseVector(residuals.Count);
Vector nu = new DenseVector(residuals.Count); Vector<double> nu = new DenseVector(residuals.Count);
Vector vecS = new DenseVector(residuals.Count); Vector<double> vecS = new DenseVector(residuals.Count);
Vector vecSdash = new DenseVector(residuals.Count); Vector<double> vecSdash = new DenseVector(residuals.Count);
Vector t = new DenseVector(residuals.Count); Vector<double> t = 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
@ -380,8 +383,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
// x_i = x_(i-1) + alpha_i p^ + omega_i s^ // x_i = x_(i-1) + alpha_i p^ + omega_i s^
result.Add(vecSdash.Multiply(omega), result); result.Add(vecSdash.Multiply(omega), result);
//vecPdash.Multiply(alpha, vecPdash);
result.Add(vecPdash.Multiply(alpha), result); result.Add(vecPdash.Multiply(alpha), result);
t.Multiply(-omega, residuals); t.Multiply(-omega, residuals);
@ -412,11 +413,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"/> A.</param> /// <param name="matrix">Instance of the <see cref="Matrix{T}"/> A.</param>
/// <param name="residual">Residual values in <see cref="Vector"/>.</param> /// <param name="residual">Residual values in <see cref="Vector{T}"/>.</param>
/// <param name="x">Instance of the <see cref="Vector"/> x.</param> /// <param name="x">Instance of the <see cref="Vector{T}"/> x.</param>
/// <param name="b">Instance of the <see cref="Vector"/> b.</param> /// <param name="b">Instance of the <see cref="Vector{T}"/> b.</param>
private static void CalculateTrueResidual(Matrix matrix, Vector residual, Vector x, Vector b) private static void CalculateTrueResidual(Matrix<double> matrix, Vector<double> residual, Vector<double> x, Vector<double> b)
{ {
// -Ax = residual // -Ax = residual
matrix.Multiply(x, residual); matrix.Multiply(x, residual);
@ -432,11 +433,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"/>.</param> /// <param name="result">Result <see cref="Vector{T}"/>.</param>
/// <param name="source">Source <see cref="Vector"/>.</param> /// <param name="source">Source <see cref="Vector{T}"/>.</param>
/// <param name="residuals">Residual <see cref="Vector"/>.</param> /// <param name="residuals">Residual <see cref="Vector{T}"/>.</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 result, Vector source, Vector residuals) private bool ShouldContinue(int iterationNumber, Vector<double> result, Vector<double> source, Vector<double> residuals)
{ {
if (_hasBeenStopped) if (_hasBeenStopped)
{ {
@ -457,10 +458,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"/>, <c>A</c>.</param> /// <param name="matrix">The coefficient <see cref="Matrix{T}"/>, <c>A</c>.</param>
/// <param name="input">The solution <see cref="Matrix"/>, <c>B</c>.</param> /// <param name="input">The solution <see cref="Matrix{T}"/>, <c>B</c>.</param>
/// <returns>The result <see cref="Matrix"/>, <c>X</c>.</returns> /// <returns>The result <see cref="Matrix{T}"/>, <c>X</c>.</returns>
public Matrix Solve(Matrix matrix, Matrix input) public Matrix<double> Solve(Matrix<double> matrix, Matrix<double> input)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -481,10 +482,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"/>, <c>A</c>.</param> /// <param name="matrix">The coefficient <see cref="Matrix{T}"/>, <c>A</c>.</param>
/// <param name="input">The solution <see cref="Matrix"/>, <c>B</c>.</param> /// <param name="input">The solution <see cref="Matrix{T}"/>, <c>B</c>.</param>
/// <param name="result">The result <see cref="Matrix"/>, <c>X</c></param> /// <param name="result">The result <see cref="Matrix{T}"/>, <c>X</c></param>
public void Solve(Matrix matrix, Matrix input, Matrix result) public void Solve(Matrix<double> matrix, Matrix<double> input, Matrix<double> result)
{ {
if (matrix == null) if (matrix == null)
{ {

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

@ -35,8 +35,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double.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 Properties; using Properties;
using Status;
/// <summary> /// <summary>
/// A composite matrix solver. The actual solver is made by a sequence of /// A composite matrix solver. The actual solver is made by a sequence of
@ -53,7 +55,7 @@ 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 public sealed class CompositeSolver : IIterativeSolver<double>
{ {
#region Internal class - DoubleComparer #region Internal class - DoubleComparer
/// <summary> /// <summary>
@ -94,19 +96,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>> SolverSetups = new Dictionary<double, List<IIterativeSolverSetup>>(); private static readonly Dictionary<double, List<IIterativeSolverSetup<double>>> SolverSetups = new Dictionary<double, List<IIterativeSolverSetup<double>>>();
#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>> SolverSetups = new SortedList<double, List<IIterativeSolverSetup>>(new DoubleComparer()); private static readonly SortedList<double, List<IIterativeSolverSetup<double>>> SolverSetups = new SortedList<double, List<IIterativeSolverSetup<double>>>(new DoubleComparer());
#endif #endif
#region Solver information loading methods #region Solver information loading methods
/// <summary> /// <summary>
/// Loads all the available <see cref="IIterativeSolverSetup"/> objects from the MathNet.Numerics assembly. /// Loads all the available <see cref="IIterativeSolverSetup{T}"/> objects from the MathNet.Numerics assembly.
/// </summary> /// </summary>
public static void LoadSolverInformation() public static void LoadSolverInformation()
{ {
@ -114,16 +116,16 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
} }
/// <summary> /// <summary>
/// Loads the available <see cref="IIterativeSolverSetup"/> objects from the MathNet.Numerics assembly. /// Loads the available <see cref="IIterativeSolverSetup{T}"/> objects from the MathNet.Numerics assembly.
/// </summary> /// </summary>
/// <param name="typesToExclude">The <see cref="IIterativeSolver"/> types that should not be loaded.</param> /// <param name="typesToExclude">The <see cref="IIterativeSolver{T}"/> 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"/> objects from the assembly specified by the file location. /// Loads the available <see cref="IIterativeSolverSetup{T}"/> 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)
@ -132,10 +134,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
} }
/// <summary> /// <summary>
/// Loads the available <see cref="IIterativeSolverSetup"/> objects from the assembly specified by the file location. /// Loads the available <see cref="IIterativeSolverSetup{T}"/> 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"/> types that should not be loaded. </param> /// <param name="typesToExclude">The <see cref="IIterativeSolver{T}"/> 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)
@ -170,7 +172,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
} }
/// <summary> /// <summary>
/// Loads the available <see cref="IIterativeSolverSetup"/> objects from the assembly specified by the assembly name. /// Loads the available <see cref="IIterativeSolverSetup{T}"/> 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)
@ -179,10 +181,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
} }
/// <summary> /// <summary>
/// Loads the available <see cref="IIterativeSolverSetup"/> objects from the assembly specified by the assembly name. /// Loads the available <see cref="IIterativeSolverSetup{T}"/> 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"/> types that should not be loaded.</param> /// <param name="typesToExclude">The <see cref="IIterativeSolver{T}"/> 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)
@ -202,7 +204,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
} }
/// <summary> /// <summary>
/// Loads the available <see cref="IIterativeSolverSetup"/> objects from the assembly specified by the type. /// Loads the available <see cref="IIterativeSolverSetup{T}"/> 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)
@ -211,10 +213,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
} }
/// <summary> /// <summary>
/// Loads the available <see cref="IIterativeSolverSetup"/> objects from the assembly specified by the type. /// Loads the available <see cref="IIterativeSolverSetup{T}"/> 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"/> types that should not be loaded.</param> /// <param name="typesToExclude">The <see cref="IIterativeSolver{T}"/> 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)
@ -226,7 +228,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
} }
/// <summary> /// <summary>
/// Loads the available <see cref="IIterativeSolverSetup"/> objects from the specified assembly. /// Loads the available <see cref="IIterativeSolverSetup{T}"/> 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)
@ -235,10 +237,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
} }
/// <summary> /// <summary>
/// Loads the available <see cref="IIterativeSolverSetup"/> objects from the specified assembly. /// Loads the available <see cref="IIterativeSolverSetup{T}"/> 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"/> types that should not be loaded.</param> /// <param name="typesToExclude">The <see cref="IIterativeSolver{T}"/> 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)
@ -262,18 +264,18 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
foreach (var type in assembly.GetTypes().Where(type => (!type.IsAbstract && !type.IsEnum && !type.IsInterface && type.IsVisible))) foreach (var type in assembly.GetTypes().Where(type => (!type.IsAbstract && !type.IsEnum && !type.IsInterface && type.IsVisible)))
{ {
interfaceTypes.AddRange(type.GetInterfaces()); interfaceTypes.AddRange(type.GetInterfaces());
if (!interfaceTypes.Any(match => typeof(IIterativeSolverSetup).IsAssignableFrom(match))) if (!interfaceTypes.Any(match => typeof(IIterativeSolverSetup<double>).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 setup; IIterativeSolverSetup<double> 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)Activator.CreateInstance(type); setup = (IIterativeSolverSetup<double>)Activator.CreateInstance(type);
} }
catch (ArgumentException) catch (ArgumentException)
{ {
@ -314,7 +316,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>()); SolverSetups.Add(ratio, new List<IIterativeSolverSetup<double>>());
} }
var list = SolverSetups[ratio]; var list = SolverSetups[ratio];
@ -327,7 +329,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> _solvers = new List<IIterativeSolver>(); private readonly List<IIterativeSolver<double>> _solvers = new List<IIterativeSolver<double>>();
/// <summary> /// <summary>
/// The status of the calculation. /// The status of the calculation.
@ -337,7 +339,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 _iterator; private IIterator<double> _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.
@ -348,7 +350,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 _currentSolver; private IIterativeSolver<double> _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.
@ -361,16 +363,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 iterator) public CompositeSolver(IIterator<double> iterator)
{ {
_iterator = iterator; _iterator = iterator;
} }
/// <summary> /// <summary>
/// Sets the <c>IIterator</c> that will be used to track the iterative process. /// Sets the <see cref="IIterator{T}"/> 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 iterator) public void SetIterator(IIterator<double> iterator)
{ {
_iterator = iterator; _iterator = iterator;
} }
@ -408,14 +410,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 Solve(Matrix matrix, Vector vector) public Vector<double> Solve(Matrix<double> matrix, Vector<double> vector)
{ {
if (vector == null) if (vector == null)
{ {
throw new ArgumentNullException(); throw new ArgumentNullException();
} }
Vector result = new DenseVector(matrix.RowCount); Vector<double> result = new DenseVector(matrix.RowCount);
Solve(matrix, vector, result); Solve(matrix, vector, result);
return result; return result;
} }
@ -427,7 +429,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 matrix, Vector input, Vector result) public void Solve(Matrix<double> matrix, Vector<double> input, Vector<double> 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
@ -568,7 +570,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 Solve(Matrix matrix, Matrix input) public Matrix<double> Solve(Matrix<double> matrix, Matrix<double> input)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -592,7 +594,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 matrix, Matrix input, Matrix result) public void Solve(Matrix<double> matrix, Matrix<double> input, Matrix<double> result)
{ {
if (matrix == null) if (matrix == null)
{ {

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

@ -31,9 +31,12 @@
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 Preconditioners; using Preconditioners;
using Properties; using Properties;
using Status;
/// <summary> /// <summary>
/// A Generalized Product Bi-Conjugate Gradient iterative matrix solver. /// A Generalized Product Bi-Conjugate Gradient iterative matrix solver.
@ -62,7 +65,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// solver. /// solver.
/// </para> /// </para>
/// </remarks> /// </remarks>
public sealed class GpBiCg : IIterativeSolver public sealed class GpBiCg : IIterativeSolver<double>
{ {
/// <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
@ -74,12 +77,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 _preconditioner; private IPreConditioner<double> _preconditioner;
/// <summary> /// <summary>
/// The iterative process controller. /// The iterative process controller.
/// </summary> /// </summary>
private IIterator _iterator; private IIterator<double> _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
@ -102,7 +105,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"/> with /// When using this constructor the solver will use the <see cref="IIterator{T}"/> 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)
@ -117,18 +120,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"/> are: /// The main advantages of using a user defined <see cref="IIterator{T}"/> 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.Status"/> property. /// the iterative procedure by calling the <see cref="IIterator{T}.Status"/> property.
/// </item> /// </item>
/// </list> /// </list>
/// </para> /// </para>
/// </remarks> /// </remarks>
/// <param name="iterator">The <see cref="IIterator"/> that will be used to monitor the iterative process.</param> /// <param name="iterator">The <see cref="IIterator{T}"/> that will be used to monitor the iterative process.</param>
public GpBiCg(IIterator iterator) : this(null, iterator) public GpBiCg(IIterator<double> iterator) : this(null, iterator)
{ {
} }
@ -136,11 +139,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"/> with /// When using this constructor the solver will use the <see cref="IIterator{T}"/> with
/// the standard settings. /// the standard settings.
/// </remarks> /// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner"/> that will be used to precondition the matrix equation.</param> /// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation.</param>
public GpBiCg(IPreConditioner preconditioner) : this(preconditioner, null) public GpBiCg(IPreConditioner<double> preconditioner) : this(preconditioner, null)
{ {
} }
@ -149,19 +152,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"/> are: /// The main advantages of using a user defined <see cref="IIterator{T}"/> 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.Status"/> property. /// the iterative procedure by calling the <see cref="IIterator{T}.Status"/> property.
/// </item> /// </item>
/// </list> /// </list>
/// </para> /// </para>
/// </remarks> /// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner"/> that will be used to precondition the matrix equation.</param> /// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation.</param>
/// <param name="iterator">The <see cref="IIterator"/> that will be used to monitor the iterative process.</param> /// <param name="iterator">The <see cref="IIterator{T}"/> that will be used to monitor the iterative process.</param>
public GpBiCg(IPreConditioner preconditioner, IIterator iterator) public GpBiCg(IPreConditioner<double> preconditioner, IIterator<double> iterator)
{ {
_iterator = iterator; _iterator = iterator;
_preconditioner = preconditioner; _preconditioner = preconditioner;
@ -212,19 +215,19 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
} }
/// <summary> /// <summary>
/// Sets the <see cref="IPreConditioner"/> that will be used to precondition the iterative process. /// Sets the <see cref="IPreConditioner{T}"/> 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 preconditioner) public void SetPreconditioner(IPreConditioner<double> preconditioner)
{ {
_preconditioner = preconditioner; _preconditioner = preconditioner;
} }
/// <summary> /// <summary>
/// Sets the <see cref="IIterator"/> that will be used to track the iterative process. /// Sets the <see cref="IIterator{T}"/> 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 iterator) public void SetIterator(IIterator<double> iterator)
{ {
_iterator = iterator; _iterator = iterator;
} }
@ -259,14 +262,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 Solve(Matrix matrix, Vector vector) public Vector<double> Solve(Matrix<double> matrix, Vector<double> vector)
{ {
if (vector == null) if (vector == null)
{ {
throw new ArgumentNullException(); throw new ArgumentNullException();
} }
Vector result = new DenseVector(matrix.RowCount); Vector<double> result = new DenseVector(matrix.RowCount);
Solve(matrix, vector, result); Solve(matrix, vector, result);
return result; return result;
} }
@ -278,7 +281,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 matrix, Vector input, Vector result) public void Solve(Matrix<double> matrix, Vector<double> input, Vector<double> 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
@ -328,11 +331,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 xtemp = new DenseVector(input.Count); Vector<double> 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 residuals = new DenseVector(matrix.RowCount); Vector<double> residuals = new DenseVector(matrix.RowCount);
CalculateTrueResidual(matrix, residuals, xtemp, input); CalculateTrueResidual(matrix, residuals, xtemp, input);
// Define the temporary scalars // Define the temporary scalars
@ -341,24 +344,24 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
// Define the temporary vectors // Define the temporary vectors
// rDash_0 = r_0 // rDash_0 = r_0
Vector rdash = new DenseVector(residuals); Vector<double> rdash = new DenseVector(residuals);
// t_-1 = 0 // t_-1 = 0
Vector t = new DenseVector(residuals.Count); Vector<double> t = new DenseVector(residuals.Count);
Vector t0 = new DenseVector(residuals.Count); Vector<double> t0 = new DenseVector(residuals.Count);
// w_-1 = 0 // w_-1 = 0
Vector w = new DenseVector(residuals.Count); Vector<double> w = new DenseVector(residuals.Count);
// Define the remaining temporary vectors // Define the remaining temporary vectors
Vector c = new DenseVector(residuals.Count); Vector<double> c = new DenseVector(residuals.Count);
Vector p = new DenseVector(residuals.Count); Vector<double> p = new DenseVector(residuals.Count);
Vector s = new DenseVector(residuals.Count); Vector<double> s = new DenseVector(residuals.Count);
Vector u = new DenseVector(residuals.Count); Vector<double> u = new DenseVector(residuals.Count);
Vector y = new DenseVector(residuals.Count); Vector<double> y = new DenseVector(residuals.Count);
Vector z = new DenseVector(residuals.Count); Vector<double> z = new DenseVector(residuals.Count);
Vector temp = new DenseVector(residuals.Count); Vector<double> temp = new DenseVector(residuals.Count);
// for (k = 0, 1, .... ) // for (k = 0, 1, .... )
var iterationNumber = 0; var iterationNumber = 0;
@ -499,11 +502,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"/> A.</param> /// <param name="matrix">Instance of the <see cref="Matrix{T}"/> A.</param>
/// <param name="residual">Residual values in <see cref="Vector"/>.</param> /// <param name="residual">Residual values in <see cref="Vector{T}"/>.</param>
/// <param name="x">Instance of the <see cref="Vector"/> x.</param> /// <param name="x">Instance of the <see cref="Vector{T}"/> x.</param>
/// <param name="b">Instance of the <see cref="Vector"/> b.</param> /// <param name="b">Instance of the <see cref="Vector{T}"/> b.</param>
private static void CalculateTrueResidual(Matrix matrix, Vector residual, Vector x, Vector b) private static void CalculateTrueResidual(Matrix<double> matrix, Vector<double> residual, Vector<double> x, Vector<double> b)
{ {
// -Ax = residual // -Ax = residual
matrix.Multiply(x, residual); matrix.Multiply(x, residual);
@ -517,11 +520,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"/>.</param> /// <param name="result">Result <see cref="Vector{T}"/>.</param>
/// <param name="source">Source <see cref="Vector"/>.</param> /// <param name="source">Source <see cref="Vector{T}"/>.</param>
/// <param name="residuals">Residual <see cref="Vector"/>.</param> /// <param name="residuals">Residual <see cref="Vector{T}"/>.</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 result, Vector source, Vector residuals) private bool ShouldContinue(int iterationNumber, Vector<double> result, Vector<double> source, Vector<double> residuals)
{ {
if (_hasBeenStopped) if (_hasBeenStopped)
{ {
@ -562,7 +565,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 Solve(Matrix matrix, Matrix input) public Matrix<double> Solve(Matrix<double> matrix, Matrix<double> input)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -586,7 +589,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 matrix, Matrix input, Matrix result) public void Solve(Matrix<double> matrix, Matrix<double> input, Matrix<double> result)
{ {
if (matrix == null) if (matrix == null)
{ {

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

@ -36,9 +36,12 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
using System.Linq; using System.Linq;
using Distributions; using Distributions;
using Factorization; using Factorization;
using Generic;
using Generic.Solvers;
using Generic.Solvers.Preconditioners;
using Generic.Solvers.Status;
using Preconditioners; using Preconditioners;
using Properties; using Properties;
using Status;
/// <summary> /// <summary>
/// A Multiple-Lanczos Bi-Conjugate Gradient stabilized iterative matrix solver. /// A Multiple-Lanczos Bi-Conjugate Gradient stabilized iterative matrix solver.
@ -63,7 +66,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// solver. /// solver.
/// </para> /// </para>
/// </remarks> /// </remarks>
public sealed class MlkBiCgStab : IIterativeSolver public sealed class MlkBiCgStab : IIterativeSolver<double>
{ {
/// <summary> /// <summary>
/// The default number of starting vectors. /// The default number of starting vectors.
@ -80,17 +83,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 _preconditioner; private IPreConditioner<double> _preconditioner;
/// <summary> /// <summary>
/// The iterative process controller. /// The iterative process controller.
/// </summary> /// </summary>
private IIterator _iterator; private IIterator<double> _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> _startingVectors; private IList<Vector<double>> _startingVectors;
/// <summary> /// <summary>
/// The number of starting vectors used by the algorithm /// The number of starting vectors used by the algorithm
@ -106,7 +109,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"/> with /// When using this constructor the solver will use the <see cref="IIterator{T}"/> 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)
@ -121,18 +124,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"/> are: /// The main advantages of using a user defined <see cref="IIterator{T}"/> 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.Status"/> property. /// the iterative procedure by calling the <see cref="IIterator{T}.Status"/> property.
/// </item> /// </item>
/// </list> /// </list>
/// </para> /// </para>
/// </remarks> /// </remarks>
/// <param name="iterator">The <see cref="IIterator"/> that will be used to monitor the iterative process.</param> /// <param name="iterator">The <see cref="IIterator{T}"/> that will be used to monitor the iterative process.</param>
public MlkBiCgStab(IIterator iterator) : this(null, iterator) public MlkBiCgStab(IIterator<double> iterator) : this(null, iterator)
{ {
} }
@ -140,11 +143,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"/> with /// When using this constructor the solver will use the <see cref="IIterator{T}"/> with
/// the standard settings. /// the standard settings.
/// </remarks> /// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner"/> that will be used to precondition the matrix equation.</param> /// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation.</param>
public MlkBiCgStab(IPreConditioner preconditioner) : this(preconditioner, null) public MlkBiCgStab(IPreConditioner<double> preconditioner) : this(preconditioner, null)
{ {
} }
@ -153,19 +156,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"/> are: /// The main advantages of using a user defined <see cref="IIterator{T}"/> 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.Status"/> property. /// the iterative procedure by calling the <see cref="IIterator{T}.Status"/> property.
/// </item> /// </item>
/// </list> /// </list>
/// </para> /// </para>
/// </remarks> /// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner"/> that will be used to precondition the matrix equation.</param> /// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation.</param>
/// <param name="iterator">The <see cref="IIterator"/> that will be used to monitor the iterative process.</param> /// <param name="iterator">The <see cref="IIterator{T}"/> that will be used to monitor the iterative process.</param>
public MlkBiCgStab(IPreConditioner preconditioner, IIterator iterator) public MlkBiCgStab(IPreConditioner<double> preconditioner, IIterator<double> iterator)
{ {
_iterator = iterator; _iterator = iterator;
_preconditioner = preconditioner; _preconditioner = preconditioner;
@ -207,19 +210,19 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
} }
/// <summary> /// <summary>
/// Sets the <see cref="IPreConditioner"/> that will be used to precondition the iterative process. /// Sets the <see cref="IPreConditioner{T}"/> 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 preconditioner) public void SetPreconditioner(IPreConditioner<double> preconditioner)
{ {
_preconditioner = preconditioner; _preconditioner = preconditioner;
} }
/// <summary> /// <summary>
/// Sets the <see cref="IIterator"/> that will be used to track the iterative process. /// Sets the <see cref="IIterator{T}"/> 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 iterator) public void SetIterator(IIterator<double> iterator)
{ {
_iterator = iterator; _iterator = iterator;
} }
@ -228,7 +231,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> StartingVectors public IList<Vector<double>> StartingVectors
{ {
[DebuggerStepThrough] [DebuggerStepThrough]
get get
@ -280,14 +283,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 Solve(Matrix matrix, Vector vector) public Vector<double> Solve(Matrix<double> matrix, Vector<double> vector)
{ {
if (vector == null) if (vector == null)
{ {
throw new ArgumentNullException(); throw new ArgumentNullException();
} }
Vector result = new DenseVector(matrix.RowCount); Vector<double> result = new DenseVector(matrix.RowCount);
Solve(matrix, vector, result); Solve(matrix, vector, result);
return result; return result;
} }
@ -299,7 +302,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 matrix, Vector input, Vector result) public void Solve(Matrix<double> matrix, Vector<double> input, Vector<double> 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
@ -348,7 +351,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 xtemp = new DenseVector(input.Count); Vector<double> 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:
@ -377,23 +380,23 @@ 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 residuals = new DenseVector(matrix.RowCount); Vector<double> 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 gtemp = new DenseVector(residuals.Count); Vector<double> gtemp = new DenseVector(residuals.Count);
Vector u = new DenseVector(residuals.Count); Vector<double> u = new DenseVector(residuals.Count);
Vector utemp = new DenseVector(residuals.Count); Vector<double> utemp = new DenseVector(residuals.Count);
Vector temp = new DenseVector(residuals.Count); Vector<double> temp = new DenseVector(residuals.Count);
Vector temp1 = new DenseVector(residuals.Count); Vector<double> temp1 = new DenseVector(residuals.Count);
Vector zd = new DenseVector(residuals.Count); Vector<double> zd = new DenseVector(residuals.Count);
Vector zg = new DenseVector(residuals.Count); Vector<double> zg = new DenseVector(residuals.Count);
Vector zw = new DenseVector(residuals.Count); Vector<double> zw = new DenseVector(residuals.Count);
var d = CreateVectorArray(_startingVectors.Count, residuals.Count); var d = CreateVectorArray(_startingVectors.Count, residuals.Count);
@ -611,7 +614,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> CreateStartingVectors(int maximumNumberOfStartingVectors, int numberOfVariables) private static IList<Vector<double>> 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
@ -622,7 +625,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 matrix = new DenseMatrix(numberOfVariables, count); Matrix<double> 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();
@ -636,7 +639,7 @@ 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>(); var result = new List<Vector<double>>();
for (var i = 0; i < orthogonalMatrix.ColumnCount; i++) for (var i = 0; i < orthogonalMatrix.ColumnCount; i++)
{ {
result.Add(orthogonalMatrix.Column(i)); result.Add(orthogonalMatrix.Column(i));
@ -654,9 +657,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[] CreateVectorArray(int arraySize, int vectorSize) private static Vector<double>[] CreateVectorArray(int arraySize, int vectorSize)
{ {
var result = new Vector[arraySize]; var result = new Vector<double>[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);
@ -668,11 +671,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"/>A.</param> /// <param name="matrix">Source <see cref="Matrix{T}"/>A.</param>
/// <param name="residual">Residual <see cref="Vector"/> data.</param> /// <param name="residual">Residual <see cref="Vector{T}"/> data.</param>
/// <param name="x">x <see cref="Vector"/> data.</param> /// <param name="x">x <see cref="Vector{T}"/> data.</param>
/// <param name="b">b <see cref="Vector"/> data.</param> /// <param name="b">b <see cref="Vector{T}"/> data.</param>
private static void CalculateTrueResidual(Matrix matrix, Vector residual, Vector x, Vector b) private static void CalculateTrueResidual(Matrix<double> matrix, Vector<double> residual, Vector<double> x, Vector<double> b)
{ {
// -Ax = residual // -Ax = residual
matrix.Multiply(x, residual); matrix.Multiply(x, residual);
@ -686,11 +689,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"/>.</param> /// <param name="result">Result <see cref="Vector{T}"/>.</param>
/// <param name="source">Source <see cref="Vector"/>.</param> /// <param name="source">Source <see cref="Vector{T}"/>.</param>
/// <param name="residuals">Residual <see cref="Vector"/>.</param> /// <param name="residuals">Residual <see cref="Vector{T}"/>.</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 result, Vector source, Vector residuals) private bool ShouldContinue(int iterationNumber, Vector<double> result, Vector<double> source, Vector<double> residuals)
{ {
if (_hasBeenStopped) if (_hasBeenStopped)
{ {
@ -714,7 +717,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 Solve(Matrix matrix, Matrix input) public Matrix<double> Solve(Matrix<double> matrix, Matrix<double> input)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -738,7 +741,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 matrix, Matrix input, Matrix result) public void Solve(Matrix<double> matrix, Matrix<double> input, Matrix<double> result)
{ {
if (matrix == null) if (matrix == null)
{ {

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

@ -31,9 +31,12 @@
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 Preconditioners; using Preconditioners;
using Properties; using Properties;
using Status;
/// <summary> /// <summary>
/// A Transpose Free Quasi-Minimal Residual (TFQMR) iterative matrix solver. /// A Transpose Free Quasi-Minimal Residual (TFQMR) iterative matrix solver.
@ -52,7 +55,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// solver. /// solver.
/// </para> /// </para>
/// </remarks> /// </remarks>
public sealed class TFQMR : IIterativeSolver public sealed class TFQMR : IIterativeSolver<double>
{ {
/// <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
@ -64,12 +67,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 _preconditioner; private IPreConditioner<double> _preconditioner;
/// <summary> /// <summary>
/// The iterative process controller. /// The iterative process controller.
/// </summary> /// </summary>
private IIterator _iterator; private IIterator<double> _iterator;
/// <summary> /// <summary>
/// Indicates if the user has stopped the solver. /// Indicates if the user has stopped the solver.
@ -80,7 +83,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"/> with /// When using this constructor the solver will use the <see cref="IIterator{T}"/> 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)
@ -95,18 +98,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"/> are: /// The main advantages of using a user defined <see cref="IIterator{T}"/> 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.Status"/> property. /// the iterative procedure by calling the <see cref="IIterator{T}.Status"/> property.
/// </item> /// </item>
/// </list> /// </list>
/// </para> /// </para>
/// </remarks> /// </remarks>
/// <param name="iterator">The <see cref="IIterator"/> that will be used to monitor the iterative process.</param> /// <param name="iterator">The <see cref="IIterator{T}"/> that will be used to monitor the iterative process.</param>
public TFQMR(IIterator iterator) : this(null, iterator) public TFQMR(IIterator<double> iterator) : this(null, iterator)
{ {
} }
@ -114,11 +117,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"/> with /// When using this constructor the solver will use the <see cref="IIterator{T}"/> with
/// the standard settings. /// the standard settings.
/// </remarks> /// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner"/> that will be used to precondition the matrix equation.</param> /// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation.</param>
public TFQMR(IPreConditioner preconditioner) : this(preconditioner, null) public TFQMR(IPreConditioner<double> preconditioner) : this(preconditioner, null)
{ {
} }
@ -127,38 +130,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"/> are: /// The main advantages of using a user defined <see cref="IIterator{T}"/> 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.Status"/> property. /// the iterative procedure by calling the <see cref="IIterator{T}.Status"/> property.
/// </item> /// </item>
/// </list> /// </list>
/// </para> /// </para>
/// </remarks> /// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner"/> that will be used to precondition the matrix equation.</param> /// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation.</param>
/// <param name="iterator">The <see cref="IIterator"/> that will be used to monitor the iterative process.</param> /// <param name="iterator">The <see cref="IIterator{T}"/> that will be used to monitor the iterative process.</param>
public TFQMR(IPreConditioner preconditioner, IIterator iterator) public TFQMR(IPreConditioner<double> preconditioner, IIterator<double> iterator)
{ {
_iterator = iterator; _iterator = iterator;
_preconditioner = preconditioner; _preconditioner = preconditioner;
} }
/// <summary> /// <summary>
/// Sets the <see cref="IPreConditioner"/> that will be used to precondition the iterative process. /// Sets the <see cref="IPreConditioner{T}"/> 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 preconditioner) public void SetPreconditioner(IPreConditioner<double> preconditioner)
{ {
_preconditioner = preconditioner; _preconditioner = preconditioner;
} }
/// <summary> /// <summary>
/// Sets the <see cref="IIterator"/> that will be used to track the iterative process. /// Sets the <see cref="IIterator{T}"/> 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 iterator) public void SetIterator(IIterator<double> iterator)
{ {
_iterator = iterator; _iterator = iterator;
} }
@ -192,14 +195,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 Solve(Matrix matrix, Vector vector) public Vector<double> Solve(Matrix<double> matrix, Vector<double> vector)
{ {
if (vector == null) if (vector == null)
{ {
throw new ArgumentNullException(); throw new ArgumentNullException();
} }
Vector result = new DenseVector(matrix.RowCount); Vector<double> result = new DenseVector(matrix.RowCount);
Solve(matrix, vector, result); Solve(matrix, vector, result);
return result; return result;
} }
@ -211,7 +214,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 matrix, Vector input, Vector result) public void Solve(Matrix<double> matrix, Vector<double> input, Vector<double> 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
@ -410,11 +413,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"/> A.</param> /// <param name="matrix">Instance of the <see cref="Matrix{T}"/> A.</param>
/// <param name="residual">Residual values in <see cref="Vector"/>.</param> /// <param name="residual">Residual values in <see cref="Vector{T}"/>.</param>
/// <param name="x">Instance of the <see cref="Vector"/> x.</param> /// <param name="x">Instance of the <see cref="Vector{T}"/> x.</param>
/// <param name="b">Instance of the <see cref="Vector"/> b.</param> /// <param name="b">Instance of the <see cref="Vector{T}"/> b.</param>
private static void CalculateTrueResidual(Matrix matrix, Vector residual, Vector x, Vector b) private static void CalculateTrueResidual(Matrix<double> matrix, Vector<double> residual, Vector<double> x, Vector<double> b)
{ {
// -Ax = residual // -Ax = residual
matrix.Multiply(x, residual); matrix.Multiply(x, residual);
@ -428,11 +431,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"/>.</param> /// <param name="result">Result <see cref="Vector{T}"/>.</param>
/// <param name="source">Source <see cref="Vector"/>.</param> /// <param name="source">Source <see cref="Vector{T}"/>.</param>
/// <param name="residuals">Residual <see cref="Vector"/>.</param> /// <param name="residuals">Residual <see cref="Vector{T}"/>.</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 result, Vector source, Vector residuals) private bool ShouldContinue(int iterationNumber, Vector<double> result, Vector<double> source, Vector<double> residuals)
{ {
if (_hasBeenStopped) if (_hasBeenStopped)
{ {
@ -466,7 +469,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 Solve(Matrix matrix, Matrix input) public Matrix<double> Solve(Matrix<double> matrix, Matrix<double> input)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -490,7 +493,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 matrix, Matrix input, Matrix result) public void Solve(Matrix<double> matrix, Matrix<double> input, Matrix<double> result)
{ {
if (matrix == null) if (matrix == null)
{ {

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

@ -33,14 +33,17 @@ 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.StopCriterium;
using Properties; using Properties;
using Status;
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 public sealed class Iterator : IIterator<double>
{ {
/// <summary> /// <summary>
/// The default status for the iterator. /// The default status for the iterator.
@ -48,10 +51,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"/> objects. /// Creates a default iterator with all the <see cref="IIterationStopCriterium{T}"/> objects.
/// </summary> /// </summary>
/// <returns>A new <see cref="IIterator"/> object.</returns> /// <returns>A new <see cref="IIterator{T}"/> object.</returns>
public static IIterator CreateDefault() public static IIterator<double> CreateDefault()
{ {
var iterator = new Iterator(); var iterator = new Iterator();
iterator.Add(new FailureStopCriterium()); iterator.Add(new FailureStopCriterium());
@ -66,7 +69,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> _stopCriterias = new Dictionary<Type, IIterationStopCriterium>(); private readonly Dictionary<Type, IIterationStopCriterium<double>> _stopCriterias = new Dictionary<Type, IIterationStopCriterium<double>>();
/// <summary> /// <summary>
/// The status of the iterator. /// The status of the iterator.
@ -93,7 +96,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> stopCriteria) public Iterator(IEnumerable<IIterationStopCriterium<double>> stopCriteria)
{ {
// Add the stop criteria // Add the stop criteria
if (stopCriteria == null) if (stopCriteria == null)
@ -108,7 +111,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
} }
/// <summary> /// <summary>
/// Adds an <see cref="IIterationStopCriterium"/> to the internal collection of stop-criteria. Only a /// Adds an <see cref="IIterationStopCriterium{T}"/> 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>
@ -117,7 +120,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 stopCriterium) public void Add(IIterationStopCriterium<double> stopCriterium)
{ {
if (stopCriterium == null) if (stopCriterium == null)
{ {
@ -134,10 +137,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
} }
/// <summary> /// <summary>
/// Removes the <see cref="IIterationStopCriterium"/> from the internal collection. /// Removes the <see cref="IIterationStopCriterium{T}"/> 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 stopCriterium) public void Remove(IIterationStopCriterium<double> stopCriterium)
{ {
if (stopCriterium == null) if (stopCriterium == null)
{ {
@ -154,11 +157,11 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
} }
/// <summary> /// <summary>
/// Indicates if the specific stop criterium is stored by the <see cref="IIterator"/>. /// Indicates if the specific stop criterium is stored by the <see cref="IIterator{T}"/>.
/// </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"/> contains the stop criterium; otherwise <c>false</c>.</returns> /// <returns><c>true</c> if the <see cref="IIterator{T}"/> contains the stop criterium; otherwise <c>false</c>.</returns>
public bool Contains(IIterationStopCriterium stopCriterium) public bool Contains(IIterationStopCriterium<double> stopCriterium)
{ {
return stopCriterium != null && _stopCriterias.ContainsKey(stopCriterium.GetType()); return stopCriterium != null && _stopCriterias.ContainsKey(stopCriterium.GetType());
} }
@ -179,7 +182,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> StoredStopCriteria internal IEnumerator<IIterationStopCriterium<double>> StoredStopCriteria
{ {
get get
{ {
@ -201,7 +204,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 <c>IIterator</c>. Result is set into <c>Status</c> field. /// by the current <see cref="IIterator{T}"/>. 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>
@ -212,7 +215,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 solutionVector, Vector sourceVector, Vector residualVector) public void DetermineStatus(int iterationNumber, Vector<double> solutionVector, Vector<double> sourceVector, Vector<double> residualVector)
{ {
if (_stopCriterias.Count == 0) if (_stopCriterias.Count == 0)
{ {
@ -284,7 +287,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
} }
/// <summary> /// <summary>
/// Resets the <see cref="IIterator"/> to the pre-calculation state. /// Resets the <see cref="IIterator{T}"/> to the pre-calculation state.
/// </summary> /// </summary>
public void ResetToPrecalculationState() public void ResetToPrecalculationState()
{ {
@ -305,9 +308,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 Clone() public IIterator<double> Clone()
{ {
var stopCriteria = _stopCriterias.Select(pair => pair.Value).Select(stopCriterium => (IIterationStopCriterium)stopCriterium.Clone()).ToList(); var stopCriteria = _stopCriterias.Select(pair => pair.Value).Select(stopCriterium => (IIterationStopCriterium<double>)stopCriterium.Clone()).ToList();
return new Iterator(stopCriteria); return new Iterator(stopCriteria);
} }

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

@ -31,13 +31,15 @@
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 public sealed class Diagonal : IPreConditioner<double>
{ {
/// <summary> /// <summary>
/// The inverse of the matrix diagonal. /// The inverse of the matrix diagonal.
@ -63,10 +65,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"/> upon which this preconditioner is based.</param> /// The <see cref="Matrix{T}"/> 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 matrix) public void Initialize(Matrix<double> matrix)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -90,7 +92,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 Approximate(Vector rhs) public Vector<double> Approximate(Vector<double> rhs)
{ {
if (rhs == null) if (rhs == null)
{ {
@ -107,7 +109,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "rhs"); throw new ArgumentException(Resources.ArgumentVectorsSameLength, "rhs");
} }
Vector result = new DenseVector(rhs.Count); Vector<double> result = new DenseVector(rhs.Count);
Approximate(rhs, result); Approximate(rhs, result);
return result; return result;
} }
@ -117,7 +119,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 rhs, Vector lhs) public void Approximate(Vector<double> rhs, Vector<double> lhs)
{ {
if (rhs == null) if (rhs == null)
{ {

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

@ -32,6 +32,8 @@ 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>
@ -51,7 +53,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 public sealed class Ilutp : IPreConditioner<double>
{ {
/// <summary> /// <summary>
/// The default fill level. /// The default fill level.
@ -255,7 +257,7 @@ 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 UpperTriangle() internal Matrix<double> UpperTriangle()
{ {
return _upper.Clone(); return _upper.Clone();
} }
@ -267,7 +269,7 @@ 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 LowerTriangle() internal Matrix<double> LowerTriangle()
{ {
return _lower.Clone(); return _lower.Clone();
} }
@ -295,13 +297,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"/> upon which this preconditioner is based. Note that the /// The <see cref="Matrix{T}"/> 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 matrix) public void Initialize(Matrix<double> matrix)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -373,8 +375,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
_pivots[i] = i; _pivots[i] = i;
} }
Vector workVector = new DenseVector(sparseMatrix.RowCount); Vector<double> workVector = new DenseVector(sparseMatrix.RowCount);
Vector rowVector = new DenseVector(sparseMatrix.ColumnCount); Vector<double> 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)
@ -529,8 +531,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"/> to pivot in</param> /// <param name="row">Row <see cref="Vector{T}"/> to pivot in</param>
private void PivotRow(Vector row) private void PivotRow(Vector<double> row)
{ {
var knownPivots = new Dictionary<int, int>(); var knownPivots = new Dictionary<int, int>();
@ -577,12 +579,12 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
} }
/// <summary> /// <summary>
/// Swap columns in the <see cref="Matrix"/> /// Swap columns in the <see cref="Matrix{T}"/>
/// </summary> /// </summary>
/// <param name="matrix">Source <see cref="Matrix"/>.</param> /// <param name="matrix">Source <see cref="Matrix{T}"/>.</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 matrix, int firstColumn, int secondColumn) private static void SwapColumns(Matrix<double> matrix, int firstColumn, int secondColumn)
{ {
for (var i = 0; i < matrix.RowCount; i++) for (var i = 0; i < matrix.RowCount; i++)
{ {
@ -598,8 +600,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"/></param> /// <param name="values">Source <see cref="Vector{T}"/></param>
private static void FindLargestItems(int lowerBound, int upperBound, int[] sortedIndices, Vector values) private static void FindLargestItems(int lowerBound, int upperBound, int[] sortedIndices, Vector<double> 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++)
@ -624,7 +626,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 Approximate(Vector rhs) public Vector<double> Approximate(Vector<double> rhs)
{ {
if (rhs == null) if (rhs == null)
{ {
@ -641,7 +643,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "rhs"); throw new ArgumentException(Resources.ArgumentVectorsSameLength, "rhs");
} }
Vector result = new DenseVector(rhs.Count); Vector<double> result = new DenseVector(rhs.Count);
Approximate(rhs, result); Approximate(rhs, result);
return result; return result;
} }
@ -651,7 +653,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 rhs, Vector lhs) public void Approximate(Vector<double> rhs, Vector<double> lhs)
{ {
if (rhs == null) if (rhs == null)
{ {
@ -676,7 +678,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 rowValues = new DenseVector(_lower.RowCount); Vector<double> 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);
@ -712,11 +714,11 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
} }
/// <summary> /// <summary>
/// Pivot elements in <see cref="Vector"/> accoring to internal pivot array /// Pivot elements in <see cref="Vector{T}"/> accoring to internal pivot array
/// </summary> /// </summary>
/// <param name="vector">Source <see cref="Vector"/>.</param> /// <param name="vector">Source <see cref="Vector{T}"/>.</param>
/// <param name="result">Result <see cref="Vector"/> after pivoting.</param> /// <param name="result">Result <see cref="Vector{T}"/> after pivoting.</param>
private void Pivot(Vector vector, Vector result) private void Pivot(Vector<double> vector, Vector<double> result)
{ {
for (var i = 0; i < _pivots.Length; i++) for (var i = 0; i < _pivots.Length; i++)
{ {

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

@ -30,6 +30,8 @@
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>
@ -46,8 +48,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"/> that contains the values that need to be sorted.</param> /// <param name="values">The <see cref="Vector{T}"/> that contains the values that need to be sorted.</param>
public static void SortDoubleIndicesDecreasing(int lowerBound, int upperBound, int[] sortedIndices, Vector values) public static void SortDoubleIndicesDecreasing(int lowerBound, int upperBound, int[] sortedIndices, Vector<double> 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.
@ -72,8 +74,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"/> that contains the values that need to be sorted.</param> /// <param name="values">The <see cref="Vector{T}"/> that contains the values that need to be sorted.</param>
private static void HeapSortDoublesIndices(int lowerBound, int upperBound, int[] sortedIndices, Vector values) private static void HeapSortDoublesIndices(int lowerBound, int upperBound, int[] sortedIndices, Vector<double> 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,8 +96,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
/// <param name="start">Root position</param> /// <param name="start">Root position</param>
/// <param name="count">Lenght of <paramref name="values"/></param> /// <param name="count">Lenght 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"/></param> /// <param name="values">Target <see cref="Vector{T}"/></param>
private static void BuildDoubleIndexHeap(int start, int count, int[] sortedIndices, Vector values) private static void BuildDoubleIndexHeap(int start, int count, int[] sortedIndices, Vector<double> values)
{ {
while (start >= 0) while (start >= 0)
{ {
@ -108,10 +110,10 @@ 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"/></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">Lenght of <paramref name="values"/></param>
private static void SiftDoubleIndices(int[] sortedIndices, Vector values, int begin, int count) private static void SiftDoubleIndices(int[] sortedIndices, Vector<double> values, int begin, int count)
{ {
var root = begin; var root = begin;
int child; int child;

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

@ -31,6 +31,8 @@
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>
@ -42,7 +44,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 public sealed class IncompleteLU : IPreConditioner<double>
{ {
/// <summary> /// <summary>
/// The matrix holding the lower (L) and upper (U) matrices. The /// The matrix holding the lower (L) and upper (U) matrices. The
@ -54,7 +56,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 UpperTriangle() internal Matrix<double> 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++)
@ -72,7 +74,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 LowerTriangle() internal Matrix<double> 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++)
@ -99,7 +101,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 matrix) public void Initialize(Matrix<double> matrix)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -161,7 +163,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 Approximate(Vector rhs) public Vector<double> Approximate(Vector<double> rhs)
{ {
if (rhs == null) if (rhs == null)
{ {
@ -178,7 +180,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "rhs"); throw new ArgumentException(Resources.ArgumentVectorsSameLength, "rhs");
} }
Vector result = new DenseVector(rhs.Count); Vector<double> result = new DenseVector(rhs.Count);
Approximate(rhs, result); Approximate(rhs, result);
return result; return result;
} }
@ -188,7 +190,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 rhs, Vector lhs) public void Approximate(Vector<double> rhs, Vector<double> lhs)
{ {
if (rhs == null) if (rhs == null)
{ {
@ -218,7 +220,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 rowValues = new DenseVector(_decompositionLU.RowCount); Vector<double> 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,14 +31,17 @@
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"/> without /// it is only used when running an <see cref="IIterativeSolver{T}"/> without
/// a preconditioner. /// a preconditioner.
/// </summary> /// </summary>
internal sealed class UnitPreconditioner : IPreConditioner internal sealed class UnitPreconditioner : IPreConditioner<double>
{ {
/// <summary> /// <summary>
/// The coefficient matrix on which this preconditioner operates. /// The coefficient matrix on which this preconditioner operates.
@ -54,7 +57,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 matrix) public void Initialize(Matrix<double> matrix)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -87,7 +90,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 rhs, Vector lhs) public void Approximate(Vector<double> rhs, Vector<double> lhs)
{ {
if (rhs == null) if (rhs == null)
{ {
@ -116,7 +119,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 Approximate(Vector rhs) public Vector<double> Approximate(Vector<double> rhs)
{ {
if (rhs == null) if (rhs == null)
{ {
@ -128,7 +131,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
throw new ArgumentException(Resources.ArgumentMatrixDimensions); throw new ArgumentException(Resources.ArgumentMatrixDimensions);
} }
Vector result = new DenseVector(rhs.Count); Vector<double> result = new DenseVector(rhs.Count);
Approximate(rhs, result); Approximate(rhs, result);
return result; return result;
} }

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

@ -32,12 +32,14 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium
{ {
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using Status; using Generic;
using Generic.Solvers.Status;
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 public sealed class DivergenceStopCriterium : IIterationStopCriterium<double>
{ {
/// <summary> /// <summary>
/// Default value for the maximum relative increase that the /// Default value for the maximum relative increase that the
@ -205,7 +207,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"/>. Result is set into <c>Status</c> field. /// by the current <see cref="IIterationStopCriterium{T}"/>. 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>
@ -216,7 +218,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 solutionVector, Vector sourceVector, Vector residualVector) public void DetermineStatus(int iterationNumber, Vector<double> solutionVector, Vector<double> sourceVector, Vector<double> residualVector)
{ {
if (iterationNumber < 0) if (iterationNumber < 0)
{ {
@ -345,7 +347,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium
} }
/// <summary> /// <summary>
/// Resets the <see cref="IIterationStopCriterium"/> to the pre-calculation state. /// Resets the <see cref="IIterationStopCriterium{T}"/> to the pre-calculation state.
/// </summary> /// </summary>
public void ResetToPrecalculationState() public void ResetToPrecalculationState()
{ {
@ -356,9 +358,9 @@ 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"/> monitors. /// <see cref="IIterationStopCriterium{T}"/> monitors.
/// </summary> /// </summary>
/// <value>Returns <see cref="StopCriterium.StopLevel.Divergence"/>.</value> /// <value>Returns <see cref="Generic.Solvers.StopCriterium.StopLevel.Divergence"/>.</value>
public StopLevel StopLevel public StopLevel StopLevel
{ {
[DebuggerStepThrough] [DebuggerStepThrough]
@ -372,7 +374,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 Clone() public IIterationStopCriterium<double> Clone()
{ {
return new DivergenceStopCriterium(_maximumRelativeIncrease, _minimumNumberOfIterations); return new DivergenceStopCriterium(_maximumRelativeIncrease, _minimumNumberOfIterations);
} }

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

@ -32,13 +32,15 @@ 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.StopCriterium;
using Properties; using Properties;
using Status;
/// <summary> /// <summary>
/// Defines an <see cref="IIterationStopCriterium"/> that monitors residuals for NaN's. /// Defines an <see cref="IIterationStopCriterium{T}"/> that monitors residuals for NaN's.
/// </summary> /// </summary>
public sealed class FailureStopCriterium : IIterationStopCriterium public sealed class FailureStopCriterium : IIterationStopCriterium<double>
{ {
/// <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
@ -63,7 +65,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"/>. Result is set into <c>Status</c> field. /// by the current <see cref="IIterationStopCriterium{T}"/>. 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>
@ -74,7 +76,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 solutionVector, Vector sourceVector, Vector residualVector) public void DetermineStatus(int iterationNumber, Vector<double> solutionVector, Vector<double> sourceVector, Vector<double> residualVector)
{ {
if (iterationNumber < 0) if (iterationNumber < 0)
{ {
@ -154,7 +156,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium
} }
/// <summary> /// <summary>
/// Resets the <see cref="IIterationStopCriterium"/> to the pre-calculation state. /// Resets the <see cref="IIterationStopCriterium{T}"/> to the pre-calculation state.
/// </summary> /// </summary>
public void ResetToPrecalculationState() public void ResetToPrecalculationState()
{ {
@ -164,7 +166,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"/> monitors. /// <see cref="IIterationStopCriterium{T}"/> monitors.
/// </summary> /// </summary>
/// <value>Returns <see cref="CalculationFailure"/>.</value> /// <value>Returns <see cref="CalculationFailure"/>.</value>
public StopLevel StopLevel public StopLevel StopLevel
@ -180,7 +182,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 Clone() public IIterationStopCriterium<double> Clone()
{ {
return new FailureStopCriterium(); return new FailureStopCriterium();
} }

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

@ -32,13 +32,15 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium
{ {
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using Status; using Generic;
using Generic.Solvers.Status;
using Generic.Solvers.StopCriterium;
/// <summary> /// <summary>
/// Defines an <see cref="IIterationStopCriterium"/> that monitors the numbers of iteration /// Defines an <see cref="IIterationStopCriterium{T}"/> that monitors the numbers of iteration
/// steps as stop criterium. /// steps as stop criterium.
/// </summary> /// </summary>
public sealed class IterationCountStopCriterium : IIterationStopCriterium public sealed class IterationCountStopCriterium : IIterationStopCriterium<double>
{ {
/// <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
@ -129,7 +131,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 solutionVector, Vector sourceVector, Vector residualVector) public void DetermineStatus(int iterationNumber, Vector<double> solutionVector, Vector<double> sourceVector, Vector<double> residualVector)
{ {
if (iterationNumber < 0) if (iterationNumber < 0)
{ {
@ -206,7 +208,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 Clone() public IIterationStopCriterium<double> Clone()
{ {
return new IterationCountStopCriterium(_maximumNumberOfIterations); return new IterationCountStopCriterium(_maximumNumberOfIterations);
} }

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

@ -32,13 +32,15 @@ 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.StopCriterium;
using Properties; using Properties;
using Status;
/// <summary> /// <summary>
/// Defines an <see cref="IIterationStopCriterium"/> that monitors residuals as stop criterium. /// Defines an <see cref="IIterationStopCriterium{T}"/> that monitors residuals as stop criterium.
/// </summary> /// </summary>
public sealed class ResidualStopCriterium : IIterationStopCriterium public sealed class ResidualStopCriterium : IIterationStopCriterium<double>
{ {
/// <summary> /// <summary>
/// The default value for the maximum value of the residual. /// The default value for the maximum value of the residual.
@ -210,7 +212,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"/>. Result is set into <c>Status</c> field. /// by the current <see cref="IIterationStopCriterium{T}"/>. 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>
@ -221,7 +223,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 solutionVector, Vector sourceVector, Vector residualVector) public void DetermineStatus(int iterationNumber, Vector<double> solutionVector, Vector<double> sourceVector, Vector<double> residualVector)
{ {
if (iterationNumber < 0) if (iterationNumber < 0)
{ {
@ -361,7 +363,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium
} }
/// <summary> /// <summary>
/// Resets the <see cref="IIterationStopCriterium"/> to the pre-calculation state. /// Resets the <see cref="IIterationStopCriterium{T}"/> to the pre-calculation state.
/// </summary> /// </summary>
public void ResetToPrecalculationState() public void ResetToPrecalculationState()
{ {
@ -372,7 +374,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"/> monitors. /// <see cref="IIterationStopCriterium{T}"/> monitors.
/// </summary> /// </summary>
/// <value>Returns <see cref="StopLevel"/>.</value> /// <value>Returns <see cref="StopLevel"/>.</value>
public StopLevel StopLevel public StopLevel StopLevel
@ -388,7 +390,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 Clone() public IIterationStopCriterium<double> Clone()
{ {
return new ResidualStopCriterium(_maximum, _minimumIterationsBelowMaximum); return new ResidualStopCriterium(_maximum, _minimumIterationsBelowMaximum);
} }

267
src/Numerics/LinearAlgebra/Double/SparseMatrix.cs

@ -31,14 +31,16 @@
namespace MathNet.Numerics.LinearAlgebra.Double namespace MathNet.Numerics.LinearAlgebra.Double
{ {
using System; using System;
using System.Text;
using Distributions; using Distributions;
using Generic;
using Properties; using Properties;
using Threading; using Threading;
/// <summary> /// <summary>
/// A Matrix class with sparse storage. The underlying storage scheme is 3-array CSR Format. /// A Matrix class with sparse storage. The underlying storage scheme is 3-array CSR Format.
/// </summary> /// </summary>
public class SparseMatrix : Matrix public class SparseMatrix : Matrix<double>
{ {
/// <summary> /// <summary>
/// Object for use in "lock" /// Object for use in "lock"
@ -192,7 +194,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns> /// <returns>
/// A <c>SparseMatrix</c> with the given dimensions. /// A <c>SparseMatrix</c> with the given dimensions.
/// </returns> /// </returns>
public override Matrix CreateMatrix(int numberOfRows, int numberOfColumns) public override Matrix<double> CreateMatrix(int numberOfRows, int numberOfColumns)
{ {
return new SparseMatrix(numberOfRows, numberOfColumns); return new SparseMatrix(numberOfRows, numberOfColumns);
} }
@ -204,7 +206,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns> /// <returns>
/// A <see cref="SparseVector"/> with the given dimension. /// A <see cref="SparseVector"/> with the given dimension.
/// </returns> /// </returns>
public override Vector CreateVector(int size) public override Vector<double> CreateVector(int size)
{ {
return new SparseVector(size); return new SparseVector(size);
} }
@ -213,7 +215,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// Returns a new matrix containing the lower triangle of this matrix. /// Returns a new matrix containing the lower triangle of this matrix.
/// </summary> /// </summary>
/// <returns>The lower triangle of this matrix.</returns> /// <returns>The lower triangle of this matrix.</returns>
public override Matrix LowerTriangle() public override Matrix<double> LowerTriangle()
{ {
var result = CreateMatrix(RowCount, ColumnCount); var result = CreateMatrix(RowCount, ColumnCount);
LowerTriangleImpl(result); LowerTriangleImpl(result);
@ -226,7 +228,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="result">Where to store the lower triangle.</param> /// <param name="result">Where to store the lower triangle.</param>
/// <exception cref="ArgumentNullException">If <paramref name="result"/> is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If <paramref name="result"/> is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If the result matrix's dimensions are not the same as this matrix.</exception> /// <exception cref="ArgumentException">If the result matrix's dimensions are not the same as this matrix.</exception>
public override void LowerTriangle(Matrix result) public override void LowerTriangle(Matrix<double> result)
{ {
if (result == null) if (result == null)
{ {
@ -255,7 +257,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// Puts the lower triangle of this matrix into the result matrix. /// Puts the lower triangle of this matrix into the result matrix.
/// </summary> /// </summary>
/// <param name="result">Where to store the lower triangle.</param> /// <param name="result">Where to store the lower triangle.</param>
private void LowerTriangleImpl(Matrix result) private void LowerTriangleImpl(Matrix<double> result)
{ {
for (var row = 0; row < result.RowCount; row++) for (var row = 0; row < result.RowCount; row++)
{ {
@ -275,7 +277,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// Returns a new matrix containing the upper triangle of this matrix. /// Returns a new matrix containing the upper triangle of this matrix.
/// </summary> /// </summary>
/// <returns>The upper triangle of this matrix.</returns> /// <returns>The upper triangle of this matrix.</returns>
public override Matrix UpperTriangle() public override Matrix<double> UpperTriangle()
{ {
var result = CreateMatrix(RowCount, ColumnCount); var result = CreateMatrix(RowCount, ColumnCount);
UpperTriangleImpl(result); UpperTriangleImpl(result);
@ -288,7 +290,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="result">Where to store the lower triangle.</param> /// <param name="result">Where to store the lower triangle.</param>
/// <exception cref="ArgumentNullException">If <paramref name="result"/> is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If <paramref name="result"/> is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If the result matrix's dimensions are not the same as this matrix.</exception> /// <exception cref="ArgumentException">If the result matrix's dimensions are not the same as this matrix.</exception>
public override void UpperTriangle(Matrix result) public override void UpperTriangle(Matrix<double> result)
{ {
if (result == null) if (result == null)
{ {
@ -317,7 +319,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// Puts the upper triangle of this matrix into the result matrix. /// Puts the upper triangle of this matrix into the result matrix.
/// </summary> /// </summary>
/// <param name="result">Where to store the lower triangle.</param> /// <param name="result">Where to store the lower triangle.</param>
private void UpperTriangleImpl(Matrix result) private void UpperTriangleImpl(Matrix<double> result)
{ {
for (var row = 0; row < result.RowCount; row++) for (var row = 0; row < result.RowCount; row++)
{ {
@ -349,7 +351,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <item><c>(rowIndex + rowLength) &gt;= Rows</c></item></list></exception> /// <item><c>(rowIndex + rowLength) &gt;= Rows</c></item></list></exception>
/// <exception cref="ArgumentException">If <paramref name="rowLength"/> or <paramref name="columnLength"/> /// <exception cref="ArgumentException">If <paramref name="rowLength"/> or <paramref name="columnLength"/>
/// is not positive.</exception> /// is not positive.</exception>
public override Matrix SubMatrix(int rowIndex, int rowLength, int columnIndex, int columnLength) public override Matrix<double> SubMatrix(int rowIndex, int rowLength, int columnIndex, int columnLength)
{ {
if (rowIndex >= RowCount || rowIndex < 0) if (rowIndex >= RowCount || rowIndex < 0)
{ {
@ -410,7 +412,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// does not contain the diagonal elements of this matrix. /// does not contain the diagonal elements of this matrix.
/// </summary> /// </summary>
/// <returns>The lower triangle of this matrix.</returns> /// <returns>The lower triangle of this matrix.</returns>
public override Matrix StrictlyLowerTriangle() public override Matrix<double> StrictlyLowerTriangle()
{ {
var result = CreateMatrix(RowCount, ColumnCount); var result = CreateMatrix(RowCount, ColumnCount);
StrictlyLowerTriangleImpl(result); StrictlyLowerTriangleImpl(result);
@ -423,7 +425,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="result">Where to store the lower triangle.</param> /// <param name="result">Where to store the lower triangle.</param>
/// <exception cref="ArgumentNullException">If <paramref name="result"/> is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If <paramref name="result"/> is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If the result matrix's dimensions are not the same as this matrix.</exception> /// <exception cref="ArgumentException">If the result matrix's dimensions are not the same as this matrix.</exception>
public override void StrictlyLowerTriangle(Matrix result) public override void StrictlyLowerTriangle(Matrix<double> result)
{ {
if (result == null) if (result == null)
{ {
@ -452,7 +454,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// Puts the strictly lower triangle of this matrix into the result matrix. /// Puts the strictly lower triangle of this matrix into the result matrix.
/// </summary> /// </summary>
/// <param name="result">Where to store the lower triangle.</param> /// <param name="result">Where to store the lower triangle.</param>
private void StrictlyLowerTriangleImpl(Matrix result) private void StrictlyLowerTriangleImpl(Matrix<double> result)
{ {
for (var row = 0; row < result.RowCount; row++) for (var row = 0; row < result.RowCount; row++)
{ {
@ -473,7 +475,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// does not contain the diagonal elements of this matrix. /// does not contain the diagonal elements of this matrix.
/// </summary> /// </summary>
/// <returns>The upper triangle of this matrix.</returns> /// <returns>The upper triangle of this matrix.</returns>
public override Matrix StrictlyUpperTriangle() public override Matrix<double> StrictlyUpperTriangle()
{ {
var result = CreateMatrix(RowCount, ColumnCount); var result = CreateMatrix(RowCount, ColumnCount);
StrictlyUpperTriangleImpl(result); StrictlyUpperTriangleImpl(result);
@ -486,7 +488,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="result">Where to store the lower triangle.</param> /// <param name="result">Where to store the lower triangle.</param>
/// <exception cref="ArgumentNullException">If <paramref name="result"/> is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If <paramref name="result"/> is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If the result matrix's dimensions are not the same as this matrix.</exception> /// <exception cref="ArgumentException">If the result matrix's dimensions are not the same as this matrix.</exception>
public override void StrictlyUpperTriangle(Matrix result) public override void StrictlyUpperTriangle(Matrix<double> result)
{ {
if (result == null) if (result == null)
{ {
@ -515,7 +517,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// Puts the strictly upper triangle of this matrix into the result matrix. /// Puts the strictly upper triangle of this matrix into the result matrix.
/// </summary> /// </summary>
/// <param name="result">Where to store the lower triangle.</param> /// <param name="result">Where to store the lower triangle.</param>
private void StrictlyUpperTriangleImpl(Matrix result) private void StrictlyUpperTriangleImpl(Matrix<double> result)
{ {
for (var row = 0; row < result.RowCount; row++) for (var row = 0; row < result.RowCount; row++)
{ {
@ -762,7 +764,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentException"> /// <exception cref="ArgumentException">
/// If this and the target matrix do not have the same dimensions.. /// If this and the target matrix do not have the same dimensions..
/// </exception> /// </exception>
public override void CopyTo(Matrix target) public override void CopyTo(Matrix<double> target)
{ {
var sparseTarget = target as SparseMatrix; var sparseTarget = target as SparseMatrix;
@ -793,47 +795,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double
} }
} }
/// <summary>
/// Indicates whether the current object is equal to another object of the same type.
/// </summary>
/// <param name="obj">
/// An object to compare with this object.
/// </param>
/// <returns>
/// <c>true</c> if the current object is equal to the <paramref name="obj"/> parameter; otherwise, <c>false</c>.
/// </returns>
public override bool Equals(object obj)
{
var sparseMatrix = obj as SparseMatrix;
if (sparseMatrix == null)
{
return base.Equals(obj);
}
// Accept if the argument is the same object as this
if (ReferenceEquals(this, sparseMatrix))
{
return true;
}
if (ColumnCount != sparseMatrix.ColumnCount || RowCount != sparseMatrix.RowCount || NonZerosCount != sparseMatrix.NonZerosCount)
{
return false;
}
// If all else fails, perform element wise comparison.
for (var index = 0; index < NonZerosCount; index++)
{
if (!_nonZeroValues[index].AlmostEqual(sparseMatrix._nonZeroValues[index]) || _columnIndices[index] != sparseMatrix._columnIndices[index])
{
return false;
}
}
return true;
}
/// <summary> /// <summary>
/// Returns a hash code for this instance. /// Returns a hash code for this instance.
/// </summary> /// </summary>
@ -860,7 +821,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// Returns the transpose of this matrix. /// Returns the transpose of this matrix.
/// </summary> /// </summary>
/// <returns>The transpose of this matrix.</returns> /// <returns>The transpose of this matrix.</returns>
public override Matrix Transpose() public override Matrix<double> Transpose()
{ {
var ret = new SparseMatrix(ColumnCount, RowCount) var ret = new SparseMatrix(ColumnCount, RowCount)
{ {
@ -957,13 +918,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double
} }
/// <summary> /// <summary>
/// Copies the requested row elements into a new <see cref="Vector"/>. /// Copies the requested row elements into a new <see cref="Vector{T}"/>.
/// </summary> /// </summary>
/// <param name="rowIndex">The row to copy elements from.</param> /// <param name="rowIndex">The row to copy elements from.</param>
/// <param name="columnIndex">The column to start copying from.</param> /// <param name="columnIndex">The column to start copying from.</param>
/// <param name="length">The number of elements to copy.</param> /// <param name="length">The number of elements to copy.</param>
/// <param name="result">The <see cref="Vector"/> to copy the column into.</param> /// <param name="result">The <see cref="Vector{T}"/> to copy the column into.</param>
/// <exception cref="ArgumentNullException">If the result <see cref="Vector"/> is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the result <see cref="Vector{T}"/> is <see langword="null" />.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="rowIndex"/> is negative, /// <exception cref="ArgumentOutOfRangeException">If <paramref name="rowIndex"/> is negative,
/// or greater than or equal to the number of columns.</exception> /// or greater than or equal to the number of columns.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="columnIndex"/> is negative, /// <exception cref="ArgumentOutOfRangeException">If <paramref name="columnIndex"/> is negative,
@ -972,7 +933,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// is greater than or equal to the number of rows.</exception> /// is greater than or equal to the number of rows.</exception>
/// <exception cref="ArgumentException">If <paramref name="length"/> is not positive.</exception> /// <exception cref="ArgumentException">If <paramref name="length"/> is not positive.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <strong>result.Count &lt; length</strong>.</exception> /// <exception cref="ArgumentOutOfRangeException">If <strong>result.Count &lt; length</strong>.</exception>
public override void Row(int rowIndex, int columnIndex, int length, Vector result) public override void Row(int rowIndex, int columnIndex, int length, Vector<double> result)
{ {
if (result == null) if (result == null)
{ {
@ -1032,7 +993,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentNullException">If lower is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If lower is <see langword="null" />.</exception>
/// <exception cref="ArgumentNullException">If the result matrix is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the result matrix is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If the result matrix's dimensions are not (Rows + lower.rows) x (Columns + lower.Columns).</exception> /// <exception cref="ArgumentException">If the result matrix's dimensions are not (Rows + lower.rows) x (Columns + lower.Columns).</exception>
public override void DiagonalStack(Matrix lower, Matrix result) public override void DiagonalStack(Matrix<double> lower, Matrix<double> result)
{ {
var lowerSparseMatrix = lower as SparseMatrix; var lowerSparseMatrix = lower as SparseMatrix;
var resultSparseMatrix = result as SparseMatrix; var resultSparseMatrix = result as SparseMatrix;
@ -1079,7 +1040,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="other">The matrix to add to this matrix.</param> /// <param name="other">The matrix to add to this matrix.</param>
/// <exception cref="ArgumentNullException">If the other matrix is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the other matrix is <see langword="null" />.</exception>
/// <exception cref="ArgumentOutOfRangeException">If the two matrices don't have the same dimensions.</exception> /// <exception cref="ArgumentOutOfRangeException">If the two matrices don't have the same dimensions.</exception>
public override void Add(Matrix other) public override void Add(Matrix<double> other)
{ {
if (ReferenceEquals(this, other)) if (ReferenceEquals(this, other))
{ {
@ -1150,7 +1111,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="other">The matrix to subtract.</param> /// <param name="other">The matrix to subtract.</param>
/// <exception cref="ArgumentNullException">If the other matrix is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the other matrix is <see langword="null" />.</exception>
/// <exception cref="ArgumentOutOfRangeException">If the two matrices don't have the same dimensions.</exception> /// <exception cref="ArgumentOutOfRangeException">If the two matrices don't have the same dimensions.</exception>
public override void Subtract(Matrix other) public override void Subtract(Matrix<double> other)
{ {
// We are substracting Matrix form itself // We are substracting Matrix form itself
if (ReferenceEquals(this, other)) if (ReferenceEquals(this, other))
@ -1245,7 +1206,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentNullException">If the result matrix is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the result matrix is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If <strong>Columns != other.Rows</strong>.</exception> /// <exception cref="ArgumentException">If <strong>Columns != other.Rows</strong>.</exception>
/// <exception cref="ArgumentException">If the result matrix's dimensions are not the Rows x other.Columns.</exception> /// <exception cref="ArgumentException">If the result matrix's dimensions are not the Rows x other.Columns.</exception>
public override void Multiply(Matrix other, Matrix result) public override void Multiply(Matrix<double> other, Matrix<double> result)
{ {
var otherSparseMatrix = other as SparseMatrix; var otherSparseMatrix = other as SparseMatrix;
var resultSparseMatrix = result as SparseMatrix; var resultSparseMatrix = result as SparseMatrix;
@ -1297,7 +1258,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentException">If <strong>Columns != other.Rows</strong>.</exception> /// <exception cref="ArgumentException">If <strong>Columns != other.Rows</strong>.</exception>
/// <exception cref="ArgumentNullException">If the other matrix is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the other matrix is <see langword="null" />.</exception>
/// <returns>The result of multiplication.</returns> /// <returns>The result of multiplication.</returns>
public override Matrix Multiply(Matrix other) public override Matrix<double> Multiply(Matrix<double> other)
{ {
var matrix = other as SparseMatrix; var matrix = other as SparseMatrix;
if (matrix == null) if (matrix == null)
@ -1324,7 +1285,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentNullException">If the result matrix is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the result matrix is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If <strong>this.Columns != other.Rows</strong>.</exception> /// <exception cref="ArgumentException">If <strong>this.Columns != other.Rows</strong>.</exception>
/// <exception cref="ArgumentException">If the result matrix's dimensions are not the this.Rows x other.Columns.</exception> /// <exception cref="ArgumentException">If the result matrix's dimensions are not the this.Rows x other.Columns.</exception>
public override void TransposeAndMultiply(Matrix other, Matrix result) public override void TransposeAndMultiply(Matrix<double> other, Matrix<double> result)
{ {
var otherSparse = other as SparseMatrix; var otherSparse = other as SparseMatrix;
var resultSparse = result as SparseMatrix; var resultSparse = result as SparseMatrix;
@ -1389,7 +1350,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentException">If <strong>this.Columns != other.Rows</strong>.</exception> /// <exception cref="ArgumentException">If <strong>this.Columns != other.Rows</strong>.</exception>
/// <exception cref="ArgumentNullException">If the other matrix is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the other matrix is <see langword="null" />.</exception>
/// <returns>The result of multiplication.</returns> /// <returns>The result of multiplication.</returns>
public override Matrix TransposeAndMultiply(Matrix other) public override Matrix<double> TransposeAndMultiply(Matrix<double> other)
{ {
var otherSparse = other as SparseMatrix; var otherSparse = other as SparseMatrix;
if (otherSparse == null) if (otherSparse == null)
@ -1444,7 +1405,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentNullException">If the result matrix is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the result matrix is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If this matrix and <paramref name="other"/> are not the same size.</exception> /// <exception cref="ArgumentException">If this matrix and <paramref name="other"/> are not the same size.</exception>
/// <exception cref="ArgumentException">If this matrix and <paramref name="result"/> are not the same size.</exception> /// <exception cref="ArgumentException">If this matrix and <paramref name="result"/> are not the same size.</exception>
public override void PointwiseMultiply(Matrix other, Matrix result) public override void PointwiseMultiply(Matrix<double> other, Matrix<double> result)
{ {
if (other == null) if (other == null)
{ {
@ -1495,7 +1456,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// </returns> /// </returns>
/// <exception cref="ArgumentException">If the parameter <paramref name="numberOfRows"/> is not positive.</exception> /// <exception cref="ArgumentException">If the parameter <paramref name="numberOfRows"/> is not positive.</exception>
/// <exception cref="ArgumentException">If the parameter <paramref name="numberOfColumns"/> is not positive.</exception> /// <exception cref="ArgumentException">If the parameter <paramref name="numberOfColumns"/> is not positive.</exception>
public override Matrix Random(int numberOfRows, int numberOfColumns, IContinuousDistribution distribution) public override Matrix<double> Random(int numberOfRows, int numberOfColumns, IContinuousDistribution distribution)
{ {
if (numberOfRows < 1) if (numberOfRows < 1)
{ {
@ -1534,7 +1495,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// </returns> /// </returns>
/// <exception cref="ArgumentException">If the parameter <paramref name="numberOfRows"/> is not positive.</exception> /// <exception cref="ArgumentException">If the parameter <paramref name="numberOfRows"/> is not positive.</exception>
/// <exception cref="ArgumentException">If the parameter <paramref name="numberOfColumns"/> is not positive.</exception> /// <exception cref="ArgumentException">If the parameter <paramref name="numberOfColumns"/> is not positive.</exception>
public override Matrix Random(int numberOfRows, int numberOfColumns, IDiscreteDistribution distribution) public override Matrix<double> Random(int numberOfRows, int numberOfColumns, IDiscreteDistribution distribution)
{ {
if (numberOfRows < 1) if (numberOfRows < 1)
{ {
@ -1592,5 +1553,165 @@ namespace MathNet.Numerics.LinearAlgebra.Double
return m; return m;
} }
#endregion #endregion
/// <summary>
/// Negates each element of this matrix.
/// </summary>
public override void Negate()
{
Multiply(-1);
}
/// <summary>
/// Indicates whether the current object is equal to another object of the same type.
/// </summary>
/// <param name="other">
/// An object to compare with this object.
/// </param>
/// <returns>
/// <c>true</c> if the current object is equal to the <paramref name="other"/> parameter; otherwise, <c>false</c>.
/// </returns>
public override bool Equals(Matrix<double> other)
{
if (other == null)
{
return false;
}
if (ColumnCount != other.ColumnCount || RowCount != other.RowCount)
{
return false;
}
// Accept if the argument is the same object as this.
if (ReferenceEquals(this, other))
{
return true;
}
var sparseMatrix = other as SparseMatrix;
if (sparseMatrix == null)
{
return base.Equals(other);
}
if (NonZerosCount != sparseMatrix.NonZerosCount)
{
return false;
}
// If all else fails, perform element wise comparison.
for (var index = 0; index < NonZerosCount; index++)
{
if (!_nonZeroValues[index].AlmostEqual(sparseMatrix._nonZeroValues[index]) || _columnIndices[index] != sparseMatrix._columnIndices[index])
{
return false;
}
}
return true;
}
/// <summary>
/// Returns a <see cref="System.String"/> that represents this instance.
/// </summary>
/// <param name="format">
/// The format to use.
/// </param>
/// <param name="formatProvider">
/// The format provider to use.
/// </param>
/// <returns>
/// A <see cref="System.String"/> that represents this instance.
/// </returns>
public override string ToString(string format, IFormatProvider formatProvider)
{
var stringBuilder = new StringBuilder();
for (var row = 0; row < RowCount; row++)
{
for (var column = 0; column < ColumnCount; column++)
{
stringBuilder.Append(At(row, column).ToString(format, formatProvider));
if (column != ColumnCount - 1)
{
stringBuilder.Append(formatProvider.GetTextInfo().ListSeparator);
}
}
if (row != RowCount - 1)
{
stringBuilder.Append(Environment.NewLine);
}
}
return stringBuilder.ToString();
}
#region Simple arithmetic of type T
/// <summary>
/// Add two values T+T
/// </summary>
/// <param name="val1">Left operand value</param>
/// <param name="val2">Right operand value</param>
/// <returns>Result of addition</returns>
protected sealed override double AddT(double val1, double val2)
{
return val1 + val2;
}
/// <summary>
/// Subtract two values T-T
/// </summary>
/// <param name="val1">Left operand value</param>
/// <param name="val2">Right operand value</param>
/// <returns>Result of subtract</returns>
protected sealed override double SubtractT(double val1, double val2)
{
return val1 - val2;
}
/// <summary>
/// Multiply two values T*T
/// </summary>
/// <param name="val1">Left operand value</param>
/// <param name="val2">Right operand value</param>
/// <returns>Result of multiplication</returns>
protected sealed override double MultiplyT(double val1, double val2)
{
return val1 * val2;
}
/// <summary>
/// Divide two values T/T
/// </summary>
/// <param name="val1">Left operand value</param>
/// <param name="val2">Right operand value</param>
/// <returns>Result of divide</returns>
protected sealed override double DivideT(double val1, double val2)
{
return val1 / val2;
}
/// <summary>
/// Is equal to one?
/// </summary>
/// <param name="val1">Value to check</param>
/// <returns>True if one; otherwise false</returns>
protected sealed override bool IsOneT(double val1)
{
return 1.0.AlmostEqualInDecimalPlaces(val1, 15);
}
/// <summary>
/// Take absolute value
/// </summary>
/// <param name="val1">Source alue</param>
/// <returns>True if one; otherwise false</returns>
protected sealed override double AbsoluteT(double val1)
{
return Math.Abs(val1);
}
#endregion
} }
} }

213
src/Numerics/LinearAlgebra/Double/SparseVector.cs

@ -30,6 +30,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using Distributions; using Distributions;
using Generic;
using NumberTheory; using NumberTheory;
using Properties; using Properties;
using Threading; using Threading;
@ -37,7 +38,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <summary> /// <summary>
/// A vector with sparse storage. /// A vector with sparse storage.
/// </summary> /// </summary>
public class SparseVector : Vector public class SparseVector : Vector<double>
{ {
/// <summary> /// <summary>
/// Lock object for the indexer. /// Lock object for the indexer.
@ -122,7 +123,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="other"> /// <param name="other">
/// The vector to create the new vector from. /// The vector to create the new vector from.
/// </param> /// </param>
public SparseVector(Vector other) : this(other.Count) public SparseVector(Vector<double> other) : this(other.Count)
{ {
var vector = other as SparseVector; var vector = other as SparseVector;
if (vector == null) if (vector == null)
@ -181,7 +182,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// Create a matrix based on this vector in column form (one single column). /// Create a matrix based on this vector in column form (one single column).
/// </summary> /// </summary>
/// <returns>This vector as a column matrix.</returns> /// <returns>This vector as a column matrix.</returns>
public override Matrix ToColumnMatrix() public override Matrix<double> ToColumnMatrix()
{ {
var matrix = new SparseMatrix(Count, 1); var matrix = new SparseMatrix(Count, 1);
for (var i = 0; i < NonZerosCount; i++) for (var i = 0; i < NonZerosCount; i++)
@ -196,7 +197,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// Create a matrix based on this vector in row form (one single row). /// Create a matrix based on this vector in row form (one single row).
/// </summary> /// </summary>
/// <returns>This vector as a row matrix.</returns> /// <returns>This vector as a row matrix.</returns>
public override Matrix ToRowMatrix() public override Matrix<double> ToRowMatrix()
{ {
var matrix = new SparseMatrix(1, Count); var matrix = new SparseMatrix(1, Count);
for (var i = 0; i < NonZerosCount; i++) for (var i = 0; i < NonZerosCount; i++)
@ -263,7 +264,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns> /// <returns>
/// A matrix with the given dimensions. /// A matrix with the given dimensions.
/// </returns> /// </returns>
public override Matrix CreateMatrix(int rows, int columns) public override Matrix<double> CreateMatrix(int rows, int columns)
{ {
return new SparseMatrix(rows, columns); return new SparseMatrix(rows, columns);
} }
@ -278,7 +279,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns> /// <returns>
/// The new <c>Vector</c>. /// The new <c>Vector</c>.
/// </returns> /// </returns>
public override Vector CreateVector(int size) public override Vector<double> CreateVector(int size)
{ {
return new SparseVector(size); return new SparseVector(size);
} }
@ -303,7 +304,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentException"> /// <exception cref="ArgumentException">
/// If <paramref name="target"/> is not the same size as this vector. /// If <paramref name="target"/> is not the same size as this vector.
/// </exception> /// </exception>
public override void CopyTo(Vector target) public override void CopyTo(Vector<double> target)
{ {
if (target == null) if (target == null)
{ {
@ -347,7 +348,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// </summary> /// </summary>
/// <param name="scalar">The scalar to add.</param> /// <param name="scalar">The scalar to add.</param>
/// <returns>A copy of the vector with the scalar added.</returns> /// <returns>A copy of the vector with the scalar added.</returns>
public override Vector Add(double scalar) public override Vector<double> Add(double scalar)
{ {
if (scalar == 0.0) if (scalar == 0.0)
{ {
@ -370,7 +371,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="result">The vector to store the result of the addition.</param> /// <param name="result">The vector to store the result of the addition.</param>
/// <exception cref="ArgumentNullException">If the result vector is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the result vector is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If this vector and <paramref name="result"/> are not the same size.</exception> /// <exception cref="ArgumentException">If this vector and <paramref name="result"/> are not the same size.</exception>
public override void Add(double scalar, Vector result) public override void Add(double scalar, Vector<double> result)
{ {
if (result == null) if (result == null)
{ {
@ -392,7 +393,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>A new vector containing the sum of both vectors.</returns> /// <returns>A new vector containing the sum of both vectors.</returns>
/// <exception cref="ArgumentNullException">If the other vector is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the other vector is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If this vector and <paramref name="other"/> are not the same size.</exception> /// <exception cref="ArgumentException">If this vector and <paramref name="other"/> are not the same size.</exception>
public override Vector Add(Vector other) public override Vector<double> Add(Vector<double> other)
{ {
if (other == null) if (other == null)
{ {
@ -494,7 +495,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentNullException">If the result vector is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the result vector is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If this vector and <paramref name="other"/> are not the same size.</exception> /// <exception cref="ArgumentException">If this vector and <paramref name="other"/> are not the same size.</exception>
/// <exception cref="ArgumentException">If this vector and <paramref name="result"/> are not the same size.</exception> /// <exception cref="ArgumentException">If this vector and <paramref name="result"/> are not the same size.</exception>
public override void Add(Vector other, Vector result) public override void Add(Vector<double> other, Vector<double> result)
{ {
if (result == null) if (result == null)
{ {
@ -545,7 +546,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="rightSide">The vector to get the values from.</param> /// <param name="rightSide">The vector to get the values from.</param>
/// <returns>A vector containing a the same values as <paramref name="rightSide"/>.</returns> /// <returns>A vector containing a the same values as <paramref name="rightSide"/>.</returns>
/// <exception cref="ArgumentNullException">If <paramref name="rightSide"/> is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If <paramref name="rightSide"/> is <see langword="null" />.</exception>
public static Vector operator +(SparseVector rightSide) public static Vector<double> operator +(SparseVector rightSide)
{ {
if (rightSide == null) if (rightSide == null)
{ {
@ -563,7 +564,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>The result of the addition.</returns> /// <returns>The result of the addition.</returns>
/// <exception cref="ArgumentException">If <paramref name="leftSide"/> and <paramref name="rightSide"/> are not the same size.</exception> /// <exception cref="ArgumentException">If <paramref name="leftSide"/> and <paramref name="rightSide"/> are not the same size.</exception>
/// <exception cref="ArgumentNullException">If <paramref name="leftSide"/> or <paramref name="rightSide"/> is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If <paramref name="leftSide"/> or <paramref name="rightSide"/> is <see langword="null" />.</exception>
public static Vector operator +(SparseVector leftSide, SparseVector rightSide) public static Vector<double> operator +(SparseVector leftSide, SparseVector rightSide)
{ {
if (rightSide == null) if (rightSide == null)
{ {
@ -588,7 +589,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// </summary> /// </summary>
/// <param name="scalar">The scalar to subtract.</param> /// <param name="scalar">The scalar to subtract.</param>
/// <returns>A new vector containing the subtraction of this vector and the scalar.</returns> /// <returns>A new vector containing the subtraction of this vector and the scalar.</returns>
public override Vector Subtract(double scalar) public override Vector<double> Subtract(double scalar)
{ {
if (scalar == 0.0) if (scalar == 0.0)
{ {
@ -611,7 +612,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="result">The vector to store the result of the subtraction.</param> /// <param name="result">The vector to store the result of the subtraction.</param>
/// <exception cref="ArgumentNullException">If the result vector is <see langword="null"/>.</exception> /// <exception cref="ArgumentNullException">If the result vector is <see langword="null"/>.</exception>
/// <exception cref="ArgumentException">If this vector and <paramref name="result"/> are not the same size.</exception> /// <exception cref="ArgumentException">If this vector and <paramref name="result"/> are not the same size.</exception>
public override void Subtract(double scalar, Vector result) public override void Subtract(double scalar, Vector<double> result)
{ {
if (result == null) if (result == null)
{ {
@ -633,7 +634,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>A new vector containing the subtraction of the the two vectors.</returns> /// <returns>A new vector containing the subtraction of the the two vectors.</returns>
/// <exception cref="ArgumentNullException">If the other vector is <see langword="null"/>.</exception> /// <exception cref="ArgumentNullException">If the other vector is <see langword="null"/>.</exception>
/// <exception cref="ArgumentException">If this vector and <paramref name="other"/> are not the same size.</exception> /// <exception cref="ArgumentException">If this vector and <paramref name="other"/> are not the same size.</exception>
public override Vector Subtract(Vector other) public override Vector<double> Subtract(Vector<double> other)
{ {
if (other == null) if (other == null)
{ {
@ -666,7 +667,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentNullException">If the result vector is <see langword="null"/>.</exception> /// <exception cref="ArgumentNullException">If the result vector is <see langword="null"/>.</exception>
/// <exception cref="ArgumentException">If this vector and <paramref name="other"/> are not the same size.</exception> /// <exception cref="ArgumentException">If this vector and <paramref name="other"/> are not the same size.</exception>
/// <exception cref="ArgumentException">If this vector and <paramref name="result"/> are not the same size.</exception> /// <exception cref="ArgumentException">If this vector and <paramref name="result"/> are not the same size.</exception>
public override void Subtract(Vector other, Vector result) public override void Subtract(Vector<double> other, Vector<double> result)
{ {
if (result == null) if (result == null)
{ {
@ -716,7 +717,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="rightSide">The vector to get the values from.</param> /// <param name="rightSide">The vector to get the values from.</param>
/// <returns>A vector containing the negated values as <paramref name="rightSide"/>.</returns> /// <returns>A vector containing the negated values as <paramref name="rightSide"/>.</returns>
/// <exception cref="ArgumentNullException">If <paramref name="rightSide"/> is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If <paramref name="rightSide"/> is <see langword="null" />.</exception>
public static Vector operator -(SparseVector rightSide) public static Vector<double> operator -(SparseVector rightSide)
{ {
if (rightSide == null) if (rightSide == null)
{ {
@ -734,7 +735,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>The result of the subtraction.</returns> /// <returns>The result of the subtraction.</returns>
/// <exception cref="ArgumentException">If <paramref name="leftSide"/> and <paramref name="rightSide"/> are not the same size.</exception> /// <exception cref="ArgumentException">If <paramref name="leftSide"/> and <paramref name="rightSide"/> are not the same size.</exception>
/// <exception cref="ArgumentNullException">If <paramref name="leftSide"/> or <paramref name="rightSide"/> is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If <paramref name="leftSide"/> or <paramref name="rightSide"/> is <see langword="null" />.</exception>
public static Vector operator -(SparseVector leftSide, SparseVector rightSide) public static Vector<double> operator -(SparseVector leftSide, SparseVector rightSide)
{ {
if (rightSide == null) if (rightSide == null)
{ {
@ -759,7 +760,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// </summary> /// </summary>
/// <returns>The negated vector.</returns> /// <returns>The negated vector.</returns>
/// <remarks>Added as an alternative to the unary negation operator.</remarks> /// <remarks>Added as an alternative to the unary negation operator.</remarks>
public override Vector Negate() public override Vector<double> Negate()
{ {
var result = new SparseVector(Count) var result = new SparseVector(Count)
{ {
@ -785,7 +786,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// </summary> /// </summary>
/// <param name="scalar">The scalar to multiply.</param> /// <param name="scalar">The scalar to multiply.</param>
/// <returns>A new vector that is the multiplication of the vector and the scalar.</returns> /// <returns>A new vector that is the multiplication of the vector and the scalar.</returns>
public override Vector Multiply(double scalar) public override Vector<double> Multiply(double scalar)
{ {
if (scalar == 1.0) if (scalar == 1.0)
{ {
@ -813,7 +814,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>The result of the addition.</returns> /// <returns>The result of the addition.</returns>
/// <exception cref="ArgumentException">If <paramref name="other"/> is not of the same size.</exception> /// <exception cref="ArgumentException">If <paramref name="other"/> is not of the same size.</exception>
/// <exception cref="ArgumentNullException">If <paramref name="other"/> is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If <paramref name="other"/> is <see langword="null" />.</exception>
public override double DotProduct(Vector other) public override double DotProduct(Vector<double> other)
{ {
if (other == null) if (other == null)
{ {
@ -953,7 +954,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <item>If <paramref name="index"/> + <paramref name="length"/> is greater than or equal to the size of the vector.</item> /// <item>If <paramref name="index"/> + <paramref name="length"/> is greater than or equal to the size of the vector.</item>
/// </list></exception> /// </list></exception>
/// <exception cref="ArgumentException">If <paramref name="length"/> is not positive.</exception> /// <exception cref="ArgumentException">If <paramref name="length"/> is not positive.</exception>
public override Vector SubVector(int index, int length) public override Vector<double> SubVector(int index, int length)
{ {
if (index < 0 || index >= Count) if (index < 0 || index >= Count)
{ {
@ -1090,7 +1091,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>A new vector which is the pointwise multiplication of the two vectors.</returns> /// <returns>A new vector which is the pointwise multiplication of the two vectors.</returns>
/// <exception cref="ArgumentNullException">If the other vector is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the other vector is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If this vector and <paramref name="other"/> are not the same size.</exception> /// <exception cref="ArgumentException">If this vector and <paramref name="other"/> are not the same size.</exception>
public override Vector PointwiseMultiply(Vector other) public override Vector<double> PointwiseMultiply(Vector<double> other)
{ {
if (other == null) if (other == null)
{ {
@ -1123,7 +1124,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>Matrix M[i,j] = u[i]*v[j] </returns> /// <returns>Matrix M[i,j] = u[i]*v[j] </returns>
/// <exception cref="ArgumentNullException">If the u vector is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the u vector is <see langword="null" />.</exception>
/// <exception cref="ArgumentNullException">If the v vector is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the v vector is <see langword="null" />.</exception>
public static Matrix /*SparseMatrix*/ OuterProduct(SparseVector u, SparseVector v) public static Matrix<double> /*SparseMatrix*/ OuterProduct(SparseVector u, SparseVector v)
{ {
if (u == null) if (u == null)
{ {
@ -1160,7 +1161,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// to the specified random distribution. /// to the specified random distribution.
/// </returns> /// </returns>
/// <exception cref="ArgumentNullException">If the length vector is non positive<see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the length vector is non positive<see langword="null" />.</exception>
public override Vector Random(int length, IContinuousDistribution randomDistribution) public override Vector<double> Random(int length, IContinuousDistribution randomDistribution)
{ {
if (length < 1) if (length < 1)
{ {
@ -1186,7 +1187,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// to the specified random distribution. /// to the specified random distribution.
/// </returns> /// </returns>
/// <exception cref="ArgumentNullException">If the n vector is non positive<see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the n vector is non positive<see langword="null" />.</exception>
public override Vector Random(int length, IDiscreteDistribution randomDistribution) public override Vector<double> Random(int length, IDiscreteDistribution randomDistribution)
{ {
if (length < 1) if (length < 1)
{ {
@ -1210,7 +1211,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// Matrix M[i,j] = this[i] * v[j]. /// Matrix M[i,j] = this[i] * v[j].
/// </returns> /// </returns>
/// <seealso cref="OuterProduct"/> /// <seealso cref="OuterProduct"/>
public Matrix TensorMultiply(SparseVector v) public Matrix<double> TensorMultiply(SparseVector v)
{ {
return OuterProduct(this, v); return OuterProduct(this, v);
} }
@ -1249,6 +1250,33 @@ namespace MathNet.Numerics.LinearAlgebra.Double
return Math.Pow(sum, 1.0 / p); return Math.Pow(sum, 1.0 / p);
} }
/// <summary>
/// Normalizes this vector to a unit vector with respect to the p-norm.
/// </summary>
/// <param name="p">
/// The p value.
/// </param>
/// <returns>
/// This vector normalized to a unit vector with respect to the p-norm.
/// </returns>
public override Vector<double> Normalize(double p)
{
if (p < 0.0)
{
throw new ArgumentOutOfRangeException("p");
}
var norm = Norm(p);
var clone = Clone();
if (norm == 0.0)
{
return clone;
}
clone.Multiply(1.0 / norm, clone);
return clone;
}
#endregion #endregion
#region Parse Functions #region Parse Functions
@ -1515,28 +1543,65 @@ namespace MathNet.Numerics.LinearAlgebra.Double
#region System.Object override #region System.Object override
/// <summary> /// <summary>
/// Check equality. If this is regular vector, then check by base implementation. If Sparse - use own method. /// Returns a hash code for this instance.
/// </summary> /// </summary>
/// <param name="obj">Object to compare</param>
/// <returns> /// <returns>
/// <c>true</c> if the specified <see cref="System.Object"/> is equal to this instance; otherwise, <c>false</c>. /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.
/// </returns> /// </returns>
public override bool Equals(object obj) public override int GetHashCode()
{ {
var sparseVector = obj as SparseVector; var hashNum = Math.Min(NonZerosCount, 20);
long hash = 0;
for (var i = 0; i < hashNum; i++)
{
#if SILVERLIGHT
hash ^= Precision.DoubleToInt64Bits(this._nonZeroValues[i].GetHashCode());
#else
hash ^= BitConverter.DoubleToInt64Bits(_nonZeroValues[i].GetHashCode());
#endif
}
if (sparseVector == null) return BitConverter.ToInt32(BitConverter.GetBytes(hash), 4);
}
#endregion
/// <summary>
/// Indicates whether the current object is equal to another object of the same type.
/// </summary>
/// <param name="other">
/// An object to compare with this object.
/// </param>
/// <returns>
/// <c>true</c> if the current object is equal to the <paramref name="other"/> parameter; otherwise, <c>false</c>.
/// </returns>
public override bool Equals(Vector<double> other)
{
// Reject equality when the argument is null or has a different length.
if (other == null)
{
return false;
}
if (Count != other.Count)
{ {
return base.Equals(obj); return false;
} }
// Accept if the argument is the same object as this. // Accept if the argument is the same object as this.
if (ReferenceEquals(this, sparseVector)) if (ReferenceEquals(this, other))
{ {
return true; return true;
} }
if ((Count != sparseVector.Count) || (NonZerosCount != sparseVector.NonZerosCount)) var sparseVector = other as SparseVector;
if (sparseVector == null)
{
return base.Equals(other);
}
if (NonZerosCount != sparseVector.NonZerosCount)
{ {
return false; return false;
} }
@ -1553,28 +1618,70 @@ namespace MathNet.Numerics.LinearAlgebra.Double
return true; return true;
} }
#region Simple arithmetic of type T
/// <summary> /// <summary>
/// Returns a hash code for this instance. /// Add two values T+T
/// </summary> /// </summary>
/// <returns> /// <param name="val1">Left operand value</param>
/// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. /// <param name="val2">Right operand value</param>
/// </returns> /// <returns>Result of addition</returns>
public override int GetHashCode() protected sealed override double AddT(double val1, double val2)
{ {
var hashNum = Math.Min(NonZerosCount, 20); return val1 + val2;
long hash = 0; }
for (var i = 0; i < hashNum; i++)
{
#if SILVERLIGHT
hash ^= Precision.DoubleToInt64Bits(this._nonZeroValues[i]);
#else
hash ^= BitConverter.DoubleToInt64Bits(_nonZeroValues[i]);
#endif
}
return BitConverter.ToInt32(BitConverter.GetBytes(hash), 4); /// <summary>
/// Subtract two values T-T
/// </summary>
/// <param name="val1">Left operand value</param>
/// <param name="val2">Right operand value</param>
/// <returns>Result of subtract</returns>
protected sealed override double SubtractT(double val1, double val2)
{
return val1 - val2;
}
/// <summary>
/// Multiply two values T*T
/// </summary>
/// <param name="val1">Left operand value</param>
/// <param name="val2">Right operand value</param>
/// <returns>Result of multiplication</returns>
protected sealed override double MultiplyT(double val1, double val2)
{
return val1 * val2;
}
/// <summary>
/// Divide two values T/T
/// </summary>
/// <param name="val1">Left operand value</param>
/// <param name="val2">Right operand value</param>
/// <returns>Result of divide</returns>
protected sealed override double DivideT(double val1, double val2)
{
return val1 / val2;
} }
/// <summary>
/// Is equal to one?
/// </summary>
/// <param name="val1">Value to check</param>
/// <returns>True if one; otherwise false</returns>
protected sealed override bool IsOneT(double val1)
{
return val1 == 1.0;
}
/// <summary>
/// Take absolute value
/// </summary>
/// <param name="val1">Source alue</param>
/// <returns>True if one; otherwise false</returns>
protected sealed override double AbsoluteT(double val1)
{
return Math.Abs(val1);
}
#endregion #endregion
} }
} }

82
src/Numerics/LinearAlgebra/Double/Factorization/Cholesky.cs → src/Numerics/LinearAlgebra/Generic/Factorization/Cholesky.cs

@ -28,9 +28,11 @@
// OTHER DEALINGS IN THE SOFTWARE. // OTHER DEALINGS IN THE SOFTWARE.
// </copyright> // </copyright>
namespace MathNet.Numerics.LinearAlgebra.Double.Factorization namespace MathNet.Numerics.LinearAlgebra.Generic.Factorization
{ {
using System; using System;
using System.Numerics;
using Generic;
/// <summary> /// <summary>
/// <para>A class which encapsulates the functionality of a Cholesky factorization.</para> /// <para>A class which encapsulates the functionality of a Cholesky factorization.</para>
@ -41,28 +43,35 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// The computation of the Cholesky factorization is done at construction time. If the matrix is not symmetric /// The computation of the Cholesky factorization is done at construction time. If the matrix is not symmetric
/// or positive definite, the constructor will throw an exception. /// or positive definite, the constructor will throw an exception.
/// </remarks> /// </remarks>
public abstract class Cholesky : ISolver /// <typeparam name="T">Supported data types are double, single, <see cref="Complex"/>, and <see cref="Complex32"/>.</typeparam>
public abstract class Cholesky<T> : ISolver<T>
where T : struct, IEquatable<T>, IFormattable
{ {
/// <summary> /// <summary>
/// Internal method which routes the call to perform the Cholesky factorization to the appropriate class. /// Internal method which routes the call to perform the Cholesky factorization to the appropriate class.
/// </summary> /// </summary>
/// <param name="matrix">The matrix to factor.</param> /// <param name="matrix">The matrix to factor.</param>
/// <returns>A cholesky factorization object.</returns> /// <returns>A cholesky factorization object.</returns>
internal static Cholesky Create(Matrix matrix) internal static Cholesky<T> Create(Matrix<T> matrix)
{ {
var dense = matrix as DenseMatrix; if (typeof(T) == typeof(double))
if (dense != null)
{ {
return new DenseCholesky(dense); var dense = matrix as LinearAlgebra.Double.DenseMatrix;
if (dense != null)
{
return new LinearAlgebra.Double.Factorization.DenseCholesky(dense) as Cholesky<T>;
}
return new LinearAlgebra.Double.Factorization.UserCholesky(matrix as Matrix<double>) as Cholesky<T>;
} }
return new UserCholesky(matrix); throw new NotImplementedException();
} }
/// <summary> /// <summary>
/// Gets or sets the lower triangular form of the Cholesky matrix /// Gets or sets the lower triangular form of the Cholesky matrix
/// </summary> /// </summary>
protected Matrix CholeskyFactor protected Matrix<T> CholeskyFactor
{ {
get; get;
set; set;
@ -71,7 +80,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <summary> /// <summary>
/// Gets the lower triangular form of the Cholesky matrix. /// Gets the lower triangular form of the Cholesky matrix.
/// </summary> /// </summary>
public virtual Matrix Factor public virtual Matrix<T> Factor
{ {
get get
{ {
@ -82,14 +91,14 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <summary> /// <summary>
/// Gets the determinant of the matrix for which the Cholesky matrix was computed. /// Gets the determinant of the matrix for which the Cholesky matrix was computed.
/// </summary> /// </summary>
public virtual double Determinant public virtual T Determinant
{ {
get get
{ {
var det = 1.0; var det = OneValueT;
for (var j = 0; j < CholeskyFactor.RowCount; j++) for (var j = 0; j < CholeskyFactor.RowCount; j++)
{ {
det *= CholeskyFactor[j, j] * CholeskyFactor[j, j]; det = MultiplyT(det, MultiplyT(CholeskyFactor[j, j], CholeskyFactor[j, j]));
} }
return det; return det;
@ -106,7 +115,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
var det = 0.0; var det = 0.0;
for (var j = 0; j < CholeskyFactor.RowCount; j++) for (var j = 0; j < CholeskyFactor.RowCount; j++)
{ {
det += 2.0 * Math.Log(CholeskyFactor[j, j]); det += 2.0 * LogT(CholeskyFactor[j, j]);
} }
return det; return det;
@ -116,9 +125,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <summary> /// <summary>
/// Solves a system of linear equations, <b>AX = B</b>, with A Cholesky factorized. /// Solves a system of linear equations, <b>AX = B</b>, with A Cholesky factorized.
/// </summary> /// </summary>
/// <param name="input">The right hand side <see cref="Matrix"/>, <b>B</b>.</param> /// <param name="input">The right hand side <see cref="Matrix{T}"/>, <b>B</b>.</param>
/// <returns>The left hand side <see cref="Matrix"/>, <b>X</b>.</returns> /// <returns>The left hand side <see cref="Matrix{T}"/>, <b>X</b>.</returns>
public virtual Matrix Solve(Matrix input) public virtual Matrix<T> Solve(Matrix<T> input)
{ {
// Check for proper arguments. // Check for proper arguments.
if (input == null) if (input == null)
@ -134,16 +143,16 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <summary> /// <summary>
/// Solves a system of linear equations, <b>AX = B</b>, with A Cholesky factorized. /// Solves a system of linear equations, <b>AX = B</b>, with A Cholesky factorized.
/// </summary> /// </summary>
/// <param name="input">The right hand side <see cref="Matrix"/>, <b>B</b>.</param> /// <param name="input">The right hand side <see cref="Matrix{T}"/>, <b>B</b>.</param>
/// <param name="result">The left hand side <see cref="Matrix"/>, <b>X</b>.</param> /// <param name="result">The left hand side <see cref="Matrix{T}"/>, <b>X</b>.</param>
public abstract void Solve(Matrix input, Matrix result); public abstract void Solve(Matrix<T> input, Matrix<T> result);
/// <summary> /// <summary>
/// Solves a system of linear equations, <b>Ax = b</b>, with A Cholesky factorized. /// Solves a system of linear equations, <b>Ax = b</b>, with A Cholesky factorized.
/// </summary> /// </summary>
/// <param name="input">The right hand side vector, <b>b</b>.</param> /// <param name="input">The right hand side vector, <b>b</b>.</param>
/// <returns>The left hand side <see cref="Vector"/>, <b>x</b>.</returns> /// <returns>The left hand side <see cref="Vector{T}"/>, <b>x</b>.</returns>
public virtual Vector Solve(Vector input) public virtual Vector<T> Solve(Vector<T> input)
{ {
// Check for proper arguments. // Check for proper arguments.
if (input == null) if (input == null)
@ -160,7 +169,34 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// Solves a system of linear equations, <b>Ax = b</b>, with A Cholesky factorized. /// Solves a system of linear equations, <b>Ax = b</b>, with A Cholesky factorized.
/// </summary> /// </summary>
/// <param name="input">The right hand side vector, <b>b</b>.</param> /// <param name="input">The right hand side vector, <b>b</b>.</param>
/// <param name="result">The left hand side <see cref="Matrix"/>, <b>x</b>.</param> /// <param name="result">The left hand side <see cref="Matrix{T}"/>, <b>x</b>.</param>
public abstract void Solve(Vector input, Vector result); public abstract void Solve(Vector<T> input, Vector<T> result);
#region Simple arithmetic of type T
/// <summary>
/// Multiply two values T*T
/// </summary>
/// <param name="val1">Left operand value</param>
/// <param name="val2">Right operand value</param>
/// <returns>Result of multiplication</returns>
protected abstract T MultiplyT(T val1, T val2);
/// <summary>
/// Returns the natural (base e) logarithm of a specified number.
/// </summary>
/// <param name="val1"> A number whose logarithm is to be found</param>
/// <returns>Natural (base e) logarithm </returns>
protected abstract double LogT(T val1);
/// <summary>
/// Gets value of type T equal to one
/// </summary>
/// <returns>One value</returns>
protected abstract T OneValueT
{
get;
}
#endregion
} }
} }

91
src/Numerics/LinearAlgebra/Double/Factorization/LU.cs → src/Numerics/LinearAlgebra/Generic/Factorization/LU.cs

@ -24,9 +24,11 @@
// OTHER DEALINGS IN THE SOFTWARE. // OTHER DEALINGS IN THE SOFTWARE.
// </copyright> // </copyright>
namespace MathNet.Numerics.LinearAlgebra.Double.Factorization namespace MathNet.Numerics.LinearAlgebra.Generic.Factorization
{ {
using System; using System;
using System.Numerics;
using Generic;
/// <summary> /// <summary>
/// <para>A class which encapsulates the functionality of an LU factorization.</para> /// <para>A class which encapsulates the functionality of an LU factorization.</para>
@ -38,12 +40,14 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <remarks> /// <remarks>
/// The computation of the LU factorization is done at construction time. /// The computation of the LU factorization is done at construction time.
/// </remarks> /// </remarks>
public abstract class LU : ISolver /// <typeparam name="T">Supported data types are double, single, <see cref="Complex"/>, and <see cref="Complex32"/>.</typeparam>
public abstract class LU<T> : ISolver<T>
where T : struct, IEquatable<T>, IFormattable
{ {
/// <summary> /// <summary>
/// Gets or sets both the L and U factors in the same matrix. /// Gets or sets both the L and U factors in the same matrix.
/// </summary> /// </summary>
protected Matrix Factors protected Matrix<T> Factors
{ {
get; get;
set; set;
@ -63,28 +67,33 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// </summary> /// </summary>
/// <param name="matrix">The matrix to factor.</param> /// <param name="matrix">The matrix to factor.</param>
/// <returns>An LU factorization object.</returns> /// <returns>An LU factorization object.</returns>
internal static LU Create(Matrix matrix) internal static LU<T> Create(Matrix<T> matrix)
{ {
var dense = matrix as DenseMatrix; if (typeof(T) == typeof(double))
if (dense != null)
{ {
return new DenseLU(dense); var dense = matrix as LinearAlgebra.Double.DenseMatrix;
if (dense != null)
{
return new LinearAlgebra.Double.Factorization.DenseLU(dense) as LU<T>;
}
return new LinearAlgebra.Double.Factorization.UserLU(matrix as Matrix<double>) as LU<T>;
} }
return new UserLU(matrix); throw new NotImplementedException();
} }
/// <summary> /// <summary>
/// Gets the lower triangular factor. /// Gets the lower triangular factor.
/// </summary> /// </summary>
public virtual Matrix L public virtual Matrix<T> L
{ {
get get
{ {
var result = Factors.LowerTriangle(); var result = Factors.LowerTriangle();
for (var i = 0; i < result.RowCount; i++) for (var i = 0; i < result.RowCount; i++)
{ {
result.At(i, i, 1); result.At(i, i, OneValueT);
} }
return result; return result;
@ -94,7 +103,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <summary> /// <summary>
/// Gets the upper triangular factor. /// Gets the upper triangular factor.
/// </summary> /// </summary>
public virtual Matrix U public virtual Matrix<T> U
{ {
get get
{ {
@ -116,20 +125,20 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <summary> /// <summary>
/// Gets the determinant of the matrix for which the LU factorization was computed. /// Gets the determinant of the matrix for which the LU factorization was computed.
/// </summary> /// </summary>
public virtual double Determinant public virtual T Determinant
{ {
get get
{ {
var det = 1.0; var det = OneValueT;
for (var j = 0; j < Factors.RowCount; j++) for (var j = 0; j < Factors.RowCount; j++)
{ {
if (Pivots[j] != j) if (Pivots[j] != j)
{ {
det = -det * Factors.At(j, j); det = MultiplyT(MinusOneValueT, MultiplyT(det, Factors.At(j, j)));
} }
else else
{ {
det *= Factors.At(j, j); det = MultiplyT(det, Factors.At(j, j));
} }
} }
@ -140,9 +149,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <summary> /// <summary>
/// Solves a system of linear equations, <b>AX = B</b>, with A LU factorized. /// Solves a system of linear equations, <b>AX = B</b>, with A LU factorized.
/// </summary> /// </summary>
/// <param name="input">The right hand side <see cref="Matrix"/>, <b>B</b>.</param> /// <param name="input">The right hand side <see cref="Matrix{T}"/>, <b>B</b>.</param>
/// <returns>The left hand side <see cref="Matrix"/>, <b>X</b>.</returns> /// <returns>The left hand side <see cref="Matrix{T}"/>, <b>X</b>.</returns>
public virtual Matrix Solve(Matrix input) public virtual Matrix<T> Solve(Matrix<T> input)
{ {
// Check for proper arguments. // Check for proper arguments.
if (input == null) if (input == null)
@ -158,16 +167,16 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <summary> /// <summary>
/// Solves a system of linear equations, <b>AX = B</b>, with A LU factorized. /// Solves a system of linear equations, <b>AX = B</b>, with A LU factorized.
/// </summary> /// </summary>
/// <param name="input">The right hand side <see cref="Matrix"/>, <b>B</b>.</param> /// <param name="input">The right hand side <see cref="Matrix{T}"/>, <b>B</b>.</param>
/// <param name="result">The left hand side <see cref="Matrix"/>, <b>X</b>.</param> /// <param name="result">The left hand side <see cref="Matrix{T}"/>, <b>X</b>.</param>
public abstract void Solve(Matrix input, Matrix result); public abstract void Solve(Matrix<T> input, Matrix<T> result);
/// <summary> /// <summary>
/// Solves a system of linear equations, <b>Ax = b</b>, with A LU factorized. /// Solves a system of linear equations, <b>Ax = b</b>, with A LU factorized.
/// </summary> /// </summary>
/// <param name="input">The right hand side vector, <b>b</b>.</param> /// <param name="input">The right hand side vector, <b>b</b>.</param>
/// <returns>The left hand side <see cref="Vector"/>, <b>x</b>.</returns> /// <returns>The left hand side <see cref="Vector{T}"/>, <b>x</b>.</returns>
public virtual Vector Solve(Vector input) public virtual Vector<T> Solve(Vector<T> input)
{ {
// Check for proper arguments. // Check for proper arguments.
if (input == null) if (input == null)
@ -184,13 +193,43 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// Solves a system of linear equations, <b>Ax = b</b>, with A LU factorized. /// Solves a system of linear equations, <b>Ax = b</b>, with A LU factorized.
/// </summary> /// </summary>
/// <param name="input">The right hand side vector, <b>b</b>.</param> /// <param name="input">The right hand side vector, <b>b</b>.</param>
/// <param name="result">The left hand side <see cref="Matrix"/>, <b>x</b>.</param> /// <param name="result">The left hand side <see cref="Matrix{T}"/>, <b>x</b>.</param>
public abstract void Solve(Vector input, Vector result); public abstract void Solve(Vector<T> input, Vector<T> result);
/// <summary> /// <summary>
/// Returns the inverse of this matrix. The inverse is calculated using LU decomposition. /// Returns the inverse of this matrix. The inverse is calculated using LU decomposition.
/// </summary> /// </summary>
/// <returns>The inverse of this matrix.</returns> /// <returns>The inverse of this matrix.</returns>
public abstract Matrix Inverse(); public abstract Matrix<T> Inverse();
#region Simple arithmetic of type T
/// <summary>
/// Multiply two values T*T
/// </summary>
/// <param name="val1">Left operand value</param>
/// <param name="val2">Right operand value</param>
/// <returns>Result of multiplication</returns>
protected abstract T MultiplyT(T val1, T val2);
/// <summary>
/// Gets value of type T equal to one
/// </summary>
/// <returns>One value</returns>
protected abstract T OneValueT
{
get;
}
/// <summary>
/// Gets value of type T equal to one
/// </summary>
/// <returns>One value</returns>
protected abstract T MinusOneValueT
{
get;
}
#endregion
} }
} }

88
src/Numerics/LinearAlgebra/Double/Factorization/QR.cs → src/Numerics/LinearAlgebra/Generic/Factorization/QR.cs

@ -24,9 +24,11 @@
// OTHER DEALINGS IN THE SOFTWARE. // OTHER DEALINGS IN THE SOFTWARE.
// </copyright> // </copyright>
namespace MathNet.Numerics.LinearAlgebra.Double.Factorization namespace MathNet.Numerics.LinearAlgebra.Generic.Factorization
{ {
using System; using System;
using System.Numerics;
using Generic;
using Properties; using Properties;
/// <summary> /// <summary>
@ -38,12 +40,14 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <remarks> /// <remarks>
/// The computation of the QR decomposition is done at construction time by Householder transformation. /// The computation of the QR decomposition is done at construction time by Householder transformation.
/// </remarks> /// </remarks>
public abstract class QR : ISolver /// <typeparam name="T">Supported data types are double, single, <see cref="Complex"/>, and <see cref="Complex32"/>.</typeparam>
public abstract class QR<T> : ISolver<T>
where T : struct, IEquatable<T>, IFormattable
{ {
/// <summary> /// <summary>
/// Gets or sets orthogonal Q matrix /// Gets or sets orthogonal Q matrix
/// </summary> /// </summary>
protected Matrix MatrixQ protected Matrix<T> MatrixQ
{ {
get; get;
set; set;
@ -52,7 +56,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <summary> /// <summary>
/// Gets or sets upper triangular factor R /// Gets or sets upper triangular factor R
/// </summary> /// </summary>
protected Matrix MatrixR protected Matrix<T> MatrixR
{ {
get; get;
set; set;
@ -63,21 +67,26 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// </summary> /// </summary>
/// <param name="matrix">The matrix to factor.</param> /// <param name="matrix">The matrix to factor.</param>
/// <returns>A QR factorization object.</returns> /// <returns>A QR factorization object.</returns>
internal static QR Create(Matrix matrix) internal static QR<T> Create(Matrix<T> matrix)
{ {
var dense = matrix as DenseMatrix; if (typeof(T) == typeof(double))
if (dense != null)
{ {
return new DenseQR(dense); var dense = matrix as LinearAlgebra.Double.DenseMatrix;
if (dense != null)
{
return new LinearAlgebra.Double.Factorization.DenseQR(dense) as QR<T>;
}
return new LinearAlgebra.Double.Factorization.UserQR(matrix as Matrix<double>) as QR<T>;
} }
return new UserQR(matrix); throw new NotImplementedException();
} }
/// <summary> /// <summary>
/// Gets orthogonal Q matrix /// Gets orthogonal Q matrix
/// </summary> /// </summary>
public virtual Matrix Q public virtual Matrix<T> Q
{ {
get get
{ {
@ -88,7 +97,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <summary> /// <summary>
/// Gets the upper triangular factor R. /// Gets the upper triangular factor R.
/// </summary> /// </summary>
public virtual Matrix R public virtual Matrix<T> R
{ {
get get
{ {
@ -108,17 +117,17 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
throw new ArgumentException(Resources.ArgumentMatrixSquare); throw new ArgumentException(Resources.ArgumentMatrixSquare);
} }
var det = 1.0; var det = OneValueT;
for (var i = 0; i < MatrixR.ColumnCount; i++) for (var i = 0; i < MatrixR.ColumnCount; i++)
{ {
det *= MatrixR.At(i, i); det = MultiplyT(det, MatrixR.At(i, i));
if (Math.Abs(MatrixR.At(i, i)).AlmostEqualInDecimalPlaces(0.0, 15)) if (AbsoluteT(MatrixR.At(i, i)).AlmostEqualInDecimalPlaces(0.0, 15))
{ {
return 0; return 0;
} }
} }
return Math.Abs(det); return AbsoluteT(det);
} }
} }
@ -132,7 +141,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
{ {
for (var i = 0; i < MatrixR.ColumnCount; i++) for (var i = 0; i < MatrixR.ColumnCount; i++)
{ {
if (Math.Abs(MatrixR.At(i, i)).AlmostEqualInDecimalPlaces(0.0, 15)) if (AbsoluteT(MatrixR.At(i, i)).AlmostEqualInDecimalPlaces(0.0, 15))
{ {
return false; return false;
} }
@ -145,9 +154,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <summary> /// <summary>
/// Solves a system of linear equations, <b>AX = B</b>, with A QR factorized. /// Solves a system of linear equations, <b>AX = B</b>, with A QR factorized.
/// </summary> /// </summary>
/// <param name="input">The right hand side <see cref="Matrix"/>, <b>B</b>.</param> /// <param name="input">The right hand side <see cref="Matrix{T}"/>, <b>B</b>.</param>
/// <returns>The left hand side <see cref="Matrix"/>, <b>X</b>.</returns> /// <returns>The left hand side <see cref="Matrix{T}"/>, <b>X</b>.</returns>
public virtual Matrix Solve(Matrix input) public virtual Matrix<T> Solve(Matrix<T> input)
{ {
// Check for proper arguments. // Check for proper arguments.
if (input == null) if (input == null)
@ -163,16 +172,16 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <summary> /// <summary>
/// Solves a system of linear equations, <b>AX = B</b>, with A QR factorized. /// Solves a system of linear equations, <b>AX = B</b>, with A QR factorized.
/// </summary> /// </summary>
/// <param name="input">The right hand side <see cref="Matrix"/>, <b>B</b>.</param> /// <param name="input">The right hand side <see cref="Matrix{T}"/>, <b>B</b>.</param>
/// <param name="result">The left hand side <see cref="Matrix"/>, <b>X</b>.</param> /// <param name="result">The left hand side <see cref="Matrix{T}"/>, <b>X</b>.</param>
public abstract void Solve(Matrix input, Matrix result); public abstract void Solve(Matrix<T> input, Matrix<T> result);
/// <summary> /// <summary>
/// Solves a system of linear equations, <b>Ax = b</b>, with A QR factorized. /// Solves a system of linear equations, <b>Ax = b</b>, with A QR factorized.
/// </summary> /// </summary>
/// <param name="input">The right hand side vector, <b>b</b>.</param> /// <param name="input">The right hand side vector, <b>b</b>.</param>
/// <returns>The left hand side <see cref="Vector"/>, <b>x</b>.</returns> /// <returns>The left hand side <see cref="Vector{T}"/>, <b>x</b>.</returns>
public virtual Vector Solve(Vector input) public virtual Vector<T> Solve(Vector<T> input)
{ {
// Check for proper arguments. // Check for proper arguments.
if (input == null) if (input == null)
@ -189,7 +198,34 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// Solves a system of linear equations, <b>Ax = b</b>, with A QR factorized. /// Solves a system of linear equations, <b>Ax = b</b>, with A QR factorized.
/// </summary> /// </summary>
/// <param name="input">The right hand side vector, <b>b</b>.</param> /// <param name="input">The right hand side vector, <b>b</b>.</param>
/// <param name="result">The left hand side <see cref="Matrix"/>, <b>x</b>.</param> /// <param name="result">The left hand side <see cref="Matrix{T}"/>, <b>x</b>.</param>
public abstract void Solve(Vector input, Vector result); public abstract void Solve(Vector<T> input, Vector<T> result);
#region Simple arithmetic of type T
/// <summary>
/// Multiply two values T*T
/// </summary>
/// <param name="val1">Left operand value</param>
/// <param name="val2">Right operand value</param>
/// <returns>Result of multiplication</returns>
protected abstract T MultiplyT(T val1, T val2);
/// <summary>
/// Take absolute value
/// </summary>
/// <param name="val">Source alue</param>
/// <returns>True if one; otherwise false</returns>
protected abstract double AbsoluteT(T val);
/// <summary>
/// Gets value of type T equal to one
/// </summary>
/// <returns>One value</returns>
protected abstract T OneValueT
{
get;
}
#endregion
} }
} }

118
src/Numerics/LinearAlgebra/Double/Factorization/Svd.cs → src/Numerics/LinearAlgebra/Generic/Factorization/Svd.cs

@ -28,9 +28,11 @@
// OTHER DEALINGS IN THE SOFTWARE. // OTHER DEALINGS IN THE SOFTWARE.
// </copyright> // </copyright>
namespace MathNet.Numerics.LinearAlgebra.Double.Factorization namespace MathNet.Numerics.LinearAlgebra.Generic.Factorization
{ {
using System; using System;
using System.Numerics;
using Generic;
using Properties; using Properties;
/// <summary> /// <summary>
@ -47,7 +49,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <remarks> /// <remarks>
/// The computation of the singular value decomposition is done at construction time. /// The computation of the singular value decomposition is done at construction time.
/// </remarks> /// </remarks>
public abstract class Svd : ISolver /// <typeparam name="T">Supported data types are double, single, <see cref="Complex"/>, and <see cref="Complex32"/>.</typeparam>
public abstract class Svd<T> : ISolver<T>
where T : struct, IEquatable<T>, IFormattable
{ {
/// <summary> /// <summary>
/// Gets or sets a value indicating whether to compute U and VT matrices during SVD factorization or not /// Gets or sets a value indicating whether to compute U and VT matrices during SVD factorization or not
@ -61,7 +65,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <summary> /// <summary>
/// Gets or sets the singular values (Σ) of matrix in ascending value. /// Gets or sets the singular values (Σ) of matrix in ascending value.
/// </summary> /// </summary>
protected Vector VectorS protected Vector<T> VectorS
{ {
get; get;
set; set;
@ -70,7 +74,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <summary> /// <summary>
/// Gets or sets left singular vectors (U - m-by-m unitary matrix) /// Gets or sets left singular vectors (U - m-by-m unitary matrix)
/// </summary> /// </summary>
protected Matrix MatrixU protected Matrix<T> MatrixU
{ {
get; get;
set; set;
@ -79,7 +83,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <summary> /// <summary>
/// Gets or sets transpose right singular vectors (transpose of V, an n-by-n unitary matrix /// Gets or sets transpose right singular vectors (transpose of V, an n-by-n unitary matrix
/// </summary> /// </summary>
protected Matrix MatrixVT protected Matrix<T> MatrixVT
{ {
get; get;
set; set;
@ -94,12 +98,12 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
get get
{ {
var eps = Math.Pow(2.0, -52.0); var eps = Math.Pow(2.0, -52.0);
var tol = Math.Max(MatrixU.RowCount, MatrixVT.ColumnCount) * VectorS[0] * eps; var tol = Math.Max(MatrixU.RowCount, MatrixVT.ColumnCount) * AbsoluteT(VectorS[0]) * eps;
var nm = Math.Min(MatrixU.RowCount, MatrixVT.ColumnCount); var nm = Math.Min(MatrixU.RowCount, MatrixVT.ColumnCount);
var rank = 0; var rank = 0;
for (var h = 0; h < nm; h++) for (var h = 0; h < nm; h++)
{ {
if (VectorS[h] > tol) if (AbsoluteT(VectorS[h]) > tol)
{ {
rank++; rank++;
} }
@ -115,26 +119,31 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <param name="matrix">The matrix to factor.</param> /// <param name="matrix">The matrix to factor.</param>
/// <param name="computeVectors">Compute the singular U and VT vectors or not.</param> /// <param name="computeVectors">Compute the singular U and VT vectors or not.</param>
/// <returns>An SVD object.</returns> /// <returns>An SVD object.</returns>
internal static Svd Create(Matrix matrix, bool computeVectors) internal static Svd<T> Create(Matrix<T> matrix, bool computeVectors)
{ {
var dense = matrix as DenseMatrix; if (typeof(T) == typeof(double))
if (dense != null)
{ {
return new DenseSvd(dense, computeVectors); var dense = matrix as LinearAlgebra.Double.DenseMatrix;
if (dense != null)
{
return new LinearAlgebra.Double.Factorization.DenseSvd(dense, computeVectors) as Svd<T>;
}
return new LinearAlgebra.Double.Factorization.UserSvd(matrix as Matrix<double>, computeVectors) as Svd<T>;
} }
return new UserSvd(matrix, computeVectors); throw new NotImplementedException();
} }
/// <summary> /// <summary>
/// Gets the two norm of the <see cref="Matrix"/>. /// Gets the two norm of the <see cref="Matrix{T}"/>.
/// </summary> /// </summary>
/// <returns>The 2-norm of the <see cref="Matrix"/>.</returns> /// <returns>The 2-norm of the <see cref="Matrix{T}"/>.</returns>
public virtual double Norm2 public virtual double Norm2
{ {
get get
{ {
return VectorS[0]; return AbsoluteT(VectorS[0]);
} }
} }
@ -147,7 +156,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
get get
{ {
var tmp = Math.Min(MatrixU.RowCount, MatrixVT.ColumnCount) - 1; var tmp = Math.Min(MatrixU.RowCount, MatrixVT.ColumnCount) - 1;
return VectorS[0] / VectorS[tmp]; return AbsoluteT(VectorS[0]) / AbsoluteT(VectorS[tmp]);
} }
} }
@ -163,38 +172,38 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
throw new ArgumentException(Resources.ArgumentMatrixSquare); throw new ArgumentException(Resources.ArgumentMatrixSquare);
} }
var det = 1.0; var det = OneValueT;
for (var i = 0; i < VectorS.Count; i++) for (var i = 0; i < VectorS.Count; i++)
{ {
det *= VectorS[i]; det = MultiplyT(det, VectorS[i]);
if (Math.Abs(VectorS[i]).AlmostEqualInDecimalPlaces(0.0, 15)) if (AbsoluteT(VectorS[i]).AlmostEqualInDecimalPlaces(0.0, 15))
{ {
return 0; return 0;
} }
} }
return Math.Abs(det); return AbsoluteT(det);
} }
} }
/// <summary>Returns the left singular vectors as a <see cref="Matrix"/>.</summary> /// <summary>Returns the left singular vectors as a <see cref="Matrix{T}"/>.</summary>
/// <returns>The left singular vectors. The matrix will be <c>null</c>, if <b>computeVectors</b> in the constructor is set to <c>false</c>.</returns> /// <returns>The left singular vectors. The matrix will be <c>null</c>, if <b>computeVectors</b> in the constructor is set to <c>false</c>.</returns>
public Matrix U() public Matrix<T> U()
{ {
return ComputeVectors ? MatrixU.Clone() : null; return ComputeVectors ? MatrixU.Clone() : null;
} }
/// <summary>Returns the right singular vectors as a <see cref="Matrix"/>.</summary> /// <summary>Returns the right singular vectors as a <see cref="Matrix{T}"/>.</summary>
/// <returns>The right singular vectors. The matrix will be <c>null</c>, if <b>computeVectors</b> in the constructor is set to <c>false</c>.</returns> /// <returns>The right singular vectors. The matrix will be <c>null</c>, if <b>computeVectors</b> in the constructor is set to <c>false</c>.</returns>
/// <remarks>This is the transpose of the V matrix.</remarks> /// <remarks>This is the transpose of the V matrix.</remarks>
public Matrix VT() public Matrix<T> VT()
{ {
return ComputeVectors ? MatrixVT.Clone() : null; return ComputeVectors ? MatrixVT.Clone() : null;
} }
/// <summary>Returns the singular values as a diagonal <see cref="Matrix"/>.</summary> /// <summary>Returns the singular values as a diagonal <see cref="Matrix{T}"/>.</summary>
/// <returns>The singular values as a diagonal <see cref="Matrix"/>.</returns> /// <returns>The singular values as a diagonal <see cref="Matrix{T}"/>.</returns>
public Matrix W() public Matrix<T> W()
{ {
var rows = MatrixU.RowCount; var rows = MatrixU.RowCount;
var columns = MatrixVT.ColumnCount; var columns = MatrixVT.ColumnCount;
@ -213,9 +222,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
return result; return result;
} }
/// <summary>Returns the singular values as a <see cref="Vector"/>.</summary> /// <summary>Returns the singular values as a <see cref="Vector{T}"/>.</summary>
/// <returns>the singular values as a <see cref="Vector"/>.</returns> /// <returns>the singular values as a <see cref="Vector{T}"/>.</returns>
public Vector S() public Vector<T> S()
{ {
return VectorS.Clone(); return VectorS.Clone();
} }
@ -223,9 +232,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <summary> /// <summary>
/// Solves a system of linear equations, <b>AX = B</b>, with A SVD factorized. /// Solves a system of linear equations, <b>AX = B</b>, with A SVD factorized.
/// </summary> /// </summary>
/// <param name="input">The right hand side <see cref="Matrix"/>, <b>B</b>.</param> /// <param name="input">The right hand side <see cref="Matrix{T}"/>, <b>B</b>.</param>
/// <returns>The left hand side <see cref="Matrix"/>, <b>X</b>.</returns> /// <returns>The left hand side <see cref="Matrix{T}"/>, <b>X</b>.</returns>
public virtual Matrix Solve(Matrix input) public virtual Matrix<T> Solve(Matrix<T> input)
{ {
// Check for proper arguments. // Check for proper arguments.
if (input == null) if (input == null)
@ -238,7 +247,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
throw new InvalidOperationException(Resources.SingularVectorsNotComputed); throw new InvalidOperationException(Resources.SingularVectorsNotComputed);
} }
Matrix result = MatrixU.CreateMatrix(MatrixVT.ColumnCount, input.ColumnCount); var result = MatrixU.CreateMatrix(MatrixVT.ColumnCount, input.ColumnCount);
Solve(input, result); Solve(input, result);
return result; return result;
} }
@ -246,16 +255,16 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <summary> /// <summary>
/// Solves a system of linear equations, <b>AX = B</b>, with A SVD factorized. /// Solves a system of linear equations, <b>AX = B</b>, with A SVD factorized.
/// </summary> /// </summary>
/// <param name="input">The right hand side <see cref="Matrix"/>, <b>B</b>.</param> /// <param name="input">The right hand side <see cref="Matrix{T}"/>, <b>B</b>.</param>
/// <param name="result">The left hand side <see cref="Matrix"/>, <b>X</b>.</param> /// <param name="result">The left hand side <see cref="Matrix{T}"/>, <b>X</b>.</param>
public abstract void Solve(Matrix input, Matrix result); public abstract void Solve(Matrix<T> input, Matrix<T> result);
/// <summary> /// <summary>
/// Solves a system of linear equations, <b>Ax = b</b>, with A SVD factorized. /// Solves a system of linear equations, <b>Ax = b</b>, with A SVD factorized.
/// </summary> /// </summary>
/// <param name="input">The right hand side vector, <b>b</b>.</param> /// <param name="input">The right hand side vector, <b>b</b>.</param>
/// <returns>The left hand side <see cref="Vector"/>, <b>x</b>.</returns> /// <returns>The left hand side <see cref="Vector{T}"/>, <b>x</b>.</returns>
public virtual Vector Solve(Vector input) public virtual Vector<T> Solve(Vector<T> input)
{ {
// Check for proper arguments. // Check for proper arguments.
if (input == null) if (input == null)
@ -277,7 +286,34 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// Solves a system of linear equations, <b>Ax = b</b>, with A SVD factorized. /// Solves a system of linear equations, <b>Ax = b</b>, with A SVD factorized.
/// </summary> /// </summary>
/// <param name="input">The right hand side vector, <b>b</b>.</param> /// <param name="input">The right hand side vector, <b>b</b>.</param>
/// <param name="result">The left hand side <see cref="Matrix"/>, <b>x</b>.</param> /// <param name="result">The left hand side <see cref="Matrix{T}"/>, <b>x</b>.</param>
public abstract void Solve(Vector input, Vector result); public abstract void Solve(Vector<T> input, Vector<T> result);
#region Simple arithmetic of type T
/// <summary>
/// Multiply two values T*T
/// </summary>
/// <param name="val1">Left operand value</param>
/// <param name="val2">Right operand value</param>
/// <returns>Result of multiplication</returns>
protected abstract T MultiplyT(T val1, T val2);
/// <summary>
/// Take absolute value
/// </summary>
/// <param name="val">Source alue</param>
/// <returns>True if one; otherwise false</returns>
protected abstract double AbsoluteT(T val);
/// <summary>
/// Gets value of type T equal to one
/// </summary>
/// <returns>One value</returns>
protected abstract T OneValueT
{
get;
}
#endregion
} }
} }

28
src/Numerics/LinearAlgebra/Double/ISolver.cs → src/Numerics/LinearAlgebra/Generic/ISolver.cs

@ -26,39 +26,43 @@
// OTHER DEALINGS IN THE SOFTWARE. // OTHER DEALINGS IN THE SOFTWARE.
// </copyright> // </copyright>
namespace MathNet.Numerics.LinearAlgebra.Double namespace MathNet.Numerics.LinearAlgebra.Generic
{ {
using System;
using System.Numerics;
/// <summary> /// <summary>
/// Classes that solves a system of linear equations, <c>AX = B</c>. /// Classes that solves a system of linear equations, <c>AX = B</c>.
/// </summary> /// </summary>
public interface ISolver /// <typeparam name="T">Supported data types are double, single, <see cref="Complex"/>, and <see cref="Complex32"/>.</typeparam>
public interface ISolver<T> where T : struct, IEquatable<T>, IFormattable
{ {
/// <summary> /// <summary>
/// Solves a system of linear equations, <c>AX = B</c>. /// Solves a system of linear equations, <c>AX = B</c>.
/// </summary> /// </summary>
/// <param name="input">The right hand side <see cref="Matrix"/>, <c>B</c>.</param> /// <param name="input">The right hand side Matrix, <c>B</c>.</param>
/// <returns>The left hand side <see cref="Matrix"/>, <c>X</c>.</returns> /// <returns>The left hand side Matrix, <c>X</c>.</returns>
Matrix Solve(Matrix input); Matrix<T> Solve(Matrix<T> input);
/// <summary> /// <summary>
/// Solves a system of linear equations, <c>AX = B</c>. /// Solves a system of linear equations, <c>AX = B</c>.
/// </summary> /// </summary>
/// <param name="input">The right hand side <see cref="Matrix"/>, <c>B</c>.</param> /// <param name="input">The right hand side Matrix, <c>B</c>.</param>
/// <param name="result">The left hand side <see cref="Matrix"/>, <c>X</c>.</param> /// <param name="result">The left hand side Matrix, <c>X</c>.</param>
void Solve(Matrix input, Matrix result); void Solve(Matrix<T> input, Matrix<T> result);
/// <summary> /// <summary>
/// Solves a system of linear equations, <c>Ax = b</c> /// Solves a system of linear equations, <c>Ax = b</c>
/// </summary> /// </summary>
/// <param name="input">The right hand side vector, <c>b</c>.</param> /// <param name="input">The right hand side vector, <c>b</c>.</param>
/// <returns>The left hand side <see cref="Vector"/>, <c>x</c>.</returns> /// <returns>The left hand side Vector, <c>x</c>.</returns>
Vector Solve(Vector input); Vector<T> Solve(Vector<T> input);
/// <summary> /// <summary>
/// Solves a system of linear equations, <c>Ax = b</c>. /// Solves a system of linear equations, <c>Ax = b</c>.
/// </summary> /// </summary>
/// <param name="input">The right hand side vector, <c>b</c>.</param> /// <param name="input">The right hand side vector, <c>b</c>.</param>
/// <param name="result">The left hand side <see cref="Matrix"/>, <c>x</c>.</param> /// <param name="result">The left hand side Matrix>, <c>x</c>.</param>
void Solve(Vector input, Vector result); void Solve(Vector<T> input, Vector<T> result);
} }
} }

259
src/Numerics/LinearAlgebra/Double/Matrix.Arithmetic.cs → src/Numerics/LinearAlgebra/Generic/Matrix.Arithmetic.cs

@ -24,9 +24,10 @@
// OTHER DEALINGS IN THE SOFTWARE. // OTHER DEALINGS IN THE SOFTWARE.
// </copyright> // </copyright>
namespace MathNet.Numerics.LinearAlgebra.Double namespace MathNet.Numerics.LinearAlgebra.Generic
{ {
using System; using System;
using System.Numerics;
using Distributions; using Distributions;
using Factorization; using Factorization;
using Properties; using Properties;
@ -35,7 +36,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <summary> /// <summary>
/// Defines the base class for <c>Matrix</c> classes. /// Defines the base class for <c>Matrix</c> classes.
/// </summary> /// </summary>
public abstract partial class Matrix /// <typeparam name="T">Supported data types are double, single, <see cref="Complex"/>, and <see cref="Complex32"/>.</typeparam>
public abstract partial class Matrix<T>
{ {
/// <summary> /// <summary>
/// Adds another matrix to this matrix. The result will be written into this matrix. /// Adds another matrix to this matrix. The result will be written into this matrix.
@ -43,7 +45,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="other">The matrix to add to this matrix.</param> /// <param name="other">The matrix to add to this matrix.</param>
/// <exception cref="ArgumentNullException">If the other matrix is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the other matrix is <see langword="null" />.</exception>
/// <exception cref="ArgumentOutOfRangeException">If the two matrices don't have the same dimensions.</exception> /// <exception cref="ArgumentOutOfRangeException">If the two matrices don't have the same dimensions.</exception>
public virtual void Add(Matrix other) public virtual void Add(Matrix<T> other)
{ {
if (other == null) if (other == null)
{ {
@ -56,13 +58,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double
} }
CommonParallel.For( CommonParallel.For(
0, 0,
RowCount, RowCount,
i => i =>
{ {
for (var j = 0; j < ColumnCount; j++) for (var j = 0; j < ColumnCount; j++)
{ {
At(i, j, At(i, j) + other.At(i, j)); At(i, j, AddT(At(i, j), other.At(i, j)));
} }
}); });
} }
@ -73,7 +75,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="other">The matrix to subtract.</param> /// <param name="other">The matrix to subtract.</param>
/// <exception cref="ArgumentNullException">If the other matrix is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the other matrix is <see langword="null" />.</exception>
/// <exception cref="ArgumentOutOfRangeException">If the two matrices don't have the same dimensions.</exception> /// <exception cref="ArgumentOutOfRangeException">If the two matrices don't have the same dimensions.</exception>
public virtual void Subtract(Matrix other) public virtual void Subtract(Matrix<T> other)
{ {
if (other == null) if (other == null)
{ {
@ -86,13 +88,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double
} }
CommonParallel.For( CommonParallel.For(
0, 0,
RowCount, RowCount,
i => i =>
{ {
for (var j = 0; j < ColumnCount; j++) for (var j = 0; j < ColumnCount; j++)
{ {
At(i, j, At(i, j) - other.At(i, j)); At(i, j, SubtractT(At(i, j), other.At(i, j)));
} }
}); });
} }
@ -101,21 +103,21 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// Multiplies each element of this matrix with a scalar. /// Multiplies each element of this matrix with a scalar.
/// </summary> /// </summary>
/// <param name="scalar">The scalar to multiply with.</param> /// <param name="scalar">The scalar to multiply with.</param>
public virtual void Multiply(double scalar) public virtual void Multiply(T scalar)
{ {
if (1.0.AlmostEqualInDecimalPlaces(scalar, 15)) if (IsOneT(scalar))
{ {
return; return;
} }
CommonParallel.For( CommonParallel.For(
0, 0,
RowCount, RowCount,
i => i =>
{ {
for (var j = 0; j < ColumnCount; j++) for (var j = 0; j < ColumnCount; j++)
{ {
At(i, j, At(i, j) * scalar); At(i, j, MultiplyT(At(i, j), scalar));
} }
}); });
} }
@ -127,7 +129,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="result">The matrix to multiply.</param> /// <param name="result">The matrix to multiply.</param>
/// <exception cref="ArgumentNullException">If the result matrix is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the result matrix is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If the result matrix's dimensions are not the same as this matrix.</exception> /// <exception cref="ArgumentException">If the result matrix's dimensions are not the same as this matrix.</exception>
public virtual void Multiply(double scalar, Matrix result) public virtual void Multiply(T scalar, Matrix<T> result)
{ {
if (result == null) if (result == null)
{ {
@ -155,7 +157,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>The result of the multiplication.</returns> /// <returns>The result of the multiplication.</returns>
/// <exception cref="ArgumentNullException">If <paramref name="rightSide"/> is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If <paramref name="rightSide"/> is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If <c>this.ColumnCount != rightSide.Count</c>.</exception> /// <exception cref="ArgumentException">If <c>this.ColumnCount != rightSide.Count</c>.</exception>
public virtual Vector Multiply(Vector rightSide) public virtual Vector<T> Multiply(Vector<T> rightSide)
{ {
var ret = CreateVector(RowCount); var ret = CreateVector(RowCount);
Multiply(rightSide, ret); Multiply(rightSide, ret);
@ -171,7 +173,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentNullException">If <paramref name="result"/> is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If <paramref name="result"/> is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If <strong>result.Count != this.RowCount</strong>.</exception> /// <exception cref="ArgumentException">If <strong>result.Count != this.RowCount</strong>.</exception>
/// <exception cref="ArgumentException">If <strong>this.ColumnCount != <paramref name="rightSide"/>.Count</strong>.</exception> /// <exception cref="ArgumentException">If <strong>this.ColumnCount != <paramref name="rightSide"/>.Count</strong>.</exception>
public virtual void Multiply(Vector rightSide, Vector result) public virtual void Multiply(Vector<T> rightSide, Vector<T> result)
{ {
if (rightSide == null) if (rightSide == null)
{ {
@ -202,14 +204,14 @@ namespace MathNet.Numerics.LinearAlgebra.Double
else else
{ {
CommonParallel.For( CommonParallel.For(
0, 0,
RowCount, RowCount,
i => i =>
{ {
double s = 0; var s = default(T);
for (var j = 0; j != ColumnCount; j++) for (var j = 0; j != ColumnCount; j++)
{ {
s += At(i, j) * rightSide[j]; s = AddT(s, MultiplyT(At(i, j), rightSide[j]));
} }
result[i] = s; result[i] = s;
@ -224,7 +226,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>The result of the multiplication.</returns> /// <returns>The result of the multiplication.</returns>
/// <exception cref="ArgumentNullException">If <paramref name="leftSide"/> is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If <paramref name="leftSide"/> is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If <strong>this.RowCount != <paramref name="leftSide"/>.Count</strong>.</exception> /// <exception cref="ArgumentException">If <strong>this.RowCount != <paramref name="leftSide"/>.Count</strong>.</exception>
public virtual Vector LeftMultiply(Vector leftSide) public virtual Vector<T> LeftMultiply(Vector<T> leftSide)
{ {
var ret = CreateVector(ColumnCount); var ret = CreateVector(ColumnCount);
LeftMultiply(leftSide, ret); LeftMultiply(leftSide, ret);
@ -240,7 +242,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentNullException">If the result matrix is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the result matrix is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If <strong>result.Count != this.ColumnCount</strong>.</exception> /// <exception cref="ArgumentException">If <strong>result.Count != this.ColumnCount</strong>.</exception>
/// <exception cref="ArgumentException">If <strong>this.RowCount != <paramref name="leftSide"/>.Count</strong>.</exception> /// <exception cref="ArgumentException">If <strong>this.RowCount != <paramref name="leftSide"/>.Count</strong>.</exception>
public virtual void LeftMultiply(Vector leftSide, Vector result) public virtual void LeftMultiply(Vector<T> leftSide, Vector<T> result)
{ {
if (leftSide == null) if (leftSide == null)
{ {
@ -271,14 +273,14 @@ namespace MathNet.Numerics.LinearAlgebra.Double
else else
{ {
CommonParallel.For( CommonParallel.For(
0, 0,
RowCount, RowCount,
j => j =>
{ {
double s = 0; var s = default(T);
for (var i = 0; i != leftSide.Count; i++) for (var i = 0; i != leftSide.Count; i++)
{ {
s += leftSide[i] * At(i, j); s = AddT(s, MultiplyT(leftSide[i], At(i, j)));
} }
result[j] = s; result[j] = s;
@ -295,7 +297,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentNullException">If the result matrix is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the result matrix is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If <strong>this.Columns != other.Rows</strong>.</exception> /// <exception cref="ArgumentException">If <strong>this.Columns != other.Rows</strong>.</exception>
/// <exception cref="ArgumentException">If the result matrix's dimensions are not the this.Rows x other.Columns.</exception> /// <exception cref="ArgumentException">If the result matrix's dimensions are not the this.Rows x other.Columns.</exception>
public virtual void Multiply(Matrix other, Matrix result) public virtual void Multiply(Matrix<T> other, Matrix<T> result)
{ {
if (other == null) if (other == null)
{ {
@ -326,16 +328,16 @@ namespace MathNet.Numerics.LinearAlgebra.Double
else else
{ {
CommonParallel.For( CommonParallel.For(
0, 0,
RowCount, RowCount,
j => j =>
{ {
for (var i = 0; i != other.ColumnCount; i++) for (var i = 0; i != other.ColumnCount; i++)
{ {
double s = 0; var s = default(T);
for (var l = 0; l < ColumnCount; l++) for (var l = 0; l < ColumnCount; l++)
{ {
s += At(j, l) * other.At(l, i); s = AddT(s, MultiplyT(At(j, l), other.At(l, i)));
} }
result.At(j, i, s); result.At(j, i, s);
@ -351,7 +353,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentException">If <strong>this.Columns != other.Rows</strong>.</exception> /// <exception cref="ArgumentException">If <strong>this.Columns != other.Rows</strong>.</exception>
/// <exception cref="ArgumentNullException">If the other matrix is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the other matrix is <see langword="null" />.</exception>
/// <returns>The result of the multiplication.</returns> /// <returns>The result of the multiplication.</returns>
public virtual Matrix Multiply(Matrix other) public virtual Matrix<T> Multiply(Matrix<T> other)
{ {
if (other == null) if (other == null)
{ {
@ -377,8 +379,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentNullException">If the result matrix is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the result matrix is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If <strong>this.Columns != other.ColumnCount</strong>.</exception> /// <exception cref="ArgumentException">If <strong>this.Columns != other.ColumnCount</strong>.</exception>
/// <exception cref="ArgumentException">If the result matrix's dimensions are not the this.RowCount x other.RowCount.</exception> /// <exception cref="ArgumentException">If the result matrix's dimensions are not the this.RowCount x other.RowCount.</exception>
public virtual void TransposeAndMultiply(Matrix other, Matrix result) public virtual void TransposeAndMultiply(Matrix<T> other, Matrix<T> result)
{ {
if (other == null) if (other == null)
{ {
throw new ArgumentNullException("other"); throw new ArgumentNullException("other");
@ -414,13 +416,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double
{ {
for (var i = 0; i < RowCount; i++) for (var i = 0; i < RowCount; i++)
{ {
double s = 0; var s = default(T);
for (var l = 0; l < ColumnCount; l++) for (var l = 0; l < ColumnCount; l++)
{ {
s += At(i, l) * other.At(j, l); s = AddT(s, MultiplyT(At(i, l), other.At(j, l)));
} }
result.At(i, j, s + result.At(i, j)); result.At(i, j, AddT(s, result.At(i, j)));
} }
}); });
} }
@ -433,7 +435,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentException">If <strong>this.Columns != other.ColumnCount</strong>.</exception> /// <exception cref="ArgumentException">If <strong>this.Columns != other.ColumnCount</strong>.</exception>
/// <exception cref="ArgumentNullException">If the other matrix is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the other matrix is <see langword="null" />.</exception>
/// <returns>The result of the multiplication.</returns> /// <returns>The result of the multiplication.</returns>
public virtual Matrix TransposeAndMultiply(Matrix other) public virtual Matrix<T> TransposeAndMultiply(Matrix<T> other)
{ {
if (other == null) if (other == null)
{ {
@ -451,12 +453,11 @@ namespace MathNet.Numerics.LinearAlgebra.Double
} }
/// <summary> /// <summary>
/// Negates each element of this matrix. /// Negate each element of this matrix.
/// </summary> /// </summary>
public virtual void Negate() /// <exception cref="ArgumentNullException">If the result matrix is <see langword="null" />.</exception>
{ /// <exception cref="ArgumentException">if the result matrix's dimensions are not the same as this matrix.</exception>
Multiply(-1); public abstract void Negate();
}
/// <summary> /// <summary>
/// Negate each element of this matrix and place the results into the result matrix. /// Negate each element of this matrix and place the results into the result matrix.
@ -464,7 +465,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="result">The result of the negation.</param> /// <param name="result">The result of the negation.</param>
/// <exception cref="ArgumentNullException">If the result matrix is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the result matrix is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">if the result matrix's dimensions are not the same as this matrix.</exception> /// <exception cref="ArgumentException">if the result matrix's dimensions are not the same as this matrix.</exception>
public virtual void Negate(Matrix result) public virtual void Negate(Matrix<T> result)
{ {
if (result == null) if (result == null)
{ {
@ -491,7 +492,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>The result of the addition.</returns> /// <returns>The result of the addition.</returns>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="leftSide"/> and <paramref name="rightSide"/> don't have the same dimensions.</exception> /// <exception cref="ArgumentOutOfRangeException">If <paramref name="leftSide"/> and <paramref name="rightSide"/> don't have the same dimensions.</exception>
/// <exception cref="ArgumentNullException">If <paramref name="leftSide"/> or <paramref name="rightSide"/> is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If <paramref name="leftSide"/> or <paramref name="rightSide"/> is <see langword="null" />.</exception>
public static Matrix operator +(Matrix leftSide, Matrix rightSide) public static Matrix<T> operator +(Matrix<T> leftSide, Matrix<T> rightSide)
{ {
if (rightSide == null) if (rightSide == null)
{ {
@ -519,7 +520,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="rightSide">The matrix to get the values from.</param> /// <param name="rightSide">The matrix to get the values from.</param>
/// <returns>A matrix containing a the same values as <paramref name="rightSide"/>.</returns> /// <returns>A matrix containing a the same values as <paramref name="rightSide"/>.</returns>
/// <exception cref="ArgumentNullException">If <paramref name="rightSide"/> is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If <paramref name="rightSide"/> is <see langword="null" />.</exception>
public static Matrix operator +(Matrix rightSide) public static Matrix<T> operator +(Matrix<T> rightSide)
{ {
if (rightSide == null) if (rightSide == null)
{ {
@ -540,7 +541,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>The result of the addition.</returns> /// <returns>The result of the addition.</returns>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="leftSide"/> and <paramref name="rightSide"/> don't have the same dimensions.</exception> /// <exception cref="ArgumentOutOfRangeException">If <paramref name="leftSide"/> and <paramref name="rightSide"/> don't have the same dimensions.</exception>
/// <exception cref="ArgumentNullException">If <paramref name="leftSide"/> or <paramref name="rightSide"/> is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If <paramref name="leftSide"/> or <paramref name="rightSide"/> is <see langword="null" />.</exception>
public static Matrix operator -(Matrix leftSide, Matrix rightSide) public static Matrix<T> operator -(Matrix<T> leftSide, Matrix<T> rightSide)
{ {
if (rightSide == null) if (rightSide == null)
{ {
@ -568,7 +569,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="rightSide">The matrix to negate.</param> /// <param name="rightSide">The matrix to negate.</param>
/// <returns>A matrix containing the negated values.</returns> /// <returns>A matrix containing the negated values.</returns>
/// <exception cref="ArgumentNullException">If <paramref name="rightSide"/> is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If <paramref name="rightSide"/> is <see langword="null" />.</exception>
public static Matrix operator -(Matrix rightSide) public static Matrix<T> operator -(Matrix<T> rightSide)
{ {
if (rightSide == null) if (rightSide == null)
{ {
@ -587,7 +588,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="rightSide">The constant to multiply the matrix by.</param> /// <param name="rightSide">The constant to multiply the matrix by.</param>
/// <returns>The result of the multiplication.</returns> /// <returns>The result of the multiplication.</returns>
/// <exception cref="ArgumentNullException">If <paramref name="leftSide"/> is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If <paramref name="leftSide"/> is <see langword="null" />.</exception>
public static Matrix operator *(Matrix leftSide, double rightSide) public static Matrix<T> operator *(Matrix<T> leftSide, T rightSide)
{ {
if (leftSide == null) if (leftSide == null)
{ {
@ -606,7 +607,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="rightSide">The constant to multiply the matrix by.</param> /// <param name="rightSide">The constant to multiply the matrix by.</param>
/// <returns>The result of the multiplication.</returns> /// <returns>The result of the multiplication.</returns>
/// <exception cref="ArgumentNullException">If <paramref name="rightSide"/> is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If <paramref name="rightSide"/> is <see langword="null" />.</exception>
public static Matrix operator *(double leftSide, Matrix rightSide) public static Matrix<T> operator *(T leftSide, Matrix<T> rightSide)
{ {
if (rightSide == null) if (rightSide == null)
{ {
@ -629,7 +630,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>The result of multiplication.</returns> /// <returns>The result of multiplication.</returns>
/// <exception cref="ArgumentNullException">If <paramref name="leftSide"/> or <paramref name="rightSide"/> is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If <paramref name="leftSide"/> or <paramref name="rightSide"/> is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If the dimensions of <paramref name="leftSide"/> or <paramref name="rightSide"/> don't conform.</exception> /// <exception cref="ArgumentException">If the dimensions of <paramref name="leftSide"/> or <paramref name="rightSide"/> don't conform.</exception>
public static Matrix operator *(Matrix leftSide, Matrix rightSide) public static Matrix<T> operator *(Matrix<T> leftSide, Matrix<T> rightSide)
{ {
if (leftSide == null) if (leftSide == null)
{ {
@ -650,13 +651,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double
} }
/// <summary> /// <summary>
/// Multiplies a <strong>Matrix</strong> and a <see cref="Vector"/>. /// Multiplies a <strong>Matrix</strong> and a Vector.
/// </summary> /// </summary>
/// <param name="leftSide">The matrix to multiply.</param> /// <param name="leftSide">The matrix to multiply.</param>
/// <param name="rightSide">The vector to multiply.</param> /// <param name="rightSide">The vector to multiply.</param>
/// <returns>The result of multiplication.</returns> /// <returns>The result of multiplication.</returns>
/// <exception cref="ArgumentNullException">If <paramref name="leftSide"/> or <paramref name="rightSide"/> is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If <paramref name="leftSide"/> or <paramref name="rightSide"/> is <see langword="null" />.</exception>
public static Vector operator *(Matrix leftSide, Vector rightSide) public static Vector<T> operator *(Matrix<T> leftSide, Vector<T> rightSide)
{ {
if (leftSide == null) if (leftSide == null)
{ {
@ -667,13 +668,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double
} }
/// <summary> /// <summary>
/// Multiplies a <see cref="Vector"/> and a <strong>Matrix</strong>. /// Multiplies a Vector and a <strong>Matrix</strong>.
/// </summary> /// </summary>
/// <param name="leftSide">The vector to multiply.</param> /// <param name="leftSide">The vector to multiply.</param>
/// <param name="rightSide">The matrix to multiply.</param> /// <param name="rightSide">The matrix to multiply.</param>
/// <returns>The result of multiplication.</returns> /// <returns>The result of multiplication.</returns>
/// <exception cref="ArgumentNullException">If <paramref name="leftSide"/> or <paramref name="rightSide"/> is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If <paramref name="leftSide"/> or <paramref name="rightSide"/> is <see langword="null" />.</exception>
public static Vector operator *(Vector leftSide, Matrix rightSide) public static Vector<T> operator *(Vector<T> leftSide, Matrix<T> rightSide)
{ {
if (rightSide == null) if (rightSide == null)
{ {
@ -690,7 +691,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentNullException">If the other matrix is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the other matrix is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If this matrix and <paramref name="other"/> are not the same size.</exception> /// <exception cref="ArgumentException">If this matrix and <paramref name="other"/> are not the same size.</exception>
/// <returns>A new matrix that is the pointwise multiplication of this matrix and <paramref name="other"/>.</returns> /// <returns>A new matrix that is the pointwise multiplication of this matrix and <paramref name="other"/>.</returns>
public virtual Matrix PointwiseMultiply(Matrix other) public virtual Matrix<T> PointwiseMultiply(Matrix<T> other)
{ {
if (other == null) if (other == null)
{ {
@ -716,7 +717,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentNullException">If the result matrix is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the result matrix is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If this matrix and <paramref name="other"/> are not the same size.</exception> /// <exception cref="ArgumentException">If this matrix and <paramref name="other"/> are not the same size.</exception>
/// <exception cref="ArgumentException">If this matrix and <paramref name="result"/> are not the same size.</exception> /// <exception cref="ArgumentException">If this matrix and <paramref name="result"/> are not the same size.</exception>
public virtual void PointwiseMultiply(Matrix other, Matrix result) public virtual void PointwiseMultiply(Matrix<T> other, Matrix<T> result)
{ {
if (other == null) if (other == null)
{ {
@ -739,13 +740,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double
} }
CommonParallel.For( CommonParallel.For(
0, 0,
ColumnCount, ColumnCount,
j => j =>
{ {
for (var i = 0; i < RowCount; i++) for (var i = 0; i < RowCount; i++)
{ {
result.At(i, j, At(i, j) * other.At(i, j)); result.At(i, j, MultiplyT(At(i, j), other.At(i, j)));
} }
}); });
} }
@ -757,7 +758,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentNullException">If the other matrix is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the other matrix is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If this matrix and <paramref name="other"/> are not the same size.</exception> /// <exception cref="ArgumentException">If this matrix and <paramref name="other"/> are not the same size.</exception>
/// <returns>A new matrix that is the pointwise division of this matrix and <paramref name="other"/>.</returns> /// <returns>A new matrix that is the pointwise division of this matrix and <paramref name="other"/>.</returns>
public virtual Matrix PointwiseDivide(Matrix other) public virtual Matrix<T> PointwiseDivide(Matrix<T> other)
{ {
if (other == null) if (other == null)
{ {
@ -783,7 +784,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentNullException">If the result matrix is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the result matrix is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If this matrix and <paramref name="other"/> are not the same size.</exception> /// <exception cref="ArgumentException">If this matrix and <paramref name="other"/> are not the same size.</exception>
/// <exception cref="ArgumentException">If this matrix and <paramref name="result"/> are not the same size.</exception> /// <exception cref="ArgumentException">If this matrix and <paramref name="result"/> are not the same size.</exception>
public virtual void PointwiseDivide(Matrix other, Matrix result) public virtual void PointwiseDivide(Matrix<T> other, Matrix<T> result)
{ {
if (other == null) if (other == null)
{ {
@ -806,13 +807,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double
} }
CommonParallel.For( CommonParallel.For(
0, 0,
ColumnCount, ColumnCount,
j => j =>
{ {
for (var i = 0; i < RowCount; i++) for (var i = 0; i < RowCount; i++)
{ {
result.At(i, j, At(i, j) / other.At(i, j)); result.At(i, j, DivideT(At(i, j), other.At(i, j)));
} }
}); });
} }
@ -828,32 +829,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// </returns> /// </returns>
/// <exception cref="ArgumentException">If the parameter <paramref name="numberOfRows"/> is not positive.</exception> /// <exception cref="ArgumentException">If the parameter <paramref name="numberOfRows"/> is not positive.</exception>
/// <exception cref="ArgumentException">If the parameter <paramref name="numberOfColumns"/> is not positive.</exception> /// <exception cref="ArgumentException">If the parameter <paramref name="numberOfColumns"/> is not positive.</exception>
public virtual Matrix Random(int numberOfRows, int numberOfColumns, IContinuousDistribution distribution) public abstract Matrix<T> Random(int numberOfRows, int numberOfColumns, IContinuousDistribution distribution);
{
if (numberOfRows < 1)
{
throw new ArgumentException(Resources.ArgumentMustBePositive, "numberOfRows");
}
if (numberOfColumns < 1)
{
throw new ArgumentException(Resources.ArgumentMustBePositive, "numberOfColumns");
}
var matrix = CreateMatrix(numberOfRows, numberOfColumns);
CommonParallel.For(
0,
ColumnCount,
j =>
{
for (var i = 0; i < matrix.RowCount; i++)
{
matrix[i, j] = distribution.Sample();
}
});
return matrix;
}
/// <summary> /// <summary>
/// Generates matrix with random elements. /// Generates matrix with random elements.
@ -866,46 +842,23 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// </returns> /// </returns>
/// <exception cref="ArgumentException">If the parameter <paramref name="numberOfRows"/> is not positive.</exception> /// <exception cref="ArgumentException">If the parameter <paramref name="numberOfRows"/> is not positive.</exception>
/// <exception cref="ArgumentException">If the parameter <paramref name="numberOfColumns"/> is not positive.</exception> /// <exception cref="ArgumentException">If the parameter <paramref name="numberOfColumns"/> is not positive.</exception>
public virtual Matrix Random(int numberOfRows, int numberOfColumns, IDiscreteDistribution distribution) public abstract Matrix<T> Random(int numberOfRows, int numberOfColumns, IDiscreteDistribution distribution);
{
if (numberOfRows < 1)
{
throw new ArgumentException(Resources.ArgumentMustBePositive, "numberOfRows");
}
if (numberOfColumns < 1)
{
throw new ArgumentException(Resources.ArgumentMustBePositive, "numberOfColumns");
}
var matrix = CreateMatrix(numberOfRows, numberOfColumns);
CommonParallel.For(
0,
ColumnCount,
j =>
{
for (var i = 0; i < matrix.RowCount; i++)
{
matrix[i, j] = distribution.Sample();
}
});
return matrix;
}
/// <summary> /// <summary>
/// Computes the trace of this matrix. /// Computes the trace of this matrix.
/// </summary> /// </summary>
/// <returns>The trace of this matrix</returns> /// <returns>The trace of this matrix</returns>
/// <exception cref="ArgumentException">If the matrix is not square</exception> /// <exception cref="ArgumentException">If the matrix is not square</exception>
public virtual double Trace() public virtual T Trace()
{ {
if (RowCount != ColumnCount) if (RowCount != ColumnCount)
{ {
throw new ArgumentException(Resources.ArgumentMatrixSquare); throw new ArgumentException(Resources.ArgumentMatrixSquare);
} }
return CommonParallel.Aggregate(0, RowCount, i => this[i, i]); var sum = default(T);
CommonParallel.For(0, RowCount, i => sum = AddT(sum, this[i, i]));
return sum;
} }
/// <summary> /// <summary>
@ -914,8 +867,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>effective numerical rank, obtained from SVD</returns> /// <returns>effective numerical rank, obtained from SVD</returns>
public virtual int Rank() public virtual int Rank()
{ {
var svd = this.Svd(false); return Svd<T>.Create(this, false).Rank;
return svd.Rank;
} }
/// <summary>Calculates the condition number of this matrix.</summary> /// <summary>Calculates the condition number of this matrix.</summary>
@ -923,34 +875,31 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <remarks>The condition number is calculated using singular value decomposition.</remarks> /// <remarks>The condition number is calculated using singular value decomposition.</remarks>
public virtual double ConditionNumber() public virtual double ConditionNumber()
{ {
var svd = this.Svd(false); return Svd<T>.Create(this, false).ConditionNumber;
return svd.ConditionNumber;
} }
/// <summary>Computes the determinant of this matrix.</summary> /// <summary>Computes the determinant of this matrix.</summary>
/// <returns>The determinant of this matrix.</returns> /// <returns>The determinant of this matrix.</returns>
public virtual double Determinant() public virtual T Determinant()
{ {
if (RowCount != ColumnCount) if (RowCount != ColumnCount)
{ {
throw new ArgumentException(Resources.ArgumentMatrixSquare); throw new ArgumentException(Resources.ArgumentMatrixSquare);
} }
var lu = this.LU(); return LU<T>.Create(this).Determinant;
return lu.Determinant;
} }
/// <summary>Computes the inverse of this matrix.</summary> /// <summary>Computes the inverse of this matrix.</summary>
/// <returns>The inverse of this matrix.</returns> /// <returns>The inverse of this matrix.</returns>
public virtual Matrix Inverse() public virtual Matrix<T> Inverse()
{ {
if (RowCount != ColumnCount) if (RowCount != ColumnCount)
{ {
throw new ArgumentException(Resources.ArgumentMatrixSquare); throw new ArgumentException(Resources.ArgumentMatrixSquare);
} }
var lu = this.LU(); return LU<T>.Create(this).Inverse();
return lu.Inverse();
} }
/// <summary> /// <summary>
@ -960,7 +909,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="other">The other matrix.</param> /// <param name="other">The other matrix.</param>
/// <exception cref="ArgumentNullException">If other is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If other is <see langword="null" />.</exception>
/// <returns>The kronecker product of the two matrices.</returns> /// <returns>The kronecker product of the two matrices.</returns>
public virtual Matrix KroneckerProduct(Matrix other) public virtual Matrix<T> KroneckerProduct(Matrix<T> other)
{ {
if (other == null) if (other == null)
{ {
@ -981,7 +930,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentNullException">If other is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If other is <see langword="null" />.</exception>
/// <exception cref="ArgumentNullException">If the result matrix is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the result matrix is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If the result matrix's dimensions are not (this.Rows * lower.rows) x (this.Columns * lower.Columns).</exception> /// <exception cref="ArgumentException">If the result matrix's dimensions are not (this.Rows * lower.rows) x (this.Columns * lower.Columns).</exception>
public virtual void KroneckerProduct(Matrix other, Matrix result) public virtual void KroneckerProduct(Matrix<T> other, Matrix<T> result)
{ {
if (other == null) if (other == null)
{ {
@ -1016,7 +965,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="p">The norm under which to normalize the columns under.</param> /// <param name="p">The norm under which to normalize the columns under.</param>
/// <returns>A normalized version of the matrix.</returns> /// <returns>A normalized version of the matrix.</returns>
/// <exception cref="ArgumentOutOfRangeException">If the parameter p is not positive.</exception> /// <exception cref="ArgumentOutOfRangeException">If the parameter p is not positive.</exception>
public virtual Matrix NormalizeColumns(int p) public virtual Matrix<T> NormalizeColumns(int p)
{ {
if (p < 1) if (p < 1)
{ {
@ -1025,17 +974,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double
var ret = Clone(); var ret = Clone();
CommonParallel.For( CommonParallel.For(
0, 0,
ColumnCount, ColumnCount,
i => i => ret.SetColumn(i, Column(i).Normalize(p)));
{
var coli = Column(i);
var norm = coli.Norm(p);
for (var j = 0; j < RowCount; j++)
{
ret[j, i] = coli[j] / norm;
}
});
return ret; return ret;
} }
@ -1045,7 +986,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="p">The norm under which to normalize the rows under.</param> /// <param name="p">The norm under which to normalize the rows under.</param>
/// <returns>A normalized version of the matrix.</returns> /// <returns>A normalized version of the matrix.</returns>
/// <exception cref="ArgumentOutOfRangeException">If the parameter p is not positive.</exception> /// <exception cref="ArgumentOutOfRangeException">If the parameter p is not positive.</exception>
public virtual Matrix NormalizeRows(int p) public virtual Matrix<T> NormalizeRows(int p)
{ {
if (p < 1) if (p < 1)
{ {
@ -1054,32 +995,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double
var ret = Clone(); var ret = Clone();
// BUG: Seems that commented-out implementation is wrong.
// CommonParallel.For(
// 0,
// ColumnCount,
// j =>
// {
// var rowj = Row(j);
// var norm = rowj.Norm(p);
// for (var i = 0; i < RowCount; i++)
// {
// ret[i, j] = rowj[j] / norm;
// }
// });
CommonParallel.For( CommonParallel.For(
0, 0,
RowCount, RowCount,
i => i => ret.SetRow(i, Row(i).Normalize(p)));
{
var rowi = Row(i);
var norm = rowi.Norm(p);
for (var j = 0; j < ColumnCount; j++)
{
ret[i, j] = rowi[j] / norm;
}
});
return ret; return ret;
} }
} }

317
src/Numerics/LinearAlgebra/Double/Matrix.cs → src/Numerics/LinearAlgebra/Generic/Matrix.cs

@ -24,10 +24,11 @@
// OTHER DEALINGS IN THE SOFTWARE. // OTHER DEALINGS IN THE SOFTWARE.
// </copyright> // </copyright>
namespace MathNet.Numerics.LinearAlgebra.Double namespace MathNet.Numerics.LinearAlgebra.Generic
{ {
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Numerics;
using System.Text; using System.Text;
using Factorization; using Factorization;
using Properties; using Properties;
@ -36,16 +37,18 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <summary> /// <summary>
/// Defines the base class for <c>Matrix</c> classes. /// Defines the base class for <c>Matrix</c> classes.
/// </summary> /// </summary>
/// <typeparam name="T">Supported data types are double, single, <see cref="Complex"/>, and <see cref="Complex32"/>.</typeparam>
[Serializable] [Serializable]
public abstract partial class Matrix : public abstract partial class Matrix<T> :
#if SILVERLIGHT #if SILVERLIGHT
IFormattable, IEquatable<Matrix> IFormattable, IEquatable<Matrix<T>>
#else #else
IFormattable, IEquatable<Matrix>, ICloneable IFormattable, IEquatable<Matrix<T>>, ICloneable
#endif #endif
where T : struct, IEquatable<T>, IFormattable
{ {
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="Matrix"/> class. /// Initializes a new instance of the Matrix class.
/// </summary> /// </summary>
/// <param name="rows"> /// <param name="rows">
/// The number of rows. /// The number of rows.
@ -70,7 +73,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
} }
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="Matrix"/> class. /// Initializes a new instance of the Matrix class.
/// </summary> /// </summary>
/// <param name="order"> /// <param name="order">
/// The order of the matrix. /// The order of the matrix.
@ -116,9 +119,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// The column of the element. /// The column of the element.
/// </param> /// </param>
/// <value>The double value to get or set.</value> /// <value>The double value to get or set.</value>
/// <remarks>This method is ranged checked. <see cref="At(int,int)"/> and <see cref="At(int,int,double)"/> /// <remarks>This method is ranged checked. <see cref="At(int,int)"/> and <see cref="At(int,int,T)"/>
/// to get and set values without range checking.</remarks> /// to get and set values without range checking.</remarks>
public virtual double this[int row, int column] public virtual T this[int row, int column]
{ {
get get
{ {
@ -145,7 +148,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns> /// <returns>
/// The requested element. /// The requested element.
/// </returns> /// </returns>
public abstract double At(int row, int column); public abstract T At(int row, int column);
/// <summary> /// <summary>
/// Sets the value of the given element. /// Sets the value of the given element.
@ -159,7 +162,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="value"> /// <param name="value">
/// The value to set the element to. /// The value to set the element to.
/// </param> /// </param>
public abstract void At(int row, int column, double value); public abstract void At(int row, int column, T value);
/// <summary> /// <summary>
/// Creates a clone of this instance. /// Creates a clone of this instance.
@ -167,7 +170,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns> /// <returns>
/// A clone of the instance. /// A clone of the instance.
/// </returns> /// </returns>
public virtual Matrix Clone() public virtual Matrix<T> Clone()
{ {
var result = CreateMatrix(RowCount, ColumnCount); var result = CreateMatrix(RowCount, ColumnCount);
CopyTo(result); CopyTo(result);
@ -186,7 +189,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentException"> /// <exception cref="ArgumentException">
/// If this and the target matrix do not have the same dimensions.. /// If this and the target matrix do not have the same dimensions..
/// </exception> /// </exception>
public virtual void CopyTo(Matrix target) public virtual void CopyTo(Matrix<T> target)
{ {
if (target == null) if (target == null)
{ {
@ -227,19 +230,19 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <remarks> /// <remarks>
/// Creates a matrix of the same matrix type as the current matrix. /// Creates a matrix of the same matrix type as the current matrix.
/// </remarks> /// </remarks>
public abstract Matrix CreateMatrix(int numberOfRows, int numberOfColumns); public abstract Matrix<T> CreateMatrix(int numberOfRows, int numberOfColumns);
/// <summary> /// <summary>
/// Creates a <see cref="Vector"/> with a the given dimension. /// Creates a Vector with a the given dimension.
/// </summary> /// </summary>
/// <param name="size">The size of the vector.</param> /// <param name="size">The size of the vector.</param>
/// <returns> /// <returns>
/// A <see cref="Vector"/> with the given dimension. /// A Vector with the given dimension.
/// </returns> /// </returns>
/// <remarks> /// <remarks>
/// Creates a vector of the same type as the current matrix. /// Creates a vector of the same type as the current matrix.
/// </remarks> /// </remarks>
public abstract Vector CreateVector(int size); public abstract Vector<T> CreateVector(int size);
/// <summary> /// <summary>
/// Returns a <see cref="System.String"/> that represents this instance. /// Returns a <see cref="System.String"/> that represents this instance.
@ -253,13 +256,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double
} }
/// <summary> /// <summary>
/// Copies a row into an <see cref="Vector"/>. /// Copies a row into an Vector.
/// </summary> /// </summary>
/// <param name="index">The row to copy.</param> /// <param name="index">The row to copy.</param>
/// <returns>A <see cref="Vector"/> containing the copied elements.</returns> /// <returns>A Vector containing the copied elements.</returns>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="index"/> is negative, /// <exception cref="ArgumentOutOfRangeException">If <paramref name="index"/> is negative,
/// or greater than or equal to the number of rows.</exception> /// or greater than or equal to the number of rows.</exception>
public virtual Vector Row(int index) public virtual Vector<T> Row(int index)
{ {
var ret = CreateVector(ColumnCount); var ret = CreateVector(ColumnCount);
Row(index, 0, ColumnCount, ret); Row(index, 0, ColumnCount, ret);
@ -267,26 +270,26 @@ namespace MathNet.Numerics.LinearAlgebra.Double
} }
/// <summary> /// <summary>
/// Copies a row into to the given <see cref="Vector"/>. /// Copies a row into to the given Vector.
/// </summary> /// </summary>
/// <param name="index">The row to copy.</param> /// <param name="index">The row to copy.</param>
/// <param name="result">The <see cref="Vector"/> to copy the row into.</param> /// <param name="result">The Vector to copy the row into.</param>
/// <exception cref="ArgumentNullException">If the result vector is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the result vector is <see langword="null" />.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="index"/> is negative, /// <exception cref="ArgumentOutOfRangeException">If <paramref name="index"/> is negative,
/// or greater than or equal to the number of rows.</exception> /// or greater than or equal to the number of rows.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <b>this.Columns != result.Count</b>.</exception> /// <exception cref="ArgumentOutOfRangeException">If <b>this.Columns != result.Count</b>.</exception>
public virtual void Row(int index, Vector result) public virtual void Row(int index, Vector<T> result)
{ {
Row(index, 0, ColumnCount, result); Row(index, 0, ColumnCount, result);
} }
/// <summary> /// <summary>
/// Copies the requested row elements into a new <see cref="Vector"/>. /// Copies the requested row elements into a new Vector.
/// </summary> /// </summary>
/// <param name="rowIndex">The row to copy elements from.</param> /// <param name="rowIndex">The row to copy elements from.</param>
/// <param name="columnIndex">The column to start copying from.</param> /// <param name="columnIndex">The column to start copying from.</param>
/// <param name="length">The number of elements to copy.</param> /// <param name="length">The number of elements to copy.</param>
/// <returns>A <see cref="Vector"/> containing the requested elements.</returns> /// <returns>A Vector containing the requested elements.</returns>
/// <exception cref="ArgumentOutOfRangeException">If: /// <exception cref="ArgumentOutOfRangeException">If:
/// <list><item><paramref name="rowIndex"/> is negative, /// <list><item><paramref name="rowIndex"/> is negative,
/// or greater than or equal to the number of rows.</item> /// or greater than or equal to the number of rows.</item>
@ -294,7 +297,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// or greater than or equal to the number of columns.</item> /// or greater than or equal to the number of columns.</item>
/// <item><c>(columnIndex + length) &gt;= Columns.</c></item></list></exception> /// <item><c>(columnIndex + length) &gt;= Columns.</c></item></list></exception>
/// <exception cref="ArgumentException">If <paramref name="length"/> is not positive.</exception> /// <exception cref="ArgumentException">If <paramref name="length"/> is not positive.</exception>
public virtual Vector Row(int rowIndex, int columnIndex, int length) public virtual Vector<T> Row(int rowIndex, int columnIndex, int length)
{ {
var ret = CreateVector(length); var ret = CreateVector(length);
Row(rowIndex, columnIndex, length, ret); Row(rowIndex, columnIndex, length, ret);
@ -302,13 +305,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double
} }
/// <summary> /// <summary>
/// Copies the requested row elements into a new <see cref="Vector"/>. /// Copies the requested row elements into a new Vector.
/// </summary> /// </summary>
/// <param name="rowIndex">The row to copy elements from.</param> /// <param name="rowIndex">The row to copy elements from.</param>
/// <param name="columnIndex">The column to start copying from.</param> /// <param name="columnIndex">The column to start copying from.</param>
/// <param name="length">The number of elements to copy.</param> /// <param name="length">The number of elements to copy.</param>
/// <param name="result">The <see cref="Vector"/> to copy the column into.</param> /// <param name="result">The Vector to copy the column into.</param>
/// <exception cref="ArgumentNullException">If the result <see cref="Vector"/> is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the result Vector is <see langword="null" />.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="rowIndex"/> is negative, /// <exception cref="ArgumentOutOfRangeException">If <paramref name="rowIndex"/> is negative,
/// or greater than or equal to the number of columns.</exception> /// or greater than or equal to the number of columns.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="columnIndex"/> is negative, /// <exception cref="ArgumentOutOfRangeException">If <paramref name="columnIndex"/> is negative,
@ -317,7 +320,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// is greater than or equal to the number of rows.</exception> /// is greater than or equal to the number of rows.</exception>
/// <exception cref="ArgumentException">If <paramref name="length"/> is not positive.</exception> /// <exception cref="ArgumentException">If <paramref name="length"/> is not positive.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <strong>result.Count &lt; length</strong>.</exception> /// <exception cref="ArgumentOutOfRangeException">If <strong>result.Count &lt; length</strong>.</exception>
public virtual void Row(int rowIndex, int columnIndex, int length, Vector result) public virtual void Row(int rowIndex, int columnIndex, int length, Vector<T> result)
{ {
if (result == null) if (result == null)
{ {
@ -356,13 +359,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double
} }
/// <summary> /// <summary>
/// Copies a column into a new <see cref="Vector"/>. /// Copies a column into a new Vector>.
/// </summary> /// </summary>
/// <param name="index">The column to copy.</param> /// <param name="index">The column to copy.</param>
/// <returns>A <see cref="Vector"/> containing the copied elements.</returns> /// <returns>A Vector containing the copied elements.</returns>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="index"/> is negative, /// <exception cref="ArgumentOutOfRangeException">If <paramref name="index"/> is negative,
/// or greater than or equal to the number of columns.</exception> /// or greater than or equal to the number of columns.</exception>
public virtual Vector Column(int index) public virtual Vector<T> Column(int index)
{ {
var result = CreateVector(RowCount); var result = CreateVector(RowCount);
Column(index, 0, RowCount, result); Column(index, 0, RowCount, result);
@ -370,26 +373,26 @@ namespace MathNet.Numerics.LinearAlgebra.Double
} }
/// <summary> /// <summary>
/// Copies a column into to the given <see cref="Vector"/>. /// Copies a column into to the given Vector.
/// </summary> /// </summary>
/// <param name="index">The column to copy.</param> /// <param name="index">The column to copy.</param>
/// <param name="result">The <see cref="Vector"/> to copy the column into.</param> /// <param name="result">The Vector to copy the column into.</param>
/// <exception cref="ArgumentNullException">If the result <see cref="Vector"/> is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the result Vector is <see langword="null" />.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="index"/> is negative, /// <exception cref="ArgumentOutOfRangeException">If <paramref name="index"/> is negative,
/// or greater than or equal to the number of columns.</exception> /// or greater than or equal to the number of columns.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <b>this.Rows != result.Count</b>.</exception> /// <exception cref="ArgumentOutOfRangeException">If <b>this.Rows != result.Count</b>.</exception>
public virtual void Column(int index, Vector result) public virtual void Column(int index, Vector<T> result)
{ {
Column(index, 0, RowCount, result); Column(index, 0, RowCount, result);
} }
/// <summary> /// <summary>
/// Copies the requested column elements into a new <see cref="Vector"/>. /// Copies the requested column elements into a new Vector.
/// </summary> /// </summary>
/// <param name="columnIndex">The column to copy elements from.</param> /// <param name="columnIndex">The column to copy elements from.</param>
/// <param name="rowIndex">The row to start copying from.</param> /// <param name="rowIndex">The row to start copying from.</param>
/// <param name="length">The number of elements to copy.</param> /// <param name="length">The number of elements to copy.</param>
/// <returns>A <see cref="Vector"/> containing the requested elements.</returns> /// <returns>A Vector containing the requested elements.</returns>
/// <exception cref="ArgumentOutOfRangeException">If: /// <exception cref="ArgumentOutOfRangeException">If:
/// <list><item><paramref name="columnIndex"/> is negative, /// <list><item><paramref name="columnIndex"/> is negative,
/// or greater than or equal to the number of columns.</item> /// or greater than or equal to the number of columns.</item>
@ -398,7 +401,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <item><c>(rowIndex + length) &gt;= Rows.</c></item></list> /// <item><c>(rowIndex + length) &gt;= Rows.</c></item></list>
/// </exception> /// </exception>
/// <exception cref="ArgumentException">If <paramref name="length"/> is not positive.</exception> /// <exception cref="ArgumentException">If <paramref name="length"/> is not positive.</exception>
public virtual Vector Column(int columnIndex, int rowIndex, int length) public virtual Vector<T> Column(int columnIndex, int rowIndex, int length)
{ {
var result = CreateVector(length); var result = CreateVector(length);
Column(columnIndex, rowIndex, length, result); Column(columnIndex, rowIndex, length, result);
@ -411,8 +414,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="columnIndex">The column to copy elements from.</param> /// <param name="columnIndex">The column to copy elements from.</param>
/// <param name="rowIndex">The row to start copying from.</param> /// <param name="rowIndex">The row to start copying from.</param>
/// <param name="length">The number of elements to copy.</param> /// <param name="length">The number of elements to copy.</param>
/// <param name="result">The <see cref="Vector"/> to copy the column into.</param> /// <param name="result">The Vector to copy the column into.</param>
/// <exception cref="ArgumentNullException">If the result <see cref="Vector"/> is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the result Vector is <see langword="null" />.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="columnIndex"/> is negative, /// <exception cref="ArgumentOutOfRangeException">If <paramref name="columnIndex"/> is negative,
/// or greater than or equal to the number of columns.</exception> /// or greater than or equal to the number of columns.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="rowIndex"/> is negative, /// <exception cref="ArgumentOutOfRangeException">If <paramref name="rowIndex"/> is negative,
@ -421,7 +424,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// is greater than or equal to the number of rows.</exception> /// is greater than or equal to the number of rows.</exception>
/// <exception cref="ArgumentException">If <paramref name="length"/> is not positive.</exception> /// <exception cref="ArgumentException">If <paramref name="length"/> is not positive.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <strong>result.Count &lt; length</strong>.</exception> /// <exception cref="ArgumentOutOfRangeException">If <strong>result.Count &lt; length</strong>.</exception>
public virtual void Column(int columnIndex, int rowIndex, int length, Vector result) public virtual void Column(int columnIndex, int rowIndex, int length, Vector<T> result)
{ {
if (result == null) if (result == null)
{ {
@ -463,7 +466,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// Returns a new matrix containing the lower triangle of this matrix. /// Returns a new matrix containing the lower triangle of this matrix.
/// </summary> /// </summary>
/// <returns>The lower triangle of this matrix.</returns> /// <returns>The lower triangle of this matrix.</returns>
public virtual Matrix LowerTriangle() public virtual Matrix<T> LowerTriangle()
{ {
var ret = CreateMatrix(RowCount, ColumnCount); var ret = CreateMatrix(RowCount, ColumnCount);
CommonParallel.For( CommonParallel.For(
@ -485,7 +488,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="result">Where to store the lower triangle.</param> /// <param name="result">Where to store the lower triangle.</param>
/// <exception cref="ArgumentNullException">If <paramref name="result"/> is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If <paramref name="result"/> is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If the result matrix's dimensions are not the same as this matrix.</exception> /// <exception cref="ArgumentException">If the result matrix's dimensions are not the same as this matrix.</exception>
public virtual void LowerTriangle(Matrix result) public virtual void LowerTriangle(Matrix<T> result)
{ {
if (result == null) if (result == null)
{ {
@ -504,7 +507,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
{ {
for (var i = 0; i < RowCount; i++) for (var i = 0; i < RowCount; i++)
{ {
result.At(i, j, i >= j ? At(i, j) : 0); result.At(i, j, i >= j ? At(i, j) : default(T));
} }
}); });
} }
@ -513,7 +516,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// Returns a new matrix containing the upper triangle of this matrix. /// Returns a new matrix containing the upper triangle of this matrix.
/// </summary> /// </summary>
/// <returns>The upper triangle of this matrix.</returns> /// <returns>The upper triangle of this matrix.</returns>
public virtual Matrix UpperTriangle() public virtual Matrix<T> UpperTriangle()
{ {
var ret = CreateMatrix(RowCount, ColumnCount); var ret = CreateMatrix(RowCount, ColumnCount);
CommonParallel.For( CommonParallel.For(
@ -538,7 +541,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="result">Where to store the lower triangle.</param> /// <param name="result">Where to store the lower triangle.</param>
/// <exception cref="ArgumentNullException">If <paramref name="result"/> is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If <paramref name="result"/> is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If the result matrix's dimensions are not the same as this matrix.</exception> /// <exception cref="ArgumentException">If the result matrix's dimensions are not the same as this matrix.</exception>
public virtual void UpperTriangle(Matrix result) public virtual void UpperTriangle(Matrix<T> result)
{ {
if (result == null) if (result == null)
{ {
@ -557,7 +560,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
{ {
for (var i = 0; i < RowCount; i++) for (var i = 0; i < RowCount; i++)
{ {
result.At(i, j, i <= j ? At(i, j) : 0); result.At(i, j, i <= j ? At(i, j) : default(T));
} }
}); });
} }
@ -578,7 +581,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <item><c>(rowIndex + rowLength) &gt;= Rows</c></item></list></exception> /// <item><c>(rowIndex + rowLength) &gt;= Rows</c></item></list></exception>
/// <exception cref="ArgumentException">If <paramref name="rowLength"/> or <paramref name="columnLength"/> /// <exception cref="ArgumentException">If <paramref name="rowLength"/> or <paramref name="columnLength"/>
/// is not positive.</exception> /// is not positive.</exception>
public virtual Matrix SubMatrix(int rowIndex, int rowLength, int columnIndex, int columnLength) public virtual Matrix<T> SubMatrix(int rowIndex, int rowLength, int columnIndex, int columnLength)
{ {
if (rowIndex >= RowCount || rowIndex < 0) if (rowIndex >= RowCount || rowIndex < 0)
{ {
@ -633,11 +636,11 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// </summary> /// </summary>
/// <returns>An <see cref="IEnumerator{T}"/> that enumerates over the matrix columns</returns> /// <returns>An <see cref="IEnumerator{T}"/> that enumerates over the matrix columns</returns>
/// <seealso cref="IEnumerator{T}"/> /// <seealso cref="IEnumerator{T}"/>
public virtual IEnumerable<KeyValuePair<int, Vector>> ColumnEnumerator() public virtual IEnumerable<KeyValuePair<int, Vector<T>>> ColumnEnumerator()
{ {
for (var i = 0; i < ColumnCount; i++) for (var i = 0; i < ColumnCount; i++)
{ {
yield return new KeyValuePair<int, Vector>(i, Column(i)); yield return new KeyValuePair<int, Vector<T>>(i, Column(i));
} }
} }
@ -654,7 +657,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <item><c>(index + length) &gt;= Columns.</c></item></list> /// <item><c>(index + length) &gt;= Columns.</c></item></list>
/// </exception> /// </exception>
/// <exception cref="ArgumentException">If <paramref name="length"/> is not positive.</exception> /// <exception cref="ArgumentException">If <paramref name="length"/> is not positive.</exception>
public virtual IEnumerable<KeyValuePair<int, Vector>> ColumnEnumerator(int index, int length) public virtual IEnumerable<KeyValuePair<int, Vector<T>>> ColumnEnumerator(int index, int length)
{ {
if (index >= ColumnCount || index < 0) if (index >= ColumnCount || index < 0)
{ {
@ -674,7 +677,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
var maxIndex = index + length; var maxIndex = index + length;
for (var i = index; i < maxIndex; i++) for (var i = index; i < maxIndex; i++)
{ {
yield return new KeyValuePair<int, Vector>(i, Column(i)); yield return new KeyValuePair<int, Vector<T>>(i, Column(i));
} }
} }
@ -690,7 +693,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// or greater than or equal to the number of rows.</item> /// or greater than or equal to the number of rows.</item>
/// <item><c>(index + length) &gt;= Rows.</c></item></list></exception> /// <item><c>(index + length) &gt;= Rows.</c></item></list></exception>
/// <exception cref="ArgumentException">If <paramref name="length"/> is not positive.</exception> /// <exception cref="ArgumentException">If <paramref name="length"/> is not positive.</exception>
public virtual IEnumerable<KeyValuePair<int, Vector>> RowEnumerator(int index, int length) public virtual IEnumerable<KeyValuePair<int, Vector<T>>> RowEnumerator(int index, int length)
{ {
if (index >= RowCount || index < 0) if (index >= RowCount || index < 0)
{ {
@ -710,7 +713,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
var maxi = index + length; var maxi = index + length;
for (var i = index; i < maxi; i++) for (var i = index; i < maxi; i++)
{ {
yield return new KeyValuePair<int, Vector>(i, Row(i)); yield return new KeyValuePair<int, Vector<T>>(i, Row(i));
} }
} }
@ -719,21 +722,21 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// </summary> /// </summary>
/// <returns>An <see cref="IEnumerator{T}"/> that enumerates over the matrix rows</returns> /// <returns>An <see cref="IEnumerator{T}"/> that enumerates over the matrix rows</returns>
/// <seealso cref="IEnumerator{T}"/> /// <seealso cref="IEnumerator{T}"/>
public virtual IEnumerable<KeyValuePair<int, Vector>> RowEnumerator() public virtual IEnumerable<KeyValuePair<int, Vector<T>>> RowEnumerator()
{ {
for (var i = 0; i < RowCount; i++) for (var i = 0; i < RowCount; i++)
{ {
yield return new KeyValuePair<int, Vector>(i, Row(i)); yield return new KeyValuePair<int, Vector<T>>(i, Row(i));
} }
} }
/// <summary> /// <summary>
/// Returns the elements of the diagonal in a <see cref="Vector"/>. /// Returns the elements of the diagonal in a Vector.
/// </summary> /// </summary>
/// <returns>The elements of the diagonal.</returns> /// <returns>The elements of the diagonal.</returns>
/// <remarks>For non-square matrices, the method returns Min(Rows, Columns) elements where /// <remarks>For non-square matrices, the method returns Min(Rows, Columns) elements where
/// i == j (i is the row index, and j is the column index).</remarks> /// i == j (i is the row index, and j is the column index).</remarks>
public virtual Vector Diagonal() public virtual Vector<T> Diagonal()
{ {
var min = Math.Min(RowCount, ColumnCount); var min = Math.Min(RowCount, ColumnCount);
var diagonal = CreateVector(min); var diagonal = CreateVector(min);
@ -749,7 +752,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// does not contain the diagonal elements of this matrix. /// does not contain the diagonal elements of this matrix.
/// </summary> /// </summary>
/// <returns>The lower triangle of this matrix.</returns> /// <returns>The lower triangle of this matrix.</returns>
public virtual Matrix StrictlyLowerTriangle() public virtual Matrix<T> StrictlyLowerTriangle()
{ {
var result = CreateMatrix(RowCount, ColumnCount); var result = CreateMatrix(RowCount, ColumnCount);
CommonParallel.For( CommonParallel.For(
@ -774,7 +777,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="result">Where to store the lower triangle.</param> /// <param name="result">Where to store the lower triangle.</param>
/// <exception cref="ArgumentNullException">If <paramref name="result"/> is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If <paramref name="result"/> is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If the result matrix's dimensions are not the same as this matrix.</exception> /// <exception cref="ArgumentException">If the result matrix's dimensions are not the same as this matrix.</exception>
public virtual void StrictlyLowerTriangle(Matrix result) public virtual void StrictlyLowerTriangle(Matrix<T> result)
{ {
if (result == null) if (result == null)
{ {
@ -793,7 +796,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
{ {
for (var j = 0; j < ColumnCount; j++) for (var j = 0; j < ColumnCount; j++)
{ {
result.At(i, j, i > j ? At(i, j) : 0); result.At(i, j, i > j ? At(i, j) : default(T));
} }
}); });
} }
@ -803,7 +806,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// does not contain the diagonal elements of this matrix. /// does not contain the diagonal elements of this matrix.
/// </summary> /// </summary>
/// <returns>The upper triangle of this matrix.</returns> /// <returns>The upper triangle of this matrix.</returns>
public virtual Matrix StrictlyUpperTriangle() public virtual Matrix<T> StrictlyUpperTriangle()
{ {
var result = CreateMatrix(RowCount, ColumnCount); var result = CreateMatrix(RowCount, ColumnCount);
CommonParallel.For( CommonParallel.For(
@ -822,6 +825,36 @@ namespace MathNet.Numerics.LinearAlgebra.Double
return result; return result;
} }
/// <summary>
/// Puts the strictly upper triangle of this matrix into the result matrix.
/// </summary>
/// <param name="result">Where to store the lower triangle.</param>
/// <exception cref="ArgumentNullException">If <paramref name="result"/> is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If the result matrix's dimensions are not the same as this matrix.</exception>
public virtual void StrictlyUpperTriangle(Matrix<T> result)
{
if (result == null)
{
throw new ArgumentNullException("result");
}
if (result.RowCount != RowCount || result.ColumnCount != ColumnCount)
{
throw new ArgumentException(Resources.ArgumentMatrixDimensions, "result");
}
CommonParallel.For(
0,
RowCount,
i =>
{
for (var j = 0; j < ColumnCount; j++)
{
result.At(i, j, i < j ? At(i, j) : default(T));
}
});
}
/// <summary> /// <summary>
/// Creates a new matrix and inserts the given column at the given index. /// Creates a new matrix and inserts the given column at the given index.
/// </summary> /// </summary>
@ -831,7 +864,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentNullException">If <paramref name="column "/> is <see langword="null" />. </exception> /// <exception cref="ArgumentNullException">If <paramref name="column "/> is <see langword="null" />. </exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="columnIndex"/> is &lt; zero or &gt; the number of columns.</exception> /// <exception cref="ArgumentOutOfRangeException">If <paramref name="columnIndex"/> is &lt; zero or &gt; the number of columns.</exception>
/// <exception cref="ArgumentException">If the size of <paramref name="column"/> != the number of rows.</exception> /// <exception cref="ArgumentException">If the size of <paramref name="column"/> != the number of rows.</exception>
public virtual Matrix InsertColumn(int columnIndex, Vector column) public virtual Matrix<T> InsertColumn(int columnIndex, Vector<T> column)
{ {
if (column == null) if (column == null)
{ {
@ -877,7 +910,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// equal the number of rows of this <strong>Matrix</strong>.</exception> /// equal the number of rows of this <strong>Matrix</strong>.</exception>
/// <exception cref="ArgumentException">If the size of <paramref name="column"/> does not /// <exception cref="ArgumentException">If the size of <paramref name="column"/> does not
/// equal the number of rows of this <strong>Matrix</strong>.</exception> /// equal the number of rows of this <strong>Matrix</strong>.</exception>
public virtual void SetColumn(int columnIndex, double[] column) public virtual void SetColumn(int columnIndex, T[] column)
{ {
if (columnIndex < 0 || columnIndex >= ColumnCount) if (columnIndex < 0 || columnIndex >= ColumnCount)
{ {
@ -901,7 +934,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
} }
/// <summary> /// <summary>
/// Copies the values of the given <see cref="Vector"/> to the specified column. /// Copies the values of the given Vector to the specified column.
/// </summary> /// </summary>
/// <param name="columnIndex">The column to copy the values to.</param> /// <param name="columnIndex">The column to copy the values to.</param>
/// <param name="column">The vector to copy the values from.</param> /// <param name="column">The vector to copy the values from.</param>
@ -910,7 +943,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// or greater than or equal to the number of columns.</exception> /// or greater than or equal to the number of columns.</exception>
/// <exception cref="ArgumentException">If the size of <paramref name="column"/> does not /// <exception cref="ArgumentException">If the size of <paramref name="column"/> does not
/// equal the number of rows of this <strong>Matrix</strong>.</exception> /// equal the number of rows of this <strong>Matrix</strong>.</exception>
public virtual void SetColumn(int columnIndex, Vector column) public virtual void SetColumn(int columnIndex, Vector<T> column)
{ {
if (columnIndex < 0 || columnIndex >= ColumnCount) if (columnIndex < 0 || columnIndex >= ColumnCount)
{ {
@ -942,7 +975,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentNullException">If <paramref name="row"/> is <see langword="null" />. </exception> /// <exception cref="ArgumentNullException">If <paramref name="row"/> is <see langword="null" />. </exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="rowIndex"/> is &lt; zero or &gt; the number of rows.</exception> /// <exception cref="ArgumentOutOfRangeException">If <paramref name="rowIndex"/> is &lt; zero or &gt; the number of rows.</exception>
/// <exception cref="ArgumentException">If the size of <paramref name="row"/> != the number of columns.</exception> /// <exception cref="ArgumentException">If the size of <paramref name="row"/> != the number of columns.</exception>
public virtual Matrix InsertRow(int rowIndex, Vector row) public virtual Matrix<T> InsertRow(int rowIndex, Vector<T> row)
{ {
if (row == null) if (row == null)
{ {
@ -977,7 +1010,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
} }
/// <summary> /// <summary>
/// Copies the values of the given <see cref="Vector"/> to the specified row. /// Copies the values of the given Vector to the specified row.
/// </summary> /// </summary>
/// <param name="rowIndex">The row to copy the values to.</param> /// <param name="rowIndex">The row to copy the values to.</param>
/// <param name="row">The vector to copy the values from.</param> /// <param name="row">The vector to copy the values from.</param>
@ -986,7 +1019,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// or greater than or equal to the number of rows.</exception> /// or greater than or equal to the number of rows.</exception>
/// <exception cref="ArgumentException">If the size of <paramref name="row"/> does not /// <exception cref="ArgumentException">If the size of <paramref name="row"/> does not
/// equal the number of columns of this <strong>Matrix</strong>.</exception> /// equal the number of columns of this <strong>Matrix</strong>.</exception>
public virtual void SetRow(int rowIndex, Vector row) public virtual void SetRow(int rowIndex, Vector<T> row)
{ {
if (rowIndex < 0 || rowIndex >= RowCount) if (rowIndex < 0 || rowIndex >= RowCount)
{ {
@ -1019,7 +1052,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// or greater than or equal to the number of rows.</exception> /// or greater than or equal to the number of rows.</exception>
/// <exception cref="ArgumentException">If the size of <paramref name="row"/> does not /// <exception cref="ArgumentException">If the size of <paramref name="row"/> does not
/// equal the number of columns of this <strong>Matrix</strong>.</exception> /// equal the number of columns of this <strong>Matrix</strong>.</exception>
public virtual void SetRow(int rowIndex, double[] row) public virtual void SetRow(int rowIndex, T[] row)
{ {
if (rowIndex < 0 || rowIndex >= RowCount) if (rowIndex < 0 || rowIndex >= RowCount)
{ {
@ -1060,7 +1093,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <item>the size of <paramref name="subMatrix"/> is not at least <paramref name="rowLength"/> x <paramref name="columnLength"/>.</item> /// <item>the size of <paramref name="subMatrix"/> is not at least <paramref name="rowLength"/> x <paramref name="columnLength"/>.</item>
/// <exception cref="ArgumentException">If <paramref name="rowLength"/> or <paramref name="columnLength"/> /// <exception cref="ArgumentException">If <paramref name="rowLength"/> or <paramref name="columnLength"/>
/// is not positive.</exception> /// is not positive.</exception>
public virtual void SetSubMatrix(int rowIndex, int rowLength, int columnIndex, int columnLength, Matrix subMatrix) public virtual void SetSubMatrix(int rowIndex, int rowLength, int columnIndex, int columnLength, Matrix<T> subMatrix)
{ {
if (rowIndex >= RowCount || rowIndex < 0) if (rowIndex >= RowCount || rowIndex < 0)
{ {
@ -1123,7 +1156,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
} }
/// <summary> /// <summary>
/// Copies the values of the given <see cref="Vector"/> to the diagonal. /// Copies the values of the given Vector to the diagonal.
/// </summary> /// </summary>
/// <param name="source">The vector to copy the values from. The length of the vector should be /// <param name="source">The vector to copy the values from. The length of the vector should be
/// Min(Rows, Columns).</param> /// Min(Rows, Columns).</param>
@ -1132,7 +1165,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// equal Min(Rows, Columns).</exception> /// equal Min(Rows, Columns).</exception>
/// <remarks>For non-square matrices, the elements of <paramref name="source"/> are copied to /// <remarks>For non-square matrices, the elements of <paramref name="source"/> are copied to
/// this[i,i].</remarks> /// this[i,i].</remarks>
public virtual void SetDiagonal(Vector source) public virtual void SetDiagonal(Vector<T> source)
{ {
if (source == null) if (source == null)
{ {
@ -1162,7 +1195,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// equal Min(Rows, Columns).</exception> /// equal Min(Rows, Columns).</exception>
/// <remarks>For non-square matrices, the elements of <paramref name="source"/> are copied to /// <remarks>For non-square matrices, the elements of <paramref name="source"/> are copied to
/// this[i,i].</remarks> /// this[i,i].</remarks>
public virtual void SetDiagonal(double[] source) public virtual void SetDiagonal(T[] source)
{ {
if (source == null) if (source == null)
{ {
@ -1182,43 +1215,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double
i => At(i, i, source[i])); i => At(i, i, source[i]));
} }
/// <summary>
/// Puts the strictly upper triangle of this matrix into the result matrix.
/// </summary>
/// <param name="result">Where to store the lower triangle.</param>
/// <exception cref="ArgumentNullException">If <paramref name="result"/> is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If the result matrix's dimensions are not the same as this matrix.</exception>
public virtual void StrictlyUpperTriangle(Matrix result)
{
if (result == null)
{
throw new ArgumentNullException("result");
}
if (result.RowCount != RowCount || result.ColumnCount != ColumnCount)
{
throw new ArgumentException(Resources.ArgumentMatrixDimensions, "result");
}
CommonParallel.For(
0,
RowCount,
i =>
{
for (var j = 0; j < ColumnCount; j++)
{
result.At(i, j, i < j ? At(i, j) : 0);
}
});
}
/// <summary> /// <summary>
/// Returns this matrix as a multidimensional array. /// Returns this matrix as a multidimensional array.
/// </summary> /// </summary>
/// <returns>A multidimensional containing the values of this matrix.</returns> /// <returns>A multidimensional containing the values of this matrix.</returns>
public virtual double[,] ToArray() public virtual T[,] ToArray()
{ {
var ret = new double[RowCount, ColumnCount]; var ret = new T[RowCount, ColumnCount];
CommonParallel.For( CommonParallel.For(
0, 0,
ColumnCount, ColumnCount,
@ -1241,9 +1244,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// 7, 8, 9 /// 7, 8, 9
/// </pre></example> /// </pre></example>
/// <returns>An array containing the matrix's elements.</returns> /// <returns>An array containing the matrix's elements.</returns>
public virtual double[] ToColumnWiseArray() public virtual T[] ToColumnWiseArray()
{ {
var ret = new double[RowCount * ColumnCount]; var ret = new T[RowCount * ColumnCount];
foreach (var column in ColumnEnumerator()) foreach (var column in ColumnEnumerator())
{ {
var columnIndex = column.Key * RowCount; var columnIndex = column.Key * RowCount;
@ -1265,9 +1268,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// 7, 8, 9 /// 7, 8, 9
/// </pre></example> /// </pre></example>
/// <returns>An array containing the matrix's elements.</returns> /// <returns>An array containing the matrix's elements.</returns>
public virtual double[] ToRowWiseArray() public virtual T[] ToRowWiseArray()
{ {
var ret = new double[RowCount * ColumnCount]; var ret = new T[RowCount * ColumnCount];
foreach (var row in RowEnumerator()) foreach (var row in RowEnumerator())
{ {
@ -1302,7 +1305,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
#endif #endif
#region IEquatable<Matrix> #region IEquatable<Matrix<T>>
/// <summary> /// <summary>
/// Indicates whether the current object is equal to another object of the same type. /// Indicates whether the current object is equal to another object of the same type.
@ -1313,7 +1316,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns> /// <returns>
/// <c>true</c> if the current object is equal to the <paramref name="other"/> parameter; otherwise, <c>false</c>. /// <c>true</c> if the current object is equal to the <paramref name="other"/> parameter; otherwise, <c>false</c>.
/// </returns> /// </returns>
public bool Equals(Matrix other) public virtual bool Equals(Matrix<T> other)
{ {
// Reject equality when the argument is null or has a different shape. // Reject equality when the argument is null or has a different shape.
if (other == null) if (other == null)
@ -1337,7 +1340,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
{ {
for (var column = 0; column < ColumnCount; column++) for (var column = 0; column < ColumnCount; column++)
{ {
if (At(row, column) != other.At(row, column)) if (!At(row, column).Equals(other.At(row, column)))
{ {
return false; return false;
} }
@ -1363,7 +1366,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns> /// <returns>
/// A <see cref="System.String"/> that represents this instance. /// A <see cref="System.String"/> that represents this instance.
/// </returns> /// </returns>
public string ToString(string format, IFormatProvider formatProvider) public virtual string ToString(string format, IFormatProvider formatProvider)
{ {
var stringBuilder = new StringBuilder(); var stringBuilder = new StringBuilder();
for (var row = 0; row < RowCount; row++) for (var row = 0; row < RowCount; row++)
@ -1423,7 +1426,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// </returns> /// </returns>
public override bool Equals(object obj) public override bool Equals(object obj)
{ {
return Equals(obj as Matrix); return Equals(obj as Matrix<T>);
} }
/// <summary> /// <summary>
@ -1442,15 +1445,14 @@ namespace MathNet.Numerics.LinearAlgebra.Double
var row = (i - col) / RowCount; var row = (i - col) / RowCount;
#if SILVERLIGHT #if SILVERLIGHT
hash ^= Precision.DoubleToInt64Bits(this[row, col]); hash ^= Precision.DoubleToInt64Bits(this[row, col].GetHashCode());
#else #else
hash ^= BitConverter.DoubleToInt64Bits(this[row, col]); hash ^= BitConverter.DoubleToInt64Bits(this[row, col].GetHashCode());
#endif #endif
} }
return BitConverter.ToInt32(BitConverter.GetBytes(hash), 4); return BitConverter.ToInt32(BitConverter.GetBytes(hash), 4);
} }
#endregion #endregion
/// <summary> /// <summary>
@ -1462,7 +1464,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
{ {
for (var j = 0; j < ColumnCount; j++) for (var j = 0; j < ColumnCount; j++)
{ {
At(i, j, 0); At(i, j, default(T));
} }
} }
} }
@ -1471,7 +1473,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// Returns the transpose of this matrix. /// Returns the transpose of this matrix.
/// </summary> /// </summary>
/// <returns>The transpose of this matrix.</returns> /// <returns>The transpose of this matrix.</returns>
public virtual Matrix Transpose() public virtual Matrix<T> Transpose()
{ {
var ret = CreateMatrix(ColumnCount, RowCount); var ret = CreateMatrix(ColumnCount, RowCount);
for (var j = 0; j < ColumnCount; j++) for (var j = 0; j < ColumnCount; j++)
@ -1548,7 +1550,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// </summary> /// </summary>
/// <param name="right">The matrix to concatenate.</param> /// <param name="right">The matrix to concatenate.</param>
/// <returns>The combined matrix.</returns> /// <returns>The combined matrix.</returns>
public virtual Matrix Append(Matrix right) public virtual Matrix<T> Append(Matrix<T> right)
{ {
if (right == null) if (right == null)
{ {
@ -1570,7 +1572,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// </summary> /// </summary>
/// <param name="right">The matrix to concatenate.</param> /// <param name="right">The matrix to concatenate.</param>
/// <param name="result">The combined matrix.</param> /// <param name="result">The combined matrix.</param>
public virtual void Append(Matrix right, Matrix result) public virtual void Append(Matrix<T> right, Matrix<T> result)
{ {
if (right == null) if (right == null)
{ {
@ -1622,7 +1624,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>The combined matrix.</returns> /// <returns>The combined matrix.</returns>
/// <exception cref="ArgumentNullException">If lower is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If lower is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If <strong>upper.Columns != lower.Columns</strong>.</exception> /// <exception cref="ArgumentException">If <strong>upper.Columns != lower.Columns</strong>.</exception>
public virtual Matrix Stack(Matrix lower) public virtual Matrix<T> Stack(Matrix<T> lower)
{ {
if (lower == null) if (lower == null)
{ {
@ -1646,7 +1648,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="result">The combined matrix.</param> /// <param name="result">The combined matrix.</param>
/// <exception cref="ArgumentNullException">If lower is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If lower is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If <strong>upper.Columns != lower.Columns</strong>.</exception> /// <exception cref="ArgumentException">If <strong>upper.Columns != lower.Columns</strong>.</exception>
public virtual void Stack(Matrix lower, Matrix result) public virtual void Stack(Matrix<T> lower, Matrix<T> result)
{ {
if (lower == null) if (lower == null)
{ {
@ -1699,7 +1701,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="lower">The lower, right matrix.</param> /// <param name="lower">The lower, right matrix.</param>
/// <exception cref="ArgumentNullException">If lower is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If lower is <see langword="null" />.</exception>
/// <returns>the combined matrix</returns> /// <returns>the combined matrix</returns>
public virtual Matrix DiagonalStack(Matrix lower) public virtual Matrix<T> DiagonalStack(Matrix<T> lower)
{ {
if (lower == null) if (lower == null)
{ {
@ -1719,7 +1721,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentNullException">If lower is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If lower is <see langword="null" />.</exception>
/// <exception cref="ArgumentNullException">If the result matrix is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the result matrix is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If the result matrix's dimensions are not (this.Rows + lower.rows) x (this.Columns + lower.Columns).</exception> /// <exception cref="ArgumentException">If the result matrix's dimensions are not (this.Rows + lower.rows) x (this.Columns + lower.Columns).</exception>
public virtual void DiagonalStack(Matrix lower, Matrix result) public virtual void DiagonalStack(Matrix<T> lower, Matrix<T> result)
{ {
if (lower == null) if (lower == null)
{ {
@ -1769,7 +1771,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
var s = 0.0; var s = 0.0;
for (var i = 0; i < RowCount; i++) for (var i = 0; i < RowCount; i++)
{ {
s += Math.Abs(At(i, j)); s += AbsoluteT(At(i, j));
} }
norm = Math.Max(norm, s); norm = Math.Max(norm, s);
@ -1784,7 +1786,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// In a later release, it will be replaced with a sparse implementation.</remarks> /// In a later release, it will be replaced with a sparse implementation.</remarks>
public virtual double L2Norm() public virtual double L2Norm()
{ {
return Svd.Create(this, false).Norm2; return Svd<T>.Create(this, false).Norm2;
} }
/// <summary>Calculates the Frobenius norm of this matrix.</summary> /// <summary>Calculates the Frobenius norm of this matrix.</summary>
@ -1796,11 +1798,11 @@ namespace MathNet.Numerics.LinearAlgebra.Double
// TODO: Replace with multiple Transpose // TODO: Replace with multiple Transpose
//// aat.Gemm(1.0, 0.0, false, true, this, this); //// aat.Gemm(1.0, 0.0, false, true, this, this);
var norm = 0.0; var norm = 0.0;
for (var i = 0; i < RowCount; i++) for (var i = 0; i < RowCount; i++)
{ {
norm += Math.Abs(aat.At(i, i)); norm += AbsoluteT(aat.At(i, i));
} }
norm = Math.Sqrt(norm); norm = Math.Sqrt(norm);
@ -1818,13 +1820,62 @@ namespace MathNet.Numerics.LinearAlgebra.Double
var s = 0.0; var s = 0.0;
for (var j = 0; j < ColumnCount; j++) for (var j = 0; j < ColumnCount; j++)
{ {
s += Math.Abs(At(i, j)); s += AbsoluteT(At(i, j));
} }
norm = Math.Max(norm, s); norm = Math.Max(norm, s);
} }
return norm; return norm;
} }
#region Simple arithmetic of type T
/// <summary>
/// Add two values T+T
/// </summary>
/// <param name="val1">Left operand value</param>
/// <param name="val2">Right operand value</param>
/// <returns>Result of addition</returns>
protected abstract T AddT(T val1, T val2);
/// <summary>
/// Subtract two values T-T
/// </summary>
/// <param name="val1">Left operand value</param>
/// <param name="val2">Right operand value</param>
/// <returns>Result of subtract</returns>
protected abstract T SubtractT(T val1, T val2);
/// <summary>
/// Multiply two values T*T
/// </summary>
/// <param name="val1">Left operand value</param>
/// <param name="val2">Right operand value</param>
/// <returns>Result of multiplication</returns>
protected abstract T MultiplyT(T val1, T val2);
/// <summary>
/// Divide two values T/T
/// </summary>
/// <param name="val1">Left operand value</param>
/// <param name="val2">Right operand value</param>
/// <returns>Result of divide</returns>
protected abstract T DivideT(T val1, T val2);
/// <summary>
/// Is equal to one?
/// </summary>
/// <param name="val1">Value to check</param>
/// <returns>True if one; otherwise false</returns>
protected abstract bool IsOneT(T val1);
/// <summary>
/// Take absolute value
/// </summary>
/// <param name="val1">Source alue</param>
/// <returns>True if one; otherwise false</returns>
protected abstract double AbsoluteT(T val1);
#endregion
} }
} }

21
src/Numerics/LinearAlgebra/Double/Solvers/IIterativeSolver.cs → src/Numerics/LinearAlgebra/Generic/Solvers/IIterativeSolver.cs

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

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

@ -28,16 +28,18 @@
// OTHER DEALINGS IN THE SOFTWARE. // OTHER DEALINGS IN THE SOFTWARE.
// </copyright> // </copyright>
namespace MathNet.Numerics.LinearAlgebra.Double.Solvers namespace MathNet.Numerics.LinearAlgebra.Generic.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>
public interface IIterativeSolverSetup /// <typeparam name="T">Supported data types are double, single, <see cref="Complex"/>, and <see cref="Complex32"/>.</typeparam>
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.
@ -53,8 +55,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double.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"/>.</returns> /// <returns>A new <see cref="IIterativeSolver{T}"/>.</returns>
IIterativeSolver CreateNew(); IIterativeSolver<T> CreateNew();
/// <summary> /// <summary>
/// Gets the relative speed of the solver. /// Gets the relative speed of the solver.

29
src/Numerics/LinearAlgebra/Double/Solvers/IIterator.cs → src/Numerics/LinearAlgebra/Generic/Solvers/IIterator.cs

@ -28,41 +28,44 @@
// OTHER DEALINGS IN THE SOFTWARE. // OTHER DEALINGS IN THE SOFTWARE.
// </copyright> // </copyright>
namespace MathNet.Numerics.LinearAlgebra.Double.Solvers namespace MathNet.Numerics.LinearAlgebra.Generic.Solvers
{ {
using System; using System;
using System.Numerics;
using 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>
public interface IIterator /// <typeparam name="T">Supported data types are double, single, <see cref="Complex"/>, and <see cref="Complex32"/>.</typeparam>
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"/> to the internal collection of stop-criteria. Only a /// Adds an <see cref="IIterationStopCriterium{T}"/> 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 stopCriterium); void Add(IIterationStopCriterium<T> stopCriterium);
/// <summary> /// <summary>
/// Removes the <see cref="IIterationStopCriterium"/> from the internal collection. /// Removes the <see cref="IIterationStopCriterium{T}"/> 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 stopCriterium); void Remove(IIterationStopCriterium<T> stopCriterium);
/// <summary> /// <summary>
/// Indicates if the specific stop criterium is stored by the <see cref="IIterator"/>. /// Indicates if the specific stop criterium is stored by the <see cref="IIterator{T}"/>.
/// </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"/> contains the stop criterium; otherwise <c>false</c>.</returns> /// <returns><c>true</c> if the <see cref="IIterator{T}"/> contains the stop criterium; otherwise <c>false</c>.</returns>
bool Contains(IIterationStopCriterium stopCriterium); bool Contains(IIterationStopCriterium<T> 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.
@ -72,7 +75,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"/>. Status is set to <c>Status</c> field of current object. /// by the current <see cref="IIterator{T}"/>. 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>
@ -83,7 +86,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>
void DetermineStatus(int iterationNumber, Vector solutionVector, Vector sourceVector, Vector residualVector); void DetermineStatus(int iterationNumber, Vector<T> solutionVector, Vector<T> sourceVector, Vector<T> residualVector);
/// <summary> /// <summary>
/// Gets the current calculation status. /// Gets the current calculation status.
@ -92,7 +95,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
ICalculationStatus Status { get; } ICalculationStatus Status { get; }
/// <summary> /// <summary>
/// Resets the <c>IIterator</c> to the pre-calculation state. /// Resets the <see cref="IIterator{T}"/> 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
@ -102,7 +105,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
void ResetToPrecalculationState(); void ResetToPrecalculationState();
#if SILVERLIGHT #if SILVERLIGHT
IIterator Clone(); IIterator<double> Clone();
#endif #endif
} }
} }

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

@ -28,8 +28,11 @@
// OTHER DEALINGS IN THE SOFTWARE. // OTHER DEALINGS IN THE SOFTWARE.
// </copyright> // </copyright>
namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners namespace MathNet.Numerics.LinearAlgebra.Generic.Solvers.Preconditioners
{ {
using System;
using System.Numerics;
/// <summary> /// <summary>
/// The base interface for preconditioner classes. /// The base interface for preconditioner classes.
/// </summary> /// </summary>
@ -48,26 +51,27 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
/// if the changes occur after creating the preconditioner. /// if the changes occur after creating the preconditioner.
/// </para> /// </para>
/// </remarks> /// </remarks>
public interface IPreConditioner /// <typeparam name="T">Supported data types are double, single, <see cref="Complex"/>, and <see cref="Complex32"/>.</typeparam>
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 matrix); void Initialize(Matrix<T> 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 Approximate(Vector rhs); Vector<double> Approximate(Vector<T> 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 rhs, Vector lhs); void Approximate(Vector<T> rhs, Vector<T> lhs);
} }
} }

2
src/Numerics/LinearAlgebra/Double/Solvers/Status/CalculationCancelled.cs → src/Numerics/LinearAlgebra/Generic/Solvers/Status/CalculationCancelled.cs

@ -28,7 +28,7 @@
// OTHER DEALINGS IN THE SOFTWARE. // OTHER DEALINGS IN THE SOFTWARE.
// </copyright> // </copyright>
namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Status namespace MathNet.Numerics.LinearAlgebra.Generic.Solvers.Status
{ {
/// <summary> /// <summary>
/// Indicates that a calculation was cancelled by the user. /// Indicates that a calculation was cancelled by the user.

2
src/Numerics/LinearAlgebra/Double/Solvers/Status/CalculationConverged.cs → src/Numerics/LinearAlgebra/Generic/Solvers/Status/CalculationConverged.cs

@ -28,7 +28,7 @@
// OTHER DEALINGS IN THE SOFTWARE. // OTHER DEALINGS IN THE SOFTWARE.
// </copyright> // </copyright>
namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Status namespace MathNet.Numerics.LinearAlgebra.Generic.Solvers.Status
{ {
/// <summary> /// <summary>
/// Indicates that a calculation has converged to the desired convergence levels. /// Indicates that a calculation has converged to the desired convergence levels.

2
src/Numerics/LinearAlgebra/Double/Solvers/Status/CalculationDiverged.cs → src/Numerics/LinearAlgebra/Generic/Solvers/Status/CalculationDiverged.cs

@ -28,7 +28,7 @@
// OTHER DEALINGS IN THE SOFTWARE. // OTHER DEALINGS IN THE SOFTWARE.
// </copyright> // </copyright>
namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Status namespace MathNet.Numerics.LinearAlgebra.Generic.Solvers.Status
{ {
/// <summary> /// <summary>
/// Indicates that the calculation diverged. /// Indicates that the calculation diverged.

2
src/Numerics/LinearAlgebra/Double/Solvers/Status/CalculationFailure.cs → src/Numerics/LinearAlgebra/Generic/Solvers/Status/CalculationFailure.cs

@ -28,7 +28,7 @@
// OTHER DEALINGS IN THE SOFTWARE. // OTHER DEALINGS IN THE SOFTWARE.
// </copyright> // </copyright>
namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Status namespace MathNet.Numerics.LinearAlgebra.Generic.Solvers.Status
{ {
/// <summary> /// <summary>
/// Indicates that a calculation has failed for some reason. /// Indicates that a calculation has failed for some reason.

2
src/Numerics/LinearAlgebra/Double/Solvers/Status/CalculationIndetermined.cs → src/Numerics/LinearAlgebra/Generic/Solvers/Status/CalculationIndetermined.cs

@ -28,7 +28,7 @@
// OTHER DEALINGS IN THE SOFTWARE. // OTHER DEALINGS IN THE SOFTWARE.
// </copyright> // </copyright>
namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Status namespace MathNet.Numerics.LinearAlgebra.Generic.Solvers.Status
{ {
/// <summary> /// <summary>
/// Indicates that the state of the calculation is indetermined, not started or stopped. /// Indicates that the state of the calculation is indetermined, not started or stopped.

2
src/Numerics/LinearAlgebra/Double/Solvers/Status/CalculationRunning.cs → src/Numerics/LinearAlgebra/Generic/Solvers/Status/CalculationRunning.cs

@ -28,7 +28,7 @@
// OTHER DEALINGS IN THE SOFTWARE. // OTHER DEALINGS IN THE SOFTWARE.
// </copyright> // </copyright>
namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Status namespace MathNet.Numerics.LinearAlgebra.Generic.Solvers.Status
{ {
/// <summary> /// <summary>
/// Indicates that the calculation is running and no results are yet known. /// Indicates that the calculation is running and no results are yet known.

2
src/Numerics/LinearAlgebra/Double/Solvers/Status/CalculationStoppedWithoutConvergence.cs → src/Numerics/LinearAlgebra/Generic/Solvers/Status/CalculationStoppedWithoutConvergence.cs

@ -28,7 +28,7 @@
// OTHER DEALINGS IN THE SOFTWARE. // OTHER DEALINGS IN THE SOFTWARE.
// </copyright> // </copyright>
namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Status namespace MathNet.Numerics.LinearAlgebra.Generic.Solvers.Status
{ {
/// <summary> /// <summary>
/// Indicates that the calculation has been stopped due to reaching the stopping /// Indicates that the calculation has been stopped due to reaching the stopping

2
src/Numerics/LinearAlgebra/Double/Solvers/Status/ICalculationStatus.cs → src/Numerics/LinearAlgebra/Generic/Solvers/Status/ICalculationStatus.cs

@ -28,7 +28,7 @@
// OTHER DEALINGS IN THE SOFTWARE. // OTHER DEALINGS IN THE SOFTWARE.
// </copyright> // </copyright>
namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Status namespace MathNet.Numerics.LinearAlgebra.Generic.Solvers.Status
{ {
/// <summary> /// <summary>
/// Defines the base interface for calculation status objects. /// Defines the base interface for calculation status objects.

17
src/Numerics/LinearAlgebra/Double/Solvers/StopCriterium/IIterationStopCriterium.cs → src/Numerics/LinearAlgebra/Generic/Solvers/StopCriterium/IIterationStopCriterium.cs

@ -24,22 +24,25 @@
// OTHER DEALINGS IN THE SOFTWARE. // OTHER DEALINGS IN THE SOFTWARE.
// </copyright> // </copyright>
namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium namespace MathNet.Numerics.LinearAlgebra.Generic.Solvers.StopCriterium
{ {
using System; using System;
using System.Numerics;
using Status; using Status;
/// <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>
public interface IIterationStopCriterium /// <typeparam name="T">Supported data types are double, single, <see cref="Complex"/>, and <see cref="Complex32"/>.</typeparam>
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"/>. Status is set to <c>Status</c> field of current object. /// by the current <see cref="IIterationStopCriterium{T}"/>. 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>
@ -50,7 +53,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>
void DetermineStatus(int iterationNumber, Vector solutionVector, Vector sourceVector, Vector residualVector); void DetermineStatus(int iterationNumber, Vector<T> solutionVector, Vector<T> sourceVector, Vector<T> residualVector);
/// <summary> /// <summary>
/// Gets the current calculation status. /// Gets the current calculation status.
@ -59,7 +62,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium
ICalculationStatus Status { get; } ICalculationStatus Status { get; }
/// <summary> /// <summary>
/// Resets the <see cref="IIterationStopCriterium"/> to the pre-calculation state. /// Resets the <see cref="IIterationStopCriterium{T}"/> 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
@ -68,12 +71,12 @@ 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"/> monitors. /// <see cref="IIterationStopCriterium{T}"/> monitors.
/// </summary> /// </summary>
StopLevel StopLevel { get; } StopLevel StopLevel { get; }
#if SILVERLIGHT #if SILVERLIGHT
IIterationStopCriterium Clone(); IIterationStopCriterium<double> Clone();
#endif #endif
} }
} }

4
src/Numerics/LinearAlgebra/Double/Solvers/StopCriterium/StopLevel.cs → src/Numerics/LinearAlgebra/Generic/Solvers/StopCriterium/StopLevel.cs

@ -24,10 +24,10 @@
// OTHER DEALINGS IN THE SOFTWARE. // OTHER DEALINGS IN THE SOFTWARE.
// </copyright> // </copyright>
namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium namespace MathNet.Numerics.LinearAlgebra.Generic.Solvers.StopCriterium
{ {
/// <summary> /// <summary>
/// Indicates what an <c>IIterationStopCriterium</c> monitors for stop criteria. /// Indicates what an <see cref="IIterationStopCriterium{T}"/> monitors for stop criteria.
/// </summary> /// </summary>
public enum StopLevel public enum StopLevel
{ {

370
src/Numerics/LinearAlgebra/Double/Vector.cs → src/Numerics/LinearAlgebra/Generic/Vector.cs

@ -24,29 +24,32 @@
// OTHER DEALINGS IN THE SOFTWARE. // OTHER DEALINGS IN THE SOFTWARE.
// </copyright> // </copyright>
namespace MathNet.Numerics.LinearAlgebra.Double namespace MathNet.Numerics.LinearAlgebra.Generic
{ {
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Numerics;
using System.Text; using System.Text;
using Distributions; using Distributions;
using Properties; using Properties;
using Threading; using Threading;
/// <summary> /// <summary>
/// Defines the base class for <c>Vector</c> classes. /// Defines the generic class for <c>Vector</c> classes.
/// </summary> /// </summary>
/// <typeparam name="T">Supported data types are double, single, <see cref="Complex"/>, and <see cref="Complex32"/>.</typeparam>
[Serializable] [Serializable]
public abstract class Vector : public abstract class Vector<T> :
#if SILVERLIGHT #if SILVERLIGHT
IFormattable, IEnumerable<double>, IEquatable<Vector> IFormattable, IEnumerable<T>, IEquatable<Vector<T>>
#else #else
IFormattable, IEnumerable<double>, IEquatable<Vector>, ICloneable IFormattable, IEnumerable<T>, IEquatable<Vector<T>>, ICloneable
#endif #endif
where T : struct, IEquatable<T>, IFormattable
{ {
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="Vector"/> class. /// Initializes a new instance of the Vector class.
/// Constructs a <strong>Vector</strong> with the given size. /// Constructs a <strong>Vector</strong> with the given size.
/// </summary> /// </summary>
/// <param name="size"> /// <param name="size">
@ -79,7 +82,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>The value of the vector at the given <paramref name="index"/>.</returns> /// <returns>The value of the vector at the given <paramref name="index"/>.</returns>
/// <exception cref="IndexOutOfRangeException">If <paramref name="index"/> is negative or /// <exception cref="IndexOutOfRangeException">If <paramref name="index"/> is negative or
/// greater than the size of the vector.</exception> /// greater than the size of the vector.</exception>
public abstract double this[int index] public abstract T this[int index]
{ {
get; get;
set; set;
@ -98,7 +101,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns> /// <returns>
/// A matrix with the given dimensions. /// A matrix with the given dimensions.
/// </returns> /// </returns>
public abstract Matrix CreateMatrix(int rows, int columns); public abstract Matrix<T> CreateMatrix(int rows, int columns);
/// <summary> /// <summary>
/// Creates a <strong>Vector</strong> of the given size using the same storage type /// Creates a <strong>Vector</strong> of the given size using the same storage type
@ -110,7 +113,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns> /// <returns>
/// The new <c>Vector</c>. /// The new <c>Vector</c>.
/// </returns> /// </returns>
public abstract Vector CreateVector(int size); public abstract Vector<T> CreateVector(int size);
#region Elementary operations #region Elementary operations
@ -121,18 +124,15 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// The scalar to add. /// The scalar to add.
/// </param> /// </param>
/// <returns>A copy of the vector with the scalar added.</returns> /// <returns>A copy of the vector with the scalar added.</returns>
public virtual Vector Add(double scalar) public virtual Vector<T> Add(T scalar)
{ {
if (scalar == 0.0) if (scalar.Equals(default(T)))
{ {
return Clone(); return Clone();
} }
var copy = Clone(); var copy = Clone();
CommonParallel.For( Add(scalar, copy);
0,
Count,
index => copy[index] += scalar);
return copy; return copy;
} }
@ -151,7 +151,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentException"> /// <exception cref="ArgumentException">
/// If this vector and <paramref name="result"/> are not the same size. /// If this vector and <paramref name="result"/> are not the same size.
/// </exception> /// </exception>
public virtual void Add(double scalar, Vector result) public virtual void Add(T scalar, Vector<T> result)
{ {
if (result == null) if (result == null)
{ {
@ -171,7 +171,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
CommonParallel.For( CommonParallel.For(
0, 0,
Count, Count,
index => result[index] += scalar); index => result[index] = AddT(result[index], scalar));
} }
/// <summary> /// <summary>
@ -183,7 +183,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <remarks> /// <remarks>
/// Added as an alternative to the unary addition operator. /// Added as an alternative to the unary addition operator.
/// </remarks> /// </remarks>
public virtual Vector Plus() public virtual Vector<T> Plus()
{ {
return Clone(); return Clone();
} }
@ -201,7 +201,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentException"> /// <exception cref="ArgumentException">
/// If this vector and <paramref name="other"/> are not the same size. /// If this vector and <paramref name="other"/> are not the same size.
/// </exception> /// </exception>
public virtual Vector Add(Vector other) public virtual Vector<T> Add(Vector<T> other)
{ {
if (other == null) if (other == null)
{ {
@ -214,10 +214,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
} }
var copy = Clone(); var copy = Clone();
CommonParallel.For( Add(other, copy);
0,
Count,
index => copy[index] += other[index]);
return copy; return copy;
} }
@ -242,7 +239,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentException"> /// <exception cref="ArgumentException">
/// If this vector and <paramref name="result"/> are not the same size. /// If this vector and <paramref name="result"/> are not the same size.
/// </exception> /// </exception>
public virtual void Add(Vector other, Vector result) public virtual void Add(Vector<T> other, Vector<T> result)
{ {
if (result == null) if (result == null)
{ {
@ -264,7 +261,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
CommonParallel.For( CommonParallel.For(
0, 0,
Count, Count,
index => result[index] = this[index] + other[index]); index => result[index] = AddT(this[index], other[index]));
} }
} }
@ -275,18 +272,15 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// The scalar to subtract. /// The scalar to subtract.
/// </param> /// </param>
/// <returns>A new vector containing the subtraction of this vector and the scalar.</returns> /// <returns>A new vector containing the subtraction of this vector and the scalar.</returns>
public virtual Vector Subtract(double scalar) public virtual Vector<T> Subtract(T scalar)
{ {
if (scalar == 0.0) if (scalar.Equals(default(T)))
{ {
return Clone(); return Clone();
} }
var copy = Clone(); var copy = Clone();
CommonParallel.For( Subtract(scalar, copy);
0,
Count,
index => copy[index] -= scalar);
return copy; return copy;
} }
@ -305,7 +299,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentException"> /// <exception cref="ArgumentException">
/// If this vector and <paramref name="result"/> are not the same size. /// If this vector and <paramref name="result"/> are not the same size.
/// </exception> /// </exception>
public virtual void Subtract(double scalar, Vector result) public virtual void Subtract(T scalar, Vector<T> result)
{ {
if (result == null) if (result == null)
{ {
@ -325,7 +319,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
CommonParallel.For( CommonParallel.For(
0, 0,
Count, Count,
index => result[index] -= scalar); index => result[index] = SubtractT(result[index], scalar));
} }
/// <summary> /// <summary>
@ -337,10 +331,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <remarks> /// <remarks>
/// Added as an alternative to the unary negation operator. /// Added as an alternative to the unary negation operator.
/// </remarks> /// </remarks>
public virtual Vector Negate() public abstract Vector<T> Negate();
{
return this * -1;
}
/// <summary> /// <summary>
/// Subtracts another vector from this vector. /// Subtracts another vector from this vector.
@ -355,7 +346,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentException"> /// <exception cref="ArgumentException">
/// If this vector and <paramref name="other"/> are not the same size. /// If this vector and <paramref name="other"/> are not the same size.
/// </exception> /// </exception>
public virtual Vector Subtract(Vector other) public virtual Vector<T> Subtract(Vector<T> other)
{ {
if (other == null) if (other == null)
{ {
@ -368,10 +359,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
} }
var copy = Clone(); var copy = Clone();
CommonParallel.For( Subtract(other, copy);
0,
Count,
index => copy[index] -= other[index]);
return copy; return copy;
} }
@ -396,7 +384,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentException"> /// <exception cref="ArgumentException">
/// If this vector and <paramref name="result"/> are not the same size. /// If this vector and <paramref name="result"/> are not the same size.
/// </exception> /// </exception>
public virtual void Subtract(Vector other, Vector result) public virtual void Subtract(Vector<T> other, Vector<T> result)
{ {
if (result == null) if (result == null)
{ {
@ -419,7 +407,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
CommonParallel.For( CommonParallel.For(
0, 0,
Count, Count,
index => result[index] = this[index] - other[index]); index => result[index] = SubtractT(this[index], other[index]));
} }
} }
@ -430,18 +418,15 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// The scalar to multiply. /// The scalar to multiply.
/// </param> /// </param>
/// <returns>A new vector that is the multiplication of the vector and the scalar.</returns> /// <returns>A new vector that is the multiplication of the vector and the scalar.</returns>
public virtual Vector Multiply(double scalar) public virtual Vector<T> Multiply(T scalar)
{ {
if (scalar == 1.0) if (IsOneT(scalar))
{ {
return Clone(); return Clone();
} }
var copy = Clone(); var copy = Clone();
CommonParallel.For( Multiply(scalar, copy);
0,
Count,
index => copy[index] *= scalar);
return copy; return copy;
} }
@ -460,7 +445,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentException"> /// <exception cref="ArgumentException">
/// If this vector and <paramref name="result"/> are not the same size. /// If this vector and <paramref name="result"/> are not the same size.
/// </exception> /// </exception>
public virtual void Multiply(double scalar, Vector result) public virtual void Multiply(T scalar, Vector<T> result)
{ {
if (result == null) if (result == null)
{ {
@ -480,7 +465,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
CommonParallel.For( CommonParallel.For(
0, 0,
Count, Count,
index => result[index] *= scalar); index => result[index] = MultiplyT(result[index], scalar));
} }
/// <summary> /// <summary>
@ -498,7 +483,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentNullException"> /// <exception cref="ArgumentNullException">
/// If <paramref name="other"/> is <see langword="null"/>. /// If <paramref name="other"/> is <see langword="null"/>.
/// </exception> /// </exception>
public virtual double DotProduct(Vector other) public virtual T DotProduct(Vector<T> other)
{ {
if (other == null) if (other == null)
{ {
@ -510,10 +495,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "other"); throw new ArgumentException(Resources.ArgumentVectorsSameLength, "other");
} }
var dot = 0.0; var dot = default(T);
for (var i = 0; i < Count; i++) for (var i = 0; i < Count; i++)
{ {
dot += this[i] * other[i]; dot = AddT(dot, MultiplyT(this[i], other[i]));
} }
return dot; return dot;
@ -526,14 +511,16 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// The scalar to divide with. /// The scalar to divide with.
/// </param> /// </param>
/// <returns>A new vector that is the division of the vector and the scalar.</returns> /// <returns>A new vector that is the division of the vector and the scalar.</returns>
public virtual Vector Divide(double scalar) public virtual Vector<T> Divide(T scalar)
{ {
if (scalar == 1.0) if (IsOneT(scalar))
{ {
return Clone(); return Clone();
} }
return Multiply(1.0 / scalar); var copy = Clone();
Divide(scalar, copy);
return copy;
} }
/// <summary> /// <summary>
@ -551,7 +538,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentException"> /// <exception cref="ArgumentException">
/// If this vector and <paramref name="result"/> are not the same size. /// If this vector and <paramref name="result"/> are not the same size.
/// </exception> /// </exception>
public virtual void Divide(double scalar, Vector result) public virtual void Divide(T scalar, Vector<T> result)
{ {
if (result == null) if (result == null)
{ {
@ -567,11 +554,11 @@ namespace MathNet.Numerics.LinearAlgebra.Double
{ {
CopyTo(result); CopyTo(result);
} }
CommonParallel.For( CommonParallel.For(
0, 0,
Count, Count,
index => result[index] /= scalar); index => result[index] = DivideT(result[index], scalar));
} }
/// <summary> /// <summary>
@ -581,7 +568,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>A new vector which is the pointwise multiplication of the two vectors.</returns> /// <returns>A new vector which is the pointwise multiplication of the two vectors.</returns>
/// <exception cref="ArgumentNullException">If the other vector is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the other vector is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If this vector and <paramref name="other"/> are not the same size.</exception> /// <exception cref="ArgumentException">If this vector and <paramref name="other"/> are not the same size.</exception>
public virtual Vector PointwiseMultiply(Vector other) public virtual Vector<T> PointwiseMultiply(Vector<T> other)
{ {
if (other == null) if (other == null)
{ {
@ -594,10 +581,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
} }
var copy = Clone(); var copy = Clone();
CommonParallel.For( PointwiseMultiply(other, copy);
0,
Count,
index => copy[index] *= other[index]);
return copy; return copy;
} }
@ -610,7 +594,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentNullException">If the result vector is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the result vector is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If this vector and <paramref name="other"/> are not the same size.</exception> /// <exception cref="ArgumentException">If this vector and <paramref name="other"/> are not the same size.</exception>
/// <exception cref="ArgumentException">If this vector and <paramref name="result"/> are not the same size.</exception> /// <exception cref="ArgumentException">If this vector and <paramref name="result"/> are not the same size.</exception>
public virtual void PointwiseMultiply(Vector other, Vector result) public virtual void PointwiseMultiply(Vector<T> other, Vector<T> result)
{ {
if (result == null) if (result == null)
{ {
@ -642,7 +626,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
CommonParallel.For( CommonParallel.For(
0, 0,
Count, Count,
index => result[index] = this[index] * other[index]); index => result[index] = MultiplyT(this[index], other[index]));
} }
} }
@ -653,7 +637,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>A new vector which is the pointwise division of the two vectors.</returns> /// <returns>A new vector which is the pointwise division of the two vectors.</returns>
/// <exception cref="ArgumentNullException">If the other vector is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the other vector is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If this vector and <paramref name="other"/> are not the same size.</exception> /// <exception cref="ArgumentException">If this vector and <paramref name="other"/> are not the same size.</exception>
public virtual Vector PointwiseDivide(Vector other) public virtual Vector<T> PointwiseDivide(Vector<T> other)
{ {
if (other == null) if (other == null)
{ {
@ -666,10 +650,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
} }
var copy = Clone(); var copy = Clone();
CommonParallel.For( PointwiseDivide(other, copy);
0,
Count,
index => copy[index] /= other[index]);
return copy; return copy;
} }
@ -682,7 +663,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentNullException">If the result vector is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the result vector is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If this vector and <paramref name="other"/> are not the same size.</exception> /// <exception cref="ArgumentException">If this vector and <paramref name="other"/> are not the same size.</exception>
/// <exception cref="ArgumentException">If this vector and <paramref name="result"/> are not the same size.</exception> /// <exception cref="ArgumentException">If this vector and <paramref name="result"/> are not the same size.</exception>
public virtual void PointwiseDivide(Vector other, Vector result) public virtual void PointwiseDivide(Vector<T> other, Vector<T> result)
{ {
if (result == null) if (result == null)
{ {
@ -714,7 +695,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
CommonParallel.For( CommonParallel.For(
0, 0,
Count, Count,
index => result[index] = this[index] / other[index]); index => result[index] = DivideT(this[index], other[index]));
} }
} }
@ -726,7 +707,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>Matrix M[i,j] = u[i]*v[j] </returns> /// <returns>Matrix M[i,j] = u[i]*v[j] </returns>
/// <exception cref="ArgumentNullException">If the u vector is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the u vector is <see langword="null" />.</exception>
/// <exception cref="ArgumentNullException">If the v vector is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the v vector is <see langword="null" />.</exception>
public static DenseMatrix OuterProduct(Vector u, Vector v) public static Matrix<T> OuterProduct(Vector<T> u, Vector<T> v)
{ {
if (u == null) if (u == null)
{ {
@ -738,17 +719,11 @@ namespace MathNet.Numerics.LinearAlgebra.Double
throw new ArgumentNullException("v"); throw new ArgumentNullException("v");
} }
var matrix = new DenseMatrix(u.Count, v.Count); var matrix = u.CreateMatrix(u.Count, v.Count);
CommonParallel.For( CommonParallel.For(
0, 0,
u.Count, u.Count,
i => i => matrix.SetRow(i, v.Multiply(u[i])));
{
for (var j = 0; j < v.Count; j++)
{
matrix.At(i, j, u[i] * v[j]);
}
});
return matrix; return matrix;
} }
@ -762,21 +737,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// to the specified random distribution. /// to the specified random distribution.
/// </returns> /// </returns>
/// <exception cref="ArgumentException">If the n vector is non-positive.</exception> /// <exception cref="ArgumentException">If the n vector is non-positive.</exception>
public virtual Vector Random(int length, IContinuousDistribution randomDistribution) public abstract Vector<T> Random(int length, IContinuousDistribution randomDistribution);
{
if (length < 1)
{
throw new ArgumentException(Resources.ArgumentMustBePositive, "length");
}
var v = CreateVector(length);
for (var index = 0; index < v.Count; index++)
{
v[index] = randomDistribution.Sample();
}
return v;
}
/// <summary> /// <summary>
/// Generates a vector with random elements /// Generates a vector with random elements
@ -788,21 +749,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// to the specified random distribution. /// to the specified random distribution.
/// </returns> /// </returns>
/// <exception cref="ArgumentException">If the n vector is not positive.</exception> /// <exception cref="ArgumentException">If the n vector is not positive.</exception>
public virtual Vector Random(int length, IDiscreteDistribution randomDistribution) public abstract Vector<T> Random(int length, IDiscreteDistribution randomDistribution);
{
if (length < 1)
{
throw new ArgumentException(Resources.ArgumentMustBePositive, "length");
}
var v = CreateVector(length);
for (var index = 0; index < v.Count; index++)
{
v[index] = randomDistribution.Sample();
}
return v;
}
/// <summary> /// <summary>
/// Tensor Product (Dyadic) of this and another vector. /// Tensor Product (Dyadic) of this and another vector.
@ -812,7 +759,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// Matrix M[i,j] = this[i] * v[j]. /// Matrix M[i,j] = this[i] * v[j].
/// </returns> /// </returns>
/// <seealso cref="OuterProduct"/> /// <seealso cref="OuterProduct"/>
public Matrix TensorMultiply(Vector v) public Matrix<T> TensorMultiply(Vector<T> v)
{ {
return OuterProduct(this, v); return OuterProduct(this, v);
} }
@ -823,7 +770,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>The value of the absolute minimum element.</returns> /// <returns>The value of the absolute minimum element.</returns>
public virtual double AbsoluteMinimum() public virtual double AbsoluteMinimum()
{ {
return Math.Abs(this[AbsoluteMinimumIndex()]); return AbsoluteT(this[AbsoluteMinimumIndex()]);
} }
/// <summary> /// <summary>
@ -833,10 +780,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double
public virtual int AbsoluteMinimumIndex() public virtual int AbsoluteMinimumIndex()
{ {
var index = 0; var index = 0;
var min = Math.Abs(this[index]); var min = AbsoluteT(this[index]);
for (var i = 1; i < Count; i++) for (var i = 1; i < Count; i++)
{ {
var test = Math.Abs(this[i]); var test = AbsoluteT(this[i]);
if (test < min) if (test < min)
{ {
index = i; index = i;
@ -846,14 +793,14 @@ namespace MathNet.Numerics.LinearAlgebra.Double
return index; return index;
} }
/// <summary> /// <summary>
/// Returns the value of the absolute maximum element. /// Returns the value of the absolute maximum element.
/// </summary> /// </summary>
/// <returns>The value of the absolute maximum element.</returns> /// <returns>The value of the absolute maximum element.</returns>
public virtual double AbsoluteMaximum() public virtual double AbsoluteMaximum()
{ {
return Math.Abs(this[AbsoluteMaximumIndex()]); return AbsoluteT(this[AbsoluteMaximumIndex()]);
} }
/// <summary> /// <summary>
@ -863,10 +810,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double
public virtual int AbsoluteMaximumIndex() public virtual int AbsoluteMaximumIndex()
{ {
var index = 0; var index = 0;
var max = Math.Abs(this[index]); var max = AbsoluteT(this[index]);
for (var i = 1; i < Count; i++) for (var i = 1; i < Count; i++)
{ {
var test = Math.Abs(this[i]); var test = AbsoluteT(this[i]);
if (test > max) if (test > max)
{ {
index = i; index = i;
@ -881,7 +828,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// Returns the value of maximum element. /// Returns the value of maximum element.
/// </summary> /// </summary>
/// <returns>The value of maximum element.</returns> /// <returns>The value of maximum element.</returns>
public virtual double Maximum() public virtual T Maximum()
{ {
return this[MaximumIndex()]; return this[MaximumIndex()];
} }
@ -890,27 +837,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// Returns the index of the absolute maximum element. /// Returns the index of the absolute maximum element.
/// </summary> /// </summary>
/// <returns>The index of absolute maximum element.</returns> /// <returns>The index of absolute maximum element.</returns>
public virtual int MaximumIndex() public abstract int MaximumIndex();
{
var index = 0;
var max = this[0];
for (var i = 1; i < Count; i++)
{
if (max < this[i])
{
index = i;
max = this[i];
}
}
return index;
}
/// <summary> /// <summary>
/// Returns the value of the minimum element. /// Returns the value of the minimum element.
/// </summary> /// </summary>
/// <returns>The value of the minimum element.</returns> /// <returns>The value of the minimum element.</returns>
public virtual double Minimum() public virtual T Minimum()
{ {
return this[MinimumIndex()]; return this[MinimumIndex()];
} }
@ -919,32 +852,18 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// Returns the index of the minimum element. /// Returns the index of the minimum element.
/// </summary> /// </summary>
/// <returns>The index of minimum element.</returns> /// <returns>The index of minimum element.</returns>
public virtual int MinimumIndex() public abstract int MinimumIndex();
{
var index = 0;
var min = this[0];
for (var i = 1; i < Count; i++)
{
if (min > this[i])
{
index = i;
min = this[i];
}
}
return index;
}
/// <summary> /// <summary>
/// Computes the sum of the vector's elements. /// Computes the sum of the vector's elements.
/// </summary> /// </summary>
/// <returns>The sum of the vector's elements.</returns> /// <returns>The sum of the vector's elements.</returns>
public virtual double Sum() public virtual T Sum()
{ {
double result = 0; var result = default(T);
for (var i = 0; i < Count; i++) for (var i = 0; i < Count; i++)
{ {
result += this[i]; result = AddT(result, this[i]);
} }
return result; return result;
@ -959,7 +878,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
double result = 0; double result = 0;
for (var i = 0; i < Count; i++) for (var i = 0; i < Count; i++)
{ {
result += Math.Abs(this[i]); result += AbsoluteT(this[i]);
} }
return result; return result;
@ -976,7 +895,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="rightSide">The vector to get the values from.</param> /// <param name="rightSide">The vector to get the values from.</param>
/// <returns>A vector containing the same values as <paramref name="rightSide"/>.</returns> /// <returns>A vector containing the same values as <paramref name="rightSide"/>.</returns>
/// <exception cref="ArgumentNullException">If <paramref name="rightSide"/> is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If <paramref name="rightSide"/> is <see langword="null" />.</exception>
public static Vector operator +(Vector rightSide) public static Vector<T> operator +(Vector<T> rightSide)
{ {
if (rightSide == null) if (rightSide == null)
{ {
@ -994,7 +913,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>The result of the addition.</returns> /// <returns>The result of the addition.</returns>
/// <exception cref="ArgumentException">If <paramref name="leftSide"/> and <paramref name="rightSide"/> are not the same size.</exception> /// <exception cref="ArgumentException">If <paramref name="leftSide"/> and <paramref name="rightSide"/> are not the same size.</exception>
/// <exception cref="ArgumentNullException">If <paramref name="leftSide"/> or <paramref name="rightSide"/> is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If <paramref name="leftSide"/> or <paramref name="rightSide"/> is <see langword="null" />.</exception>
public static Vector operator +(Vector leftSide, Vector rightSide) public static Vector<T> operator +(Vector<T> leftSide, Vector<T> rightSide)
{ {
if (rightSide == null) if (rightSide == null)
{ {
@ -1020,7 +939,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="rightSide">The vector to get the values from.</param> /// <param name="rightSide">The vector to get the values from.</param>
/// <returns>A vector containing the negated values as <paramref name="rightSide"/>.</returns> /// <returns>A vector containing the negated values as <paramref name="rightSide"/>.</returns>
/// <exception cref="ArgumentNullException">If <paramref name="rightSide"/> is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If <paramref name="rightSide"/> is <see langword="null" />.</exception>
public static Vector operator -(Vector rightSide) public static Vector<T> operator -(Vector<T> rightSide)
{ {
if (rightSide == null) if (rightSide == null)
{ {
@ -1038,7 +957,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>The result of the subtraction.</returns> /// <returns>The result of the subtraction.</returns>
/// <exception cref="ArgumentException">If <paramref name="leftSide"/> and <paramref name="rightSide"/> are not the same size.</exception> /// <exception cref="ArgumentException">If <paramref name="leftSide"/> and <paramref name="rightSide"/> are not the same size.</exception>
/// <exception cref="ArgumentNullException">If <paramref name="leftSide"/> or <paramref name="rightSide"/> is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If <paramref name="leftSide"/> or <paramref name="rightSide"/> is <see langword="null" />.</exception>
public static Vector operator -(Vector leftSide, Vector rightSide) public static Vector<T> operator -(Vector<T> leftSide, Vector<T> rightSide)
{ {
if (rightSide == null) if (rightSide == null)
{ {
@ -1065,7 +984,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="rightSide">The scalar value.</param> /// <param name="rightSide">The scalar value.</param>
/// <returns>The result of the multiplication.</returns> /// <returns>The result of the multiplication.</returns>
/// <exception cref="ArgumentNullException">If <paramref name="leftSide"/> is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If <paramref name="leftSide"/> is <see langword="null" />.</exception>
public static Vector operator *(Vector leftSide, double rightSide) public static Vector<T> operator *(Vector<T> leftSide, T rightSide)
{ {
if (leftSide == null) if (leftSide == null)
{ {
@ -1082,7 +1001,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="rightSide">The vector to scale.</param> /// <param name="rightSide">The vector to scale.</param>
/// <returns>The result of the multiplication.</returns> /// <returns>The result of the multiplication.</returns>
/// <exception cref="ArgumentNullException">If <paramref name="rightSide"/> is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If <paramref name="rightSide"/> is <see langword="null" />.</exception>
public static Vector operator *(double leftSide, Vector rightSide) public static Vector<T> operator *(T leftSide, Vector<T> rightSide)
{ {
if (rightSide == null) if (rightSide == null)
{ {
@ -1100,7 +1019,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>The dot product between the two vectors.</returns> /// <returns>The dot product between the two vectors.</returns>
/// <exception cref="ArgumentException">If <paramref name="leftSide"/> and <paramref name="rightSide"/> are not the same size.</exception> /// <exception cref="ArgumentException">If <paramref name="leftSide"/> and <paramref name="rightSide"/> are not the same size.</exception>
/// <exception cref="ArgumentNullException">If <paramref name="leftSide"/> or <paramref name="rightSide"/> is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If <paramref name="leftSide"/> or <paramref name="rightSide"/> is <see langword="null" />.</exception>
public static double operator *(Vector leftSide, Vector rightSide) public static T operator *(Vector<T> leftSide, Vector<T> rightSide)
{ {
if (rightSide == null) if (rightSide == null)
{ {
@ -1127,14 +1046,14 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="rightSide">The scalar value.</param> /// <param name="rightSide">The scalar value.</param>
/// <returns>The result of the division.</returns> /// <returns>The result of the division.</returns>
/// <exception cref="ArgumentNullException">If <paramref name="leftSide"/> is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If <paramref name="leftSide"/> is <see langword="null" />.</exception>
public static Vector operator /(Vector leftSide, double rightSide) public static Vector<T> operator /(Vector<T> leftSide, T rightSide)
{ {
if (leftSide == null) if (leftSide == null)
{ {
throw new ArgumentNullException("leftSide"); throw new ArgumentNullException("leftSide");
} }
return leftSide.Multiply(1.0 / rightSide); return leftSide.Divide(rightSide);
} }
#endregion #endregion
@ -1162,14 +1081,14 @@ namespace MathNet.Numerics.LinearAlgebra.Double
return CommonParallel.Select( return CommonParallel.Select(
0, 0,
Count, Count,
(index, localData) => Math.Max(localData, Math.Abs(this[index])), (index, localData) => Math.Max(localData, AbsoluteT(this[index])),
Math.Max); Math.Max);
} }
var sum = CommonParallel.Aggregate( var sum = CommonParallel.Aggregate(
0, 0,
Count, Count,
index => Math.Pow(Math.Abs(this[index]), p)); index => Math.Pow(AbsoluteT(this[index]), p));
return Math.Pow(sum, 1.0 / p); return Math.Pow(sum, 1.0 / p);
} }
@ -1183,24 +1102,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns> /// <returns>
/// This vector normalized to a unit vector with respect to the p-norm. /// This vector normalized to a unit vector with respect to the p-norm.
/// </returns> /// </returns>
public virtual Vector Normalize(double p) public abstract Vector<T> Normalize(double p);
{
if (p < 0.0)
{
throw new ArgumentOutOfRangeException("p");
}
var norm = Norm(p);
var clone = Clone();
if (norm == 0.0)
{
return clone;
}
clone.Multiply(1.0 / norm, clone);
return clone;
}
#endregion #endregion
@ -1212,7 +1114,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns> /// <returns>
/// A deep-copy clone of the vector. /// A deep-copy clone of the vector.
/// </returns> /// </returns>
public Vector Clone() public Vector<T> Clone()
{ {
var retrunVector = CreateVector(Count); var retrunVector = CreateVector(Count);
CopyTo(retrunVector); CopyTo(retrunVector);
@ -1231,7 +1133,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentException"> /// <exception cref="ArgumentException">
/// If <paramref name="target"/> is not the same size as this vector. /// If <paramref name="target"/> is not the same size as this vector.
/// </exception> /// </exception>
public virtual void CopyTo(Vector target) public virtual void CopyTo(Vector<T> target)
{ {
if (target == null) if (target == null)
{ {
@ -1269,7 +1171,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="count"> /// <param name="count">
/// The number of elements to copy. /// The number of elements to copy.
/// </param> /// </param>
public virtual void CopyTo(Vector destination, int offset, int destinationOffset, int count) public virtual void CopyTo(Vector<T> destination, int offset, int destinationOffset, int count)
{ {
if (destination == null) if (destination == null)
{ {
@ -1321,9 +1223,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns> /// <returns>
/// The vector's data as an array. /// The vector's data as an array.
/// </returns> /// </returns>
public virtual double[] ToArray() public virtual T[] ToArray()
{ {
var ret = new double[Count]; var ret = new T[Count];
for (var i = 0; i < ret.Length; i++) for (var i = 0; i < ret.Length; i++)
{ {
ret[i] = this[i]; ret[i] = this[i];
@ -1338,7 +1240,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns> /// <returns>
/// This vector as a column matrix. /// This vector as a column matrix.
/// </returns> /// </returns>
public virtual Matrix ToColumnMatrix() public virtual Matrix<T> ToColumnMatrix()
{ {
var matrix = CreateMatrix(Count, 1); var matrix = CreateMatrix(Count, 1);
for (var i = 0; i < Count; i++) for (var i = 0; i < Count; i++)
@ -1355,7 +1257,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns> /// <returns>
/// This vector as a row matrix. /// This vector as a row matrix.
/// </returns> /// </returns>
public virtual Matrix ToRowMatrix() public virtual Matrix<T> ToRowMatrix()
{ {
var matrix = CreateMatrix(1, Count); var matrix = CreateMatrix(1, Count);
for (var i = 0; i < Count; i++) for (var i = 0; i < Count; i++)
@ -1377,7 +1279,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <item>If <paramref name="index"/> + <paramref name="length"/> is greater than or equal to the size of the vector.</item> /// <item>If <paramref name="index"/> + <paramref name="length"/> is greater than or equal to the size of the vector.</item>
/// </list></exception> /// </list></exception>
/// <exception cref="ArgumentException">If <paramref name="length"/> is not positive.</exception> /// <exception cref="ArgumentException">If <paramref name="length"/> is not positive.</exception>
public virtual Vector SubVector(int index, int length) public virtual Vector<T> SubVector(int index, int length)
{ {
if (index < 0 || index >= Count) if (index < 0 || index >= Count)
{ {
@ -1409,7 +1311,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="values">The array containing the values to use.</param> /// <param name="values">The array containing the values to use.</param>
/// <exception cref="ArgumentNullException">If <paramref name="values"/> is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If <paramref name="values"/> is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If <paramref name="values"/> is not the same size as this vector.</exception> /// <exception cref="ArgumentException">If <paramref name="values"/> is not the same size as this vector.</exception>
public virtual void SetValues(double[] values) public virtual void SetValues(T[] values)
{ {
if (values == null) if (values == null)
{ {
@ -1465,7 +1367,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
#endregion #endregion
#region IEnumerable<double> #region IEnumerable<T>
/// <summary> /// <summary>
/// Returns an enumerator that iterates through the collection. /// Returns an enumerator that iterates through the collection.
@ -1473,7 +1375,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns> /// <returns>
/// A <see cref="T:System.Collections.Generic.IEnumerator`1"/> that can be used to iterate through the collection. /// A <see cref="T:System.Collections.Generic.IEnumerator`1"/> that can be used to iterate through the collection.
/// </returns> /// </returns>
public virtual IEnumerator<double> GetEnumerator() public virtual IEnumerator<T> GetEnumerator()
{ {
for (var index = 0; index < Count; index++) for (var index = 0; index < Count; index++)
{ {
@ -1497,11 +1399,11 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// being the value of the element at that index. For sparse vectors, the enumerator will exclude all elements /// being the value of the element at that index. For sparse vectors, the enumerator will exclude all elements
/// with a zero value. /// with a zero value.
/// </remarks> /// </remarks>
public virtual IEnumerable<KeyValuePair<int, double>> GetIndexedEnumerator() public virtual IEnumerable<KeyValuePair<int, T>> GetIndexedEnumerator()
{ {
for (var i = 0; i < Count; i++) for (var i = 0; i < Count; i++)
{ {
yield return new KeyValuePair<int, double>(i, this[i]); yield return new KeyValuePair<int, T>(i, this[i]);
} }
} }
@ -1516,7 +1418,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns> /// <returns>
/// <c>true</c> if the current object is equal to the <paramref name="other"/> parameter; otherwise, <c>false</c>. /// <c>true</c> if the current object is equal to the <paramref name="other"/> parameter; otherwise, <c>false</c>.
/// </returns> /// </returns>
public bool Equals(Vector other) public virtual bool Equals(Vector<T> other)
{ {
// Reject equality when the argument is null or has a different length. // Reject equality when the argument is null or has a different length.
if (other == null) if (other == null)
@ -1538,7 +1440,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
// If all else fails, perform element wise comparison. // If all else fails, perform element wise comparison.
for (var index = 0; index < Count; index++) for (var index = 0; index < Count; index++)
{ {
if (!this[index].AlmostEqual(other[index])) if (!this[index].Equals(other[index]))
{ {
return false; return false;
} }
@ -1577,7 +1479,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns> /// <returns>
/// A <see cref="System.String"/> that represents this instance. /// A <see cref="System.String"/> that represents this instance.
/// </returns> /// </returns>
public string ToString(string format, IFormatProvider formatProvider) public virtual string ToString(string format, IFormatProvider formatProvider)
{ {
var stringBuilder = new StringBuilder(); var stringBuilder = new StringBuilder();
for (var index = 0; index < Count; index++) for (var index = 0; index < Count; index++)
@ -1591,7 +1493,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double
return stringBuilder.ToString(); return stringBuilder.ToString();
} }
#endregion #endregion
#endregion #endregion
@ -1609,7 +1510,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// </returns> /// </returns>
public override bool Equals(object obj) public override bool Equals(object obj)
{ {
return Equals(obj as Vector); return Equals(obj as Vector<T>);
} }
/// <summary> /// <summary>
@ -1625,9 +1526,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double
for (var i = 0; i < hashNum; i++) for (var i = 0; i < hashNum; i++)
{ {
#if SILVERLIGHT #if SILVERLIGHT
hash ^= Precision.DoubleToInt64Bits(this[i]); hash ^= Precision.DoubleToInt64Bits(AbsoluteT(this[i]));
#else #else
hash ^= BitConverter.DoubleToInt64Bits(this[i]); hash ^= BitConverter.DoubleToInt64Bits(this[i].GetHashCode());
#endif #endif
} }
@ -1652,7 +1553,56 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// </summary> /// </summary>
public virtual void Clear() public virtual void Clear()
{ {
CommonParallel.For(0, Count, index => this[index] = 0); CommonParallel.For(0, Count, index => this[index] = default(T));
} }
#region Simple arithmetic of type T
/// <summary>
/// Add two values T+T
/// </summary>
/// <param name="val1">Left operand value</param>
/// <param name="val2">Right operand value</param>
/// <returns>Result of addition</returns>
protected abstract T AddT(T val1, T val2);
/// <summary>
/// Subtract two values T-T
/// </summary>
/// <param name="val1">Left operand value</param>
/// <param name="val2">Right operand value</param>
/// <returns>Result of subtract</returns>
protected abstract T SubtractT(T val1, T val2);
/// <summary>
/// Multiply two values T*T
/// </summary>
/// <param name="val1">Left operand value</param>
/// <param name="val2">Right operand value</param>
/// <returns>Result of multiplication</returns>
protected abstract T MultiplyT(T val1, T val2);
/// <summary>
/// Divide two values T/T
/// </summary>
/// <param name="val1">Left operand value</param>
/// <param name="val2">Right operand value</param>
/// <returns>Result of divide</returns>
protected abstract T DivideT(T val1, T val2);
/// <summary>
/// Is equal to one?
/// </summary>
/// <param name="val1">Value to check</param>
/// <returns>True if one; otherwise false</returns>
protected abstract bool IsOneT(T val1);
/// <summary>
/// Take absolute value
/// </summary>
/// <param name="val1">Source alue</param>
/// <returns>True if one; otherwise false</returns>
protected abstract double AbsoluteT(T val1);
#endregion
} }
} }

44
src/Numerics/Numerics.csproj

@ -110,20 +110,20 @@
<Compile Include="LinearAlgebra\Double\DenseMatrix.cs" /> <Compile Include="LinearAlgebra\Double\DenseMatrix.cs" />
<Compile Include="LinearAlgebra\Double\DenseVector.cs" /> <Compile Include="LinearAlgebra\Double\DenseVector.cs" />
<Compile Include="LinearAlgebra\Double\DiagonalMatrix.cs" /> <Compile Include="LinearAlgebra\Double\DiagonalMatrix.cs" />
<Compile Include="LinearAlgebra\Double\Factorization\Cholesky.cs" /> <Compile Include="LinearAlgebra\Generic\Factorization\Cholesky.cs" />
<Compile Include="LinearAlgebra\Double\Factorization\DenseCholesky.cs" /> <Compile Include="LinearAlgebra\Double\Factorization\DenseCholesky.cs" />
<Compile Include="LinearAlgebra\Double\Factorization\DenseLU.cs" /> <Compile Include="LinearAlgebra\Double\Factorization\DenseLU.cs" />
<Compile Include="LinearAlgebra\Double\Factorization\DenseQR.cs" /> <Compile Include="LinearAlgebra\Double\Factorization\DenseQR.cs" />
<Compile Include="LinearAlgebra\Double\Factorization\DenseSvd.cs" /> <Compile Include="LinearAlgebra\Double\Factorization\DenseSvd.cs" />
<Compile Include="LinearAlgebra\Double\Factorization\ExtensionMethods.cs" /> <Compile Include="LinearAlgebra\Double\Factorization\ExtensionMethods.cs" />
<Compile Include="LinearAlgebra\Double\Factorization\GramSchmidt.cs" /> <Compile Include="LinearAlgebra\Double\Factorization\GramSchmidt.cs" />
<Compile Include="LinearAlgebra\Double\Factorization\LU.cs" /> <Compile Include="LinearAlgebra\Generic\Factorization\LU.cs" />
<Compile Include="LinearAlgebra\Double\Factorization\QR.cs" /> <Compile Include="LinearAlgebra\Generic\Factorization\QR.cs" />
<Compile Include="LinearAlgebra\Double\Factorization\SparseCholesky.cs" /> <Compile Include="LinearAlgebra\Double\Factorization\SparseCholesky.cs" />
<Compile Include="LinearAlgebra\Double\Factorization\SparseLU.cs" /> <Compile Include="LinearAlgebra\Double\Factorization\SparseLU.cs" />
<Compile Include="LinearAlgebra\Double\Factorization\SparseQR.cs" /> <Compile Include="LinearAlgebra\Double\Factorization\SparseQR.cs" />
<Compile Include="LinearAlgebra\Double\Factorization\SparseSvd.cs" /> <Compile Include="LinearAlgebra\Double\Factorization\SparseSvd.cs" />
<Compile Include="LinearAlgebra\Double\Factorization\Svd.cs" /> <Compile Include="LinearAlgebra\Generic\Factorization\Svd.cs" />
<Compile Include="LinearAlgebra\Double\Factorization\UserCholesky.cs" /> <Compile Include="LinearAlgebra\Double\Factorization\UserCholesky.cs" />
<Compile Include="LinearAlgebra\Double\Factorization\UserLU.cs" /> <Compile Include="LinearAlgebra\Double\Factorization\UserLU.cs" />
<Compile Include="LinearAlgebra\Double\Factorization\UserQR.cs" /> <Compile Include="LinearAlgebra\Double\Factorization\UserQR.cs" />
@ -135,12 +135,10 @@
<Compile Include="LinearAlgebra\Double\IO\Matlab\MatlabParser.cs" /> <Compile Include="LinearAlgebra\Double\IO\Matlab\MatlabParser.cs" />
<Compile Include="LinearAlgebra\Double\IO\MatrixReader.cs" /> <Compile Include="LinearAlgebra\Double\IO\MatrixReader.cs" />
<Compile Include="LinearAlgebra\Double\IO\MatrixWriter.cs" /> <Compile Include="LinearAlgebra\Double\IO\MatrixWriter.cs" />
<Compile Include="LinearAlgebra\Double\ISolver.cs" /> <Compile Include="LinearAlgebra\Generic\ISolver.cs" />
<Compile Include="LinearAlgebra\Double\Matrix.Arithmetic.cs" /> <Compile Include="LinearAlgebra\Generic\Solvers\IIterativeSolver.cs" />
<Compile Include="LinearAlgebra\Double\Matrix.cs" /> <Compile Include="LinearAlgebra\Generic\Solvers\IIterativeSolverSetup.cs" />
<Compile Include="LinearAlgebra\Double\Solvers\IIterativeSolver.cs" /> <Compile Include="LinearAlgebra\Generic\Solvers\IIterator.cs" />
<Compile Include="LinearAlgebra\Double\Solvers\IIterativeSolverSetup.cs" />
<Compile Include="LinearAlgebra\Double\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" />
@ -153,25 +151,27 @@
<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\Double\Solvers\Preconditioners\IPreConditioner.cs" /> <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\Double\Solvers\Status\CalculationCancelled.cs" /> <Compile Include="LinearAlgebra\Generic\Solvers\Status\CalculationCancelled.cs" />
<Compile Include="LinearAlgebra\Double\Solvers\Status\CalculationConverged.cs" /> <Compile Include="LinearAlgebra\Generic\Solvers\Status\CalculationConverged.cs" />
<Compile Include="LinearAlgebra\Double\Solvers\Status\CalculationDiverged.cs" /> <Compile Include="LinearAlgebra\Generic\Solvers\Status\CalculationDiverged.cs" />
<Compile Include="LinearAlgebra\Double\Solvers\Status\CalculationFailure.cs" /> <Compile Include="LinearAlgebra\Generic\Solvers\Status\CalculationFailure.cs" />
<Compile Include="LinearAlgebra\Double\Solvers\Status\CalculationIndetermined.cs" /> <Compile Include="LinearAlgebra\Generic\Solvers\Status\CalculationIndetermined.cs" />
<Compile Include="LinearAlgebra\Double\Solvers\Status\CalculationRunning.cs" /> <Compile Include="LinearAlgebra\Generic\Solvers\Status\CalculationRunning.cs" />
<Compile Include="LinearAlgebra\Double\Solvers\Status\CalculationStoppedWithoutConvergence.cs" /> <Compile Include="LinearAlgebra\Generic\Solvers\Status\CalculationStoppedWithoutConvergence.cs" />
<Compile Include="LinearAlgebra\Double\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\Double\Solvers\StopCriterium\IIterationStopCriterium.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\Double\Solvers\StopCriterium\StopLevel.cs" /> <Compile Include="LinearAlgebra\Generic\Solvers\StopCriterium\StopLevel.cs" />
<Compile Include="LinearAlgebra\Double\SparseMatrix.cs" /> <Compile Include="LinearAlgebra\Double\SparseMatrix.cs" />
<Compile Include="LinearAlgebra\Double\SparseVector.cs" /> <Compile Include="LinearAlgebra\Double\SparseVector.cs" />
<Compile Include="LinearAlgebra\Double\Vector.cs" /> <Compile Include="LinearAlgebra\Generic\Matrix.Arithmetic.cs" />
<Compile Include="LinearAlgebra\Generic\Matrix.cs" />
<Compile Include="LinearAlgebra\Generic\Vector.cs" />
<Compile Include="Permutation.cs" /> <Compile Include="Permutation.cs" />
<Compile Include="Distributions\Continuous\Beta.cs" /> <Compile Include="Distributions\Continuous\Beta.cs" />
<Compile Include="Distributions\Continuous\ContinuousUniform.cs" /> <Compile Include="Distributions\Continuous\ContinuousUniform.cs" />

130
src/Silverlight/Silverlight.csproj

@ -224,9 +224,6 @@
<Compile Include="..\Numerics\LinearAlgebra\Double\DiagonalMatrix.cs"> <Compile Include="..\Numerics\LinearAlgebra\Double\DiagonalMatrix.cs">
<Link>LinearAlgebra\Double\DiagonalMatrix.cs</Link> <Link>LinearAlgebra\Double\DiagonalMatrix.cs</Link>
</Compile> </Compile>
<Compile Include="..\Numerics\LinearAlgebra\Double\Factorization\Cholesky.cs">
<Link>LinearAlgebra\Double\Factorization\Cholesky.cs</Link>
</Compile>
<Compile Include="..\Numerics\LinearAlgebra\Double\Factorization\DenseCholesky.cs"> <Compile Include="..\Numerics\LinearAlgebra\Double\Factorization\DenseCholesky.cs">
<Link>LinearAlgebra\Double\Factorization\DenseCholesky.cs</Link> <Link>LinearAlgebra\Double\Factorization\DenseCholesky.cs</Link>
</Compile> </Compile>
@ -245,12 +242,6 @@
<Compile Include="..\Numerics\LinearAlgebra\Double\Factorization\GramSchmidt.cs"> <Compile Include="..\Numerics\LinearAlgebra\Double\Factorization\GramSchmidt.cs">
<Link>LinearAlgebra\Double\Factorization\GramSchmidt.cs</Link> <Link>LinearAlgebra\Double\Factorization\GramSchmidt.cs</Link>
</Compile> </Compile>
<Compile Include="..\Numerics\LinearAlgebra\Double\Factorization\LU.cs">
<Link>LinearAlgebra\Double\Factorization\LU.cs</Link>
</Compile>
<Compile Include="..\Numerics\LinearAlgebra\Double\Factorization\QR.cs">
<Link>LinearAlgebra\Double\Factorization\QR.cs</Link>
</Compile>
<Compile Include="..\Numerics\LinearAlgebra\Double\Factorization\SparseCholesky.cs"> <Compile Include="..\Numerics\LinearAlgebra\Double\Factorization\SparseCholesky.cs">
<Link>LinearAlgebra\Double\Factorization\SparseCholesky.cs</Link> <Link>LinearAlgebra\Double\Factorization\SparseCholesky.cs</Link>
</Compile> </Compile>
@ -263,9 +254,6 @@
<Compile Include="..\Numerics\LinearAlgebra\Double\Factorization\SparseSvd.cs"> <Compile Include="..\Numerics\LinearAlgebra\Double\Factorization\SparseSvd.cs">
<Link>LinearAlgebra\Double\Factorization\SparseSvd.cs</Link> <Link>LinearAlgebra\Double\Factorization\SparseSvd.cs</Link>
</Compile> </Compile>
<Compile Include="..\Numerics\LinearAlgebra\Double\Factorization\Svd.cs">
<Link>LinearAlgebra\Double\Factorization\Svd.cs</Link>
</Compile>
<Compile Include="..\Numerics\LinearAlgebra\Double\Factorization\UserCholesky.cs"> <Compile Include="..\Numerics\LinearAlgebra\Double\Factorization\UserCholesky.cs">
<Link>LinearAlgebra\Double\Factorization\UserCholesky.cs</Link> <Link>LinearAlgebra\Double\Factorization\UserCholesky.cs</Link>
</Compile> </Compile>
@ -290,24 +278,6 @@
<Compile Include="..\Numerics\LinearAlgebra\Double\IO\MatrixWriter.cs"> <Compile Include="..\Numerics\LinearAlgebra\Double\IO\MatrixWriter.cs">
<Link>LinearAlgebra\Double\IO\MatrixWriter.cs</Link> <Link>LinearAlgebra\Double\IO\MatrixWriter.cs</Link>
</Compile> </Compile>
<Compile Include="..\Numerics\LinearAlgebra\Double\ISolver.cs">
<Link>LinearAlgebra\Double\ISolver.cs</Link>
</Compile>
<Compile Include="..\Numerics\LinearAlgebra\Double\Matrix.Arithmetic.cs">
<Link>LinearAlgebra\Double\Matrix.Arithmetic.cs</Link>
</Compile>
<Compile Include="..\Numerics\LinearAlgebra\Double\Matrix.cs">
<Link>LinearAlgebra\Double\Matrix.cs</Link>
</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>
@ -338,62 +308,92 @@
<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>
<Compile Include="..\Numerics\LinearAlgebra\Double\Solvers\Status\CalculationCancelled.cs">
<Link>LinearAlgebra\Double\Solvers\Status\CalculationCancelled.cs</Link>
</Compile>
<Compile Include="..\Numerics\LinearAlgebra\Double\Solvers\Status\CalculationConverged.cs">
<Link>LinearAlgebra\Double\Solvers\Status\CalculationConverged.cs</Link>
</Compile>
<Compile Include="..\Numerics\LinearAlgebra\Double\Solvers\Status\CalculationDiverged.cs">
<Link>LinearAlgebra\Double\Solvers\Status\CalculationDiverged.cs</Link>
</Compile>
<Compile Include="..\Numerics\LinearAlgebra\Double\Solvers\Status\CalculationFailure.cs">
<Link>LinearAlgebra\Double\Solvers\Status\CalculationFailure.cs</Link>
</Compile>
<Compile Include="..\Numerics\LinearAlgebra\Double\Solvers\Status\CalculationIndetermined.cs">
<Link>LinearAlgebra\Double\Solvers\Status\CalculationIndetermined.cs</Link>
</Compile>
<Compile Include="..\Numerics\LinearAlgebra\Double\Solvers\Status\CalculationRunning.cs">
<Link>LinearAlgebra\Double\Solvers\Status\CalculationRunning.cs</Link>
</Compile>
<Compile Include="..\Numerics\LinearAlgebra\Double\Solvers\Status\CalculationStoppedWithoutConvergence.cs">
<Link>LinearAlgebra\Double\Solvers\Status\CalculationStoppedWithoutConvergence.cs</Link>
</Compile>
<Compile Include="..\Numerics\LinearAlgebra\Double\Solvers\Status\ICalculationStatus.cs">
<Link>LinearAlgebra\Double\Solvers\Status\ICalculationStatus.cs</Link>
</Compile>
<Compile Include="..\Numerics\LinearAlgebra\Double\Solvers\StopCriterium\DivergenceStopCriterium.cs"> <Compile Include="..\Numerics\LinearAlgebra\Double\Solvers\StopCriterium\DivergenceStopCriterium.cs">
<Link>LinearAlgebra\Double\Solvers\StopCriterium\DivergenceStopCriterium.cs</Link> <Link>LinearAlgebra\Double\Solvers\StopCriterium\DivergenceStopCriterium.cs</Link>
</Compile> </Compile>
<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>
<Compile Include="..\Numerics\LinearAlgebra\Double\Solvers\StopCriterium\ResidualStopCriterium.cs"> <Compile Include="..\Numerics\LinearAlgebra\Double\Solvers\StopCriterium\ResidualStopCriterium.cs">
<Link>LinearAlgebra\Double\Solvers\StopCriterium\ResidualStopCriterium.cs</Link> <Link>LinearAlgebra\Double\Solvers\StopCriterium\ResidualStopCriterium.cs</Link>
</Compile> </Compile>
<Compile Include="..\Numerics\LinearAlgebra\Double\Solvers\StopCriterium\StopLevel.cs">
<Link>LinearAlgebra\Double\Solvers\StopCriterium\StopLevel.cs</Link>
</Compile>
<Compile Include="..\Numerics\LinearAlgebra\Double\SparseMatrix.cs"> <Compile Include="..\Numerics\LinearAlgebra\Double\SparseMatrix.cs">
<Link>LinearAlgebra\Double\SparseMatrix.cs</Link> <Link>LinearAlgebra\Double\SparseMatrix.cs</Link>
</Compile> </Compile>
<Compile Include="..\Numerics\LinearAlgebra\Double\SparseVector.cs"> <Compile Include="..\Numerics\LinearAlgebra\Double\SparseVector.cs">
<Link>LinearAlgebra\Double\SparseVector.cs</Link> <Link>LinearAlgebra\Double\SparseVector.cs</Link>
</Compile> </Compile>
<Compile Include="..\Numerics\LinearAlgebra\Double\Vector.cs"> <Compile Include="..\Numerics\LinearAlgebra\Generic\Factorization\Cholesky.cs">
<Link>LinearAlgebra\Double\Vector.cs</Link> <Link>LinearAlgebra\Generic\Factorization\Cholesky.cs</Link>
</Compile>
<Compile Include="..\Numerics\LinearAlgebra\Generic\Factorization\LU.cs">
<Link>LinearAlgebra\Generic\Factorization\LU.cs</Link>
</Compile>
<Compile Include="..\Numerics\LinearAlgebra\Generic\Factorization\QR.cs">
<Link>LinearAlgebra\Generic\Factorization\QR.cs</Link>
</Compile>
<Compile Include="..\Numerics\LinearAlgebra\Generic\Factorization\Svd.cs">
<Link>LinearAlgebra\Generic\Factorization\Svd.cs</Link>
</Compile>
<Compile Include="..\Numerics\LinearAlgebra\Generic\ISolver.cs">
<Link>LinearAlgebra\Generic\ISolver.cs</Link>
</Compile>
<Compile Include="..\Numerics\LinearAlgebra\Generic\Matrix.Arithmetic.cs">
<Link>LinearAlgebra\Generic\Matrix.Arithmetic.cs</Link>
</Compile>
<Compile Include="..\Numerics\LinearAlgebra\Generic\Matrix.cs">
<Link>LinearAlgebra\Generic\Matrix.cs</Link>
</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">
<Link>LinearAlgebra\Generic\Solvers\Status\CalculationCancelled.cs</Link>
</Compile>
<Compile Include="..\Numerics\LinearAlgebra\Generic\Solvers\Status\CalculationConverged.cs">
<Link>LinearAlgebra\Generic\Solvers\Status\CalculationConverged.cs</Link>
</Compile>
<Compile Include="..\Numerics\LinearAlgebra\Generic\Solvers\Status\CalculationDiverged.cs">
<Link>LinearAlgebra\Generic\Solvers\Status\CalculationDiverged.cs</Link>
</Compile>
<Compile Include="..\Numerics\LinearAlgebra\Generic\Solvers\Status\CalculationFailure.cs">
<Link>LinearAlgebra\Generic\Solvers\Status\CalculationFailure.cs</Link>
</Compile>
<Compile Include="..\Numerics\LinearAlgebra\Generic\Solvers\Status\CalculationIndetermined.cs">
<Link>LinearAlgebra\Generic\Solvers\Status\CalculationIndetermined.cs</Link>
</Compile>
<Compile Include="..\Numerics\LinearAlgebra\Generic\Solvers\Status\CalculationRunning.cs">
<Link>LinearAlgebra\Generic\Solvers\Status\CalculationRunning.cs</Link>
</Compile>
<Compile Include="..\Numerics\LinearAlgebra\Generic\Solvers\Status\CalculationStoppedWithoutConvergence.cs">
<Link>LinearAlgebra\Generic\Solvers\Status\CalculationStoppedWithoutConvergence.cs</Link>
</Compile>
<Compile Include="..\Numerics\LinearAlgebra\Generic\Solvers\Status\ICalculationStatus.cs">
<Link>LinearAlgebra\Generic\Solvers\Status\ICalculationStatus.cs</Link>
</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">
<Link>LinearAlgebra\Generic\Solvers\StopCriterium\StopLevel.cs</Link>
</Compile>
<Compile Include="..\Numerics\LinearAlgebra\Generic\Vector.cs">
<Link>LinearAlgebra\Generic\Vector.cs</Link>
</Compile> </Compile>
<Compile Include="..\Numerics\NumberTheory\IntegerTheory.cs"> <Compile Include="..\Numerics\NumberTheory\IntegerTheory.cs">
<Link>NumberTheory\IntegerTheory.cs</Link> <Link>NumberTheory\IntegerTheory.cs</Link>

11
src/UnitTests/LinearAlgebraTests/Double/DenseMatrixTests.cs

@ -31,27 +31,28 @@
namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
{ {
using System.Collections.Generic; using System.Collections.Generic;
using LinearAlgebra.Generic;
using MbUnit.Framework; using MbUnit.Framework;
using LinearAlgebra.Double; using LinearAlgebra.Double;
public class DenseMatrixTests : MatrixTests public class DenseMatrixTests : MatrixTests
{ {
protected override Matrix CreateMatrix(int rows, int columns) protected override Matrix<double> CreateMatrix(int rows, int columns)
{ {
return new DenseMatrix(rows, columns); return new DenseMatrix(rows, columns);
} }
protected override Matrix CreateMatrix(double[,] data) protected override Matrix<double> CreateMatrix(double[,] data)
{ {
return new DenseMatrix(data); return new DenseMatrix(data);
} }
protected override Vector CreateVector(int size) protected override Vector<double> CreateVector(int size)
{ {
return new DenseVector(size); return new DenseVector(size);
} }
protected override Vector CreateVector(double[] data) protected override Vector<double> CreateVector(double[] data)
{ {
return new DenseVector(data); return new DenseVector(data);
} }
@ -59,7 +60,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Test] [Test]
public void CanCreateMatrixFrom1DArray() public void CanCreateMatrixFrom1DArray()
{ {
Dictionary<string, Matrix> testData = new Dictionary<string, Matrix> var testData = new Dictionary<string, Matrix<double>>
{ {
{ "Singular3x3", new DenseMatrix(3, 3, new[] { 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 2.0, 2.0, 2.0 }) }, { "Singular3x3", new DenseMatrix(3, 3, new[] { 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 2.0, 2.0, 2.0 }) },
{ "Square3x3", new DenseMatrix(3, 3, new[] { -1.1, 0.0, -4.4, -2.2, 1.1, 5.5, -3.3, 2.2, 6.6 }) }, { "Square3x3", new DenseMatrix(3, 3, new[] { -1.1, 0.0, -4.4, -2.2, 1.1, 5.5, -3.3, 2.2, 6.6 }) },

13
src/UnitTests/LinearAlgebraTests/Double/DenseVectorTests.cs

@ -29,16 +29,17 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using LinearAlgebra.Double; using LinearAlgebra.Double;
using LinearAlgebra.Generic;
using MbUnit.Framework; using MbUnit.Framework;
public class DenseVectorTests : VectorTests public class DenseVectorTests : VectorTests
{ {
protected override Vector CreateVector(int size) protected override Vector<double> CreateVector(int size)
{ {
return new DenseVector(size); return new DenseVector(size);
} }
protected override Vector CreateVector(IList<double> data) protected override Vector<double> CreateVector(IList<double> data)
{ {
var vector = new DenseVector(data.Count); var vector = new DenseVector(data.Count);
for (var index = 0; index < data.Count; index++) for (var index = 0; index < data.Count; index++)
@ -85,7 +86,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[MultipleAsserts] [MultipleAsserts]
public void CanCreateDenseVectorFromAnotherVector() public void CanCreateDenseVectorFromAnotherVector()
{ {
var vector = (Vector)new DenseVector(Data); var vector = (Vector<double>)new DenseVector(Data);
var other = new DenseVector(vector); var other = new DenseVector(vector);
Assert.AreNotSame(vector, other); Assert.AreNotSame(vector, other);
@ -258,7 +259,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
{ {
var vector1 = CreateVector(Data); var vector1 = CreateVector(Data);
var vector2 = CreateVector(Data); var vector2 = CreateVector(Data);
Matrix m = Vector.OuterProduct(vector1, vector2); Matrix<double> m = Vector<double>.OuterProduct(vector1, vector2);
for (var i = 0; i < vector1.Count; i++) for (var i = 0; i < vector1.Count; i++)
{ {
for (var j = 0; j < vector2.Count; j++) for (var j = 0; j < vector2.Count; j++)
@ -274,7 +275,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
{ {
DenseVector vector1 = null; DenseVector vector1 = null;
var vector2 = CreateVector(Data); var vector2 = CreateVector(Data);
Vector.OuterProduct(vector1, vector2); Vector<double>.OuterProduct(vector1, vector2);
} }
[Test] [Test]
@ -283,7 +284,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
{ {
var vector1 = CreateVector(Data); var vector1 = CreateVector(Data);
DenseVector vector2 = null; DenseVector vector2 = null;
Vector.OuterProduct(vector1, vector2); Vector<double>.OuterProduct(vector1, vector2);
} }
} }
} }

13
src/UnitTests/LinearAlgebraTests/Double/DiagonalMatrixTests.cs

@ -33,6 +33,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using LinearAlgebra.Generic;
using MbUnit.Framework; using MbUnit.Framework;
using LinearAlgebra.Double; using LinearAlgebra.Double;
@ -51,29 +52,29 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
{ "Wide2x3", new [,] { { -1.1, 0.0, 0.0 }, { 0.0, 1.1, 0.0 } } } { "Wide2x3", new [,] { { -1.1, 0.0, 0.0 }, { 0.0, 1.1, 0.0 } } }
}; };
TestMatrices = new Dictionary<string, Matrix>(); TestMatrices = new Dictionary<string, Matrix<double>>();
foreach (var name in TestData2D.Keys) foreach (var name in TestData2D.Keys)
{ {
TestMatrices.Add(name, CreateMatrix(TestData2D[name])); TestMatrices.Add(name, CreateMatrix(TestData2D[name]));
} }
} }
protected override Matrix CreateMatrix(int rows, int columns) protected override Matrix<double> CreateMatrix(int rows, int columns)
{ {
return new DiagonalMatrix(rows, columns); return new DiagonalMatrix(rows, columns);
} }
protected override Matrix CreateMatrix(double[,] data) protected override Matrix<double> CreateMatrix(double[,] data)
{ {
return new DiagonalMatrix(data); return new DiagonalMatrix(data);
} }
protected override Vector CreateVector(int size) protected override Vector<double> CreateVector(int size)
{ {
return new DenseVector(size); return new DenseVector(size);
} }
protected override Vector CreateVector(double[] data) protected override Vector<double> CreateVector(double[] data)
{ {
return new DenseVector(data); return new DenseVector(data);
} }
@ -81,7 +82,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Test] [Test]
public void CanCreateMatrixFromDiagonalArray() public void CanCreateMatrixFromDiagonalArray()
{ {
var testData = new Dictionary<string, Matrix> var testData = new Dictionary<string, Matrix<double>>
{ {
{ "Singular3x3", new DiagonalMatrix(3, 3, new[] { 1.0, 0.0, 3.0}) }, { "Singular3x3", new DiagonalMatrix(3, 3, new[] { 1.0, 0.0, 3.0}) },
{ "Square3x3", new DiagonalMatrix(4, 4, new[] { -1.1, 1.1, 6.6 }) }, { "Square3x3", new DiagonalMatrix(4, 4, new[] { -1.1, 1.1, 6.6 }) },

9
src/UnitTests/LinearAlgebraTests/Double/LinearAlgebraProviderTests.cs

@ -33,6 +33,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
using System; using System;
using Algorithms.LinearAlgebra; using Algorithms.LinearAlgebra;
using LinearAlgebra.Double; using LinearAlgebra.Double;
using LinearAlgebra.Generic;
using MbUnit.Framework; using MbUnit.Framework;
[TestFixture] [TestFixture]
@ -343,22 +344,22 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
} }
protected override Matrix CreateMatrix(int rows, int columns) protected override Matrix<double> CreateMatrix(int rows, int columns)
{ {
return new DenseMatrix(rows, columns); return new DenseMatrix(rows, columns);
} }
protected override Matrix CreateMatrix(double[,] data) protected override Matrix<double> CreateMatrix(double[,] data)
{ {
return new DenseMatrix(data); return new DenseMatrix(data);
} }
protected override Vector CreateVector(int size) protected override Vector<double> CreateVector(int size)
{ {
return new DenseVector(size); return new DenseVector(size);
} }
protected override Vector CreateVector(double[] data) protected override Vector<double> CreateVector(double[] data)
{ {
return new DenseVector(data); return new DenseVector(data);
} }

27
src/UnitTests/LinearAlgebraTests/Double/MatrixLoader.cs

@ -33,17 +33,18 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
{ {
using System.Collections.Generic; using System.Collections.Generic;
using LinearAlgebra.Double; using LinearAlgebra.Double;
using MbUnit.Framework; using LinearAlgebra.Generic;
using MbUnit.Framework;
public abstract class MatrixLoader public abstract class MatrixLoader
{ {
protected Dictionary<string, double[,]> TestData2D; protected Dictionary<string, double[,]> TestData2D;
protected Dictionary<string, Matrix> TestMatrices; protected Dictionary<string, Matrix<double>> TestMatrices;
protected abstract Matrix CreateMatrix(int rows, int columns); protected abstract Matrix<double> CreateMatrix(int rows, int columns);
protected abstract Matrix CreateMatrix(double[,] data); protected abstract Matrix<double> CreateMatrix(double[,] data);
protected abstract Vector CreateVector(int size); protected abstract Vector<double> CreateVector(int size);
protected abstract Vector CreateVector(double[] data); protected abstract Vector<double> CreateVector(double[] data);
[SetUp] [SetUp]
public virtual void SetupMatrices() public virtual void SetupMatrices()
@ -58,14 +59,14 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
{ "Wide2x3", new[,] { { -1.1, -2.2, -3.3 }, { 0.0, 1.1, 2.2 } } }, { "Wide2x3", new[,] { { -1.1, -2.2, -3.3 }, { 0.0, 1.1, 2.2 } } },
}; };
TestMatrices = new Dictionary<string, Matrix>(); TestMatrices = new Dictionary<string, Matrix<double>>();
foreach (var name in TestData2D.Keys) foreach (var name in TestData2D.Keys)
{ {
TestMatrices.Add(name, CreateMatrix(TestData2D[name])); TestMatrices.Add(name, CreateMatrix(TestData2D[name]));
} }
} }
public static Matrix GenerateRandomDenseMatrix(int row, int col) public static Matrix<double> GenerateRandomDenseMatrix(int row, int col)
{ {
// Fill a matrix with standard random numbers. // Fill a matrix with standard random numbers.
var normal = new Distributions.Normal(); var normal = new Distributions.Normal();
@ -83,7 +84,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
return matrixA; return matrixA;
} }
public static Matrix GenerateRandomPositiveDefiniteDenseMatrix(int order) public static Matrix<double> GenerateRandomPositiveDefiniteDenseMatrix(int order)
{ {
// Fill a matrix with standard random numbers. // Fill a matrix with standard random numbers.
var normal = new Distributions.Normal(); var normal = new Distributions.Normal();
@ -101,7 +102,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
return matrixA.Transpose() * matrixA; return matrixA.Transpose() * matrixA;
} }
public static Vector GenerateRandomDenseVector(int order) public static Vector<double> GenerateRandomDenseVector(int order)
{ {
// Fill a matrix with standard random numbers. // Fill a matrix with standard random numbers.
var normal = new Distributions.Normal(); var normal = new Distributions.Normal();
@ -116,7 +117,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
return v; return v;
} }
public static Matrix GenerateRandomUserDefinedMatrix(int row, int col) public static Matrix<double> GenerateRandomUserDefinedMatrix(int row, int col)
{ {
// Fill a matrix with standard random numbers. // Fill a matrix with standard random numbers.
var normal = new Distributions.Normal(); var normal = new Distributions.Normal();
@ -134,7 +135,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
return matrixA; return matrixA;
} }
public static Matrix GenerateRandomPositiveDefiniteUserDefinedMatrix(int order) public static Matrix<double> GenerateRandomPositiveDefiniteUserDefinedMatrix(int order)
{ {
// Fill a matrix with standard random numbers. // Fill a matrix with standard random numbers.
var normal = new Distributions.Normal(); var normal = new Distributions.Normal();
@ -152,7 +153,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
return matrixA.Transpose() * matrixA; return matrixA.Transpose() * matrixA;
} }
public static Vector GenerateRandomUserDefinedVector(int order) public static Vector<double> GenerateRandomUserDefinedVector(int order)
{ {
// Fill a matrix with standard random numbers. // Fill a matrix with standard random numbers.
var normal = new Distributions.Normal(); var normal = new Distributions.Normal();

221
src/UnitTests/LinearAlgebraTests/Double/MatrixTests.Arithmetic.cs

@ -29,6 +29,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
using System; using System;
using Distributions; using Distributions;
using LinearAlgebra.Double; using LinearAlgebra.Double;
using LinearAlgebra.Generic;
using MbUnit.Framework; using MbUnit.Framework;
public abstract partial class MatrixTests public abstract partial class MatrixTests
@ -40,7 +41,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[MultipleAsserts] [MultipleAsserts]
public void CanMultiplyWithScalar(double scalar) public void CanMultiplyWithScalar(double scalar)
{ {
var matrix = this.TestMatrices["Singular3x3"]; var matrix = TestMatrices["Singular3x3"];
var clone = matrix.Clone(); var clone = matrix.Clone();
clone.Multiply(scalar); clone.Multiply(scalar);
@ -56,7 +57,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Test] [Test]
public void CanMultiplyWithVector() public void CanMultiplyWithVector()
{ {
var A = this.TestMatrices["Singular3x3"]; var A = TestMatrices["Singular3x3"];
var x = new DenseVector(new[] { 1.0, 2.0, 3.0 }); var x = new DenseVector(new[] { 1.0, 2.0, 3.0 });
var y = A * x; var y = A * x;
@ -73,7 +74,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Test] [Test]
public void CanMultiplyWithVectorIntoResult() public void CanMultiplyWithVectorIntoResult()
{ {
var A = this.TestMatrices["Singular3x3"]; var A = TestMatrices["Singular3x3"];
var x = new DenseVector(new[] { 1.0, 2.0, 3.0 }); var x = new DenseVector(new[] { 1.0, 2.0, 3.0 });
var y = new DenseVector(3); var y = new DenseVector(3);
A.Multiply(x, y); A.Multiply(x, y);
@ -89,7 +90,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Test] [Test]
public void CanMultiplyWithVectorIntoResultWhenUpdatingInputArgument() public void CanMultiplyWithVectorIntoResultWhenUpdatingInputArgument()
{ {
var A = this.TestMatrices["Singular3x3"]; var A = TestMatrices["Singular3x3"];
var x = new DenseVector(new[] { 1.0, 2.0, 3.0 }); var x = new DenseVector(new[] { 1.0, 2.0, 3.0 });
var y = x; var y = x;
A.Multiply(x, x); A.Multiply(x, x);
@ -109,9 +110,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentNullException] [ExpectedArgumentNullException]
public void MultiplyWithVectorIntoResultFailsWhenResultIsNull() public void MultiplyWithVectorIntoResultFailsWhenResultIsNull()
{ {
var A = this.TestMatrices["Singular3x3"]; var A = TestMatrices["Singular3x3"];
var x = new DenseVector(new[] { 1.0, 2.0, 3.0 }); var x = new DenseVector(new[] { 1.0, 2.0, 3.0 });
Vector y = null; Vector<double> y = null;
A.Multiply(x, y); A.Multiply(x, y);
} }
@ -119,9 +120,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentException] [ExpectedArgumentException]
public void MultiplyWithVectorIntoResultFailsWhenResultIsTooLarge() public void MultiplyWithVectorIntoResultFailsWhenResultIsTooLarge()
{ {
var A = this.TestMatrices["Singular3x3"]; var A = TestMatrices["Singular3x3"];
var x = new DenseVector(new[] { 1.0, 2.0, 3.0 }); var x = new DenseVector(new[] { 1.0, 2.0, 3.0 });
Vector y = new DenseVector(4); Vector<double> y = new DenseVector(4);
A.Multiply(x, y); A.Multiply(x, y);
} }
@ -132,7 +133,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[MultipleAsserts] [MultipleAsserts]
public void CanOperatorLeftMultiplyWithScalar(double scalar) public void CanOperatorLeftMultiplyWithScalar(double scalar)
{ {
var matrix = this.TestMatrices["Singular3x3"]; var matrix = TestMatrices["Singular3x3"];
var clone = matrix * scalar; var clone = matrix * scalar;
for (var i = 0; i < matrix.RowCount; i++) for (var i = 0; i < matrix.RowCount; i++)
@ -151,7 +152,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[MultipleAsserts] [MultipleAsserts]
public void CanOperatorRightMultiplyWithScalar(double scalar) public void CanOperatorRightMultiplyWithScalar(double scalar)
{ {
var matrix = this.TestMatrices["Singular3x3"]; var matrix = TestMatrices["Singular3x3"];
var clone = matrix * scalar; var clone = matrix * scalar;
for (var i = 0; i < matrix.RowCount; i++) for (var i = 0; i < matrix.RowCount; i++)
@ -170,7 +171,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[MultipleAsserts] [MultipleAsserts]
public void CanMultiplyWithScalarIntoResult(double scalar) public void CanMultiplyWithScalarIntoResult(double scalar)
{ {
var matrix = this.TestMatrices["Singular3x3"]; var matrix = TestMatrices["Singular3x3"];
var result = matrix.Clone(); var result = matrix.Clone();
matrix.Multiply(scalar, result); matrix.Multiply(scalar, result);
@ -187,8 +188,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentNullException))] [ExpectedException(typeof(ArgumentNullException))]
public void MultiplyWithScalarIntoResultFailsWhenResultIsNull() public void MultiplyWithScalarIntoResultFailsWhenResultIsNull()
{ {
var matrix = this.TestMatrices["Singular3x3"]; var matrix = TestMatrices["Singular3x3"];
Matrix result = null; Matrix<double> result = null;
matrix.Multiply(2.3, result); matrix.Multiply(2.3, result);
} }
@ -196,8 +197,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentException] [ExpectedArgumentException]
public void MultiplyWithScalarFailsWhenResultHasMoreRows() public void MultiplyWithScalarFailsWhenResultHasMoreRows()
{ {
var matrix = this.TestMatrices["Singular3x3"]; var matrix = TestMatrices["Singular3x3"];
var result = this.CreateMatrix(matrix.RowCount + 1, matrix.ColumnCount); var result = CreateMatrix(matrix.RowCount + 1, matrix.ColumnCount);
matrix.Multiply(2.3, result); matrix.Multiply(2.3, result);
} }
@ -205,8 +206,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentException] [ExpectedArgumentException]
public void MultiplyWithScalarFailsWhenResultHasMoreColumns() public void MultiplyWithScalarFailsWhenResultHasMoreColumns()
{ {
var matrix = this.TestMatrices["Singular3x3"]; var matrix = TestMatrices["Singular3x3"];
var result = this.CreateMatrix(matrix.RowCount, matrix.ColumnCount + 1); var result = CreateMatrix(matrix.RowCount, matrix.ColumnCount + 1);
matrix.Multiply(2.3, result); matrix.Multiply(2.3, result);
} }
@ -214,7 +215,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentNullException))] [ExpectedException(typeof(ArgumentNullException))]
public void OperatorLeftMultiplyWithScalarFailsWhenMatrixIsNull() public void OperatorLeftMultiplyWithScalarFailsWhenMatrixIsNull()
{ {
Matrix matrix = null; Matrix<double> matrix = null;
var result = 2.3 * matrix; var result = 2.3 * matrix;
} }
@ -222,7 +223,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentNullException))] [ExpectedException(typeof(ArgumentNullException))]
public void OperatorRightMultiplyWithScalarFailsWhenMatrixIsNull() public void OperatorRightMultiplyWithScalarFailsWhenMatrixIsNull()
{ {
Matrix matrix = null; Matrix<double> matrix = null;
var result = matrix * 2.3; var result = matrix * 2.3;
} }
@ -231,8 +232,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Row("Singular4x4", "Square4x4")] [Row("Singular4x4", "Square4x4")]
public void CanAddMatrix(string mtxA, string mtxB) public void CanAddMatrix(string mtxA, string mtxB)
{ {
var A = this.TestMatrices[mtxA]; var A = TestMatrices[mtxA];
var B = this.TestMatrices[mtxB]; var B = TestMatrices[mtxB];
var matrix = A.Clone(); var matrix = A.Clone();
matrix.Add(B); matrix.Add(B);
@ -249,8 +250,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentNullException))] [ExpectedException(typeof(ArgumentNullException))]
public void AddMatrixThrowsExceptionWhenArgumentIsNull() public void AddMatrixThrowsExceptionWhenArgumentIsNull()
{ {
var matrix = this.TestMatrices["Singular4x4"]; var matrix = TestMatrices["Singular4x4"];
Matrix other = null; Matrix<double> other = null;
matrix.Add(other); matrix.Add(other);
} }
@ -258,8 +259,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentOutOfRangeException))] [ExpectedException(typeof(ArgumentOutOfRangeException))]
public void AddMatrixThrowsExceptionArgumentHasTooFewColumns() public void AddMatrixThrowsExceptionArgumentHasTooFewColumns()
{ {
var matrix = this.TestMatrices["Singular3x3"]; var matrix = TestMatrices["Singular3x3"];
var other = this.TestMatrices["Tall3x2"]; var other = TestMatrices["Tall3x2"];
matrix.Add(other); matrix.Add(other);
} }
@ -267,8 +268,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentOutOfRangeException))] [ExpectedException(typeof(ArgumentOutOfRangeException))]
public void AddMatrixThrowsExceptionArgumentHasTooFewRows() public void AddMatrixThrowsExceptionArgumentHasTooFewRows()
{ {
var matrix = this.TestMatrices["Singular3x3"]; var matrix = TestMatrices["Singular3x3"];
var other = this.TestMatrices["Wide2x3"]; var other = TestMatrices["Wide2x3"];
matrix.Add(other); matrix.Add(other);
} }
@ -277,8 +278,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Row("Singular4x4", "Square4x4")] [Row("Singular4x4", "Square4x4")]
public void AddOperator(string mtxA, string mtxB) public void AddOperator(string mtxA, string mtxB)
{ {
var A = this.TestMatrices[mtxA]; var A = TestMatrices[mtxA];
var B = this.TestMatrices[mtxB]; var B = TestMatrices[mtxB];
var result = A + B; var result = A + B;
for (var i = 0; i < A.RowCount; i++) for (var i = 0; i < A.RowCount; i++)
@ -294,8 +295,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentNullException))] [ExpectedException(typeof(ArgumentNullException))]
public void AddOperatorThrowsExceptionWhenLeftsideIsNull() public void AddOperatorThrowsExceptionWhenLeftsideIsNull()
{ {
Matrix matrix = null; Matrix<double> matrix = null;
var other = this.TestMatrices["Singular3x3"]; var other = TestMatrices["Singular3x3"];
var result = matrix + other; var result = matrix + other;
} }
@ -303,8 +304,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentNullException))] [ExpectedException(typeof(ArgumentNullException))]
public void AddOperatorThrowsExceptionWhenRightsideIsNull() public void AddOperatorThrowsExceptionWhenRightsideIsNull()
{ {
var matrix = this.TestMatrices["Singular3x3"]; var matrix = TestMatrices["Singular3x3"];
Matrix other = null; Matrix<double> other = null;
var result = matrix + other; var result = matrix + other;
} }
@ -312,8 +313,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentOutOfRangeException))] [ExpectedException(typeof(ArgumentOutOfRangeException))]
public void AddOperatorThrowsExceptionWhenRightsideHasTooFewColumns() public void AddOperatorThrowsExceptionWhenRightsideHasTooFewColumns()
{ {
var matrix = this.TestMatrices["Singular3x3"]; var matrix = TestMatrices["Singular3x3"];
var other = this.TestMatrices["Tall3x2"]; var other = TestMatrices["Tall3x2"];
var result = matrix + other; var result = matrix + other;
} }
@ -321,8 +322,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentOutOfRangeException))] [ExpectedException(typeof(ArgumentOutOfRangeException))]
public void AddOperatorThrowsExceptionWhenRightsideHasTooFewRows() public void AddOperatorThrowsExceptionWhenRightsideHasTooFewRows()
{ {
var matrix = this.TestMatrices["Singular3x3"]; var matrix = TestMatrices["Singular3x3"];
var other = this.TestMatrices["Wide2x3"]; var other = TestMatrices["Wide2x3"];
var result = matrix + other; var result = matrix + other;
} }
@ -331,8 +332,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Row("Singular4x4", "Square4x4")] [Row("Singular4x4", "Square4x4")]
public void CanSubtractMatrix(string mtxA, string mtxB) public void CanSubtractMatrix(string mtxA, string mtxB)
{ {
var A = this.TestMatrices[mtxA]; var A = TestMatrices[mtxA];
var B = this.TestMatrices[mtxB]; var B = TestMatrices[mtxB];
var matrix = A.Clone(); var matrix = A.Clone();
matrix.Subtract(B); matrix.Subtract(B);
@ -349,8 +350,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentNullException))] [ExpectedException(typeof(ArgumentNullException))]
public void SubtractMatrixThrowsExceptionWhenRightSideIsNull() public void SubtractMatrixThrowsExceptionWhenRightSideIsNull()
{ {
var matrix = this.TestMatrices["Singular4x4"]; var matrix = TestMatrices["Singular4x4"];
Matrix other = null; Matrix<double> other = null;
matrix.Subtract(other); matrix.Subtract(other);
} }
@ -358,8 +359,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentOutOfRangeException))] [ExpectedException(typeof(ArgumentOutOfRangeException))]
public void SubtractMatrixThrowsExceptionWhenRightSideHasTooFewColumns() public void SubtractMatrixThrowsExceptionWhenRightSideHasTooFewColumns()
{ {
var matrix = this.TestMatrices["Singular3x3"]; var matrix = TestMatrices["Singular3x3"];
var other = this.TestMatrices["Tall3x2"]; var other = TestMatrices["Tall3x2"];
matrix.Subtract(other); matrix.Subtract(other);
} }
@ -367,8 +368,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentOutOfRangeException))] [ExpectedException(typeof(ArgumentOutOfRangeException))]
public void SubtractMatrixThrowsExceptionWhenRightSideHasTooFewRows() public void SubtractMatrixThrowsExceptionWhenRightSideHasTooFewRows()
{ {
var matrix = this.TestMatrices["Singular3x3"]; var matrix = TestMatrices["Singular3x3"];
var other = this.TestMatrices["Wide2x3"]; var other = TestMatrices["Wide2x3"];
matrix.Subtract(other); matrix.Subtract(other);
} }
@ -377,8 +378,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Row("Singular4x4", "Square4x4")] [Row("Singular4x4", "Square4x4")]
public void SubtractOperator(string mtxA, string mtxB) public void SubtractOperator(string mtxA, string mtxB)
{ {
var A = this.TestMatrices[mtxA]; var A = TestMatrices[mtxA];
var B = this.TestMatrices[mtxB]; var B = TestMatrices[mtxB];
var result = A - B; var result = A - B;
for (var i = 0; i < A.RowCount; i++) for (var i = 0; i < A.RowCount; i++)
@ -394,8 +395,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentNullException))] [ExpectedException(typeof(ArgumentNullException))]
public void SubtractOperatorThrowsExceptionWhenLeftsideIsNull() public void SubtractOperatorThrowsExceptionWhenLeftsideIsNull()
{ {
Matrix matrix = null; Matrix<double> matrix = null;
var other = this.TestMatrices["Singular3x3"]; var other = TestMatrices["Singular3x3"];
var result = matrix - other; var result = matrix - other;
} }
@ -403,8 +404,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentNullException))] [ExpectedException(typeof(ArgumentNullException))]
public void SubtractOperatorThrowsExceptionWhenRightsideIsNull() public void SubtractOperatorThrowsExceptionWhenRightsideIsNull()
{ {
var matrix = this.TestMatrices["Singular3x3"]; var matrix = TestMatrices["Singular3x3"];
Matrix other = null; Matrix<double> other = null;
var result = matrix - other; var result = matrix - other;
} }
@ -412,8 +413,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentOutOfRangeException))] [ExpectedException(typeof(ArgumentOutOfRangeException))]
public void SubtractOperatorThrowsExceptionWhenRightsideHasTooFewColumns() public void SubtractOperatorThrowsExceptionWhenRightsideHasTooFewColumns()
{ {
var matrix = this.TestMatrices["Singular3x3"]; var matrix = TestMatrices["Singular3x3"];
var other = this.TestMatrices["Tall3x2"]; var other = TestMatrices["Tall3x2"];
var result = matrix - other; var result = matrix - other;
} }
@ -421,8 +422,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentOutOfRangeException))] [ExpectedException(typeof(ArgumentOutOfRangeException))]
public void SubtractOperatorThrowsExceptionWhenRightsideHasTooFewRows() public void SubtractOperatorThrowsExceptionWhenRightsideHasTooFewRows()
{ {
var matrix = this.TestMatrices["Singular3x3"]; var matrix = TestMatrices["Singular3x3"];
var other = this.TestMatrices["Wide2x3"]; var other = TestMatrices["Wide2x3"];
var result = matrix - other; var result = matrix - other;
} }
@ -435,8 +436,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[MultipleAsserts] [MultipleAsserts]
public void CanMultiplyMatrixWithMatrix(string nameA, string nameB) public void CanMultiplyMatrixWithMatrix(string nameA, string nameB)
{ {
var A = this.TestMatrices[nameA]; var A = TestMatrices[nameA];
var B = this.TestMatrices[nameB]; var B = TestMatrices[nameB];
var C = A * B; var C = A * B;
Assert.AreEqual(C.RowCount, A.RowCount); Assert.AreEqual(C.RowCount, A.RowCount);
@ -459,8 +460,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[MultipleAsserts] [MultipleAsserts]
public void CanTransposeAndMultiplyMatrixWithMatrix(string nameA) public void CanTransposeAndMultiplyMatrixWithMatrix(string nameA)
{ {
var A = this.TestMatrices[nameA]; var A = TestMatrices[nameA];
var B = this.TestMatrices[nameA]; var B = TestMatrices[nameA];
var C = A.TransposeAndMultiply(B); var C = A.TransposeAndMultiply(B);
Assert.AreEqual(C.RowCount, A.RowCount); Assert.AreEqual(C.RowCount, A.RowCount);
@ -479,8 +480,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentException))] [ExpectedException(typeof(ArgumentException))]
public void TransposeAndMultiplyMatrixMatrixFailsWhenSizesAreIncompatible() public void TransposeAndMultiplyMatrixMatrixFailsWhenSizesAreIncompatible()
{ {
var matrix = this.TestMatrices["Singular3x3"]; var matrix = TestMatrices["Singular3x3"];
var other = this.TestMatrices["Tall3x2"]; var other = TestMatrices["Tall3x2"];
var result = matrix.TransposeAndMultiply(other); var result = matrix.TransposeAndMultiply(other);
} }
@ -488,8 +489,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentNullException))] [ExpectedException(typeof(ArgumentNullException))]
public void TransposeAndMultiplyMatrixMatrixFailsWhenRightArgumentIsNull() public void TransposeAndMultiplyMatrixMatrixFailsWhenRightArgumentIsNull()
{ {
var matrix = this.TestMatrices["Wide2x3"]; var matrix = TestMatrices["Wide2x3"];
Matrix other = null; Matrix<double> other = null;
var result = matrix.TransposeAndMultiply(other); var result = matrix.TransposeAndMultiply(other);
} }
@ -502,9 +503,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[MultipleAsserts] [MultipleAsserts]
public void CanTransposeAndMultiplyMatrixWithMatrixIntoResult(string nameA) public void CanTransposeAndMultiplyMatrixWithMatrixIntoResult(string nameA)
{ {
var A = this.TestMatrices[nameA]; var A = TestMatrices[nameA];
var B = this.TestMatrices[nameA]; var B = TestMatrices[nameA];
var C = this.CreateMatrix(A.RowCount, B.RowCount); var C = CreateMatrix(A.RowCount, B.RowCount);
A.TransposeAndMultiply(B, C); A.TransposeAndMultiply(B, C);
Assert.AreEqual(C.RowCount, A.RowCount); Assert.AreEqual(C.RowCount, A.RowCount);
@ -523,8 +524,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentException))] [ExpectedException(typeof(ArgumentException))]
public void MultiplyMatrixMatrixFailsWhenSizesAreIncompatible() public void MultiplyMatrixMatrixFailsWhenSizesAreIncompatible()
{ {
var matrix = this.TestMatrices["Singular3x3"]; var matrix = TestMatrices["Singular3x3"];
var other = this.TestMatrices["Wide2x3"]; var other = TestMatrices["Wide2x3"];
var result = matrix * other; var result = matrix * other;
} }
@ -532,8 +533,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentNullException))] [ExpectedException(typeof(ArgumentNullException))]
public void MultiplyMatrixMatrixFailsWhenLeftArgumentIsNull() public void MultiplyMatrixMatrixFailsWhenLeftArgumentIsNull()
{ {
Matrix matrix = null; Matrix<double> matrix = null;
var other = this.TestMatrices["Wide2x3"]; var other = TestMatrices["Wide2x3"];
var result = matrix * other; var result = matrix * other;
} }
@ -541,8 +542,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentNullException))] [ExpectedException(typeof(ArgumentNullException))]
public void MultiplyMatrixMatrixFailsWhenRightArgumentIsNull() public void MultiplyMatrixMatrixFailsWhenRightArgumentIsNull()
{ {
var matrix = this.TestMatrices["Wide2x3"]; var matrix = TestMatrices["Wide2x3"];
Matrix other = null; Matrix<double> other = null;
var result = matrix * other; var result = matrix * other;
} }
@ -555,9 +556,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[MultipleAsserts] [MultipleAsserts]
public virtual void CanMultiplyMatrixWithMatrixIntoResult(string nameA, string nameB) public virtual void CanMultiplyMatrixWithMatrixIntoResult(string nameA, string nameB)
{ {
var A = this.TestMatrices[nameA]; var A = TestMatrices[nameA];
var B = this.TestMatrices[nameB]; var B = TestMatrices[nameB];
var C = this.CreateMatrix(A.RowCount, B.ColumnCount); var C = CreateMatrix(A.RowCount, B.ColumnCount);
A.Multiply(B, C); A.Multiply(B, C);
Assert.AreEqual(C.RowCount, A.RowCount); Assert.AreEqual(C.RowCount, A.RowCount);
@ -581,7 +582,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[MultipleAsserts] [MultipleAsserts]
public void CanNegate(string name) public void CanNegate(string name)
{ {
var matrix = this.TestMatrices[name]; var matrix = TestMatrices[name];
var copy = matrix.Clone(); var copy = matrix.Clone();
copy.Negate(); copy.Negate();
@ -604,7 +605,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[MultipleAsserts] [MultipleAsserts]
public void CanNegateIntoResult(string name) public void CanNegateIntoResult(string name)
{ {
var matrix = this.TestMatrices[name]; var matrix = TestMatrices[name];
var copy = matrix.Clone(); var copy = matrix.Clone();
matrix.Negate(copy); matrix.Negate(copy);
@ -622,8 +623,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentNullException] [ExpectedArgumentNullException]
public void NegateIntoResultFailsWhenResultIsNull() public void NegateIntoResultFailsWhenResultIsNull()
{ {
var matrix = this.TestMatrices["Singular3x3"]; var matrix = TestMatrices["Singular3x3"];
Matrix copy = null; Matrix<double> copy = null;
matrix.Negate(copy); matrix.Negate(copy);
} }
@ -631,8 +632,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentException] [ExpectedArgumentException]
public void NegateIntoResultFailsWhenResultHasMoreRows() public void NegateIntoResultFailsWhenResultHasMoreRows()
{ {
var matrix = this.TestMatrices["Singular3x3"]; var matrix = TestMatrices["Singular3x3"];
var target = this.CreateMatrix(matrix.RowCount + 1, matrix.ColumnCount); var target = CreateMatrix(matrix.RowCount + 1, matrix.ColumnCount);
matrix.Negate(target); matrix.Negate(target);
} }
@ -640,8 +641,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentException] [ExpectedArgumentException]
public void NegateIntoResultFailsWhenResultHasMoreColumns() public void NegateIntoResultFailsWhenResultHasMoreColumns()
{ {
var matrix = this.TestMatrices["Singular3x3"]; var matrix = TestMatrices["Singular3x3"];
var target = this.CreateMatrix(matrix.RowCount + 1, matrix.ColumnCount); var target = CreateMatrix(matrix.RowCount + 1, matrix.ColumnCount);
matrix.Negate(target); matrix.Negate(target);
} }
@ -649,9 +650,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Test] [Test]
public void KroneckerProduct() public void KroneckerProduct()
{ {
var A = this.TestMatrices["Wide2x3"]; var A = TestMatrices["Wide2x3"];
var B = this.TestMatrices["Square3x3"]; var B = TestMatrices["Square3x3"];
var result = this.CreateMatrix(A.RowCount * B.RowCount, A.ColumnCount * B.ColumnCount); var result = CreateMatrix(A.RowCount * B.RowCount, A.ColumnCount * B.ColumnCount);
A.KroneckerProduct(B, result); A.KroneckerProduct(B, result);
for (var i = 0; i < A.RowCount; i++) for (var i = 0; i < A.RowCount; i++)
{ {
@ -671,8 +672,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Test] [Test]
public void KroneckerProductResult() public void KroneckerProductResult()
{ {
var A = this.TestMatrices["Wide2x3"]; var A = TestMatrices["Wide2x3"];
var B = this.TestMatrices["Square3x3"]; var B = TestMatrices["Square3x3"];
var result = A.KroneckerProduct(B); var result = A.KroneckerProduct(B);
for (var i = 0; i < A.RowCount; i++) for (var i = 0; i < A.RowCount; i++)
{ {
@ -695,7 +696,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Row(-4, ExpectedException = typeof(ArgumentOutOfRangeException))] [Row(-4, ExpectedException = typeof(ArgumentOutOfRangeException))]
public void NormalizeColumns(int pValue) public void NormalizeColumns(int pValue)
{ {
var matrix = this.TestMatrices["Square4x4"]; var matrix = TestMatrices["Square4x4"];
var result = matrix.NormalizeColumns(pValue); var result = matrix.NormalizeColumns(pValue);
for (var j = 0; j < result.ColumnCount; j++) for (var j = 0; j < result.ColumnCount; j++)
{ {
@ -710,7 +711,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Row(-3, ExpectedException = typeof(ArgumentOutOfRangeException))] [Row(-3, ExpectedException = typeof(ArgumentOutOfRangeException))]
public void NormalizeRows(int pValue) public void NormalizeRows(int pValue)
{ {
var matrix = this.TestMatrices["Square4x4"].NormalizeRows(pValue); var matrix = TestMatrices["Square4x4"].NormalizeRows(pValue);
for (var i = 0; i < matrix.RowCount; i++) for (var i = 0; i < matrix.RowCount; i++)
{ {
var row = matrix.Row(i); var row = matrix.Row(i);
@ -721,7 +722,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Test] [Test]
public void PointwiseMultiplyResult() public void PointwiseMultiplyResult()
{ {
foreach (var data in this.TestMatrices.Values) foreach (var data in TestMatrices.Values)
{ {
var other = data.Clone(); var other = data.Clone();
var result = data.Clone(); var result = data.Clone();
@ -749,8 +750,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentNullException))] [ExpectedException(typeof(ArgumentNullException))]
public void PointwiseMultiplyWithNullOtherShouldThrowException() public void PointwiseMultiplyWithNullOtherShouldThrowException()
{ {
var matrix = this.TestMatrices["Wide2x3"]; var matrix = TestMatrices["Wide2x3"];
Matrix other = null; Matrix<double> other = null;
var result = matrix.Clone(); var result = matrix.Clone();
matrix.PointwiseMultiply(other, result); matrix.PointwiseMultiply(other, result);
} }
@ -759,7 +760,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentNullException))] [ExpectedException(typeof(ArgumentNullException))]
public void PointwiseMultiplyWithResultNullShouldThrowException() public void PointwiseMultiplyWithResultNullShouldThrowException()
{ {
var matrix = this.TestMatrices["Wide2x3"]; var matrix = TestMatrices["Wide2x3"];
var other = matrix.Clone(); var other = matrix.Clone();
matrix.PointwiseMultiply(other, null); matrix.PointwiseMultiply(other, null);
} }
@ -768,8 +769,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentException))] [ExpectedException(typeof(ArgumentException))]
public void PointwiseMultiplyWithInvalidOtherMatrixDimensionsShouldThrowException() public void PointwiseMultiplyWithInvalidOtherMatrixDimensionsShouldThrowException()
{ {
var matrix = this.TestMatrices["Wide2x3"]; var matrix = TestMatrices["Wide2x3"];
var other = this.CreateMatrix(matrix.RowCount + 1, matrix.ColumnCount); var other = CreateMatrix(matrix.RowCount + 1, matrix.ColumnCount);
var result = matrix.Clone(); var result = matrix.Clone();
matrix.PointwiseMultiply(other, result); matrix.PointwiseMultiply(other, result);
} }
@ -778,16 +779,16 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentException))] [ExpectedException(typeof(ArgumentException))]
public void PointwiseMultiplyWithInvalidResultMatrixDimensionsShouldThrowException() public void PointwiseMultiplyWithInvalidResultMatrixDimensionsShouldThrowException()
{ {
var matrix = this.TestMatrices["Wide2x3"]; var matrix = TestMatrices["Wide2x3"];
var other = matrix.Clone(); var other = matrix.Clone();
var result = this.CreateMatrix(matrix.RowCount + 1, matrix.ColumnCount); var result = CreateMatrix(matrix.RowCount + 1, matrix.ColumnCount);
matrix.PointwiseMultiply(other, result); matrix.PointwiseMultiply(other, result);
} }
[Test] [Test]
public virtual void PointwiseDivideResult() public virtual void PointwiseDivideResult()
{ {
foreach (var data in this.TestMatrices.Values) foreach (var data in TestMatrices.Values)
{ {
var other = data.Clone(); var other = data.Clone();
var result = data.Clone(); var result = data.Clone();
@ -815,8 +816,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentNullException))] [ExpectedException(typeof(ArgumentNullException))]
public void PointwiseDivideWithNullOtherShouldThrowException() public void PointwiseDivideWithNullOtherShouldThrowException()
{ {
var matrix = this.TestMatrices["Wide2x3"]; var matrix = TestMatrices["Wide2x3"];
Matrix other = null; Matrix<double> other = null;
var result = matrix.Clone(); var result = matrix.Clone();
matrix.PointwiseDivide(other, result); matrix.PointwiseDivide(other, result);
} }
@ -825,7 +826,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentNullException))] [ExpectedException(typeof(ArgumentNullException))]
public void PointwiseDivideWithResultNullShouldThrowException() public void PointwiseDivideWithResultNullShouldThrowException()
{ {
var matrix = this.TestMatrices["Wide2x3"]; var matrix = TestMatrices["Wide2x3"];
var other = matrix.Clone(); var other = matrix.Clone();
matrix.PointwiseDivide(other, null); matrix.PointwiseDivide(other, null);
} }
@ -834,8 +835,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentException))] [ExpectedException(typeof(ArgumentException))]
public void PointwiseDivideWithInvalidOtherMatrixDimensionsShouldThrowException() public void PointwiseDivideWithInvalidOtherMatrixDimensionsShouldThrowException()
{ {
var matrix = this.TestMatrices["Wide2x3"]; var matrix = TestMatrices["Wide2x3"];
var other = this.CreateMatrix(matrix.RowCount + 1, matrix.ColumnCount); var other = CreateMatrix(matrix.RowCount + 1, matrix.ColumnCount);
var result = matrix.Clone(); var result = matrix.Clone();
matrix.PointwiseDivide(other, result); matrix.PointwiseDivide(other, result);
} }
@ -844,9 +845,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentException))] [ExpectedException(typeof(ArgumentException))]
public void PointwiseDivideWithInvalidResultMatrixDimensionsShouldThrowException() public void PointwiseDivideWithInvalidResultMatrixDimensionsShouldThrowException()
{ {
var matrix = this.TestMatrices["Wide2x3"]; var matrix = TestMatrices["Wide2x3"];
var other = matrix.Clone(); var other = matrix.Clone();
var result = this.CreateMatrix(matrix.RowCount + 1, matrix.ColumnCount); var result = CreateMatrix(matrix.RowCount + 1, matrix.ColumnCount);
matrix.PointwiseDivide(other, result); matrix.PointwiseDivide(other, result);
} }
@ -855,7 +856,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Row(-2, ExpectedException = typeof(ArgumentException))] [Row(-2, ExpectedException = typeof(ArgumentException))]
public void RandomWithNonPositiveNumberOfRowsShouldThrowException(int numberOfRows) public void RandomWithNonPositiveNumberOfRowsShouldThrowException(int numberOfRows)
{ {
var matrix = this.CreateMatrix(2, 3); var matrix = CreateMatrix(2, 3);
matrix = matrix.Random(numberOfRows, 4, new ContinuousUniform()); matrix = matrix.Random(numberOfRows, 4, new ContinuousUniform());
} }
@ -864,14 +865,14 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Row(-2, ExpectedException = typeof(ArgumentException))] [Row(-2, ExpectedException = typeof(ArgumentException))]
public void RandomWithNonPositiveNumberOfRowsShouldThrowException2(int numberOfRows) public void RandomWithNonPositiveNumberOfRowsShouldThrowException2(int numberOfRows)
{ {
var matrix = this.CreateMatrix(2, 3); var matrix = CreateMatrix(2, 3);
matrix = matrix.Random(numberOfRows, 4, new DiscreteUniform(0, 2)); matrix = matrix.Random(numberOfRows, 4, new DiscreteUniform(0, 2));
} }
[Test] [Test]
public void Trace() public void Trace()
{ {
var matrix = this.TestMatrices["Square3x3"]; var matrix = TestMatrices["Square3x3"];
var trace = matrix.Trace(); var trace = matrix.Trace();
Assert.AreEqual(6.6, trace); Assert.AreEqual(6.6, trace);
} }
@ -880,7 +881,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentException] [ExpectedArgumentException]
public void TraceOfNonSquareMatrixShouldThrowException() public void TraceOfNonSquareMatrixShouldThrowException()
{ {
var matrix = this.TestMatrices["Wide2x3"]; var matrix = TestMatrices["Wide2x3"];
var trace = matrix.Trace(); var trace = matrix.Trace();
} }
} }

320
src/UnitTests/LinearAlgebraTests/Double/MatrixTests.cs

@ -27,7 +27,7 @@
namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
{ {
using System; using System;
using LinearAlgebra.Double; using LinearAlgebra.Generic;
using MbUnit.Framework; using MbUnit.Framework;
[TestFixture] [TestFixture]
@ -42,7 +42,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[MultipleAsserts] [MultipleAsserts]
public void CanCloneMatrix(string name) public void CanCloneMatrix(string name)
{ {
var matrix = this.CreateMatrix(this.TestData2D[name]); var matrix = CreateMatrix(TestData2D[name]);
var clone = matrix.Clone(); var clone = matrix.Clone();
Assert.AreNotSame(matrix, clone); Assert.AreNotSame(matrix, clone);
@ -66,8 +66,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[MultipleAsserts] [MultipleAsserts]
public void CanCloneMatrixUsingICloneable(string name) public void CanCloneMatrixUsingICloneable(string name)
{ {
var matrix = this.TestMatrices[name]; var matrix = TestMatrices[name];
var clone = (Matrix)((ICloneable)matrix).Clone(); var clone = (Matrix<double>)((ICloneable)matrix).Clone();
Assert.AreNotSame(matrix, clone); Assert.AreNotSame(matrix, clone);
Assert.AreEqual(matrix.RowCount, clone.RowCount); Assert.AreEqual(matrix.RowCount, clone.RowCount);
@ -90,8 +90,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[MultipleAsserts] [MultipleAsserts]
public void CanCopyTo(string name) public void CanCopyTo(string name)
{ {
var matrix = this.TestMatrices[name]; var matrix = TestMatrices[name];
var copy = this.CreateMatrix(matrix.RowCount, matrix.ColumnCount); var copy = CreateMatrix(matrix.RowCount, matrix.ColumnCount);
matrix.CopyTo(copy); matrix.CopyTo(copy);
Assert.AreNotSame(matrix, copy); Assert.AreNotSame(matrix, copy);
@ -108,8 +108,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentNullException] [ExpectedArgumentNullException]
public void CopyToFailsWhenTargetIsNull() public void CopyToFailsWhenTargetIsNull()
{ {
var matrix = this.TestMatrices["Singular3x3"]; var matrix = TestMatrices["Singular3x3"];
Matrix target = null; Matrix<double> target = null;
matrix.CopyTo(target); matrix.CopyTo(target);
} }
@ -117,8 +117,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentException] [ExpectedArgumentException]
public void CopyToFailsWhenTargetHasMoreRows() public void CopyToFailsWhenTargetHasMoreRows()
{ {
var matrix = this.TestMatrices["Singular3x3"]; var matrix = TestMatrices["Singular3x3"];
var target = this.CreateMatrix(matrix.RowCount + 1, matrix.ColumnCount); var target = CreateMatrix(matrix.RowCount + 1, matrix.ColumnCount);
matrix.CopyTo(target); matrix.CopyTo(target);
} }
@ -126,8 +126,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentException] [ExpectedArgumentException]
public void CopyToFailsWhenTargetHasMoreColumns() public void CopyToFailsWhenTargetHasMoreColumns()
{ {
var matrix = this.TestMatrices["Singular3x3"]; var matrix = TestMatrices["Singular3x3"];
var target = this.CreateMatrix(matrix.RowCount + 1, matrix.ColumnCount); var target = CreateMatrix(matrix.RowCount + 1, matrix.ColumnCount);
matrix.CopyTo(target); matrix.CopyTo(target);
} }
@ -140,7 +140,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Test] [Test]
public void CanCreateMatrix() public void CanCreateMatrix()
{ {
var expected = this.CreateMatrix(5, 6); var expected = CreateMatrix(5, 6);
var actual = expected.CreateMatrix(5, 6); var actual = expected.CreateMatrix(5, 6);
Assert.AreEqual(expected.GetType(), actual.GetType(), "Matrices are same type."); Assert.AreEqual(expected.GetType(), actual.GetType(), "Matrices are same type.");
} }
@ -154,9 +154,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[MultipleAsserts] [MultipleAsserts]
public void CanEquateMatrices(string name) public void CanEquateMatrices(string name)
{ {
var matrix1 = this.CreateMatrix(this.TestData2D[name]); var matrix1 = CreateMatrix(TestData2D[name]);
var matrix2 = this.CreateMatrix(this.TestData2D[name]); var matrix2 = CreateMatrix(TestData2D[name]);
var matrix3 = this.CreateMatrix(this.TestData2D[name].GetLength(0), this.TestData2D[name].GetLength(1)); var matrix3 = CreateMatrix(TestData2D[name].GetLength(0), TestData2D[name].GetLength(1));
Assert.IsTrue(matrix1.Equals(matrix1)); Assert.IsTrue(matrix1.Equals(matrix1));
Assert.IsTrue(matrix1.Equals(matrix2)); Assert.IsTrue(matrix1.Equals(matrix2));
Assert.IsFalse(matrix1.Equals(matrix3)); Assert.IsFalse(matrix1.Equals(matrix3));
@ -172,7 +172,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentOutOfRangeException] [ExpectedArgumentOutOfRangeException]
public void ThrowsArgumentExceptionIfSizeIsNotPositive(int rows, int columns) public void ThrowsArgumentExceptionIfSizeIsNotPositive(int rows, int columns)
{ {
var A = this.CreateMatrix(rows, columns); var A = CreateMatrix(rows, columns);
} }
[Test] [Test]
@ -183,7 +183,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Row("Wide2x3")] [Row("Wide2x3")]
public void TestingForEqualityWithNonMatrixReturnsFalse(string name) public void TestingForEqualityWithNonMatrixReturnsFalse(string name)
{ {
var matrix = this.CreateMatrix(this.TestData2D[name]); var matrix = CreateMatrix(TestData2D[name]);
Assert.IsFalse(matrix.Equals(2)); Assert.IsFalse(matrix.Equals(2));
} }
@ -195,8 +195,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Row("Wide2x3")] [Row("Wide2x3")]
public void CanTestForEqualityUsingObjectEquals(string name) public void CanTestForEqualityUsingObjectEquals(string name)
{ {
var matrix1 = this.CreateMatrix(this.TestData2D[name]); var matrix1 = CreateMatrix(TestData2D[name]);
var matrix2 = this.CreateMatrix(this.TestData2D[name]); var matrix2 = CreateMatrix(TestData2D[name]);
Assert.IsTrue(matrix1.Equals((object)matrix2)); Assert.IsTrue(matrix1.Equals((object)matrix2));
} }
@ -207,7 +207,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentOutOfRangeException))] [ExpectedException(typeof(ArgumentOutOfRangeException))]
public void RangeCheckFails(int i, int j, string name) public void RangeCheckFails(int i, int j, string name)
{ {
var d = this.TestMatrices[name][i, j]; var d = TestMatrices[name][i, j];
} }
[Test] [Test]
@ -219,7 +219,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Test] [Test]
public void CanClearMatrix() public void CanClearMatrix()
{ {
var matrix = this.TestMatrices["Singular3x3"].Clone(); var matrix = TestMatrices["Singular3x3"].Clone();
matrix.Clear(); matrix.Clear();
for (var i = 0; i < matrix.RowCount; i++) for (var i = 0; i < matrix.RowCount; i++)
{ {
@ -237,7 +237,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Row(2, "Square3x3")] [Row(2, "Square3x3")]
public void CanGetRow(int rowIndex, string name) public void CanGetRow(int rowIndex, string name)
{ {
var matrix = this.TestMatrices[name]; var matrix = TestMatrices[name];
var row = matrix.Row(rowIndex); var row = matrix.Row(rowIndex);
Assert.AreEqual(matrix.ColumnCount, row.Count); Assert.AreEqual(matrix.ColumnCount, row.Count);
@ -251,7 +251,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentOutOfRangeException))] [ExpectedException(typeof(ArgumentOutOfRangeException))]
public void GetRowThrowsArgumentOutOfRangeWithNegativeIndex() public void GetRowThrowsArgumentOutOfRangeWithNegativeIndex()
{ {
var matrix = this.TestMatrices["Singular3x3"]; var matrix = TestMatrices["Singular3x3"];
matrix.Row(-1); matrix.Row(-1);
} }
@ -259,7 +259,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentOutOfRangeException))] [ExpectedException(typeof(ArgumentOutOfRangeException))]
public void GetRowThrowsArgumentOutOfRangeWithOverflowingRowIndex() public void GetRowThrowsArgumentOutOfRangeWithOverflowingRowIndex()
{ {
var matrix = this.TestMatrices["Singular3x3"]; var matrix = TestMatrices["Singular3x3"];
matrix.Row(matrix.RowCount); matrix.Row(matrix.RowCount);
} }
@ -270,7 +270,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Row(2, "Square3x3")] [Row(2, "Square3x3")]
public void CanGetRowWithResult(int rowIndex, string name) public void CanGetRowWithResult(int rowIndex, string name)
{ {
var matrix = this.TestMatrices[name]; var matrix = TestMatrices[name];
var row = CreateVector(matrix.ColumnCount); var row = CreateVector(matrix.ColumnCount);
matrix.Row(rowIndex, row); matrix.Row(rowIndex, row);
@ -285,7 +285,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentNullException))] [ExpectedException(typeof(ArgumentNullException))]
public void GetRowWithResultFailsWhenResultIsNull() public void GetRowWithResultFailsWhenResultIsNull()
{ {
var matrix = this.TestMatrices["Singular3x3"]; var matrix = TestMatrices["Singular3x3"];
matrix.Row(0, null); matrix.Row(0, null);
} }
@ -293,7 +293,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentOutOfRangeException))] [ExpectedException(typeof(ArgumentOutOfRangeException))]
public void GetRowWithResultThrowsArgumentOutOfRangeWithNegativeIndex() public void GetRowWithResultThrowsArgumentOutOfRangeWithNegativeIndex()
{ {
var matrix = this.TestMatrices["Singular3x3"]; var matrix = TestMatrices["Singular3x3"];
var row = CreateVector(matrix.ColumnCount); var row = CreateVector(matrix.ColumnCount);
matrix.Row(-1, row); matrix.Row(-1, row);
} }
@ -302,7 +302,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentOutOfRangeException))] [ExpectedException(typeof(ArgumentOutOfRangeException))]
public void GetRowWithResultThrowsArgumentOutOfRangeWithOverflowingRowIndex() public void GetRowWithResultThrowsArgumentOutOfRangeWithOverflowingRowIndex()
{ {
var matrix = this.TestMatrices["Singular3x3"]; var matrix = TestMatrices["Singular3x3"];
var row = CreateVector(matrix.ColumnCount); var row = CreateVector(matrix.ColumnCount);
matrix.Row(matrix.RowCount, row); matrix.Row(matrix.RowCount, row);
} }
@ -314,7 +314,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Row(2, 0, 3, "Square3x3")] [Row(2, 0, 3, "Square3x3")]
public void CanGetRowWithRange(int rowIndex, int start, int length, string name) public void CanGetRowWithRange(int rowIndex, int start, int length, string name)
{ {
var matrix = this.TestMatrices[name]; var matrix = TestMatrices[name];
var row = matrix.Row(rowIndex, start, length); var row = matrix.Row(rowIndex, start, length);
Assert.AreEqual(length, row.Count); Assert.AreEqual(length, row.Count);
@ -328,7 +328,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentException))] [ExpectedException(typeof(ArgumentException))]
public void GetRowWithRangeResultArgumentExeptionWhenLengthIsZero() public void GetRowWithRangeResultArgumentExeptionWhenLengthIsZero()
{ {
var matrix = this.TestMatrices["Singular3x3"]; var matrix = TestMatrices["Singular3x3"];
var result = CreateVector(matrix.ColumnCount); var result = CreateVector(matrix.ColumnCount);
matrix.Row(0, 0, 0, result); matrix.Row(0, 0, 0, result);
} }
@ -337,8 +337,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentException))] [ExpectedException(typeof(ArgumentException))]
public void GetRowWithRangeFailsWithTooSmallResultVector() public void GetRowWithRangeFailsWithTooSmallResultVector()
{ {
var matrix = this.TestMatrices["Singular3x3"]; var matrix = TestMatrices["Singular3x3"];
var result = this.CreateVector(matrix.ColumnCount - 1); var result = CreateVector(matrix.ColumnCount - 1);
matrix.Row(0, 0, 0, result); matrix.Row(0, 0, 0, result);
} }
@ -349,7 +349,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Row(2, "Square3x3")] [Row(2, "Square3x3")]
public void CanGetColumn(int colIndex, string name) public void CanGetColumn(int colIndex, string name)
{ {
var matrix = this.TestMatrices[name]; var matrix = TestMatrices[name];
var col = matrix.Column(colIndex); var col = matrix.Column(colIndex);
Assert.AreEqual(matrix.RowCount, col.Count); Assert.AreEqual(matrix.RowCount, col.Count);
@ -363,7 +363,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentOutOfRangeException))] [ExpectedException(typeof(ArgumentOutOfRangeException))]
public void GetColumnThrowsArgumentOutOfRangeWithNegativeIndex() public void GetColumnThrowsArgumentOutOfRangeWithNegativeIndex()
{ {
var matrix = this.TestMatrices["Singular3x3"]; var matrix = TestMatrices["Singular3x3"];
matrix.Column(-1); matrix.Column(-1);
} }
@ -371,7 +371,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentOutOfRangeException))] [ExpectedException(typeof(ArgumentOutOfRangeException))]
public void GetColumnThrowsArgumentOutOfRangeWithOverflowingRowIndex() public void GetColumnThrowsArgumentOutOfRangeWithOverflowingRowIndex()
{ {
var matrix = this.TestMatrices["Singular3x3"]; var matrix = TestMatrices["Singular3x3"];
matrix.Column(matrix.ColumnCount); matrix.Column(matrix.ColumnCount);
} }
@ -382,7 +382,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Row(2, "Square3x3")] [Row(2, "Square3x3")]
public void CanGetColumnWithResult(int colIndex, string name) public void CanGetColumnWithResult(int colIndex, string name)
{ {
var matrix = this.TestMatrices[name]; var matrix = TestMatrices[name];
var col = CreateVector(matrix.RowCount); var col = CreateVector(matrix.RowCount);
matrix.Column(colIndex, col); matrix.Column(colIndex, col);
@ -397,7 +397,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentNullException))] [ExpectedException(typeof(ArgumentNullException))]
public void GetColumnFailsWhenResultIsNull() public void GetColumnFailsWhenResultIsNull()
{ {
var matrix = this.TestMatrices["Singular3x3"]; var matrix = TestMatrices["Singular3x3"];
matrix.Column(0, null); matrix.Column(0, null);
} }
@ -405,7 +405,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentOutOfRangeException))] [ExpectedException(typeof(ArgumentOutOfRangeException))]
public void GetColumnWithResultThrowsArgumentOutOfRangeWithNegativeIndex() public void GetColumnWithResultThrowsArgumentOutOfRangeWithNegativeIndex()
{ {
var matrix = this.TestMatrices["Singular3x3"]; var matrix = TestMatrices["Singular3x3"];
var column = CreateVector(matrix.ColumnCount); var column = CreateVector(matrix.ColumnCount);
matrix.Column(-1, column); matrix.Column(-1, column);
} }
@ -414,7 +414,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentOutOfRangeException))] [ExpectedException(typeof(ArgumentOutOfRangeException))]
public void GetColumnWithResultThrowsArgumentOutOfRangeWithOverflowingRowIndex() public void GetColumnWithResultThrowsArgumentOutOfRangeWithOverflowingRowIndex()
{ {
var matrix = this.TestMatrices["Singular3x3"]; var matrix = TestMatrices["Singular3x3"];
var column = CreateVector(matrix.RowCount); var column = CreateVector(matrix.RowCount);
matrix.Row(matrix.ColumnCount, column); matrix.Row(matrix.ColumnCount, column);
} }
@ -426,7 +426,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Row(2, 0, 3, "Square3x3")] [Row(2, 0, 3, "Square3x3")]
public void CanGetColumnWithRange(int colIndex, int start, int length, string name) public void CanGetColumnWithRange(int colIndex, int start, int length, string name)
{ {
var matrix = this.TestMatrices[name]; var matrix = TestMatrices[name];
var col = matrix.Column(colIndex, start, length); var col = matrix.Column(colIndex, start, length);
Assert.AreEqual(length, col.Count); Assert.AreEqual(length, col.Count);
@ -440,7 +440,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentException))] [ExpectedException(typeof(ArgumentException))]
public void GetColumnWithRangeResultArgumentExeptionWhenLengthIsZero() public void GetColumnWithRangeResultArgumentExeptionWhenLengthIsZero()
{ {
var matrix = this.TestMatrices["Singular3x3"]; var matrix = TestMatrices["Singular3x3"];
var col = CreateVector(matrix.RowCount); var col = CreateVector(matrix.RowCount);
matrix.Column(0, 0, 0, col); matrix.Column(0, 0, 0, col);
} }
@ -449,8 +449,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentException))] [ExpectedException(typeof(ArgumentException))]
public void GetColumnWithRangeFailsWithTooSmallResultVector() public void GetColumnWithRangeFailsWithTooSmallResultVector()
{ {
var matrix = this.TestMatrices["Singular3x3"]; var matrix = TestMatrices["Singular3x3"];
var result = this.CreateVector(matrix.RowCount - 1); var result = CreateVector(matrix.RowCount - 1);
matrix.Column(0, 0, matrix.RowCount, result); matrix.Column(0, 0, matrix.RowCount, result);
} }
@ -461,7 +461,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Row(2, "Square3x3")] [Row(2, "Square3x3")]
public void CanSetRow(int rowIndex, string name) public void CanSetRow(int rowIndex, string name)
{ {
var matrix = this.TestMatrices[name].Clone(); var matrix = TestMatrices[name].Clone();
matrix.SetRow(rowIndex, CreateVector(matrix.ColumnCount)); matrix.SetRow(rowIndex, CreateVector(matrix.ColumnCount));
for (var i = 0; i < matrix.RowCount; i++) for (var i = 0; i < matrix.RowCount; i++)
@ -474,7 +474,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
} }
else else
{ {
Assert.AreEqual(this.TestMatrices[name][i, j], matrix[i, j]); Assert.AreEqual(TestMatrices[name][i, j], matrix[i, j]);
} }
} }
} }
@ -487,7 +487,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Row(2, "Square3x3")] [Row(2, "Square3x3")]
public void CanSetColumn(int colIndex, string name) public void CanSetColumn(int colIndex, string name)
{ {
var matrix = this.TestMatrices[name].Clone(); var matrix = TestMatrices[name].Clone();
matrix.SetColumn(colIndex, CreateVector(matrix.ColumnCount)); matrix.SetColumn(colIndex, CreateVector(matrix.ColumnCount));
for (var i = 0; i < matrix.RowCount; i++) for (var i = 0; i < matrix.RowCount; i++)
@ -500,7 +500,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
} }
else else
{ {
Assert.AreEqual(this.TestMatrices[name][i, j], matrix[i, j]); Assert.AreEqual(TestMatrices[name][i, j], matrix[i, j]);
} }
} }
} }
@ -515,8 +515,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[MultipleAsserts] [MultipleAsserts]
public void UpperTriangleResult(string name) public void UpperTriangleResult(string name)
{ {
var data = this.TestMatrices[name]; var data = TestMatrices[name];
var result = this.CreateMatrix(data.RowCount, data.ColumnCount); var result = CreateMatrix(data.RowCount, data.ColumnCount);
var lower = data.UpperTriangle(); var lower = data.UpperTriangle();
for (var i = 0; i < data.RowCount; i++) for (var i = 0; i < data.RowCount; i++)
{ {
@ -539,8 +539,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentNullException] [ExpectedArgumentNullException]
public void UpperTriangleWithResultNullShouldThrowException() public void UpperTriangleWithResultNullShouldThrowException()
{ {
var data = this.TestMatrices["Square3x3"]; var data = TestMatrices["Square3x3"];
Matrix result = null; Matrix<double> result = null;
data.UpperTriangle(result); data.UpperTriangle(result);
} }
@ -548,8 +548,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentException] [ExpectedArgumentException]
public void UpperTriangleWithUnEqualRowsShouldThrowException() public void UpperTriangleWithUnEqualRowsShouldThrowException()
{ {
var data = this.TestMatrices["Square3x3"]; var data = TestMatrices["Square3x3"];
var result = this.CreateMatrix(data.RowCount + 1, data.ColumnCount); var result = CreateMatrix(data.RowCount + 1, data.ColumnCount);
data.UpperTriangle(result); data.UpperTriangle(result);
} }
@ -557,15 +557,15 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentException] [ExpectedArgumentException]
public void UpperTriangleWithUnEqualColumnsShouldThrowException() public void UpperTriangleWithUnEqualColumnsShouldThrowException()
{ {
var data = this.TestMatrices["Square3x3"]; var data = TestMatrices["Square3x3"];
var result = this.CreateMatrix(data.RowCount, data.ColumnCount + 1); var result = CreateMatrix(data.RowCount, data.ColumnCount + 1);
data.UpperTriangle(result); data.UpperTriangle(result);
} }
[Test] [Test]
public void StrictlyLowerTriangle() public void StrictlyLowerTriangle()
{ {
foreach (var data in this.TestMatrices.Values) foreach (var data in TestMatrices.Values)
{ {
var lower = data.StrictlyLowerTriangle(); var lower = data.StrictlyLowerTriangle();
for (var i = 0; i < data.RowCount; i++) for (var i = 0; i < data.RowCount; i++)
@ -588,9 +588,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Test] [Test]
public void StrictlyLowerTriangleResult() public void StrictlyLowerTriangleResult()
{ {
foreach (var data in this.TestMatrices.Values) foreach (var data in TestMatrices.Values)
{ {
var lower = this.CreateMatrix(data.RowCount, data.ColumnCount); var lower = CreateMatrix(data.RowCount, data.ColumnCount);
data.StrictlyLowerTriangle(lower); data.StrictlyLowerTriangle(lower);
for (var i = 0; i < data.RowCount; i++) for (var i = 0; i < data.RowCount; i++)
{ {
@ -613,8 +613,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentNullException] [ExpectedArgumentNullException]
public void StrictlyLowerTriangleWithNullParameterShouldThrowException() public void StrictlyLowerTriangleWithNullParameterShouldThrowException()
{ {
var data = this.TestMatrices["Square3x3"]; var data = TestMatrices["Square3x3"];
Matrix lower = null; Matrix<double> lower = null;
data.StrictlyLowerTriangle(lower); data.StrictlyLowerTriangle(lower);
} }
@ -622,8 +622,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentException] [ExpectedArgumentException]
public void StrictlyLowerTriangleWithInvalidColumnNumberShouldThrowException() public void StrictlyLowerTriangleWithInvalidColumnNumberShouldThrowException()
{ {
var data = this.TestMatrices["Square3x3"]; var data = TestMatrices["Square3x3"];
var lower = this.CreateMatrix(data.RowCount, data.ColumnCount + 1); var lower = CreateMatrix(data.RowCount, data.ColumnCount + 1);
data.StrictlyLowerTriangle(lower); data.StrictlyLowerTriangle(lower);
} }
@ -631,8 +631,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentException] [ExpectedArgumentException]
public void StrictlyLowerTriangleWithInvalidRowNumberShouldThrowException() public void StrictlyLowerTriangleWithInvalidRowNumberShouldThrowException()
{ {
var data = this.TestMatrices["Square3x3"]; var data = TestMatrices["Square3x3"];
var lower = this.CreateMatrix(data.RowCount + 1, data.ColumnCount); var lower = CreateMatrix(data.RowCount + 1, data.ColumnCount);
data.StrictlyLowerTriangle(lower); data.StrictlyLowerTriangle(lower);
} }
@ -640,7 +640,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Test] [Test]
public void StrictlyUpperTriangle() public void StrictlyUpperTriangle()
{ {
foreach (var data in this.TestMatrices.Values) foreach (var data in TestMatrices.Values)
{ {
var lower = data.StrictlyUpperTriangle(); var lower = data.StrictlyUpperTriangle();
for (var i = 0; i < data.RowCount; i++) for (var i = 0; i < data.RowCount; i++)
@ -663,9 +663,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Test] [Test]
public void StrictlyUpperTriangleResult() public void StrictlyUpperTriangleResult()
{ {
foreach (var data in this.TestMatrices.Values) foreach (var data in TestMatrices.Values)
{ {
var lower = this.CreateMatrix(data.RowCount, data.ColumnCount); var lower = CreateMatrix(data.RowCount, data.ColumnCount);
data.StrictlyUpperTriangle(lower); data.StrictlyUpperTriangle(lower);
for (var i = 0; i < data.RowCount; i++) for (var i = 0; i < data.RowCount; i++)
{ {
@ -688,8 +688,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentNullException] [ExpectedArgumentNullException]
public void StrictlyUpperTriangleWithNullParameterShouldThrowException() public void StrictlyUpperTriangleWithNullParameterShouldThrowException()
{ {
var data = this.TestMatrices["Square3x3"]; var data = TestMatrices["Square3x3"];
Matrix lower = null; Matrix<double> lower = null;
data.StrictlyUpperTriangle(lower); data.StrictlyUpperTriangle(lower);
} }
@ -697,8 +697,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentException] [ExpectedArgumentException]
public void StrictlyUpperTriangleWithInvalidColumnNumberShouldThrowException() public void StrictlyUpperTriangleWithInvalidColumnNumberShouldThrowException()
{ {
var data = this.TestMatrices["Square3x3"]; var data = TestMatrices["Square3x3"];
var lower = this.CreateMatrix(data.RowCount, data.ColumnCount + 1); var lower = CreateMatrix(data.RowCount, data.ColumnCount + 1);
data.StrictlyUpperTriangle(lower); data.StrictlyUpperTriangle(lower);
} }
@ -706,8 +706,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentException] [ExpectedArgumentException]
public void StrictlyUpperTriangleWithInvalidRowNumberShouldThrowException() public void StrictlyUpperTriangleWithInvalidRowNumberShouldThrowException()
{ {
var data = this.TestMatrices["Square3x3"]; var data = TestMatrices["Square3x3"];
var lower = this.CreateMatrix(data.RowCount + 1, data.ColumnCount); var lower = CreateMatrix(data.RowCount + 1, data.ColumnCount);
data.StrictlyUpperTriangle(lower); data.StrictlyUpperTriangle(lower);
} }
@ -720,7 +720,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[MultipleAsserts] [MultipleAsserts]
public void CanTransposeMatrix(string name) public void CanTransposeMatrix(string name)
{ {
var matrix = this.CreateMatrix(this.TestData2D[name]); var matrix = CreateMatrix(TestData2D[name]);
var transpose = matrix.Transpose(); var transpose = matrix.Transpose();
Assert.AreNotSame(matrix, transpose); Assert.AreNotSame(matrix, transpose);
@ -744,7 +744,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Row("Singular3x3", new double[] { 1, 2, 3, 4, 5 }, ExpectedException = typeof(ArgumentException))] [Row("Singular3x3", new double[] { 1, 2, 3, 4, 5 }, ExpectedException = typeof(ArgumentException))]
public virtual void SetColumnWithArray(string name, double[] column) public virtual void SetColumnWithArray(string name, double[] column)
{ {
var matrix = this.TestMatrices[name]; var matrix = TestMatrices[name];
for (var i = 0; i < matrix.ColumnCount; i++) for (var i = 0; i < matrix.ColumnCount; i++)
{ {
matrix.SetColumn(i, column); matrix.SetColumn(i, column);
@ -759,7 +759,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentOutOfRangeException] [ExpectedArgumentOutOfRangeException]
public void SetColumnArrayWithInvalidColumnIndexShouldThrowException() public void SetColumnArrayWithInvalidColumnIndexShouldThrowException()
{ {
var matrix = this.TestMatrices["Square3x3"]; var matrix = TestMatrices["Square3x3"];
double[] column = { 1, 2, 3 }; double[] column = { 1, 2, 3 };
matrix.SetColumn(-1, column); matrix.SetColumn(-1, column);
} }
@ -768,7 +768,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentOutOfRangeException] [ExpectedArgumentOutOfRangeException]
public void SetColumnArrayWithInvalidColumnIndexShouldThrowException2() public void SetColumnArrayWithInvalidColumnIndexShouldThrowException2()
{ {
var matrix = this.TestMatrices["Square3x3"]; var matrix = TestMatrices["Square3x3"];
double[] column = { 1, 2, 3 }; double[] column = { 1, 2, 3 };
matrix.SetColumn(matrix.ColumnCount + 1, column); matrix.SetColumn(matrix.ColumnCount + 1, column);
} }
@ -781,7 +781,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Row("Singular3x3", new double[] { 1, 2, 3, 4, 5 }, ExpectedException = typeof(ArgumentException))] [Row("Singular3x3", new double[] { 1, 2, 3, 4, 5 }, ExpectedException = typeof(ArgumentException))]
public virtual void SetColumnWithVector(string name, double[] column) public virtual void SetColumnWithVector(string name, double[] column)
{ {
var matrix = this.TestMatrices[name]; var matrix = TestMatrices[name];
var columnVector = CreateVector(column); var columnVector = CreateVector(column);
for (var i = 0; i < matrix.ColumnCount; i++) for (var i = 0; i < matrix.ColumnCount; i++)
{ {
@ -797,8 +797,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentNullException] [ExpectedArgumentNullException]
public void SetColumnWithNullVectorShouldThrowException() public void SetColumnWithNullVectorShouldThrowException()
{ {
var matrix = this.TestMatrices["Square3x3"]; var matrix = TestMatrices["Square3x3"];
Vector columnVector = null; Vector<double> columnVector = null;
matrix.SetColumn(1, columnVector); matrix.SetColumn(1, columnVector);
} }
@ -806,8 +806,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentOutOfRangeException] [ExpectedArgumentOutOfRangeException]
public void SetColumnVectorWithInvalidColumnIndexShouldThrowException() public void SetColumnVectorWithInvalidColumnIndexShouldThrowException()
{ {
var matrix = this.TestMatrices["Square3x3"]; var matrix = TestMatrices["Square3x3"];
var column = this.CreateVector(new double[] { 1, 2, 3 }); var column = CreateVector(new double[] { 1, 2, 3 });
matrix.SetColumn(-1, column); matrix.SetColumn(-1, column);
} }
@ -815,15 +815,15 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentOutOfRangeException] [ExpectedArgumentOutOfRangeException]
public void SetColumnVectorWithInvalidColumnIndexShouldThrowException2() public void SetColumnVectorWithInvalidColumnIndexShouldThrowException2()
{ {
var matrix = this.TestMatrices["Square3x3"]; var matrix = TestMatrices["Square3x3"];
var column = this.CreateVector(new double[] { 1, 2, 3 }); var column = CreateVector(new double[] { 1, 2, 3 });
matrix.SetColumn(matrix.ColumnCount + 1, column); matrix.SetColumn(matrix.ColumnCount + 1, column);
} }
[Test] [Test]
public void InsertColumn() public void InsertColumn()
{ {
var matrix = this.CreateMatrix(3, 3); var matrix = CreateMatrix(3, 3);
var column = CreateVector(matrix.RowCount); var column = CreateVector(matrix.RowCount);
for (var i = 0; i < column.Count; i++) for (var i = 0; i < column.Count; i++)
{ {
@ -855,7 +855,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentNullException))] [ExpectedException(typeof(ArgumentNullException))]
public void InsertNullColumnShouldThrowExecption() public void InsertNullColumnShouldThrowExecption()
{ {
var matrix = this.TestMatrices["Square3x3"]; var matrix = TestMatrices["Square3x3"];
matrix.InsertColumn(0, null); matrix.InsertColumn(0, null);
} }
@ -864,15 +864,15 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Row(5, ExpectedException = typeof(ArgumentOutOfRangeException))] [Row(5, ExpectedException = typeof(ArgumentOutOfRangeException))]
public void InsertColumnWithInvalidColumnIndexShouldThrowExceptiopn(int columnIndex) public void InsertColumnWithInvalidColumnIndexShouldThrowExceptiopn(int columnIndex)
{ {
var matrix = this.CreateMatrix(3, 3); var matrix = CreateMatrix(3, 3);
var column = CreateVector(matrix.RowCount); var column = CreateVector(matrix.RowCount);
matrix.InsertColumn(columnIndex, column); matrix.InsertColumn(columnIndex, column);
} }
public void InsertColumnWithInvalidNumberOfElementsShouldThrowException() public void InsertColumnWithInvalidNumberOfElementsShouldThrowException()
{ {
var matrix = this.CreateMatrix(3, 3); var matrix = CreateMatrix(3, 3);
var column = this.CreateVector(matrix.RowCount + 1); var column = CreateVector(matrix.RowCount + 1);
matrix.InsertColumn(0, column); matrix.InsertColumn(0, column);
} }
@ -885,7 +885,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Row("Singular3x3", new double[] { 1, 2, 3, 4, 5 }, ExpectedException = typeof(ArgumentException))] [Row("Singular3x3", new double[] { 1, 2, 3, 4, 5 }, ExpectedException = typeof(ArgumentException))]
public virtual void SetRowWithArray(string name, double[] row) public virtual void SetRowWithArray(string name, double[] row)
{ {
var matrix = this.TestMatrices[name]; var matrix = TestMatrices[name];
for (var i = 0; i < matrix.RowCount; i++) for (var i = 0; i < matrix.RowCount; i++)
{ {
matrix.SetRow(i, row); matrix.SetRow(i, row);
@ -900,7 +900,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentOutOfRangeException] [ExpectedArgumentOutOfRangeException]
public void SetRowArrayWithInvalidRowIndexShouldThrowException() public void SetRowArrayWithInvalidRowIndexShouldThrowException()
{ {
var matrix = this.TestMatrices["Square3x3"]; var matrix = TestMatrices["Square3x3"];
double[] row = { 1, 2, 3 }; double[] row = { 1, 2, 3 };
matrix.SetRow(-1, row); matrix.SetRow(-1, row);
} }
@ -909,7 +909,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentOutOfRangeException] [ExpectedArgumentOutOfRangeException]
public void SetRowArrayWithInvalidRowIndexShouldThrowException2() public void SetRowArrayWithInvalidRowIndexShouldThrowException2()
{ {
var matrix = this.TestMatrices["Square3x3"]; var matrix = TestMatrices["Square3x3"];
double[] row = { 1, 2, 3 }; double[] row = { 1, 2, 3 };
matrix.SetRow(matrix.RowCount + 1, row); matrix.SetRow(matrix.RowCount + 1, row);
} }
@ -922,7 +922,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Row("Singular3x3", new double[] { 1, 2, 3, 4, 5 }, ExpectedException = typeof(ArgumentException))] [Row("Singular3x3", new double[] { 1, 2, 3, 4, 5 }, ExpectedException = typeof(ArgumentException))]
public virtual void SetRowWithVector(string name, double[] row) public virtual void SetRowWithVector(string name, double[] row)
{ {
var matrix = this.TestMatrices[name]; var matrix = TestMatrices[name];
var rowVector = CreateVector(row); var rowVector = CreateVector(row);
for (var i = 0; i < matrix.RowCount; i++) for (var i = 0; i < matrix.RowCount; i++)
{ {
@ -938,8 +938,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentNullException] [ExpectedArgumentNullException]
public void SetRowWithNullVectorShouldThrowException() public void SetRowWithNullVectorShouldThrowException()
{ {
var matrix = this.TestMatrices["Square3x3"]; var matrix = TestMatrices["Square3x3"];
Vector rowVector = null; Vector<double> rowVector = null;
matrix.SetRow(1, rowVector); matrix.SetRow(1, rowVector);
} }
@ -947,8 +947,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentOutOfRangeException] [ExpectedArgumentOutOfRangeException]
public void SetRowVectorWithInvalidRowIndexShouldThrowException() public void SetRowVectorWithInvalidRowIndexShouldThrowException()
{ {
var matrix = this.TestMatrices["Square3x3"]; var matrix = TestMatrices["Square3x3"];
var row = this.CreateVector(new double[] { 1, 2, 3 }); var row = CreateVector(new double[] { 1, 2, 3 });
matrix.SetRow(-1, row); matrix.SetRow(-1, row);
} }
@ -956,8 +956,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentOutOfRangeException] [ExpectedArgumentOutOfRangeException]
public void SetRowVectorWithInvalidRowIndexShouldThrowException2() public void SetRowVectorWithInvalidRowIndexShouldThrowException2()
{ {
var matrix = this.TestMatrices["Square3x3"]; var matrix = TestMatrices["Square3x3"];
var row = this.CreateVector(new double[] { 1, 2, 3 }); var row = CreateVector(new double[] { 1, 2, 3 });
matrix.SetRow(matrix.RowCount + 1, row); matrix.SetRow(matrix.RowCount + 1, row);
} }
@ -974,7 +974,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Row(0, 2, 0, -1, ExpectedException = typeof(ArgumentException))] [Row(0, 2, 0, -1, ExpectedException = typeof(ArgumentException))]
public virtual void SetSubMatrix(int rowStart, int rowLength, int colStart, int colLength) public virtual void SetSubMatrix(int rowStart, int rowLength, int colStart, int colLength)
{ {
foreach (var matrix in this.TestMatrices.Values) foreach (var matrix in TestMatrices.Values)
{ {
var subMatrix = matrix.SubMatrix(0, 2, 0, 2); var subMatrix = matrix.SubMatrix(0, 2, 0, 2);
subMatrix[0, 0] = 10.0; subMatrix[0, 0] = 10.0;
@ -997,8 +997,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentNullException] [ExpectedArgumentNullException]
public void SetSubMatrixWithNullSubMatrixShouldThrowException() public void SetSubMatrixWithNullSubMatrixShouldThrowException()
{ {
var data = this.TestMatrices["Square3x3"]; var data = TestMatrices["Square3x3"];
Matrix subMatrix = null; Matrix<double> subMatrix = null;
data.SetSubMatrix(0, 2, 0, 2, subMatrix); data.SetSubMatrix(0, 2, 0, 2, subMatrix);
} }
@ -1009,7 +1009,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Row("Tall3x2", new double[] { 1, 2 })] [Row("Tall3x2", new double[] { 1, 2 })]
public void SetDiagonalVector(string name, double[] diagonal) public void SetDiagonalVector(string name, double[] diagonal)
{ {
var matrix = this.TestMatrices[name]; var matrix = TestMatrices[name];
var vector = CreateVector(diagonal); var vector = CreateVector(diagonal);
matrix.SetDiagonal(vector); matrix.SetDiagonal(vector);
@ -1026,8 +1026,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentNullException] [ExpectedArgumentNullException]
public void SetDiagonalWithNullVectorParameterShouldThrowException() public void SetDiagonalWithNullVectorParameterShouldThrowException()
{ {
var matrix = this.TestMatrices["Square3x3"]; var matrix = TestMatrices["Square3x3"];
Vector vector = null; Vector<double> vector = null;
matrix.SetDiagonal(vector); matrix.SetDiagonal(vector);
} }
@ -1039,7 +1039,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Row("Square3x3", null, ExpectedException = typeof(ArgumentNullException))] [Row("Square3x3", null, ExpectedException = typeof(ArgumentNullException))]
public void SetDiagonalArray(string name, double[] diagonal) public void SetDiagonalArray(string name, double[] diagonal)
{ {
var matrix = this.TestMatrices[name]; var matrix = TestMatrices[name];
matrix.SetDiagonal(diagonal); matrix.SetDiagonal(diagonal);
var min = Math.Min(matrix.ColumnCount, matrix.RowCount); var min = Math.Min(matrix.ColumnCount, matrix.RowCount);
Assert.AreEqual(diagonal.Length, min); Assert.AreEqual(diagonal.Length, min);
@ -1052,7 +1052,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Test] [Test]
public void InsertRow() public void InsertRow()
{ {
var matrix = this.CreateMatrix(3, 3); var matrix = CreateMatrix(3, 3);
var row = CreateVector(matrix.ColumnCount); var row = CreateVector(matrix.ColumnCount);
for (var i = 0; i < row.Count; i++) for (var i = 0; i < row.Count; i++)
{ {
@ -1084,7 +1084,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentNullException))] [ExpectedException(typeof(ArgumentNullException))]
public void InsertNullRowShouldThrowExecption() public void InsertNullRowShouldThrowExecption()
{ {
var matrix = this.TestMatrices["Square3x3"]; var matrix = TestMatrices["Square3x3"];
matrix.InsertRow(0, null); matrix.InsertRow(0, null);
} }
@ -1093,22 +1093,22 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Row(5, ExpectedException = typeof(ArgumentOutOfRangeException))] [Row(5, ExpectedException = typeof(ArgumentOutOfRangeException))]
public void InsertRowWithInvalidRowIndexShouldThrowExceptiopn(int rowIndex) public void InsertRowWithInvalidRowIndexShouldThrowExceptiopn(int rowIndex)
{ {
var matrix = this.CreateMatrix(3, 3); var matrix = CreateMatrix(3, 3);
var row = CreateVector(matrix.ColumnCount); var row = CreateVector(matrix.ColumnCount);
matrix.InsertRow(rowIndex, row); matrix.InsertRow(rowIndex, row);
} }
public void InsertRowWithInvalidNumberOfElementsShouldThrowException() public void InsertRowWithInvalidNumberOfElementsShouldThrowException()
{ {
var matrix = this.CreateMatrix(3, 3); var matrix = CreateMatrix(3, 3);
var row = this.CreateVector(matrix.ColumnCount + 1); var row = CreateVector(matrix.ColumnCount + 1);
matrix.InsertRow(0, row); matrix.InsertRow(0, row);
} }
[Test] [Test]
public void ToArray() public void ToArray()
{ {
foreach (var data in this.TestMatrices.Values) foreach (var data in TestMatrices.Values)
{ {
var array = data.ToArray(); var array = data.ToArray();
Assert.AreEqual(data.RowCount, array.GetLength(0)); Assert.AreEqual(data.RowCount, array.GetLength(0));
@ -1127,7 +1127,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Test] [Test]
public void ToColumnWiseArray() public void ToColumnWiseArray()
{ {
foreach (var data in this.TestMatrices.Values) foreach (var data in TestMatrices.Values)
{ {
var array = data.ToColumnWiseArray(); var array = data.ToColumnWiseArray();
Assert.AreEqual(data.RowCount * data.ColumnCount, array.Length); Assert.AreEqual(data.RowCount * data.ColumnCount, array.Length);
@ -1145,7 +1145,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Test] [Test]
public void ToRowWiseArray() public void ToRowWiseArray()
{ {
foreach (var data in this.TestMatrices.Values) foreach (var data in TestMatrices.Values)
{ {
var array = data.ToRowWiseArray(); var array = data.ToRowWiseArray();
Assert.AreEqual(data.RowCount * data.ColumnCount, array.Length); Assert.AreEqual(data.RowCount * data.ColumnCount, array.Length);
@ -1168,8 +1168,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[MultipleAsserts] [MultipleAsserts]
public virtual void CanPermuteMatrixRows(string name) public virtual void CanPermuteMatrixRows(string name)
{ {
var matrix = this.CreateMatrix(this.TestData2D[name]); var matrix = CreateMatrix(TestData2D[name]);
var matrixp = this.CreateMatrix(this.TestData2D[name]); var matrixp = CreateMatrix(TestData2D[name]);
var permutation = new Permutation(new[] { 2, 0, 1 }); var permutation = new Permutation(new[] { 2, 0, 1 });
matrixp.PermuteRows(permutation); matrixp.PermuteRows(permutation);
@ -1193,8 +1193,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[MultipleAsserts] [MultipleAsserts]
public virtual void CanPermuteMatrixColumns(string name) public virtual void CanPermuteMatrixColumns(string name)
{ {
var matrix = this.CreateMatrix(this.TestData2D[name]); var matrix = CreateMatrix(TestData2D[name]);
var matrixp = this.CreateMatrix(this.TestData2D[name]); var matrixp = CreateMatrix(TestData2D[name]);
var permutation = new Permutation(new[] { 2, 0, 1 }); var permutation = new Permutation(new[] { 2, 0, 1 });
matrixp.PermuteColumns(permutation); matrixp.PermuteColumns(permutation);
@ -1214,8 +1214,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Test] [Test]
public void CanAppendMatrices() public void CanAppendMatrices()
{ {
var left = this.CreateMatrix(this.TestData2D["Singular3x3"]); var left = CreateMatrix(TestData2D["Singular3x3"]);
var right = this.CreateMatrix(this.TestData2D["Tall3x2"]); var right = CreateMatrix(TestData2D["Tall3x2"]);
var result = left.Append(right); var result = left.Append(right);
Assert.AreEqual(left.ColumnCount + right.ColumnCount, result.ColumnCount); Assert.AreEqual(left.ColumnCount + right.ColumnCount, result.ColumnCount);
Assert.AreEqual(left.RowCount, right.RowCount); Assert.AreEqual(left.RowCount, right.RowCount);
@ -1240,8 +1240,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentNullException] [ExpectedArgumentNullException]
public void CanAppendWithRightParameterNullShouldThrowException() public void CanAppendWithRightParameterNullShouldThrowException()
{ {
var left = this.TestMatrices["Square3x3"]; var left = TestMatrices["Square3x3"];
Matrix right = null; Matrix<double> right = null;
left.Append(right); left.Append(right);
} }
@ -1249,9 +1249,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentNullException] [ExpectedArgumentNullException]
public void CanAppendWithResultParameterNullShouldThrowException() public void CanAppendWithResultParameterNullShouldThrowException()
{ {
var left = this.TestMatrices["Square3x3"]; var left = TestMatrices["Square3x3"];
var right = this.TestMatrices["Tall3x2"]; var right = TestMatrices["Tall3x2"];
Matrix result = null; Matrix<double> result = null;
left.Append(right, result); left.Append(right, result);
} }
@ -1259,8 +1259,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentException] [ExpectedArgumentException]
public void AppendingTwoMatricesWithDifferentRowCountShouldThrowException() public void AppendingTwoMatricesWithDifferentRowCountShouldThrowException()
{ {
var left = this.TestMatrices["Square3x3"]; var left = TestMatrices["Square3x3"];
var right = this.TestMatrices["Wide2x3"]; var right = TestMatrices["Wide2x3"];
var result = left.Append(right); var result = left.Append(right);
} }
@ -1268,17 +1268,17 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentException] [ExpectedArgumentException]
public void AppendingWithInvalidResultMatrixColumnsShouldThrowException() public void AppendingWithInvalidResultMatrixColumnsShouldThrowException()
{ {
var left = this.TestMatrices["Square3x3"]; var left = TestMatrices["Square3x3"];
var right = this.TestMatrices["Tall3x2"]; var right = TestMatrices["Tall3x2"];
var result = this.CreateMatrix(3, 2); var result = CreateMatrix(3, 2);
left.Append(right, result); left.Append(right, result);
} }
[Test] [Test]
public void CanStackMatrices() public void CanStackMatrices()
{ {
var top = this.TestMatrices["Square3x3"]; var top = TestMatrices["Square3x3"];
var bottom = this.TestMatrices["Wide2x3"]; var bottom = TestMatrices["Wide2x3"];
var result = top.Stack(bottom); var result = top.Stack(bottom);
Assert.AreEqual(top.RowCount + bottom.RowCount, result.RowCount); Assert.AreEqual(top.RowCount + bottom.RowCount, result.RowCount);
Assert.AreEqual(top.ColumnCount, result.ColumnCount); Assert.AreEqual(top.ColumnCount, result.ColumnCount);
@ -1303,9 +1303,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentNullException] [ExpectedArgumentNullException]
public void StackingWithBottomParameterNullShouldThrowException() public void StackingWithBottomParameterNullShouldThrowException()
{ {
var top = this.TestMatrices["Square3x3"]; var top = TestMatrices["Square3x3"];
Matrix bottom = null; Matrix<double> bottom = null;
var result = this.CreateMatrix(top.RowCount + top.RowCount, top.ColumnCount); var result = CreateMatrix(top.RowCount + top.RowCount, top.ColumnCount);
top.Stack(bottom, result); top.Stack(bottom, result);
} }
@ -1313,9 +1313,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentNullException] [ExpectedArgumentNullException]
public void StackingWithResultParameterNullShouldThrowException() public void StackingWithResultParameterNullShouldThrowException()
{ {
var top = this.TestMatrices["Square3x3"]; var top = TestMatrices["Square3x3"];
var bottom = this.TestMatrices["Square3x3"]; var bottom = TestMatrices["Square3x3"];
Matrix result = null; Matrix<double> result = null;
top.Stack(bottom, result); top.Stack(bottom, result);
} }
@ -1323,9 +1323,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentException] [ExpectedArgumentException]
public void StackingTwoMatricesWithDifferentColumnsShouldThrowException() public void StackingTwoMatricesWithDifferentColumnsShouldThrowException()
{ {
var top = this.TestMatrices["Square3x3"]; var top = TestMatrices["Square3x3"];
var lower = this.TestMatrices["Tall3x2"]; var lower = TestMatrices["Tall3x2"];
var result = this.CreateMatrix(top.RowCount + lower.RowCount, top.ColumnCount); var result = CreateMatrix(top.RowCount + lower.RowCount, top.ColumnCount);
top.Stack(lower, result); top.Stack(lower, result);
} }
@ -1333,17 +1333,17 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentException] [ExpectedArgumentException]
public void StackingWithInvalidResultMatrixRowsShouldThrowException() public void StackingWithInvalidResultMatrixRowsShouldThrowException()
{ {
var top = this.TestMatrices["Square3x3"]; var top = TestMatrices["Square3x3"];
var bottom = this.TestMatrices["Wide2x3"]; var bottom = TestMatrices["Wide2x3"];
var result = this.CreateMatrix(1, 3); var result = CreateMatrix(1, 3);
top.Stack(bottom, result); top.Stack(bottom, result);
} }
[Test] [Test]
public void CanDiagonallyStackMatrics() public void CanDiagonallyStackMatrics()
{ {
var top = this.TestMatrices["Tall3x2"]; var top = TestMatrices["Tall3x2"];
var bottom = this.TestMatrices["Wide2x3"]; var bottom = TestMatrices["Wide2x3"];
var result = top.DiagonalStack(bottom); var result = top.DiagonalStack(bottom);
Assert.AreEqual(top.RowCount + bottom.RowCount, result.RowCount); Assert.AreEqual(top.RowCount + bottom.RowCount, result.RowCount);
Assert.AreEqual(top.ColumnCount + bottom.ColumnCount, result.ColumnCount); Assert.AreEqual(top.ColumnCount + bottom.ColumnCount, result.ColumnCount);
@ -1372,17 +1372,17 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentNullException] [ExpectedArgumentNullException]
public void DiagonalStackWithLowerNullShouldThrowException() public void DiagonalStackWithLowerNullShouldThrowException()
{ {
var top = this.TestMatrices["Square3x3"]; var top = TestMatrices["Square3x3"];
Matrix lower = null; Matrix<double> lower = null;
top.DiagonalStack(lower); top.DiagonalStack(lower);
} }
[Test] [Test]
public virtual void CanDiagonallyStackMatricesWithPassingResult() public virtual void CanDiagonallyStackMatricesWithPassingResult()
{ {
var top = this.TestMatrices["Tall3x2"]; var top = TestMatrices["Tall3x2"];
var bottom = this.TestMatrices["Wide2x3"]; var bottom = TestMatrices["Wide2x3"];
var result = this.CreateMatrix(top.RowCount + bottom.RowCount, top.ColumnCount + bottom.ColumnCount); var result = CreateMatrix(top.RowCount + bottom.RowCount, top.ColumnCount + bottom.ColumnCount);
top.DiagonalStack(bottom, result); top.DiagonalStack(bottom, result);
Assert.AreEqual(top.RowCount + bottom.RowCount, result.RowCount); Assert.AreEqual(top.RowCount + bottom.RowCount, result.RowCount);
Assert.AreEqual(top.ColumnCount + bottom.ColumnCount, result.ColumnCount); Assert.AreEqual(top.ColumnCount + bottom.ColumnCount, result.ColumnCount);
@ -1411,9 +1411,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentNullException] [ExpectedArgumentNullException]
public void DiagonalStackWithResultNullShouldThrowException() public void DiagonalStackWithResultNullShouldThrowException()
{ {
var top = this.TestMatrices["Square3x3"]; var top = TestMatrices["Square3x3"];
var lower = this.TestMatrices["Wide2x3"]; var lower = TestMatrices["Wide2x3"];
Matrix result = null; Matrix<double> result = null;
top.DiagonalStack(lower, result); top.DiagonalStack(lower, result);
} }
@ -1421,9 +1421,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentException] [ExpectedArgumentException]
public void DiagonalStackWithInvalidResultMatrixShouldThrowException() public void DiagonalStackWithInvalidResultMatrixShouldThrowException()
{ {
var top = this.TestMatrices["Square3x3"]; var top = TestMatrices["Square3x3"];
var lower = this.TestMatrices["Wide2x3"]; var lower = TestMatrices["Wide2x3"];
var result = this.CreateMatrix(top.RowCount + lower.RowCount + 2, top.ColumnCount + lower.ColumnCount); var result = CreateMatrix(top.RowCount + lower.RowCount + 2, top.ColumnCount + lower.ColumnCount);
top.DiagonalStack(lower, result); top.DiagonalStack(lower, result);
} }
@ -1443,7 +1443,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Test] [Test]
public virtual void InfinityNorm() public virtual void InfinityNorm()
{ {
Matrix matrix = TestMatrices["Square3x3"]; var matrix = TestMatrices["Square3x3"];
Assert.AreEqual(16.5, matrix.InfinityNorm()); Assert.AreEqual(16.5, matrix.InfinityNorm());
matrix = TestMatrices["Wide2x3"]; matrix = TestMatrices["Wide2x3"];
@ -1456,7 +1456,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Test] [Test]
public virtual void L1Norm() public virtual void L1Norm()
{ {
Matrix matrix = TestMatrices["Square3x3"]; var matrix = TestMatrices["Square3x3"];
Assert.AreEqual(12.1, matrix.L1Norm()); Assert.AreEqual(12.1, matrix.L1Norm());
matrix = TestMatrices["Wide2x3"]; matrix = TestMatrices["Wide2x3"];

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

@ -3,8 +3,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
using LinearAlgebra.Double; using LinearAlgebra.Double;
using LinearAlgebra.Double.Solvers; using LinearAlgebra.Double.Solvers;
using LinearAlgebra.Double.Solvers.Iterative; using LinearAlgebra.Double.Solvers.Iterative;
using LinearAlgebra.Double.Solvers.Status;
using LinearAlgebra.Double.Solvers.StopCriterium; using LinearAlgebra.Double.Solvers.StopCriterium;
using LinearAlgebra.Generic;
using LinearAlgebra.Generic.Solvers.Status;
using LinearAlgebra.Generic.Solvers.StopCriterium;
using MbUnit.Framework; using MbUnit.Framework;
[TestFixture] [TestFixture]
@ -18,7 +20,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
public void SolveWideMatrix() public void SolveWideMatrix()
{ {
var matrix = new SparseMatrix(2, 3); var matrix = new SparseMatrix(2, 3);
Vector input = new DenseVector(2); Vector<double> input = new DenseVector(2);
var solver = new BiCgStab(); var solver = new BiCgStab();
solver.Solve(matrix, input); solver.Solve(matrix, input);
@ -29,7 +31,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
public void SolveLongMatrix() public void SolveLongMatrix()
{ {
var matrix = new SparseMatrix(3, 2); var matrix = new SparseMatrix(3, 2);
Vector input = new DenseVector(3); Vector<double> input = new DenseVector(3);
var solver = new BiCgStab(); var solver = new BiCgStab();
solver.Solve(matrix, input); solver.Solve(matrix, input);
@ -40,13 +42,13 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
public void SolveUnitMatrixAndBackMultiply() public void SolveUnitMatrixAndBackMultiply()
{ {
// Create the identity matrix // Create the identity matrix
Matrix matrix = SparseMatrix.Identity(100); Matrix<double> matrix = SparseMatrix.Identity(100);
// Create the y vector // Create the y vector
Vector y = new DenseVector(matrix.RowCount, 1); Vector<double> 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[] var monitor = new Iterator(new IIterationStopCriterium<double>[]
{ {
new IterationCountStopCriterium(MaximumIterations), new IterationCountStopCriterium(MaximumIterations),
new ResidualStopCriterium(ConvergenceBoundary), new ResidualStopCriterium(ConvergenceBoundary),
@ -80,16 +82,16 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
public void SolveScaledUnitMatrixAndBackMultiply() public void SolveScaledUnitMatrixAndBackMultiply()
{ {
// Create the identity matrix // Create the identity matrix
Matrix matrix = SparseMatrix.Identity(100); Matrix<double> matrix = SparseMatrix.Identity(100);
// Scale it with a funny number // Scale it with a funny number
matrix.Multiply(System.Math.PI); matrix.Multiply(System.Math.PI);
// Create the y vector // Create the y vector
Vector y = new DenseVector(matrix.RowCount, 1); Vector<double> 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[] var monitor = new Iterator(new IIterationStopCriterium<double>[]
{ {
new IterationCountStopCriterium(MaximumIterations), new IterationCountStopCriterium(MaximumIterations),
new ResidualStopCriterium(ConvergenceBoundary), new ResidualStopCriterium(ConvergenceBoundary),
@ -162,10 +164,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
} }
// Create the y vector // Create the y vector
Vector y = new DenseVector(matrix.RowCount, 1); Vector<double> 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[] var monitor = new Iterator(new IIterationStopCriterium<double>[]
{ {
new IterationCountStopCriterium(MaximumIterations), new IterationCountStopCriterium(MaximumIterations),
new ResidualStopCriterium(ConvergenceBoundary), new ResidualStopCriterium(ConvergenceBoundary),
@ -204,7 +206,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order);
var vectorb = MatrixLoader.GenerateRandomDenseVector(order); var vectorb = MatrixLoader.GenerateRandomDenseVector(order);
var monitor = new Iterator(new IIterationStopCriterium[] var monitor = new Iterator(new IIterationStopCriterium<double>[]
{ {
new IterationCountStopCriterium(1000), new IterationCountStopCriterium(1000),
new ResidualStopCriterium(1e-10), new ResidualStopCriterium(1e-10),
@ -233,7 +235,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order);
var matrixB = MatrixLoader.GenerateRandomDenseMatrix(order, order); var matrixB = MatrixLoader.GenerateRandomDenseMatrix(order, order);
var monitor = new Iterator(new IIterationStopCriterium[] var monitor = new Iterator(new IIterationStopCriterium<double>[]
{ {
new IterationCountStopCriterium(1000), new IterationCountStopCriterium(1000),
new ResidualStopCriterium(1e-10) new ResidualStopCriterium(1e-10)

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

@ -3,8 +3,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
using LinearAlgebra.Double; using LinearAlgebra.Double;
using LinearAlgebra.Double.Solvers; using LinearAlgebra.Double.Solvers;
using LinearAlgebra.Double.Solvers.Iterative; using LinearAlgebra.Double.Solvers.Iterative;
using LinearAlgebra.Double.Solvers.Status;
using LinearAlgebra.Double.Solvers.StopCriterium; using LinearAlgebra.Double.Solvers.StopCriterium;
using LinearAlgebra.Generic;
using LinearAlgebra.Generic.Solvers.Status;
using LinearAlgebra.Generic.Solvers.StopCriterium;
using MbUnit.Framework; using MbUnit.Framework;
[TestFixture] [TestFixture]
@ -18,7 +20,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
public void SolveWideMatrix() public void SolveWideMatrix()
{ {
var matrix = new SparseMatrix(2, 3); var matrix = new SparseMatrix(2, 3);
Vector input = new DenseVector(2); Vector<double> input = new DenseVector(2);
var solver = new GpBiCg(); var solver = new GpBiCg();
solver.Solve(matrix, input); solver.Solve(matrix, input);
@ -29,7 +31,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
public void SolveLongMatrix() public void SolveLongMatrix()
{ {
var matrix = new SparseMatrix(3, 2); var matrix = new SparseMatrix(3, 2);
Vector input = new DenseVector(3); Vector<double> input = new DenseVector(3);
var solver = new GpBiCg(); var solver = new GpBiCg();
solver.Solve(matrix, input); solver.Solve(matrix, input);
@ -40,13 +42,13 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
public void SolveUnitMatrixAndBackMultiply() public void SolveUnitMatrixAndBackMultiply()
{ {
// Create the identity matrix // Create the identity matrix
Matrix matrix = SparseMatrix.Identity(100); Matrix<double> matrix = SparseMatrix.Identity(100);
// Create the y vector // Create the y vector
Vector y = new DenseVector(matrix.RowCount, 1); Vector<double> 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[] var monitor = new Iterator(new IIterationStopCriterium<double>[]
{ {
new IterationCountStopCriterium(MaximumIterations), new IterationCountStopCriterium(MaximumIterations),
new ResidualStopCriterium(ConvergenceBoundary), new ResidualStopCriterium(ConvergenceBoundary),
@ -80,16 +82,16 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
public void SolveScaledUnitMatrixAndBackMultiply() public void SolveScaledUnitMatrixAndBackMultiply()
{ {
// Create the identity matrix // Create the identity matrix
Matrix matrix = SparseMatrix.Identity(100); Matrix<double> matrix = SparseMatrix.Identity(100);
// Scale it with a funny number // Scale it with a funny number
matrix.Multiply(System.Math.PI); matrix.Multiply(System.Math.PI);
// Create the y vector // Create the y vector
Vector y = new DenseVector(matrix.RowCount, 1); Vector<double> 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[] var monitor = new Iterator(new IIterationStopCriterium<double>[]
{ {
new IterationCountStopCriterium(MaximumIterations), new IterationCountStopCriterium(MaximumIterations),
new ResidualStopCriterium(ConvergenceBoundary), new ResidualStopCriterium(ConvergenceBoundary),
@ -163,10 +165,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
} }
// Create the y vector // Create the y vector
Vector y = new DenseVector(matrix.RowCount, 1); Vector<double> 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[] var monitor = new Iterator(new IIterationStopCriterium<double>[]
{ {
new IterationCountStopCriterium(MaximumIterations), new IterationCountStopCriterium(MaximumIterations),
new ResidualStopCriterium(ConvergenceBoundary), new ResidualStopCriterium(ConvergenceBoundary),
@ -206,7 +208,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order);
var vectorb = MatrixLoader.GenerateRandomDenseVector(order); var vectorb = MatrixLoader.GenerateRandomDenseVector(order);
var monitor = new Iterator(new IIterationStopCriterium[] var monitor = new Iterator(new IIterationStopCriterium<double>[]
{ {
new IterationCountStopCriterium(1000), new IterationCountStopCriterium(1000),
new ResidualStopCriterium(1e-10), new ResidualStopCriterium(1e-10),
@ -235,7 +237,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order);
var matrixB = MatrixLoader.GenerateRandomDenseMatrix(order, order); var matrixB = MatrixLoader.GenerateRandomDenseMatrix(order, order);
var monitor = new Iterator(new IIterationStopCriterium[] var monitor = new Iterator(new IIterationStopCriterium<double>[]
{ {
new IterationCountStopCriterium(1000), new IterationCountStopCriterium(1000),
new ResidualStopCriterium(1e-10) new ResidualStopCriterium(1e-10)

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

@ -3,8 +3,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
using LinearAlgebra.Double; using LinearAlgebra.Double;
using LinearAlgebra.Double.Solvers; using LinearAlgebra.Double.Solvers;
using LinearAlgebra.Double.Solvers.Iterative; using LinearAlgebra.Double.Solvers.Iterative;
using LinearAlgebra.Double.Solvers.Status;
using LinearAlgebra.Double.Solvers.StopCriterium; using LinearAlgebra.Double.Solvers.StopCriterium;
using LinearAlgebra.Generic;
using LinearAlgebra.Generic.Solvers.Status;
using LinearAlgebra.Generic.Solvers.StopCriterium;
using MbUnit.Framework; using MbUnit.Framework;
[TestFixture] [TestFixture]
@ -18,7 +20,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
public void SolveWideMatrix() public void SolveWideMatrix()
{ {
var matrix = new SparseMatrix(2, 3); var matrix = new SparseMatrix(2, 3);
Vector input = new DenseVector(2); Vector<double> input = new DenseVector(2);
var solver = new MlkBiCgStab(); var solver = new MlkBiCgStab();
solver.Solve(matrix, input); solver.Solve(matrix, input);
@ -29,7 +31,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
public void SolveLongMatrix() public void SolveLongMatrix()
{ {
var matrix = new SparseMatrix(3, 2); var matrix = new SparseMatrix(3, 2);
Vector input = new DenseVector(3); Vector<double> input = new DenseVector(3);
var solver = new MlkBiCgStab(); var solver = new MlkBiCgStab();
solver.Solve(matrix, input); solver.Solve(matrix, input);
@ -40,13 +42,13 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
public void SolveUnitMatrixAndBackMultiply() public void SolveUnitMatrixAndBackMultiply()
{ {
// Create the identity matrix // Create the identity matrix
Matrix matrix = SparseMatrix.Identity(100); Matrix<double> matrix = SparseMatrix.Identity(100);
// Create the y vector // Create the y vector
Vector y = new DenseVector(matrix.RowCount, 1); Vector<double> 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[] var monitor = new Iterator(new IIterationStopCriterium<double>[]
{ {
new IterationCountStopCriterium(MaximumIterations), new IterationCountStopCriterium(MaximumIterations),
new ResidualStopCriterium(ConvergenceBoundary), new ResidualStopCriterium(ConvergenceBoundary),
@ -81,16 +83,16 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
public void SolveScaledUnitMatrixAndBackMultiply() public void SolveScaledUnitMatrixAndBackMultiply()
{ {
// Create the identity matrix // Create the identity matrix
Matrix matrix = SparseMatrix.Identity(100); Matrix<double> matrix = SparseMatrix.Identity(100);
// Scale it with a funny number // Scale it with a funny number
matrix.Multiply(System.Math.PI); matrix.Multiply(System.Math.PI);
// Create the y vector // Create the y vector
Vector y = new DenseVector(matrix.RowCount, 1); Vector<double> 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[] var monitor = new Iterator(new IIterationStopCriterium<double>[]
{ {
new IterationCountStopCriterium(MaximumIterations), new IterationCountStopCriterium(MaximumIterations),
new ResidualStopCriterium(ConvergenceBoundary), new ResidualStopCriterium(ConvergenceBoundary),
@ -162,10 +164,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
} }
// Create the y vector // Create the y vector
Vector y = new DenseVector(matrix.RowCount, 1); Vector<double> 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[] var monitor = new Iterator(new IIterationStopCriterium<double>[]
{ {
new IterationCountStopCriterium(MaximumIterations), new IterationCountStopCriterium(MaximumIterations),
new ResidualStopCriterium(ConvergenceBoundary), new ResidualStopCriterium(ConvergenceBoundary),
@ -204,7 +206,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order);
var vectorb = MatrixLoader.GenerateRandomDenseVector(order); var vectorb = MatrixLoader.GenerateRandomDenseVector(order);
var monitor = new Iterator(new IIterationStopCriterium[] var monitor = new Iterator(new IIterationStopCriterium<double>[]
{ {
new IterationCountStopCriterium(1000), new IterationCountStopCriterium(1000),
new ResidualStopCriterium(1e-10), new ResidualStopCriterium(1e-10),
@ -233,7 +235,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order);
var matrixB = MatrixLoader.GenerateRandomDenseMatrix(order, order); var matrixB = MatrixLoader.GenerateRandomDenseMatrix(order, order);
var monitor = new Iterator(new IIterationStopCriterium[] var monitor = new Iterator(new IIterationStopCriterium<double>[]
{ {
new IterationCountStopCriterium(1000), new IterationCountStopCriterium(1000),
new ResidualStopCriterium(1e-10) new ResidualStopCriterium(1e-10)

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

@ -3,8 +3,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
using LinearAlgebra.Double; using LinearAlgebra.Double;
using LinearAlgebra.Double.Solvers; using LinearAlgebra.Double.Solvers;
using LinearAlgebra.Double.Solvers.Iterative; using LinearAlgebra.Double.Solvers.Iterative;
using LinearAlgebra.Double.Solvers.Status;
using LinearAlgebra.Double.Solvers.StopCriterium; using LinearAlgebra.Double.Solvers.StopCriterium;
using LinearAlgebra.Generic;
using LinearAlgebra.Generic.Solvers.Status;
using LinearAlgebra.Generic.Solvers.StopCriterium;
using MbUnit.Framework; using MbUnit.Framework;
[TestFixture] [TestFixture]
@ -18,7 +20,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
public void SolveWideMatrix() public void SolveWideMatrix()
{ {
var matrix = new SparseMatrix(2, 3); var matrix = new SparseMatrix(2, 3);
Vector input = new DenseVector(2); Vector<double> input = new DenseVector(2);
var solver = new TFQMR(); var solver = new TFQMR();
solver.Solve(matrix, input); solver.Solve(matrix, input);
@ -29,7 +31,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
public void SolveLongMatrix() public void SolveLongMatrix()
{ {
var matrix = new SparseMatrix(3, 2); var matrix = new SparseMatrix(3, 2);
Vector input = new DenseVector(3); Vector<double> input = new DenseVector(3);
var solver = new TFQMR(); var solver = new TFQMR();
solver.Solve(matrix, input); solver.Solve(matrix, input);
@ -40,13 +42,13 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
public void SolveUnitMatrixAndBackMultiply() public void SolveUnitMatrixAndBackMultiply()
{ {
// Create the identity matrix // Create the identity matrix
Matrix matrix = SparseMatrix.Identity(100); Matrix<double> matrix = SparseMatrix.Identity(100);
// Create the y vector // Create the y vector
Vector y = new DenseVector(matrix.RowCount, 1); Vector<double> 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[] var monitor = new Iterator(new IIterationStopCriterium<double>[]
{ {
new IterationCountStopCriterium(MaximumIterations), new IterationCountStopCriterium(MaximumIterations),
new ResidualStopCriterium(ConvergenceBoundary), new ResidualStopCriterium(ConvergenceBoundary),
@ -81,16 +83,16 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
public void SolveScaledUnitMatrixAndBackMultiply() public void SolveScaledUnitMatrixAndBackMultiply()
{ {
// Create the identity matrix // Create the identity matrix
Matrix matrix = SparseMatrix.Identity(100); Matrix<double> matrix = SparseMatrix.Identity(100);
// Scale it with a funny number // Scale it with a funny number
matrix.Multiply(System.Math.PI); matrix.Multiply(System.Math.PI);
// Create the y vector // Create the y vector
Vector y = new DenseVector(matrix.RowCount, 1); Vector<double> 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[] var monitor = new Iterator(new IIterationStopCriterium<double>[]
{ {
new IterationCountStopCriterium(MaximumIterations), new IterationCountStopCriterium(MaximumIterations),
new ResidualStopCriterium(ConvergenceBoundary), new ResidualStopCriterium(ConvergenceBoundary),
@ -162,10 +164,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
} }
// Create the y vector // Create the y vector
Vector y = new DenseVector(matrix.RowCount, 1); Vector<double> 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[] var monitor = new Iterator(new IIterationStopCriterium<double>[]
{ {
new IterationCountStopCriterium(MaximumIterations), new IterationCountStopCriterium(MaximumIterations),
new ResidualStopCriterium(ConvergenceBoundary), new ResidualStopCriterium(ConvergenceBoundary),
@ -204,7 +206,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order);
var vectorb = MatrixLoader.GenerateRandomDenseVector(order); var vectorb = MatrixLoader.GenerateRandomDenseVector(order);
var monitor = new Iterator(new IIterationStopCriterium[] var monitor = new Iterator(new IIterationStopCriterium<double>[]
{ {
new IterationCountStopCriterium(1000), new IterationCountStopCriterium(1000),
new ResidualStopCriterium(1e-10), new ResidualStopCriterium(1e-10),
@ -233,7 +235,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order);
var matrixB = MatrixLoader.GenerateRandomDenseMatrix(order, order); var matrixB = MatrixLoader.GenerateRandomDenseMatrix(order, order);
var monitor = new Iterator(new IIterationStopCriterium[] var monitor = new Iterator(new IIterationStopCriterium<double>[]
{ {
new IterationCountStopCriterium(1000), new IterationCountStopCriterium(1000),
new ResidualStopCriterium(1e-10) new ResidualStopCriterium(1e-10)

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

@ -4,8 +4,9 @@
using System.Collections.Generic; using System.Collections.Generic;
using LinearAlgebra.Double; using LinearAlgebra.Double;
using LinearAlgebra.Double.Solvers; using LinearAlgebra.Double.Solvers;
using LinearAlgebra.Double.Solvers.Status;
using LinearAlgebra.Double.Solvers.StopCriterium; using LinearAlgebra.Double.Solvers.StopCriterium;
using LinearAlgebra.Generic.Solvers.Status;
using LinearAlgebra.Generic.Solvers.StopCriterium;
using MbUnit.Framework; using MbUnit.Framework;
[TestFixture] [TestFixture]
@ -24,7 +25,7 @@
[MultipleAsserts] [MultipleAsserts]
public void CreateWithEmptyCollection() public void CreateWithEmptyCollection()
{ {
var iterator = new Iterator(new IIterationStopCriterium[] { }); var iterator = new Iterator(new IIterationStopCriterium<double>[] { });
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");
} }
@ -33,7 +34,7 @@
[MultipleAsserts] [MultipleAsserts]
public void CreateWithCollectionWithNulls() public void CreateWithCollectionWithNulls()
{ {
var iterator = new Iterator(new IIterationStopCriterium[] { null, null }); var iterator = new Iterator(new IIterationStopCriterium<double>[] { 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");
} }
@ -42,7 +43,7 @@
[ExpectedArgumentException] [ExpectedArgumentException]
public void CreateWithDuplicates() public void CreateWithDuplicates()
{ {
new Iterator(new IIterationStopCriterium[] new Iterator(new IIterationStopCriterium<double>[]
{ {
new FailureStopCriterium(), new FailureStopCriterium(),
new FailureStopCriterium() new FailureStopCriterium()
@ -53,7 +54,7 @@
[MultipleAsserts] [MultipleAsserts]
public void CreateWithCollection() public void CreateWithCollection()
{ {
var criteria = new List<IIterationStopCriterium> var criteria = new List<IIterationStopCriterium<double>>
{ {
new FailureStopCriterium(), new FailureStopCriterium(),
new DivergenceStopCriterium(), new DivergenceStopCriterium(),
@ -96,7 +97,7 @@
[MultipleAsserts] [MultipleAsserts]
public void Add() public void Add()
{ {
var criteria = new List<IIterationStopCriterium> var criteria = new List<IIterationStopCriterium<double>>
{ {
new FailureStopCriterium(), new FailureStopCriterium(),
new DivergenceStopCriterium(), new DivergenceStopCriterium(),
@ -126,7 +127,7 @@
[ExpectedArgumentNullException] [ExpectedArgumentNullException]
public void RemoveWithNullStopCriterium() public void RemoveWithNullStopCriterium()
{ {
var criteria = new List<IIterationStopCriterium> var criteria = new List<IIterationStopCriterium<double>>
{ {
new FailureStopCriterium(), new FailureStopCriterium(),
new DivergenceStopCriterium(), new DivergenceStopCriterium(),
@ -143,7 +144,7 @@
[MultipleAsserts] [MultipleAsserts]
public void RemoveWithNonExistingStopCriterium() public void RemoveWithNonExistingStopCriterium()
{ {
var criteria = new List<IIterationStopCriterium> var criteria = new List<IIterationStopCriterium<double>>
{ {
new FailureStopCriterium(), new FailureStopCriterium(),
new DivergenceStopCriterium(), new DivergenceStopCriterium(),
@ -160,7 +161,7 @@
[MultipleAsserts] [MultipleAsserts]
public void Remove() public void Remove()
{ {
var criteria = new List<IIterationStopCriterium> var criteria = new List<IIterationStopCriterium<double>>
{ {
new FailureStopCriterium(), new FailureStopCriterium(),
new DivergenceStopCriterium(), new DivergenceStopCriterium(),
@ -192,7 +193,7 @@
[ExpectedException(typeof(ArgumentOutOfRangeException))] [ExpectedException(typeof(ArgumentOutOfRangeException))]
public void DetermineStatusWithNegativeIterationNumber() public void DetermineStatusWithNegativeIterationNumber()
{ {
var criteria = new List<IIterationStopCriterium> var criteria = new List<IIterationStopCriterium<double>>
{ {
new FailureStopCriterium(), new FailureStopCriterium(),
new DivergenceStopCriterium(), new DivergenceStopCriterium(),
@ -211,7 +212,7 @@
[ExpectedArgumentNullException] [ExpectedArgumentNullException]
public void DetermineStatusWithNullSolutionVector() public void DetermineStatusWithNullSolutionVector()
{ {
var criteria = new List<IIterationStopCriterium> var criteria = new List<IIterationStopCriterium<double>>
{ {
new FailureStopCriterium(), new FailureStopCriterium(),
new DivergenceStopCriterium(), new DivergenceStopCriterium(),
@ -230,7 +231,7 @@
[ExpectedArgumentNullException] [ExpectedArgumentNullException]
public void DetermineStatusWithNullSourceVector() public void DetermineStatusWithNullSourceVector()
{ {
var criteria = new List<IIterationStopCriterium> var criteria = new List<IIterationStopCriterium<double>>
{ {
new FailureStopCriterium(), new FailureStopCriterium(),
new DivergenceStopCriterium(), new DivergenceStopCriterium(),
@ -249,7 +250,7 @@
[ExpectedArgumentNullException] [ExpectedArgumentNullException]
public void DetermineStatusWithNullResidualVector() public void DetermineStatusWithNullResidualVector()
{ {
var criteria = new List<IIterationStopCriterium> var criteria = new List<IIterationStopCriterium<double>>
{ {
new FailureStopCriterium(), new FailureStopCriterium(),
new DivergenceStopCriterium(), new DivergenceStopCriterium(),
@ -268,7 +269,7 @@
[MultipleAsserts] [MultipleAsserts]
public void DetermineStatus() public void DetermineStatus()
{ {
var criteria = new List<IIterationStopCriterium> var criteria = new List<IIterationStopCriterium<double>>
{ {
new FailureStopCriterium(), new FailureStopCriterium(),
new DivergenceStopCriterium(), new DivergenceStopCriterium(),
@ -296,7 +297,7 @@
[MultipleAsserts] [MultipleAsserts]
public void ResetToPrecalculationState() public void ResetToPrecalculationState()
{ {
var criteria = new List<IIterationStopCriterium> var criteria = new List<IIterationStopCriterium<double>>
{ {
new FailureStopCriterium(), new FailureStopCriterium(),
new DivergenceStopCriterium(), new DivergenceStopCriterium(),
@ -323,7 +324,7 @@
[MultipleAsserts] [MultipleAsserts]
public void Clone() public void Clone()
{ {
var criteria = new List<IIterationStopCriterium> var criteria = new List<IIterationStopCriterium<double>>
{ {
new FailureStopCriterium(), new FailureStopCriterium(),
new DivergenceStopCriterium(), new DivergenceStopCriterium(),

8
src/UnitTests/LinearAlgebraTests/Double/Solvers/Preconditioners/DiagonalTest.cs

@ -2,23 +2,25 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Precondit
{ {
using LinearAlgebra.Double; using LinearAlgebra.Double;
using LinearAlgebra.Double.Solvers.Preconditioners; using LinearAlgebra.Double.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 CreatePreconditioner() internal override IPreConditioner<double> CreatePreconditioner()
{ {
return new Diagonal(); return new Diagonal();
} }
protected override void CheckResult(IPreConditioner preconditioner, SparseMatrix matrix, Vector vector, Vector result) protected override void CheckResult(IPreConditioner<double> preconditioner, SparseMatrix matrix, Vector<double> vector, Vector<double> 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 product = new DenseVector(result.Count); Vector<double> 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++)

14
src/UnitTests/LinearAlgebraTests/Double/Solvers/Preconditioners/IlutpTest.cs

@ -4,6 +4,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Precondit
using System.Reflection; using System.Reflection;
using LinearAlgebra.Double; using LinearAlgebra.Double;
using LinearAlgebra.Double.Solvers.Preconditioners; using LinearAlgebra.Double.Solvers.Preconditioners;
using LinearAlgebra.Generic;
using LinearAlgebra.Generic.Solvers.Preconditioners;
using MbUnit.Framework; using MbUnit.Framework;
[TestFixture] [TestFixture]
@ -71,7 +73,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Precondit
return result; return result;
} }
internal override IPreConditioner CreatePreconditioner() internal override IPreConditioner<double> CreatePreconditioner()
{ {
_pivotTolerance = 0; _pivotTolerance = 0;
_dropTolerance = 0.0; _dropTolerance = 0.0;
@ -79,13 +81,13 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Precondit
return InternalCreatePreconditioner(); return InternalCreatePreconditioner();
} }
protected override void CheckResult(IPreConditioner preconditioner, SparseMatrix matrix, Vector vector, Vector result) protected override void CheckResult(IPreConditioner<double> preconditioner, SparseMatrix matrix, Vector<double> vector, Vector<double> 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 product = new DenseVector(result.Count); Vector<double> 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++)
{ {
@ -108,7 +110,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Precondit
_fillLevel = 100; _fillLevel = 100;
var preconditioner = CreatePreconditioner(); var preconditioner = CreatePreconditioner();
preconditioner.Initialize(newMatrix); preconditioner.Initialize(newMatrix);
Vector result = new DenseVector(vector.Count); Vector<double> result = new DenseVector(vector.Count);
preconditioner.Approximate(vector, result); preconditioner.Approximate(vector, result);
CheckResult(preconditioner, newMatrix, vector, result); CheckResult(preconditioner, newMatrix, vector, result);
} }
@ -127,7 +129,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Precondit
_fillLevel = 100; _fillLevel = 100;
var preconditioner = CreatePreconditioner(); var preconditioner = CreatePreconditioner();
preconditioner.Initialize(newMatrix); preconditioner.Initialize(newMatrix);
Vector result = new DenseVector(vector.Count); Vector<double> result = new DenseVector(vector.Count);
preconditioner.Approximate(vector, result); preconditioner.Approximate(vector, result);
CheckResult(preconditioner, newMatrix, vector, result); CheckResult(preconditioner, newMatrix, vector, result);
} }
@ -240,7 +242,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Precondit
FillLevel = 10 FillLevel = 10
}; };
preconditioner.Initialize(newMatrix); preconditioner.Initialize(newMatrix);
Vector result = new DenseVector(vector.Count); Vector<double> result = new DenseVector(vector.Count);
preconditioner.Approximate(vector, result); preconditioner.Approximate(vector, result);
CheckResult(preconditioner, newMatrix, vector, result); CheckResult(preconditioner, newMatrix, vector, result);
} }

18
src/UnitTests/LinearAlgebraTests/Double/Solvers/Preconditioners/IncompleteLUTest.cs

@ -4,6 +4,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Precondit
using System.Reflection; using System.Reflection;
using LinearAlgebra.Double; using LinearAlgebra.Double;
using LinearAlgebra.Double.Solvers.Preconditioners; using LinearAlgebra.Double.Solvers.Preconditioners;
using LinearAlgebra.Generic;
using LinearAlgebra.Generic.Solvers.Preconditioners;
using MbUnit.Framework; using MbUnit.Framework;
[TestFixture] [TestFixture]
@ -22,28 +24,28 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Precondit
return (T)obj; return (T)obj;
} }
private static Matrix GetUpperTriangle(IncompleteLU ilu) private static Matrix<double> GetUpperTriangle(IncompleteLU ilu)
{ {
return GetMethod<Matrix>(ilu, "UpperTriangle"); return GetMethod<Matrix<double>>(ilu, "UpperTriangle");
} }
private static Matrix GetLowerTriangle(IncompleteLU ilu) private static Matrix<double> GetLowerTriangle(IncompleteLU ilu)
{ {
return GetMethod<Matrix>(ilu, "LowerTriangle"); return GetMethod<Matrix<double>>(ilu, "LowerTriangle");
} }
internal override IPreConditioner CreatePreconditioner() internal override IPreConditioner<double> CreatePreconditioner()
{ {
return new IncompleteLU(); return new IncompleteLU();
} }
protected override void CheckResult(IPreConditioner preconditioner, SparseMatrix matrix, Vector vector, Vector result) protected override void CheckResult(IPreConditioner<double> preconditioner, SparseMatrix matrix, Vector<double> vector, Vector<double> 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 product = new DenseVector(result.Count); Vector<double> 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++)

19
src/UnitTests/LinearAlgebraTests/Double/Solvers/Preconditioners/PreConditionerTest.cs

@ -1,7 +1,8 @@
namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Preconditioners namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Preconditioners
{ {
using LinearAlgebra.Double; using LinearAlgebra.Double;
using LinearAlgebra.Double.Solvers.Preconditioners; using LinearAlgebra.Generic;
using LinearAlgebra.Generic.Solvers.Preconditioners;
using MbUnit.Framework; using MbUnit.Framework;
public abstract class PreconditionerTest public abstract class PreconditionerTest
@ -19,9 +20,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Precondit
return matrix; return matrix;
} }
protected Vector CreateStandardBcVector(int size) protected Vector<double> CreateStandardBcVector(int size)
{ {
Vector vector = new DenseVector(size); Vector<double> 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;
@ -30,9 +31,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Precondit
return vector; return vector;
} }
internal abstract IPreConditioner CreatePreconditioner(); internal abstract IPreConditioner<double> CreatePreconditioner();
protected abstract void CheckResult(IPreConditioner preconditioner, SparseMatrix matrix, Vector vector, Vector result); protected abstract void CheckResult(IPreConditioner<double> preconditioner, SparseMatrix matrix, Vector<double> vector, Vector<double> result);
[Test] [Test]
[MultipleAsserts] [MultipleAsserts]
@ -62,7 +63,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Precondit
var preconditioner = CreatePreconditioner(); var preconditioner = CreatePreconditioner();
preconditioner.Initialize(newMatrix); preconditioner.Initialize(newMatrix);
Vector result = new DenseVector(vector.Count); Vector<double> result = new DenseVector(vector.Count);
preconditioner.Approximate(vector, result); preconditioner.Approximate(vector, result);
CheckResult(preconditioner, newMatrix, vector, result); CheckResult(preconditioner, newMatrix, vector, result);
@ -79,7 +80,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Precondit
var preconditioner = CreatePreconditioner(); var preconditioner = CreatePreconditioner();
preconditioner.Initialize(newMatrix); preconditioner.Initialize(newMatrix);
Vector result = new DenseVector(vector.Count + 10); Vector<double> result = new DenseVector(vector.Count + 10);
preconditioner.Approximate(vector, result); preconditioner.Approximate(vector, result);
} }
@ -94,7 +95,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Precondit
var preconditioner = CreatePreconditioner(); var preconditioner = CreatePreconditioner();
preconditioner.Initialize(newMatrix); preconditioner.Initialize(newMatrix);
Vector result = new DenseVector(vector.Count + 10); Vector<double> result = new DenseVector(vector.Count + 10);
preconditioner.Approximate(null, result); preconditioner.Approximate(null, result);
} }
@ -109,7 +110,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Precondit
var preconditioner = CreatePreconditioner(); var preconditioner = CreatePreconditioner();
preconditioner.Initialize(newMatrix); preconditioner.Initialize(newMatrix);
Vector result = null; Vector<double> result = null;
preconditioner.Approximate(vector, result); preconditioner.Approximate(vector, result);
} }

6
src/UnitTests/LinearAlgebraTests/Double/Solvers/Preconditioners/UnitPreconditionerTest.cs

@ -2,17 +2,19 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Precondit
{ {
using LinearAlgebra.Double; using LinearAlgebra.Double;
using LinearAlgebra.Double.Solvers.Preconditioners; using LinearAlgebra.Double.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 CreatePreconditioner() internal override IPreConditioner<double> CreatePreconditioner()
{ {
return new UnitPreconditioner(); return new UnitPreconditioner();
} }
protected override void CheckResult(IPreConditioner preconditioner, SparseMatrix matrix, Vector vector, Vector result) protected override void CheckResult(IPreConditioner<double> preconditioner, SparseMatrix matrix, Vector<double> vector, Vector<double> result)
{ {
Assert.AreEqual(typeof(UnitPreconditioner), preconditioner.GetType(), "#01"); Assert.AreEqual(typeof(UnitPreconditioner), preconditioner.GetType(), "#01");

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

@ -1,8 +1,8 @@
namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.StopCriterium namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.StopCriterium
{ {
using LinearAlgebra.Double; using LinearAlgebra.Double;
using LinearAlgebra.Double.Solvers.Status;
using LinearAlgebra.Double.Solvers.StopCriterium; using LinearAlgebra.Double.Solvers.StopCriterium;
using LinearAlgebra.Generic.Solvers.Status;
using MbUnit.Framework; using MbUnit.Framework;
[TestFixture] [TestFixture]

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

@ -1,8 +1,8 @@
namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.StopCriterium namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.StopCriterium
{ {
using LinearAlgebra.Double; using LinearAlgebra.Double;
using LinearAlgebra.Double.Solvers.Status;
using LinearAlgebra.Double.Solvers.StopCriterium; using LinearAlgebra.Double.Solvers.StopCriterium;
using LinearAlgebra.Generic.Solvers.Status;
using MbUnit.Framework; using MbUnit.Framework;
[TestFixture] [TestFixture]

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

@ -1,8 +1,8 @@
namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.StopCriterium namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.StopCriterium
{ {
using LinearAlgebra.Double; using LinearAlgebra.Double;
using LinearAlgebra.Double.Solvers.Status;
using LinearAlgebra.Double.Solvers.StopCriterium; using LinearAlgebra.Double.Solvers.StopCriterium;
using LinearAlgebra.Generic.Solvers.Status;
using MbUnit.Framework; using MbUnit.Framework;
[TestFixture] [TestFixture]

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

@ -1,8 +1,8 @@
namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.StopCriterium namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.StopCriterium
{ {
using LinearAlgebra.Double; using LinearAlgebra.Double;
using LinearAlgebra.Double.Solvers.Status;
using LinearAlgebra.Double.Solvers.StopCriterium; using LinearAlgebra.Double.Solvers.StopCriterium;
using LinearAlgebra.Generic.Solvers.Status;
using MbUnit.Framework; using MbUnit.Framework;
[TestFixture] [TestFixture]

11
src/UnitTests/LinearAlgebraTests/Double/SparseMatrixTests.cs

@ -31,27 +31,28 @@
namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
{ {
using System.Collections.Generic; using System.Collections.Generic;
using LinearAlgebra.Generic;
using MbUnit.Framework; using MbUnit.Framework;
using LinearAlgebra.Double; using LinearAlgebra.Double;
public class SparseMatrixTests : MatrixTests public class SparseMatrixTests : MatrixTests
{ {
protected override Matrix CreateMatrix(int rows, int columns) protected override Matrix<double> CreateMatrix(int rows, int columns)
{ {
return new SparseMatrix(rows, columns); return new SparseMatrix(rows, columns);
} }
protected override Matrix CreateMatrix(double[,] data) protected override Matrix<double> CreateMatrix(double[,] data)
{ {
return new SparseMatrix(data); return new SparseMatrix(data);
} }
protected override Vector CreateVector(int size) protected override Vector<double> CreateVector(int size)
{ {
return new SparseVector(size); return new SparseVector(size);
} }
protected override Vector CreateVector(double[] data) protected override Vector<double> CreateVector(double[] data)
{ {
return new SparseVector(data); return new SparseVector(data);
} }
@ -59,7 +60,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Test] [Test]
public void CanCreateMatrixFrom1DArray() public void CanCreateMatrixFrom1DArray()
{ {
var testData = new Dictionary<string, Matrix> var testData = new Dictionary<string, Matrix<double>>
{ {
{ "Singular3x3", new SparseMatrix(3, 3, new double[] { 1, 1, 1, 1, 1, 1, 2, 2, 2 }) }, { "Singular3x3", new SparseMatrix(3, 3, new double[] { 1, 1, 1, 1, 1, 1, 2, 2, 2 }) },
{ "Square3x3", new SparseMatrix(3, 3, new[] { -1.1, 0.0, -4.4, -2.2, 1.1, 5.5, -3.3, 2.2, 6.6 }) }, { "Square3x3", new SparseMatrix(3, 3, new[] { -1.1, 0.0, -4.4, -2.2, 1.1, 5.5, -3.3, 2.2, 6.6 }) },

15
src/UnitTests/LinearAlgebraTests/Double/SparseVectorTest.cs

@ -32,17 +32,18 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
{ {
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using LinearAlgebra.Generic;
using MbUnit.Framework; using MbUnit.Framework;
using LinearAlgebra.Double; using LinearAlgebra.Double;
public class SparseVectorTest : VectorTests public class SparseVectorTest : VectorTests
{ {
protected override Vector CreateVector(int size) protected override Vector<double> CreateVector(int size)
{ {
return new SparseVector(size); return new SparseVector(size);
} }
protected override Vector CreateVector(IList<double> data) protected override Vector<double> CreateVector(IList<double> data)
{ {
var vector = new SparseVector(data.Count); var vector = new SparseVector(data.Count);
for (var index = 0; index < data.Count; index++) for (var index = 0; index < data.Count; index++)
@ -85,7 +86,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[MultipleAsserts] [MultipleAsserts]
public void CanCreateSparseVectorFromAnotherVector() public void CanCreateSparseVectorFromAnotherVector()
{ {
var vector = (Vector)new SparseVector(Data); var vector = (Vector<double>)new SparseVector(Data);
var other = new SparseVector(vector); var other = new SparseVector(vector);
Assert.AreNotSame(vector, other); Assert.AreNotSame(vector, other);
@ -257,7 +258,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
{ {
var vector1 = CreateVector(Data); var vector1 = CreateVector(Data);
var vector2 = CreateVector(Data); var vector2 = CreateVector(Data);
Matrix m = Vector.OuterProduct(vector1, vector2); Matrix<double> m = Vector<double>.OuterProduct(vector1, vector2);
for (var i = 0; i < vector1.Count; i++) for (var i = 0; i < vector1.Count; i++)
{ {
for (var j = 0; j < vector2.Count; j++) for (var j = 0; j < vector2.Count; j++)
@ -273,7 +274,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
{ {
SparseVector vector1 = null; SparseVector vector1 = null;
var vector2 = CreateVector(Data); var vector2 = CreateVector(Data);
Vector.OuterProduct(vector1, vector2); Vector<double>.OuterProduct(vector1, vector2);
} }
[Test] [Test]
@ -282,7 +283,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
{ {
var vector1 = CreateVector(Data); var vector1 = CreateVector(Data);
SparseVector vector2 = null; SparseVector vector2 = null;
Vector.OuterProduct(vector1, vector2); Vector<double>.OuterProduct(vector1, vector2);
} }
#endregion #endregion
@ -290,7 +291,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[MultipleAsserts] [MultipleAsserts]
public void CanCreateSparseVectorFromDenseVector() public void CanCreateSparseVectorFromDenseVector()
{ {
var vector = (Vector)new DenseVector(Data); var vector = (Vector<double>)new DenseVector(Data);
var other = new SparseVector(vector); var other = new SparseVector(vector);
Assert.AreNotSame(vector, other); Assert.AreNotSame(vector, other);

110
src/UnitTests/LinearAlgebraTests/Double/UserDefinedMatrixTests.cs

@ -30,9 +30,14 @@
namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
{ {
using LinearAlgebra.Double; using System;
using System.Text;
using Distributions;
using LinearAlgebra.Generic;
using Properties;
using Threading;
internal class UserDefinedMatrix : Matrix internal class UserDefinedMatrix : Matrix<double>
{ {
private readonly double[,] _data; private readonly double[,] _data;
@ -61,12 +66,12 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
_data[row, column] = value; _data[row, column] = value;
} }
public override Matrix CreateMatrix(int numberOfRows, int numberOfColumns) public override Matrix<double> CreateMatrix(int numberOfRows, int numberOfColumns)
{ {
return new UserDefinedMatrix(numberOfRows, numberOfColumns); return new UserDefinedMatrix(numberOfRows, numberOfColumns);
} }
public override Vector CreateVector(int size) public override Vector<double> CreateVector(int size)
{ {
return new UserDefinedVector(size); return new UserDefinedVector(size);
} }
@ -81,26 +86,115 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
return m; return m;
} }
public override void Negate()
{
Multiply(-1);
}
public override Matrix<double> Random(int numberOfRows, int numberOfColumns, IContinuousDistribution distribution)
{
if (numberOfRows < 1)
{
throw new ArgumentException(Resources.ArgumentMustBePositive, "numberOfRows");
}
if (numberOfColumns < 1)
{
throw new ArgumentException(Resources.ArgumentMustBePositive, "numberOfColumns");
}
var matrix = CreateMatrix(numberOfRows, numberOfColumns);
CommonParallel.For(
0,
ColumnCount,
j =>
{
for (var i = 0; i < matrix.RowCount; i++)
{
matrix[i, j] = distribution.Sample();
}
});
return matrix;
}
public override Matrix<double> Random(int numberOfRows, int numberOfColumns, IDiscreteDistribution distribution)
{
if (numberOfRows < 1)
{
throw new ArgumentException(Resources.ArgumentMustBePositive, "numberOfRows");
}
if (numberOfColumns < 1)
{
throw new ArgumentException(Resources.ArgumentMustBePositive, "numberOfColumns");
}
var matrix = CreateMatrix(numberOfRows, numberOfColumns);
CommonParallel.For(
0,
ColumnCount,
j =>
{
for (var i = 0; i < matrix.RowCount; i++)
{
matrix[i, j] = distribution.Sample();
}
});
return matrix;
}
protected sealed override double AddT(double val1, double val2)
{
return val1 + val2;
}
protected sealed override double SubtractT(double val1, double val2)
{
return val1 - val2;
}
protected sealed override double MultiplyT(double val1, double val2)
{
return val1 * val2;
}
protected sealed override double DivideT(double val1, double val2)
{
return val1 / val2;
}
protected sealed override bool IsOneT(double val1)
{
return 1.0.AlmostEqualInDecimalPlaces(val1, 15);
}
protected sealed override double AbsoluteT(double val1)
{
return Math.Abs(val1);
}
} }
public class UserDefinedMatrixTests : MatrixTests public class UserDefinedMatrixTests : MatrixTests
{ {
protected override Matrix CreateMatrix(int rows, int columns) protected override Matrix<double> CreateMatrix(int rows, int columns)
{ {
return new UserDefinedMatrix(rows, columns); return new UserDefinedMatrix(rows, columns);
} }
protected override Matrix CreateMatrix(double[,] data) protected override Matrix<double> CreateMatrix(double[,] data)
{ {
return new UserDefinedMatrix(data); return new UserDefinedMatrix(data);
} }
protected override Vector CreateVector(int size) protected override Vector<double> CreateVector(int size)
{ {
return new UserDefinedVector(size); return new UserDefinedVector(size);
} }
protected override Vector CreateVector(double[] data) protected override Vector<double> CreateVector(double[] data)
{ {
return new UserDefinedVector(data); return new UserDefinedVector(data);
} }

141
src/UnitTests/LinearAlgebraTests/Double/UserDefinedVectorTests.cs

@ -30,10 +30,15 @@
namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
{ {
using System;
using System.Collections.Generic; using System.Collections.Generic;
using LinearAlgebra.Double; using System.Text;
using Distributions;
using LinearAlgebra.Generic;
using Properties;
using Threading;
internal class UserDefinedVector : Vector internal class UserDefinedVector : Vector<double>
{ {
private readonly double[] _data; private readonly double[] _data;
@ -62,25 +67,149 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
} }
} }
public override Matrix CreateMatrix(int rows, int columns) public override Matrix<double> CreateMatrix(int rows, int columns)
{ {
return new UserDefinedMatrix(rows, columns); return new UserDefinedMatrix(rows, columns);
} }
public override Vector CreateVector(int size) public override Vector<double> CreateVector(int size)
{ {
return new UserDefinedVector(size); return new UserDefinedVector(size);
} }
public override Vector<double> Negate()
{
var result = new UserDefinedVector(Count);
CommonParallel.For(
0,
_data.Length,
index => result[index] = -_data[index]);
return result;
}
public override Vector<double> Random(int length, IContinuousDistribution randomDistribution)
{
if (length < 1)
{
throw new ArgumentException(Resources.ArgumentMustBePositive, "length");
}
var v = (UserDefinedVector)CreateVector(length);
for (var index = 0; index < v._data.Length; index++)
{
v._data[index] = randomDistribution.Sample();
}
return v;
}
public override Vector<double> Random(int length, IDiscreteDistribution randomDistribution)
{
if (length < 1)
{
throw new ArgumentException(Resources.ArgumentMustBePositive, "length");
}
var v = (UserDefinedVector)CreateVector(length);
for (var index = 0; index < v._data.Length; index++)
{
v._data[index] = randomDistribution.Sample();
}
return v;
}
public override int MinimumIndex()
{
var index = 0;
var min = _data[0];
for (var i = 1; i < Count; i++)
{
if (min > _data[i])
{
index = i;
min = _data[i];
}
}
return index;
}
public override int MaximumIndex()
{
var index = 0;
var max = _data[0];
for (var i = 1; i < Count; i++)
{
if (max < _data[i])
{
index = i;
max = _data[i];
}
}
return index;
}
public override Vector<double> Normalize(double p)
{
if (p < 0.0)
{
throw new ArgumentOutOfRangeException("p");
}
var norm = Norm(p);
var clone = Clone();
if (norm == 0.0)
{
return clone;
}
clone.Multiply(1.0 / norm, clone);
return clone;
}
protected sealed override double AddT(double val1, double val2)
{
return val1 + val2;
}
protected sealed override double SubtractT(double val1, double val2)
{
return val1 - val2;
}
protected sealed override double MultiplyT(double val1, double val2)
{
return val1 * val2;
}
protected sealed override double DivideT(double val1, double val2)
{
return val1 / val2;
}
protected sealed override bool IsOneT(double val1)
{
return val1 == 1.0;
}
protected sealed override double AbsoluteT(double val1)
{
return Math.Abs(val1);
}
} }
public class UserDefinedVectorTests : VectorTests public class UserDefinedVectorTests : VectorTests
{ {
protected override Vector CreateVector(int size) protected override Vector<double> CreateVector(int size)
{ {
return new UserDefinedVector(size); return new UserDefinedVector(size);
} }
protected override Vector CreateVector(IList<double> data) protected override Vector<double> CreateVector(IList<double> data)
{ {
var vector = new UserDefinedVector(data.Count); var vector = new UserDefinedVector(data.Count);
for (var index = 0; index < data.Count; index++) for (var index = 0; index < data.Count; index++)

45
src/UnitTests/LinearAlgebraTests/Double/VectorTests.Arithmetic.cs

@ -28,6 +28,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
{ {
using System; using System;
using LinearAlgebra.Double; using LinearAlgebra.Double;
using LinearAlgebra.Generic;
using MbUnit.Framework; using MbUnit.Framework;
public abstract partial class VectorTests public abstract partial class VectorTests
@ -47,8 +48,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Test] [Test]
public void OperatorPlusThrowsArgumentNullExceptionWhenCallOnNullVector() public void OperatorPlusThrowsArgumentNullExceptionWhenCallOnNullVector()
{ {
Vector vector = null; Vector<double> vector = null;
Vector other = null; Vector<double> other = null;
Assert.Throws<ArgumentNullException>(() => other = +vector); Assert.Throws<ArgumentNullException>(() => other = +vector);
} }
@ -154,7 +155,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Test] [Test]
public void AdditionOperatorThrowsArgumentNullExpectionIfAVectorIsNull() public void AdditionOperatorThrowsArgumentNullExpectionIfAVectorIsNull()
{ {
Vector a = null; Vector<double> a = null;
var b = CreateVector(Data.Length); var b = CreateVector(Data.Length);
Assert.Throws<ArgumentNullException>(() => a += b); Assert.Throws<ArgumentNullException>(() => a += b);
@ -273,8 +274,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Test] [Test]
public void OperatorNegateThrowsArgumentNullExceptionWhenCallOnNullVector() public void OperatorNegateThrowsArgumentNullExceptionWhenCallOnNullVector()
{ {
Vector vector = null; Vector<double> vector = null;
Vector other = null; Vector<double> other = null;
Assert.Throws<ArgumentNullException>(() => other = -vector); Assert.Throws<ArgumentNullException>(() => other = -vector);
} }
@ -379,7 +380,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Test] [Test]
public void SubtractionOperatorThrowsArgumentNullExpectionIfAVectorIsNull() public void SubtractionOperatorThrowsArgumentNullExpectionIfAVectorIsNull()
{ {
Vector a = null; Vector<double> a = null;
var b = CreateVector(Data.Length); var b = CreateVector(Data.Length);
Assert.Throws<ArgumentNullException>(() => a -= b); Assert.Throws<ArgumentNullException>(() => a -= b);
@ -650,8 +651,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[MultipleAsserts] [MultipleAsserts]
public void OperatorMultiplyThrowsArgumentNullExceptionWhenVectorIsNull() public void OperatorMultiplyThrowsArgumentNullExceptionWhenVectorIsNull()
{ {
Vector vector = null; Vector<double> vector = null;
Vector result = null; Vector<double> result = null;
Assert.Throws<ArgumentNullException>(() => result = vector * 2.0); Assert.Throws<ArgumentNullException>(() => result = vector * 2.0);
Assert.Throws<ArgumentNullException>(() => result = 2.0 * vector); Assert.Throws<ArgumentNullException>(() => result = 2.0 * vector);
} }
@ -659,7 +660,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Test] [Test]
public void OperatorDivideThrowsArgumentNullExceptionWhenVectorIsNull() public void OperatorDivideThrowsArgumentNullExceptionWhenVectorIsNull()
{ {
Vector vector = null; Vector<double> vector = null;
Assert.Throws<ArgumentNullException>(() => vector = vector / 2.0); Assert.Throws<ArgumentNullException>(() => vector = vector / 2.0);
} }
@ -677,7 +678,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
public void DotProductThrowsExceptionWhenArgumentIsNull() public void DotProductThrowsExceptionWhenArgumentIsNull()
{ {
var dataA = CreateVector(Data); var dataA = CreateVector(Data);
Vector dataB = null; Vector<double> dataB = null;
dataA.DotProduct(dataB); dataA.DotProduct(dataB);
} }
@ -706,7 +707,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
public void OperatorDotProductThrowsExceptionWhenLeftArgumentIsNull() public void OperatorDotProductThrowsExceptionWhenLeftArgumentIsNull()
{ {
var dataA = CreateVector(Data); var dataA = CreateVector(Data);
Vector dataB = null; Vector<double> dataB = null;
var d = dataA * dataB; var d = dataA * dataB;
} }
@ -715,7 +716,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentNullException] [ExpectedArgumentNullException]
public void OperatorDotProductThrowsExceptionWhenRightArgumentIsNull() public void OperatorDotProductThrowsExceptionWhenRightArgumentIsNull()
{ {
Vector dataA = null; Vector<double> dataA = null;
var dataB = CreateVector(Data); var dataB = CreateVector(Data);
var d = dataA * dataB; var d = dataA * dataB;
@ -761,7 +762,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
public void PointwiseMultiplyWithOtherNullShouldThrowException() public void PointwiseMultiplyWithOtherNullShouldThrowException()
{ {
var vector1 = CreateVector(Data); var vector1 = CreateVector(Data);
Vector vector2 = null; Vector<double> vector2 = null;
var result = CreateVector(vector1.Count); var result = CreateVector(vector1.Count);
vector1.PointwiseMultiply(vector2, result); vector1.PointwiseMultiply(vector2, result);
} }
@ -772,7 +773,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
{ {
var vector1 = CreateVector(Data); var vector1 = CreateVector(Data);
var vector2 = vector1.Clone(); var vector2 = vector1.Clone();
Vector result = null; Vector<double> result = null;
vector1.PointwiseMultiply(vector2, result); vector1.PointwiseMultiply(vector2, result);
} }
@ -816,7 +817,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
public void PointwiseDivideWithOtherNullShouldThrowException() public void PointwiseDivideWithOtherNullShouldThrowException()
{ {
var vector1 = CreateVector(Data); var vector1 = CreateVector(Data);
Vector vector2 = null; Vector<double> vector2 = null;
var result = CreateVector(vector1.Count); var result = CreateVector(vector1.Count);
vector1.PointwiseDivide(vector2, result); vector1.PointwiseDivide(vector2, result);
} }
@ -827,7 +828,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
{ {
var vector1 = CreateVector(Data); var vector1 = CreateVector(Data);
var vector2 = vector1.Clone(); var vector2 = vector1.Clone();
Vector result = null; Vector<double> result = null;
vector1.PointwiseDivide(vector2, result); vector1.PointwiseDivide(vector2, result);
} }
@ -846,7 +847,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
{ {
var vector1 = CreateVector(Data); var vector1 = CreateVector(Data);
var vector2 = CreateVector(Data); var vector2 = CreateVector(Data);
Matrix m = Vector.OuterProduct(vector1, vector2); Matrix<double> m = Vector<double>.OuterProduct(vector1, vector2);
for (var i = 0; i < vector1.Count; i++) for (var i = 0; i < vector1.Count; i++)
{ {
for (var j = 0; j < vector2.Count; j++) for (var j = 0; j < vector2.Count; j++)
@ -860,9 +861,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentNullException] [ExpectedArgumentNullException]
public void OuterProductWithFirstParameterNullShouldThrowException() public void OuterProductWithFirstParameterNullShouldThrowException()
{ {
Vector vector1 = null; Vector<double> vector1 = null;
var vector2 = CreateVector(Data); var vector2 = CreateVector(Data);
Vector.OuterProduct(vector1, vector2); Vector<double>.OuterProduct(vector1, vector2);
} }
[Test] [Test]
@ -870,8 +871,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
public void OutercProductWithSecondParameterNullShouldThrowException() public void OutercProductWithSecondParameterNullShouldThrowException()
{ {
var vector1 = CreateVector(Data); var vector1 = CreateVector(Data);
Vector vector2 = null; Vector<double> vector2 = null;
Vector.OuterProduct(vector1, vector2); Vector<double>.OuterProduct(vector1, vector2);
} }
[Test] [Test]
@ -894,7 +895,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
public void TensorMultiplyWithNullParameterNullShouldThrowException() public void TensorMultiplyWithNullParameterNullShouldThrowException()
{ {
var vector1 = CreateVector(Data); var vector1 = CreateVector(Data);
Vector vector2 = null; Vector<double> vector2 = null;
vector1.TensorMultiply(vector2); vector1.TensorMultiply(vector2);
} }
} }

10
src/UnitTests/LinearAlgebraTests/Double/VectorTests.cs

@ -31,7 +31,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using Distributions; using Distributions;
using LinearAlgebra.Double; using LinearAlgebra.Generic;
using MbUnit.Framework; using MbUnit.Framework;
[TestFixture] [TestFixture]
@ -59,7 +59,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
public void CanCloneVectorUsingICloneable() public void CanCloneVectorUsingICloneable()
{ {
var vector = CreateVector(Data); var vector = CreateVector(Data);
var clone = (Vector)((ICloneable)vector).Clone(); var clone = (Vector<double>)((ICloneable)vector).Clone();
Assert.AreNotSame(vector, clone); Assert.AreNotSame(vector, clone);
Assert.AreEqual(vector.Count, clone.Count); Assert.AreEqual(vector.Count, clone.Count);
@ -196,7 +196,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
public void VectorGetHashCode() public void VectorGetHashCode()
{ {
var vector = CreateVector(new double[] { 1, 2, 3, 4 }); var vector = CreateVector(new double[] { 1, 2, 3, 4 });
Assert.AreEqual(2145910784, vector.GetHashCode()); Assert.AreEqual(2096640, vector.GetHashCode());
} }
[Test] [Test]
@ -433,7 +433,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
} }
} }
protected abstract Vector CreateVector(int size); protected abstract Vector<double> CreateVector(int size);
protected abstract Vector CreateVector(IList<double> data); protected abstract Vector<double> CreateVector(IList<double> data);
} }
} }
Loading…
Cancel
Save