Browse Source

andriy's conversion to a generic matrix

pull/36/head
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>
namespace MathNet.Numerics.LinearAlgebra.Double
open MathNet.Numerics.LinearAlgebra
open MathNet.Numerics.LinearAlgebra.Generic
/// A module which implements functional dense vector operations.
module DenseMatrix =
@ -81,7 +81,7 @@ module DenseMatrix =
A
/// 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 A = new DenseMatrix(n,n)
for i=0 to n-1 do
@ -89,13 +89,13 @@ module DenseMatrix =
A
/// 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)
for i=0 to n-1 do A.SetRow(i, f i)
A
/// 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)
for i=0 to m-1 do A.SetColumn(i, f i)
A

6
src/FSharp/Main.fs

@ -31,12 +31,12 @@
namespace MathNet.Numerics
open MathNet.Numerics.LinearAlgebra.Double
open MathNet.Numerics.LinearAlgebra.Generic
/// A module which implements some F# utility functions.
module FSharp =
/// 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.
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
open MathNet.Numerics.LinearAlgebra.Double
open MathNet.Numerics.LinearAlgebra.Generic
/// A module which implements functional matrix operations.
module Matrix =
/// 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 m = A.ColumnCount
let mutable acc = acc0
@ -46,7 +47,7 @@ module Matrix =
acc
/// 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 m = A.ColumnCount
let mutable acc = acc0
@ -56,13 +57,13 @@ module Matrix =
acc
/// Create a 2D array from a matrix.
let inline toArray2 (A: #Matrix) =
let inline toArray2 (A: #Matrix<float>) =
let n = A.RowCount
let m = A.ColumnCount
Array2D.init n m (fun i j -> (A.Item(i,j)))
/// 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 i = 0
let mutable j = 0
@ -73,7 +74,7 @@ module Matrix =
b
/// 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 i = 0
let mutable j = 0
@ -84,7 +85,7 @@ module Matrix =
b
/// 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 i = 0
let mutable j = 0
@ -95,7 +96,7 @@ module Matrix =
b
/// 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 i = 0
let mutable j = 0
@ -106,7 +107,7 @@ module Matrix =
b
/// 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 M = A.ColumnCount
let C = A.Clone()
@ -116,7 +117,7 @@ module Matrix =
C
/// 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 M = A.ColumnCount
let C = A.Clone()
@ -126,25 +127,25 @@ module Matrix =
C
/// 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 j=0 to A.ColumnCount-1 do
A.Item(i,j) <- f i j
/// 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 j=0 to A.ColumnCount-1 do
A.Item(i,j) <- f i j (A.Item(i,j))
/// 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
for j in 0 .. A.ColumnCount-1 do
if A.Item(i,j) <> 0.0 then yield (i,j, A.Item(i,j)) }
/// 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
for i=0 to A.RowCount-1 do
for j=0 to A.ColumnCount-1 do
@ -152,49 +153,49 @@ module Matrix =
f
/// 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 j=0 to A.ColumnCount-1 do
f (A.Item(i,j))
()
/// 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 j=0 to A.ColumnCount-1 do
f i j (A.Item(i,j))
()
/// 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
for i=0 to A.RowCount-1 do
macc <- f macc (A.Item(i,k))
macc
/// 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
for i=0 to A.ColumnCount-1 do
macc <- f macc (A.Item(k,i))
macc
/// 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)
for k=0 to A.ColumnCount-1 do
let mutable macc = acc
for i=0 to A.RowCount-1 do
macc <- f macc (A.Item(i,k))
v.[k] <- macc
v :> Vector
v :> Vector<float>
/// 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)
for k=0 to A.RowCount-1 do
let mutable macc = acc
for i=0 to A.ColumnCount-1 do
macc <- f macc (A.Item(k,i))
v.[k] <- macc
v :> Vector
v :> Vector<float>

8
src/FSharp/SparseMatrix.fs

@ -31,7 +31,7 @@
namespace MathNet.Numerics.LinearAlgebra.Double
open MathNet.Numerics.LinearAlgebra
open MathNet.Numerics.LinearAlgebra.Generic
/// A module which implements functional sparse vector operations.
module SparseMatrix =
@ -55,7 +55,7 @@ module SparseMatrix =
A
/// 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 A = new Double.SparseMatrix(n,n)
for i=0 to n-1 do
@ -63,13 +63,13 @@ module SparseMatrix =
A
/// 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)
for i=0 to n-1 do A.SetRow(i, f i)
A
/// 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)
for i=0 to n-1 do A.SetColumn(i, f i)
A

42
src/FSharp/Vector.fs

@ -31,77 +31,77 @@
namespace MathNet.Numerics.LinearAlgebra.Double
open MathNet.Numerics.LinearAlgebra
open MathNet.Numerics.LinearAlgebra.Generic
/// A module which implements functional vector operations.
module Vector =
/// Transform a vector into an array.
let inline toArray (v: #Vector) =
let inline toArray (v: #Vector<float>) =
let n = v.Count
Array.init n (fun i -> v.Item(i))
/// Transform a vector into an array.
let inline toList (v: #Vector) =
let inline toList (v: #Vector<float>) =
let n = v.Count
List.init n (fun i -> v.Item(i))
/// 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
v.Item(i) <- f (v.Item(i))
()
/// 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
v.Item(i) <- f i (v.Item(i))
()
/// 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.
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.
/// <include file='../../../../FSharpExamples/DenseVector.xml' path='example'/>
let inline map f (v: #Vector) =
let inline map f (v: #Vector<float>) =
let w = v.Clone()
mapInPlace (fun x -> f x) w
w
/// 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
f (v.Item i)
/// 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
f i (v.Item i)
/// 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()
mapiInPlace f w
w
/// 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
for i=0 to v.Count-1 do
acc <- f acc (v.Item(i))
acc
/// 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
for i=0 to v.Count-1 do
acc <- f i acc (v.Item(i))
acc
/// 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 i = 0
while b && i < v.Count do
@ -110,7 +110,7 @@ module Vector =
b
/// 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 i = 0
while not(b) && i < v.Count do
@ -119,7 +119,7 @@ module Vector =
b
/// 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 i = 0
while b && i < v.Count do
@ -128,7 +128,7 @@ module Vector =
b
/// 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 i = 0
while not(b) && i < v.Count do
@ -137,7 +137,7 @@ module Vector =
b
/// 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 mutable p = v.Item(0)
for i=1 to v.Count-1 do
@ -146,7 +146,7 @@ module Vector =
w
/// 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 mutable p = v.Item(v.Count-1)
for i=2 to v.Count do
@ -155,14 +155,14 @@ module Vector =
w
/// 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)
for i=1 to v.Count-1 do
p <- f p (v.Item(i))
p
/// 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)
for i=2 to v.Count do
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 MathNet.Numerics
open MathNet.Numerics.LinearAlgebra.Double
open MathNet.Numerics.LinearAlgebra.Generic
/// Flag to specify wether we want pretty printing or tab separated output.
let prettyPrint = false
@ -61,7 +61,7 @@ let FunctionList : (string * (float -> float) * (float -> float)) [] =
/// A vector with random entries.
let w =
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.
let sw = new System.Diagnostics.Stopwatch()

5
src/FSharpUnitTests/FsUnit.fs

@ -29,6 +29,7 @@ namespace FsUnit
open MathNet.Numerics
open MathNet.Numerics.LinearAlgebra.Double
open MathNet.Numerics.LinearAlgebra.Generic
type Result =
| Pass
@ -174,7 +175,7 @@ module SpecOps =
else Fail (sprintf "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 () ->
let mutable f = true
for i=0 to expected.Count-1 do
@ -184,7 +185,7 @@ module SpecOps =
else Fail (sprintf "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 () ->
let mutable f = true
for i=0 to expected.RowCount-1 do

25
src/FSharpUnitTests/Program.fs

@ -1,6 +1,7 @@
open FsUnit
open MathNet.Numerics.FSharp
open MathNet.Numerics.LinearAlgebra.Double
open MathNet.Numerics.LinearAlgebra.Generic
/// Unit tests for the dense vector type.
let DenseVectorTests =
@ -29,13 +30,13 @@ let DenseVectorTests =
let SparseVectorTests =
/// 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" [
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"
((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 =
/// 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
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" [
spec "Vector.toArray"
@ -86,9 +87,9 @@ let VectorTests =
spec "Vector.existsi"
(Vector.existsi (fun i x -> x = 0.3 && i = 2) smallv |> should equal true)
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"
(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"
(Vector.reduce (fun acc x -> acc ** x) smallv |> should approximately_equal 14 0.990295218585507)
spec "Vector.reduce_right"
@ -141,9 +142,9 @@ let MatrixTests =
spec "Matrix.foldRow"
(Matrix.foldRow (+) 0.0 largeM 0 |> should equal 4950.0)
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"
(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 =
/// 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" [
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"
((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"
(SparseMatrix.constDiag 100 2.0 |> should equal (2.0 * (SparseMatrix.Identity 100)))
spec "SparseMatrix.diag"

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

@ -27,12 +27,18 @@
namespace MathNet.Numerics.LinearAlgebra.Double
{
using System;
using System.Text;
using Distributions;
using Factorization;
using Generic;
using Generic.Factorization;
using Properties;
using Threading;
/// <summary>
/// A Matrix class with dense storage. The underlying storage is a one dimensional array in column-major order.
/// </summary>
public class DenseMatrix : Matrix
public class DenseMatrix : Matrix<double>
{
/// <summary>
/// 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>
/// A <c>DenseMatrix</c> with the given dimensions.
/// </returns>
public override Matrix CreateMatrix(int numberOfRows, int numberOfColumns)
public override Matrix<double> CreateMatrix(int numberOfRows, int numberOfColumns)
{
return new DenseMatrix(numberOfRows, numberOfColumns);
}
/// <summary>
/// Creates a <see cref="Vector"/> with a the given dimension.
/// Creates a <see cref="Vector{T}"/> with a the given dimension.
/// </summary>
/// <param name="size">The size of the vector.</param>
/// <returns>
/// A <see cref="Vector"/> with the given dimension.
/// A <see cref="Vector{T}"/> with the given dimension.
/// </returns>
public override Vector CreateVector(int size)
public override Vector<double> CreateVector(int size)
{
return new DenseVector(size);
}
@ -200,7 +206,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// Returns the transpose of this matrix.
/// </summary>
/// <returns>The transpose of this matrix.</returns>
public override Matrix Transpose()
public override Matrix<double> Transpose()
{
var ret = new DenseMatrix(ColumnCount, RowCount);
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>
/// <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>
public override void Add(Matrix other)
public override void Add(Matrix<double> other)
{
var m = other as DenseMatrix;
if (m == null)
@ -318,7 +324,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="other">The matrix to subtract.</param>
/// <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>
public override void Subtract(Matrix other)
public override void Subtract(Matrix<double> other)
{
var m = other as DenseMatrix;
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="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>
public override void Multiply(Matrix other, Matrix result)
public override void Multiply(Matrix<double> other, Matrix<double> result)
{
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="ArgumentNullException">If the other matrix is <see langword="null" />.</exception>
/// <returns>The result of multiplication.</returns>
public override Matrix Multiply(Matrix other)
public override Matrix<double> Multiply(Matrix<double> other)
{
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="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>
public override void TransposeAndMultiply(Matrix other, Matrix result)
public override void TransposeAndMultiply(Matrix<double> other, Matrix<double> result)
{
var otherDense = other 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="ArgumentNullException">If the other matrix is <see langword="null" />.</exception>
/// <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;
if (otherDense == null)
@ -563,5 +569,155 @@ namespace MathNet.Numerics.LinearAlgebra.Double
}
#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.Globalization;
using System.Linq;
using System.Text;
using Distributions;
using Generic;
using NumberTheory;
using Properties;
using Threading;
@ -38,7 +40,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <summary>
/// A vector using dense storage.
/// </summary>
public class DenseVector : Vector
public class DenseVector : Vector<double>
{
/// <summary>
/// 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">
/// The vector to create the new vector from.
/// </param>
public DenseVector(Vector other)
public DenseVector(Vector<double> other)
: this(other.Count)
{
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).
/// </summary>
/// <returns>This vector as a column matrix.</returns>
public override Matrix ToColumnMatrix()
public override Matrix<double> ToColumnMatrix()
{
var matrix = new DenseMatrix(Count, 1);
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).
/// </summary>
/// <returns>This vector as a row matrix.</returns>
public override Matrix ToRowMatrix()
public override Matrix<double> ToRowMatrix()
{
var matrix = new DenseMatrix(1, Count);
for (var i = 0; i < Data.Length; i++)
@ -232,7 +234,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>
/// A matrix with the given dimensions.
/// </returns>
public override Matrix CreateMatrix(int rows, int columns)
public override Matrix<double> CreateMatrix(int rows, int columns)
{
return new DenseMatrix(rows, columns);
}
@ -247,7 +249,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>
/// The new <c>Vector</c>.
/// </returns>
public override Vector CreateVector(int size)
public override Vector<double> CreateVector(int size)
{
return new DenseVector(size);
}
@ -264,7 +266,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentException">
/// If <paramref name="target"/> is not the same size as this vector.
/// </exception>
public override void CopyTo(Vector target)
public override void CopyTo(Vector<double> target)
{
if (target == null)
{
@ -300,7 +302,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// </summary>
/// <param name="scalar">The scalar to add.</param>
/// <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)
{
@ -322,7 +324,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <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="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)
{
@ -355,7 +357,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <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="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)
{
@ -388,7 +390,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <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="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)
{
@ -436,7 +438,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="rightSide">The vector to get the values from.</param>
/// <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>
public static Vector operator +(DenseVector rightSide)
public static Vector<double> operator +(DenseVector rightSide)
{
if (rightSide == null)
{
@ -454,7 +456,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <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="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)
{
@ -479,7 +481,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// </summary>
/// <param name="scalar">The scalar to subtract.</param>
/// <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)
{
@ -501,7 +503,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <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="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)
{
@ -534,7 +536,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <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="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)
{
@ -567,7 +569,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <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="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)
{
@ -614,7 +616,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="rightSide">The vector to get the values from.</param>
/// <returns>A vector containing the negated values as <paramref name="rightSide"/>.</returns>
/// <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)
{
@ -632,7 +634,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <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="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)
{
@ -657,7 +659,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// </summary>
/// <returns>The negated vector.</returns>
/// <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);
CommonParallel.For(
@ -673,7 +675,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// </summary>
/// <param name="scalar">The scalar to multiply.</param>
/// <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)
{
@ -692,7 +694,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>The result of the addition.</returns>
/// <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>
public override double DotProduct(Vector other)
public override double DotProduct(Vector<double> other)
{
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>
/// </list></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)
{
@ -991,7 +993,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <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="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)
{
@ -1027,7 +1029,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <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="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)
{
@ -1078,7 +1080,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <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="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)
{
@ -1114,7 +1116,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <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="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)
{
@ -1202,7 +1204,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// to the specified random distribution.
/// </returns>
/// <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)
{
@ -1228,7 +1230,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// to the specified random distribution.
/// </returns>
/// <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)
{
@ -1252,7 +1254,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// Matrix M[i,j] = this[i] * v[j].
/// </returns>
/// <seealso cref="OuterProduct"/>
public Matrix TensorMultiply(DenseVector v)
public Matrix<double> TensorMultiply(DenseVector v)
{
return OuterProduct(this, v);
}
@ -1301,6 +1303,33 @@ namespace MathNet.Numerics.LinearAlgebra.Double
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
#region Parse Functions
@ -1469,5 +1498,71 @@ namespace MathNet.Numerics.LinearAlgebra.Double
{
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.Linq;
using System.Text;
using Distributions;
using Generic;
using Properties;
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
/// 0.0 or NaN; these settings will cause no change to the diagonal matrix.
/// </remarks>
public class DiagonalMatrix : Matrix
public class DiagonalMatrix : Matrix<double>
{
/// <summary>
/// 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>
/// A <c>DiagonalMatrix</c> with the given dimensions.
/// </returns>
public override Matrix CreateMatrix(int numberOfRows, int numberOfColumns)
public override Matrix<double> CreateMatrix(int numberOfRows, int numberOfColumns)
{
return new DiagonalMatrix(numberOfRows, numberOfColumns);
}
/// <summary>
/// Creates a <see cref="Vector"/> with a the given dimension.
/// Creates a <see cref="Vector{T}"/> with a the given dimension.
/// </summary>
/// <param name="size">The size of the vector.</param>
/// <returns>
/// A <see cref="Vector"/> with the given dimension.
/// A <see cref="Vector{T}"/> with the given dimension.
/// </returns>
public override Vector CreateVector(int size)
public override Vector<double> CreateVector(int 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="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>
public override void Add(Matrix other)
public override void Add(Matrix<double> other)
{
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="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>
public override void Subtract(Matrix other)
public override void Subtract(Matrix<double> other)
{
if (other == null)
{
@ -390,7 +393,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
}
/// <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>
/// <param name="source">The vector to copy the values from. The length of the vector should be
/// Min(Rows, Columns).</param>
@ -399,7 +402,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// equal Min(Rows, Columns).</exception>
/// <remarks>For non-square matrices, the elements of <paramref name="source"/> are copied to
/// this[i,i].</remarks>
public override void SetDiagonal(Vector source)
public override void SetDiagonal(Vector<double> source)
{
var denseSource = source as DenseVector;
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="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>
public override void Multiply(Matrix other, Matrix result)
public override void Multiply(Matrix<double> other, Matrix<double> result)
{
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="ArgumentNullException">If the other matrix is <see langword="null" />.</exception>
/// <returns>The result of multiplication.</returns>
public override Matrix Multiply(Matrix other)
public override Matrix<double> Multiply(Matrix<double> other)
{
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="ArgumentException">If <strong>result.Count != this.RowCount</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)
{
@ -574,7 +577,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <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>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)
{
@ -635,7 +638,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>The elements of the diagonal.</returns>
/// <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>
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
// 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="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>
public override void TransposeAndMultiply(Matrix other, Matrix result)
public override void TransposeAndMultiply(Matrix<double> other, Matrix<double> result)
{
var otherDiagonal = other 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="ArgumentNullException">If the other matrix is <see langword="null" />.</exception>
/// <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;
if (otherDiagonal == null)
@ -732,7 +735,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentException">
/// If this and the target matrix do not have the same dimensions..
/// </exception>
public override void CopyTo(Matrix target)
public override void CopyTo(Matrix<double> target)
{
var diagonalTarget = target as DiagonalMatrix;
@ -759,7 +762,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// Returns the transpose of this matrix.
/// </summary>
/// <returns>The transpose of this matrix.</returns>
public override Matrix Transpose()
public override Matrix<double> Transpose()
{
var ret = new DiagonalMatrix(ColumnCount, RowCount);
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="rowIndex">The row to start copying from.</param>
/// <param name="length">The number of elements to copy.</param>
/// <param name="result">The <see cref="Vector"/> to copy the column into.</param>
/// <exception cref="ArgumentNullException">If the result <see cref="Vector"/> is <see langword="null" />.</exception>
/// <param name="result">The <see cref="Vector{T}"/> to copy the column into.</param>
/// <exception cref="ArgumentNullException">If the result <see cref="Vector{T}"/> is <see langword="null" />.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="columnIndex"/> is negative,
/// or greater than or equal to the number of columns.</exception>
/// <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>
/// <exception cref="ArgumentException">If <paramref name="length"/> is not positive.</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)
{
@ -823,13 +826,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double
}
/// <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>
/// <param name="rowIndex">The row to copy elements from.</param>
/// <param name="columnIndex">The column to start copying from.</param>
/// <param name="length">The number of elements to copy.</param>
/// <param name="result">The <see cref="Vector"/> to copy the column into.</param>
/// <exception cref="ArgumentNullException">If the result <see cref="Vector"/> is <see langword="null" />.</exception>
/// <param name="result">The <see cref="Vector{T}"/> to copy the column into.</param>
/// <exception cref="ArgumentNullException">If the result <see cref="Vector{T}"/> is <see langword="null" />.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="rowIndex"/> is negative,
/// or greater than or equal to the number of columns.</exception>
/// <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>
/// <exception cref="ArgumentException">If <paramref name="length"/> is not positive.</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)
{
@ -913,10 +916,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double
{
var maxSv = double.NegativeInfinity;
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]));
minSv = Math.Min(minSv, Math.Abs(Data[i]));
maxSv = Math.Max(maxSv, Math.Abs(t));
minSv = Math.Min(minSv, Math.Abs(t));
}
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 singular.</exception>
/// <returns>The inverse of this matrix.</returns>
public override Matrix Inverse()
public override Matrix<double> Inverse()
{
if (RowCount != ColumnCount)
{
@ -953,7 +956,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// Returns a new matrix containing the lower triangle of this matrix.
/// </summary>
/// <returns>The lower triangle of this matrix.</returns>
public override Matrix LowerTriangle()
public override Matrix<double> LowerTriangle()
{
return Clone();
}
@ -964,7 +967,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <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 override void LowerTriangle(Matrix result)
public override void LowerTriangle(Matrix<double> result)
{
if (result == null)
{
@ -993,7 +996,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// does not contain the diagonal elements of this matrix.
/// </summary>
/// <returns>The lower triangle of this matrix.</returns>
public override Matrix StrictlyLowerTriangle()
public override Matrix<double> StrictlyLowerTriangle()
{
return new DiagonalMatrix(RowCount, ColumnCount);
}
@ -1004,7 +1007,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <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 override void StrictlyLowerTriangle(Matrix result)
public override void StrictlyLowerTriangle(Matrix<double> result)
{
if (result == null)
{
@ -1023,7 +1026,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// Returns a new matrix containing the upper triangle of this matrix.
/// </summary>
/// <returns>The upper triangle of this matrix.</returns>
public override Matrix UpperTriangle()
public override Matrix<double> UpperTriangle()
{
return Clone();
}
@ -1034,7 +1037,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <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 override void UpperTriangle(Matrix result)
public override void UpperTriangle(Matrix<double> result)
{
if (result == null)
{
@ -1058,7 +1061,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// does not contain the diagonal elements of this matrix.
/// </summary>
/// <returns>The upper triangle of this matrix.</returns>
public override Matrix StrictlyUpperTriangle()
public override Matrix<double> StrictlyUpperTriangle()
{
return new DiagonalMatrix(RowCount, ColumnCount);
}
@ -1069,7 +1072,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <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 override void StrictlyUpperTriangle(Matrix result)
public override void StrictlyUpperTriangle(Matrix<double> result)
{
if (result == null)
{
@ -1100,7 +1103,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <item><c>(rowIndex + rowLength) &gt;= Rows</c></item></list></exception>
/// <exception cref="ArgumentException">If <paramref name="rowLength"/> or <paramref name="columnLength"/>
/// 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)
{
@ -1186,7 +1189,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <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="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)
{
@ -1229,7 +1232,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <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="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)
{
@ -1270,7 +1273,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>The combined <see cref="SparseMatrix"/>.</returns>
/// <exception cref="ArgumentNullException">If lower is <see langword="null" />.</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)
{
@ -1294,7 +1297,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="result">The combined <see cref="SparseMatrix"/>.</param>
/// <exception cref="ArgumentNullException">If lower is <see langword="null" />.</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)
{
@ -1340,7 +1343,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// </summary>
/// <param name="right">The matrix to concatenate.</param>
/// <returns>The combined <see cref="SparseMatrix"/>.</returns>
public override Matrix Append(Matrix right)
public override Matrix<double> Append(Matrix<double> right)
{
if (right == null)
{
@ -1362,7 +1365,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// </summary>
/// <param name="right">The matrix to concatenate.</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)
{
@ -1411,7 +1414,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="lower">The lower, right matrix.</param>
/// <exception cref="ArgumentNullException">If lower is <see langword="null" />.</exception>
/// <returns>the combined matrix</returns>
public override Matrix DiagonalStack(Matrix lower)
public override Matrix<double> DiagonalStack(Matrix<double> lower)
{
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 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>
public override void DiagonalStack(Matrix lower, Matrix result)
public override void DiagonalStack(Matrix<double> lower, Matrix<double> result)
{
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="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>
public override void PointwiseMultiply(Matrix other, Matrix result)
public override void PointwiseMultiply(Matrix<double> other, Matrix<double> result)
{
if (other == null)
{
@ -1548,5 +1551,191 @@ namespace MathNet.Numerics.LinearAlgebra.Double
}
#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
{
using System;
using Generic;
using Generic.Factorization;
using Properties;
/// <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
/// or positive definite, the constructor will throw an exception.
/// </remarks>
public class DenseCholesky : Cholesky
public class DenseCholesky : Cholesky<double>
{
/// <summary>
/// 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>
/// Solves a system of linear equations, <b>AX = B</b>, with A Cholesky factorized.
/// </summary>
/// <param name="input">The right hand side <see cref="Matrix"/>, <b>B</b>.</param>
/// <param name="result">The left hand side <see cref="Matrix"/>, <b>X</b>.</param>
public override void Solve(Matrix input, Matrix result)
/// <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{T}"/>, <b>X</b>.</param>
public override void Solve(Matrix<double> input, Matrix<double> result)
{
// Check for proper arguments.
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.
/// </summary>
/// <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>
public override void Solve(Vector input, Vector result)
/// <param name="result">The left hand side <see cref="Matrix{T}"/>, <b>x</b>.</param>
public override void Solve(Vector<double> input, Vector<double> result)
{
// Check for proper arguments.
if (input == null)
@ -172,5 +174,38 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
var dfactor = (DenseMatrix)CholeskyFactor;
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
{
using System;
using Generic;
using Generic.Factorization;
using Properties;
/// <summary>
@ -41,7 +43,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <remarks>
/// The computation of the LU factorization is done at construction time.
/// </remarks>
public class DenseLU : LU
public class DenseLU : LU<double>
{
/// <summary>
/// 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>
/// Solves a system of linear equations, <c>AX = B</c>, with A LU factorized.
/// </summary>
/// <param name="input">The right hand side <see cref="Matrix"/>, <c>B</c>.</param>
/// <param name="result">The left hand side <see cref="Matrix"/>, <c>X</c>.</param>
public override void Solve(Matrix input, Matrix result)
/// <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{T}"/>, <c>X</c>.</param>
public override void Solve(Matrix<double> input, Matrix<double> result)
{
// Check for proper arguments.
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.
/// </summary>
/// <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>
public override void Solve(Vector input, Vector result)
/// <param name="result">The left hand side <see cref="Matrix{T}"/>, <c>x</c>.</param>
public override void Solve(Vector<double> input, Vector<double> result)
{
// Check for proper arguments.
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.
/// </summary>
/// <returns>The inverse of this matrix.</returns>
public override Matrix Inverse()
public override Matrix<double> Inverse()
{
var result = (DenseMatrix)Factors.Clone();
Control.LinearAlgebraProvider.LUInverseFactored(result.Data, result.RowCount, Pivots);
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
{
using System;
using Generic;
using Generic.Factorization;
using Properties;
/// <summary>
@ -42,7 +44,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <remarks>
/// The computation of the QR decomposition is done at construction time by Householder transformation.
/// </remarks>
public class DenseQR : QR
public class DenseQR : QR<double>
{
/// <summary>
/// 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>
/// Solves a system of linear equations, <b>AX = B</b>, with A QR factorized.
/// </summary>
/// <param name="input">The right hand side <see cref="Matrix"/>, <b>B</b>.</param>
/// <param name="result">The left hand side <see cref="Matrix"/>, <b>X</b>.</param>
public override void Solve(Matrix input, Matrix result)
/// <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{T}"/>, <b>X</b>.</param>
public override void Solve(Matrix<double> input, Matrix<double> result)
{
// Check for proper arguments.
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.
/// </summary>
/// <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>
public override void Solve(Vector input, Vector result)
/// <param name="result">The left hand side <see cref="Matrix{T}"/>, <b>x</b>.</param>
public override void Solve(Vector<double> input, Vector<double> result)
{
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);
}
#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
{
using System;
using Generic;
using Generic.Factorization;
using Properties;
/// <summary>
@ -46,7 +48,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <remarks>
/// The computation of the singular value decomposition is done at construction time.
/// </remarks>
public class DenseSvd : Svd
public class DenseSvd : Svd<double>
{
/// <summary>
/// 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>
/// Solves a system of linear equations, <b>AX = B</b>, with A SVD factorized.
/// </summary>
/// <param name="input">The right hand side <see cref="Matrix"/>, <b>B</b>.</param>
/// <param name="result">The left hand side <see cref="Matrix"/>, <b>X</b>.</param>
public override void Solve(Matrix input, Matrix result)
/// <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{T}"/>, <b>X</b>.</param>
public override void Solve(Matrix<double> input, Matrix<double> result)
{
// Check for proper arguments.
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.
/// </summary>
/// <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>
public override void Solve(Vector input, Vector result)
/// <param name="result">The left hand side <see cref="Matrix{T}"/>, <b>x</b>.</param>
public override void Solve(Vector<double> input, Vector<double> result)
{
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);
}
#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
{
using Generic;
using Generic.Factorization;
/// <summary>
/// Extension methods which return factorizations for the various matrix classes.
/// </summary>
@ -40,9 +43,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// </summary>
/// <param name="matrix">The matrix to factor.</param>
/// <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>
@ -50,9 +53,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// </summary>
/// <param name="matrix">The matrix to factor.</param>
/// <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>
@ -60,9 +63,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// </summary>
/// <param name="matrix">The matrix to factor.</param>
/// <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>
@ -70,7 +73,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// </summary>
/// <param name="matrix">The matrix to factor.</param>
/// <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.
return new GramSchmidt(matrix);
@ -82,9 +85,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <param name="matrix">The matrix to factor.</param>
/// <param name="computeVectors">Compute the singular U and VT vectors or not.</param>
/// <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
{
using System;
using Generic;
using Generic.Factorization;
using Properties;
/// <summary>
@ -40,7 +42,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <remarks>
/// The computation of the QR decomposition is done at construction time by modified Gram-Schmidt Orthogonalization.
/// </remarks>
public class GramSchmidt : QR
public class GramSchmidt : QR<double>
{
/// <summary>
/// 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="ArgumentException">If <paramref name="matrix"/> row count is less then column count</exception>
/// <exception cref="ArgumentException">If <paramref name="matrix"/> is rank deficient</exception>
public GramSchmidt(Matrix matrix)
public GramSchmidt(Matrix<double> matrix)
{
if (matrix == null)
{
@ -133,9 +135,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <summary>
/// Solves a system of linear equations, <b>AX = B</b>, with A QR factorized.
/// </summary>
/// <param name="input">The right hand side <see cref="Matrix"/>, <b>B</b>.</param>
/// <param name="result">The left hand side <see cref="Matrix"/>, <b>X</b>.</param>
public override void Solve(Matrix input, Matrix result)
/// <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{T}"/>, <b>X</b>.</param>
public override void Solve(Matrix<double> input, Matrix<double> result)
{
// Check for proper arguments.
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.
/// </summary>
/// <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>
public override void Solve(Vector input, Vector result)
/// <param name="result">The left hand side <see cref="Matrix{T}"/>, <b>x</b>.</param>
public override void Solve(Vector<double> input, Vector<double> result)
{
if (input == null)
{
@ -280,5 +282,38 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
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
{
using System;
using Generic;
using Generic.Factorization;
using Properties;
/// <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
/// or positive definite, the constructor will throw an exception.
/// </remarks>
public class SparseCholesky : Cholesky
public class SparseCholesky : Cholesky<double>
{
/// <summary>
/// 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="ArgumentException">If <paramref name="matrix"/> is not a square matrix.</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)
{
@ -96,13 +98,12 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
}
}
/// <summary>
/// Solves a system of linear equations, <b>AX = B</b>, with A Cholesky factorized.
/// </summary>
/// <param name="input">The right hand side <see cref="Matrix"/>, <b>B</b>.</param>
/// <param name="result">The left hand side <see cref="Matrix"/>, <b>X</b>.</param>
public override void Solve(Matrix input, Matrix result)
/// <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{T}"/>, <b>X</b>.</param>
public override void Solve(Matrix<double> input, Matrix<double> result)
{
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.
/// </summary>
/// <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>
public override void Solve(Vector input, Vector result)
/// <param name="result">The left hand side <see cref="Matrix{T}"/>, <b>x</b>.</param>
public override void Solve(Vector<double> input, Vector<double> result)
{
// Check for proper arguments.
if (input == null)
@ -219,5 +220,39 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
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
{
using System;
using Generic;
using Generic.Factorization;
using Properties;
/// <summary>
@ -41,7 +43,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <remarks>
/// The computation of the LU factorization is done at construction time.
/// </remarks>
public class SparseLU : LU
public class SparseLU : LU<double>
{
/// <summary>
/// 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>
/// <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>
public SparseLU(Matrix matrix)
public SparseLU(Matrix<double> matrix)
{
if (matrix == null)
{
@ -132,9 +134,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <summary>
/// Solves a system of linear equations, <c>AX = B</c>, with A LU factorized.
/// </summary>
/// <param name="input">The right hand side <see cref="Matrix"/>, <c>B</c>.</param>
/// <param name="result">The left hand side <see cref="Matrix"/>, <c>X</c>.</param>
public override void Solve(Matrix input, Matrix result)
/// <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{T}"/>, <c>X</c>.</param>
public override void Solve(Matrix<double> input, Matrix<double> result)
{
// Check for proper arguments.
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.
/// </summary>
/// <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>
public override void Solve(Vector input, Vector result)
/// <param name="result">The left hand side <see cref="Matrix{T}"/>, <c>x</c>.</param>
public override void Solve(Vector<double> input, Vector<double> result)
{
// Check for proper arguments.
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.
/// </summary>
/// <returns>The inverse of this matrix.</returns>
public override Matrix Inverse()
public override Matrix<double> Inverse()
{
var order = Factors.RowCount;
var inverse = Factors.CreateMatrix(order, order);
@ -296,5 +298,37 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
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.Linq;
using Generic;
using Generic.Factorization;
using Properties;
/// <summary>
@ -43,7 +45,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <remarks>
/// The computation of the QR decomposition is done at construction time by Householder transformation.
/// </remarks>
public class SparseQR : QR
public class SparseQR : QR<double>
{
/// <summary>
/// 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>
/// <param name="matrix">The matrix to factor.</param>
/// <exception cref="ArgumentNullException">If <paramref name="matrix"/> is <c>null</c>.</exception>
public SparseQR(Matrix matrix)
public SparseQR(Matrix<double> matrix)
{
if (matrix == null)
{
@ -93,7 +95,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <param name="rowEnd">The last row</param>
/// <param name="column">Column index</param>
/// <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 u = new double[ru];
@ -147,7 +149,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <param name="rowEnd">The last row</param>
/// <param name="columnStart">The first 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)
{
@ -180,9 +182,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <summary>
/// Solves a system of linear equations, <b>AX = B</b>, with A QR factorized.
/// </summary>
/// <param name="input">The right hand side <see cref="Matrix"/>, <b>B</b>.</param>
/// <param name="result">The left hand side <see cref="Matrix"/>, <b>X</b>.</param>
public override void Solve(Matrix input, Matrix result)
/// <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{T}"/>, <b>X</b>.</param>
public override void Solve(Matrix<double> input, Matrix<double> result)
{
// Check for proper arguments.
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.
/// </summary>
/// <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>
public override void Solve(Vector input, Vector result)
/// <param name="result">The left hand side <see cref="Matrix{T}"/>, <b>x</b>.</param>
public override void Solve(Vector<double> input, Vector<double> result)
{
if (input == null)
{
@ -328,5 +330,38 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
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
{
using System;
using Generic;
using Generic.Factorization;
using Properties;
/// <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.
/// Then there exists a factorization of the form M = UΣVT where:
/// - U is an m-by-m unitary matrix;
@ -46,7 +48,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <remarks>
/// The computation of the singular value decomposition is done at construction time.
/// </remarks>
public class SparseSvd : Svd
public class SparseSvd : Svd<double>
{
/// <summary>
/// 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>
/// <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>
public SparseSvd(Matrix matrix, bool computeVectors)
public SparseSvd(Matrix<double> matrix, bool computeVectors)
{
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="columnA">Column A 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++)
{
@ -621,7 +623,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <param name="column">Column to scale</param>
/// <param name="rowStart">Row to scale from</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++)
{
@ -708,7 +710,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <param name="column">Column index</param>
/// <param name="rowStart">Start row index</param>
/// <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;
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="rowStart">Starting row index</param>
/// <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;
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="c">Scalar "c" 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++)
{
@ -780,9 +782,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <summary>
/// Solves a system of linear equations, <b>AX = B</b>, with A SVD factorized.
/// </summary>
/// <param name="input">The right hand side <see cref="Matrix"/>, <b>B</b>.</param>
/// <param name="result">The left hand side <see cref="Matrix"/>, <b>X</b>.</param>
public override void Solve(Matrix input, Matrix result)
/// <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{T}"/>, <b>X</b>.</param>
public override void Solve(Matrix<double> input, Matrix<double> result)
{
// Check for proper arguments.
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.
/// </summary>
/// <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>
public override void Solve(Vector input, Vector result)
/// <param name="result">The left hand side <see cref="Matrix{T}"/>, <b>x</b>.</param>
public override void Solve(Vector<double> input, Vector<double> result)
{
if (input == null)
{
@ -919,5 +921,39 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
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
{
using System;
using Generic;
using Generic.Factorization;
using Properties;
/// <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
/// or positive definite, the constructor will throw an exception.
/// </remarks>
public class UserCholesky : Cholesky
public class UserCholesky : Cholesky<double>
{
/// <summary>
/// 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="ArgumentException">If <paramref name="matrix"/> is not a square matrix.</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)
{
@ -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>
/// Solves a system of linear equations, <b>AX = B</b>, with A Cholesky factorized.
/// </summary>
/// <param name="input">The right hand side <see cref="Matrix"/>, <b>B</b>.</param>
/// <param name="result">The left hand side <see cref="Matrix"/>, <b>X</b>.</param>
public override void Solve(Matrix input, Matrix result)
/// <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{T}"/>, <b>X</b>.</param>
public override void Solve(Matrix<double> input, Matrix<double> result)
{
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.
/// </summary>
/// <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>
public override void Solve(Vector input, Vector result)
/// <param name="result">The left hand side <see cref="Matrix{T}"/>, <b>x</b>.</param>
public override void Solve(Vector<double> input, Vector<double> result)
{
// Check for proper arguments.
if (input == null)
@ -218,5 +254,39 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
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
{
using System;
using Generic;
using Generic.Factorization;
using Properties;
/// <summary>
@ -41,7 +43,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <remarks>
/// The computation of the LU factorization is done at construction time.
/// </remarks>
public class UserLU : LU
public class UserLU : LU<double>
{
/// <summary>
/// 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>
/// <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>
public UserLU(Matrix matrix)
public UserLU(Matrix<double> matrix)
{
if (matrix == null)
{
@ -132,9 +134,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <summary>
/// Solves a system of linear equations, <c>AX = B</c>, with A LU factorized.
/// </summary>
/// <param name="input">The right hand side <see cref="Matrix"/>, <c>B</c>.</param>
/// <param name="result">The left hand side <see cref="Matrix"/>, <c>X</c>.</param>
public override void Solve(Matrix input, Matrix result)
/// <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{T}"/>, <c>X</c>.</param>
public override void Solve(Matrix<double> input, Matrix<double> result)
{
// Check for proper arguments.
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.
/// </summary>
/// <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>
public override void Solve(Vector input, Vector result)
/// <param name="result">The left hand side <see cref="Matrix{T}"/>, <c>x</c>.</param>
public override void Solve(Vector<double> input, Vector<double> result)
{
// Check for proper arguments.
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.
/// </summary>
/// <returns>The inverse of this matrix.</returns>
public override Matrix Inverse()
public override Matrix<double> Inverse()
{
var order = Factors.RowCount;
var inverse = Factors.CreateMatrix(order, order);
@ -296,5 +298,37 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
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.Linq;
using Generic;
using Generic.Factorization;
using Properties;
/// <summary>
@ -43,7 +45,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <remarks>
/// The computation of the QR decomposition is done at construction time by Householder transformation.
/// </remarks>
public class UserQR : QR
public class UserQR : QR<double>
{
/// <summary>
/// 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>
/// <param name="matrix">The matrix to factor.</param>
/// <exception cref="ArgumentNullException">If <paramref name="matrix"/> is <c>null</c>.</exception>
public UserQR(Matrix matrix)
public UserQR(Matrix<double> matrix)
{
if (matrix == null)
{
@ -93,7 +95,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <param name="rowEnd">The last row</param>
/// <param name="column">Column index</param>
/// <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 u = new double[ru];
@ -147,7 +149,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <param name="rowEnd">The last row</param>
/// <param name="columnStart">The first 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)
{
@ -180,9 +182,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <summary>
/// Solves a system of linear equations, <b>AX = B</b>, with A QR factorized.
/// </summary>
/// <param name="input">The right hand side <see cref="Matrix"/>, <b>B</b>.</param>
/// <param name="result">The left hand side <see cref="Matrix"/>, <b>X</b>.</param>
public override void Solve(Matrix input, Matrix result)
/// <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{T}"/>, <b>X</b>.</param>
public override void Solve(Matrix<double> input, Matrix<double> result)
{
// Check for proper arguments.
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.
/// </summary>
/// <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>
public override void Solve(Vector input, Vector result)
/// <param name="result">The left hand side <see cref="Matrix{T}"/>, <b>x</b>.</param>
public override void Solve(Vector<double> input, Vector<double> result)
{
if (input == null)
{
@ -327,5 +329,38 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
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
{
using System;
using Generic;
using Generic.Factorization;
using Properties;
/// <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.
/// Then there exists a factorization of the form M = UΣVT where:
/// - U is an m-by-m unitary matrix;
@ -46,7 +48,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <remarks>
/// The computation of the singular value decomposition is done at construction time.
/// </remarks>
public class UserSvd : Svd
public class UserSvd : Svd<double>
{
/// <summary>
/// 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>
/// <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>
public UserSvd(Matrix matrix, bool computeVectors)
public UserSvd(Matrix<double> matrix, bool computeVectors)
{
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="columnA">Column A 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++)
{
@ -621,7 +623,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <param name="column">Column to scale</param>
/// <param name="rowStart">Row to scale from</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++)
{
@ -708,7 +710,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <param name="column">Column index</param>
/// <param name="rowStart">Start row index</param>
/// <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;
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="rowStart">Starting row index</param>
/// <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;
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="c">Scalar "c" 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++)
{
@ -780,9 +782,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <summary>
/// Solves a system of linear equations, <b>AX = B</b>, with A SVD factorized.
/// </summary>
/// <param name="input">The right hand side <see cref="Matrix"/>, <b>B</b>.</param>
/// <param name="result">The left hand side <see cref="Matrix"/>, <b>X</b>.</param>
public override void Solve(Matrix input, Matrix result)
/// <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{T}"/>, <b>X</b>.</param>
public override void Solve(Matrix<double> input, Matrix<double> result)
{
// Check for proper arguments.
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.
/// </summary>
/// <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>
public override void Solve(Vector input, Vector result)
/// <param name="result">The left hand side <see cref="Matrix{T}"/>, <b>x</b>.</param>
public override void Solve(Vector<double> input, Vector<double> result)
{
if (input == null)
{
@ -919,5 +921,39 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
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.Reflection;
using System.Text.RegularExpressions;
using Generic;
/// <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.
/// </summary>
/// <typeparam name="TMatrix">The type of the matrix to return.</typeparam>
public class DelimitedReader<TMatrix> : MatrixReader<TMatrix>
where TMatrix : Matrix
where TMatrix : Matrix<double>
{
/// <summary>
/// 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.Globalization;
using System.IO;
using Generic;
/// <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.
/// </summary>
public class DelimitedWriter : MatrixWriter
@ -115,13 +116,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double.IO
}
/// <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>
/// <param name="matrix">The matrix to write.</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>
/// <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)
{

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

@ -29,6 +29,7 @@
namespace MathNet.Numerics.LinearAlgebra.Double.IO.Matlab
{
using System.Collections.Generic;
using Generic;
/// <summary>
/// Represents a Matlab file
@ -38,7 +39,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.IO.Matlab
/// <summary>
/// Matrices in a matlab file stored as 1-D arrays
/// </summary>
private readonly IDictionary<string, Matrix> _matrices = new SortedList<string, Matrix>();
private readonly IDictionary<string, Matrix<double>> _matrices = new SortedList<string, Matrix<double>>();
/// <summary>
/// Gets or sets the header text.
@ -56,7 +57,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.IO.Matlab
/// Gets the first matrix.
/// </summary>
/// <value>The first matrix.</value>
public Matrix FirstMatrix
public Matrix<double> FirstMatrix
{
get
{
@ -73,7 +74,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.IO.Matlab
/// Gets the matrices.
/// </summary>
/// <value>The matrices.</value>
public IDictionary<string, Matrix> Matrices
public IDictionary<string, Matrix<double>> 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.Text;
using Common.IO.Matlab;
using Generic;
using Properties;
using zlib;
@ -296,7 +297,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.IO.Matlab
size = reader.ReadInt32();
}
Matrix matrix;
Matrix<double> matrix;
switch (arrayClass)
{
case ArrayClass.Sparse:
@ -331,7 +332,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.IO.Matlab
/// <param name="columns">The number of columns.</param>
/// <param name="size">The size of the block.</param>
/// <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
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
reader.BaseStream.Seek(4, SeekOrigin.Current);
Matrix matrix = new SparseMatrix(rows, columns);
Matrix<double> matrix = new SparseMatrix(rows, columns);
var col = 0;
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="columns">The number of columns.</param>
/// <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)
{
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.Collections.Generic;
using System.IO;
using Generic;
using Matlab;
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"/>
/// is returned.
/// </returns>
public Matrix ReadMatrix()
public Matrix<double> ReadMatrix()
{
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"/>
/// is returned. <see langword="null"/> is returned if a matrix with the requests name doesn't exist.
/// </returns>
public Matrix ReadMatrix(string matrixName)
public Matrix<double> ReadMatrix(string matrixName)
{
Stream stream;
if (_filename == null)
@ -119,7 +120,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.IO
var parser = new MatlabParser(stream, names);
var file = parser.Parse();
Matrix matrix = null;
Matrix<double> matrix = null;
if (string.IsNullOrEmpty(matrixName))
{
matrix = file.FirstMatrix;
@ -142,7 +143,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.IO
/// Reads all matrices from the file or stream.
/// </summary>
/// <returns>All matrices from the file or stream.</returns>
public Matrix[] ReadMatrices()
public Matrix<double>[] ReadMatrices()
{
return ReadMatrices(new string[] { });
}
@ -154,7 +155,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.IO
/// <returns>
/// The named matrices from the file or stream.
/// </returns>
public Matrix[] ReadMatrices(IEnumerable<string> names)
public Matrix<double>[] ReadMatrices(IEnumerable<string> names)
{
Stream stream;
if (_filename == null)
@ -170,7 +171,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.IO
var parser = new MatlabParser(stream, names);
var file = parser.Parse();
var matrices = new Matrix[file.Matrices.Count];
var matrices = new Matrix<double>[file.Matrices.Count];
var i = 0;
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.IO;
using Generic;
using Properties;
/// <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>
/// <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>
/// Reads a <see cref="Matrix"/> from a file.
/// Reads a <see cref="Matrix{T}"/> from a file.
/// </summary>
/// <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="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="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)
{
@ -56,7 +57,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.IO
}
/// <summary>
/// Reads a <see cref="Matrix"/> from a <see cref="Stream"/>.
/// Reads a <see cref="Matrix{T}"/> from a <see cref="Stream"/>.
/// </summary>
/// <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>

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

@ -31,19 +31,21 @@ using System.IO;
namespace MathNet.Numerics.LinearAlgebra.Double.IO
{
using Generic;
/// <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>
public abstract class MatrixWriter
{
/// <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.
/// </summary>
/// <param name="matrix">The matrix to write.</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>
public void WriteMatrix(Matrix matrix, string file)
public void WriteMatrix(Matrix<double> matrix, string file)
{
if (matrix == null)
{
@ -62,14 +64,14 @@ namespace MathNet.Numerics.LinearAlgebra.Double.IO
}
/// <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.
/// </summary>
/// <param name="matrix">the matrix to write.</param>
/// <param name="file">The file to write the matrix to.</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>
public void WriteMatrix(Matrix matrix, string file, string format)
public void WriteMatrix(Matrix<double> matrix, string file, string format)
{
if (matrix == null)
{
@ -93,12 +95,12 @@ namespace MathNet.Numerics.LinearAlgebra.Double.IO
}
/// <summary>
/// Writes the given <see cref="Matrix"/> to the given stream.
/// Writes the given <see cref="Matrix{T}"/> to the given stream.
/// </summary>
/// <param name="matrix">The matrix to write.</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>
public void WriteMatrix(Matrix matrix, Stream stream)
public void WriteMatrix(Matrix<double> matrix, Stream stream)
{
if (matrix == null)
{
@ -117,13 +119,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double.IO
}
/// <summary>
/// Writes the given <see cref="Matrix"/> to the given stream.
/// Writes the given <see cref="Matrix{T}"/> to the given stream.
/// </summary>
/// <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="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>
public void WriteMatrix(Matrix matrix, Stream stream, string format)
public void WriteMatrix(Matrix<double> matrix, Stream stream, string format)
{
if (matrix == null)
{
@ -142,12 +144,12 @@ namespace MathNet.Numerics.LinearAlgebra.Double.IO
}
/// <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>
/// <param name="matrix">The matrix to write.</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>
public void WriteMatrix(Matrix matrix, TextWriter writer)
public void WriteMatrix(Matrix<double> matrix, TextWriter writer)
{
if (matrix == null)
{
@ -163,13 +165,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double.IO
}
/// <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>
/// <param name="matrix">The matrix to write.</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>
/// <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)
{
@ -190,6 +192,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double.IO
/// <param name="matrix">The matrix to serialize.</param>
/// <param name="writer">The <see cref="TextWriter"/> to write the matrix to.</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
{
using System;
using Generic;
using Generic.Solvers;
using Generic.Solvers.Preconditioners;
using Generic.Solvers.Status;
using Preconditioners;
using Properties;
using Status;
/// <summary>
/// A Bi-Conjugate Gradient stabilized iterative matrix solver.
@ -64,7 +67,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// solver.
/// </para>
/// </remarks>
public sealed class BiCgStab : IIterativeSolver
public sealed class BiCgStab : IIterativeSolver<double>
{
/// <summary>
/// The status used if there is no status, i.e. the solver hasn't run yet and there is no
@ -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
/// pre-conditioner will be used.
/// </summary>
private IPreConditioner _preconditioner;
private IPreConditioner<double> _preconditioner;
/// <summary>
/// The iterative process controller.
/// </summary>
private IIterator _iterator;
private IIterator<double> _iterator;
/// <summary>
/// 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.
/// </summary>
/// <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.
/// </remarks>
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.
/// </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">
/// <item>It is possible to set the desired convergence limits.</item>
/// <item>
/// It is possible to check the reason for which the solver finished
/// the iterative procedure by calling the <see cref="IIterator.Status"/> property.
/// the iterative procedure by calling the <see cref="IIterator{T}.Status"/> property.
/// </item>
/// </list>
/// </para>
/// </remarks>
/// <param name="iterator">The <see cref="IIterator"/> that will be used to monitor the iterative process. </param>
public BiCgStab(IIterator iterator) : this(null, iterator)
/// <param name="iterator">The <see cref="IIterator{T}"/> that will be used to monitor the iterative process. </param>
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.
/// </summary>
/// <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.
/// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner"/> that will be used to precondition the matrix equation.</param>
public BiCgStab(IPreConditioner preconditioner) : this(preconditioner, null)
/// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation.</param>
public BiCgStab(IPreConditioner<double> preconditioner) : this(preconditioner, null)
{
}
@ -139,38 +142,38 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// </summary>
/// <remarks>
/// <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">
/// <item>It is possible to set the desired convergence limits.</item>
/// <item>
/// It is possible to check the reason for which the solver finished
/// the iterative procedure by calling the <see cref="IIterator.Status"/> property.
/// the iterative procedure by calling the <see cref="IIterator{T}.Status"/> property.
/// </item>
/// </list>
/// </para>
/// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner"/> 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>
public BiCgStab(IPreConditioner preconditioner, IIterator iterator)
/// <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{T}"/> that will be used to monitor the iterative process. </param>
public BiCgStab(IPreConditioner<double> preconditioner, IIterator<double> iterator)
{
_iterator = iterator;
_preconditioner = preconditioner;
}
/// <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>
/// <param name="preconditioner">The preconditioner.</param>
public void SetPreconditioner(IPreConditioner preconditioner)
public void SetPreconditioner(IPreConditioner<double> preconditioner)
{
_preconditioner = preconditioner;
}
/// <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>
/// <param name="iterator">The iterator.</param>
public void SetIterator(IIterator iterator)
public void SetIterator(IIterator<double> 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
/// solution vector and x is the unknown vector.
/// </summary>
/// <param name="matrix">The coefficient <see cref="Matrix"/>, <c>A</c>.</param>
/// <param name="vector">The solution <see cref="Vector"/>, <c>b</c>.</param>
/// <returns>The result <see cref="Vector"/>, <c>x</c>.</returns>
public Vector Solve(Matrix matrix, Vector vector)
/// <param name="matrix">The coefficient <see cref="Matrix{T}"/>, <c>A</c>.</param>
/// <param name="vector">The solution <see cref="Vector{T}"/>, <c>b</c>.</param>
/// <returns>The result <see cref="Vector{T}"/>, <c>x</c>.</returns>
public Vector<double> Solve(Matrix<double> matrix, Vector<double> vector)
{
if (vector == null)
{
throw new ArgumentNullException();
}
Vector result = new DenseVector(matrix.RowCount);
Vector<double> result = new DenseVector(matrix.RowCount);
Solve(matrix, vector, 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
/// solution vector and x is the unknown vector.
/// </summary>
/// <param name="matrix">The coefficient <see cref="Matrix"/>, <c>A</c>.</param>
/// <param name="input">The solution <see cref="Vector"/>, <c>b</c>.</param>
/// <param name="result">The result <see cref="Vector"/>, <c>x</c>.</param>
public void Solve(Matrix matrix, Vector input, Vector result)
/// <param name="matrix">The coefficient <see cref="Matrix{T}"/>, <c>A</c>.</param>
/// <param name="input">The solution <see cref="Vector{T}"/>, <c>b</c>.</param>
/// <param name="result">The result <see cref="Vector{T}"/>, <c>x</c>.</param>
public void Solve(Matrix<double> matrix, Vector<double> input, Vector<double> result)
{
// If we were stopped before, we are no longer
// 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
// In this case we take x_0 = vector
// 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);
// 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
// coefficients. All vectors are mangled in each iteration.
// These are defined here to prevent stressing the garbage collector
Vector vecP = new DenseVector(residuals.Count);
Vector vecPdash = new DenseVector(residuals.Count);
Vector nu = new DenseVector(residuals.Count);
Vector vecS = new DenseVector(residuals.Count);
Vector vecSdash = new DenseVector(residuals.Count);
Vector t = new DenseVector(residuals.Count);
Vector<double> vecP = new DenseVector(residuals.Count);
Vector<double> vecPdash = new DenseVector(residuals.Count);
Vector<double> nu = new DenseVector(residuals.Count);
Vector<double> vecS = new DenseVector(residuals.Count);
Vector<double> vecSdash = new DenseVector(residuals.Count);
Vector<double> t = new DenseVector(residuals.Count);
// create some temporary double variables that are needed
// 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^
result.Add(vecSdash.Multiply(omega), result);
//vecPdash.Multiply(alpha, vecPdash);
result.Add(vecPdash.Multiply(alpha), result);
t.Multiply(-omega, residuals);
@ -412,11 +413,11 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// <summary>
/// Calculates the true residual of the matrix equation Ax = b according to: residual = b - Ax
/// </summary>
/// <param name="matrix">Instance of the <see cref="Matrix"/> A.</param>
/// <param name="residual">Residual values in <see cref="Vector"/>.</param>
/// <param name="x">Instance of the <see cref="Vector"/> x.</param>
/// <param name="b">Instance of the <see cref="Vector"/> b.</param>
private static void CalculateTrueResidual(Matrix matrix, Vector residual, Vector x, Vector b)
/// <param name="matrix">Instance of the <see cref="Matrix{T}"/> A.</param>
/// <param name="residual">Residual values in <see cref="Vector{T}"/>.</param>
/// <param name="x">Instance of the <see cref="Vector{T}"/> x.</param>
/// <param name="b">Instance of the <see cref="Vector{T}"/> b.</param>
private static void CalculateTrueResidual(Matrix<double> matrix, Vector<double> residual, Vector<double> x, Vector<double> b)
{
// -Ax = residual
matrix.Multiply(x, residual);
@ -432,11 +433,11 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// Determine if calculation should continue
/// </summary>
/// <param name="iterationNumber">Number of iterations passed</param>
/// <param name="result">Result <see cref="Vector"/>.</param>
/// <param name="source">Source <see cref="Vector"/>.</param>
/// <param name="residuals">Residual <see cref="Vector"/>.</param>
/// <param name="result">Result <see cref="Vector{T}"/>.</param>
/// <param name="source">Source <see cref="Vector{T}"/>.</param>
/// <param name="residuals">Residual <see cref="Vector{T}"/>.</param>
/// <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)
{
@ -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
/// solution matrix and X is the unknown matrix.
/// </summary>
/// <param name="matrix">The coefficient <see cref="Matrix"/>, <c>A</c>.</param>
/// <param name="input">The solution <see cref="Matrix"/>, <c>B</c>.</param>
/// <returns>The result <see cref="Matrix"/>, <c>X</c>.</returns>
public Matrix Solve(Matrix matrix, Matrix input)
/// <param name="matrix">The coefficient <see cref="Matrix{T}"/>, <c>A</c>.</param>
/// <param name="input">The solution <see cref="Matrix{T}"/>, <c>B</c>.</param>
/// <returns>The result <see cref="Matrix{T}"/>, <c>X</c>.</returns>
public Matrix<double> Solve(Matrix<double> matrix, Matrix<double> input)
{
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
/// solution matrix and X is the unknown matrix.
/// </summary>
/// <param name="matrix">The coefficient <see cref="Matrix"/>, <c>A</c>.</param>
/// <param name="input">The solution <see cref="Matrix"/>, <c>B</c>.</param>
/// <param name="result">The result <see cref="Matrix"/>, <c>X</c></param>
public void Solve(Matrix matrix, Matrix input, Matrix result)
/// <param name="matrix">The coefficient <see cref="Matrix{T}"/>, <c>A</c>.</param>
/// <param name="input">The solution <see cref="Matrix{T}"/>, <c>B</c>.</param>
/// <param name="result">The result <see cref="Matrix{T}"/>, <c>X</c></param>
public void Solve(Matrix<double> matrix, Matrix<double> input, Matrix<double> result)
{
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.Linq;
using System.Reflection;
using Generic;
using Generic.Solvers;
using Generic.Solvers.Status;
using Properties;
using Status;
/// <summary>
/// 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.
/// </para>
/// </remarks>
public sealed class CompositeSolver : IIterativeSolver
public sealed class CompositeSolver : IIterativeSolver<double>
{
#region Internal class - DoubleComparer
/// <summary>
@ -94,19 +96,19 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
private static readonly ICalculationStatus RunningStatus = new CalculationRunning();
#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
/// <summary>
/// The collection of iterative solver setups. Stored based on the
/// ratio between the relative speed and relative accuracy.
/// </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
#region Solver information loading methods
/// <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>
public static void LoadSolverInformation()
{
@ -114,16 +116,16 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
}
/// <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>
/// <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)
{
LoadSolverInformationFromAssembly(Assembly.GetExecutingAssembly(), typesToExclude);
}
/// <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>
/// <param name="assemblyLocation">The fully qualified path to the assembly.</param>
public static void LoadSolverInformationFromAssembly(string assemblyLocation)
@ -132,10 +134,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
}
/// <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>
/// <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)
{
if (assemblyLocation == null)
@ -170,7 +172,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
}
/// <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>
/// <param name="assemblyName">The <see cref="AssemblyName"/> of the assembly that should be searched for setup objects. </param>
public static void LoadSolverInformationFromAssembly(AssemblyName assemblyName)
@ -179,10 +181,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
}
/// <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>
/// <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)
{
if (assemblyName == null)
@ -202,7 +204,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
}
/// <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>
/// <param name="typeInAssembly">The type in the assembly which should be searched for setup objects.</param>
public static void LoadSolverInformationFromAssembly(Type typeInAssembly)
@ -211,10 +213,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
}
/// <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>
/// <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)
{
if (typeInAssembly == null)
@ -226,7 +228,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
}
/// <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>
/// <param name="assembly">The assembly which will be searched for setup objects.</param>
public static void LoadSolverInformationFromAssembly(Assembly assembly)
@ -235,10 +237,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
}
/// <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>
/// <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)
{
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)))
{
interfaceTypes.AddRange(type.GetInterfaces());
if (!interfaceTypes.Any(match => typeof(IIterativeSolverSetup).IsAssignableFrom(match)))
if (!interfaceTypes.Any(match => typeof(IIterativeSolverSetup<double>).IsAssignableFrom(match)))
{
continue;
}
// See if we actually want this type of iterative solver
IIterativeSolverSetup setup;
IIterativeSolverSetup<double> setup;
try
{
// 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?
setup = (IIterativeSolverSetup)Activator.CreateInstance(type);
setup = (IIterativeSolverSetup<double>)Activator.CreateInstance(type);
}
catch (ArgumentException)
{
@ -314,7 +316,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
var ratio = setup.SolutionSpeed / setup.Reliability;
if (!SolverSetups.ContainsKey(ratio))
{
SolverSetups.Add(ratio, new List<IIterativeSolverSetup>());
SolverSetups.Add(ratio, new List<IIterativeSolverSetup<double>>());
}
var list = SolverSetups[ratio];
@ -327,7 +329,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// <summary>
/// The collection of solvers that will be used to
/// </summary>
private readonly List<IIterativeSolver> _solvers = new List<IIterativeSolver>();
private readonly List<IIterativeSolver<double>> _solvers = new List<IIterativeSolver<double>>();
/// <summary>
/// The status of the calculation.
@ -337,7 +339,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// <summary>
/// The iterator that is used to control the iteration process.
/// </summary>
private IIterator _iterator;
private IIterator<double> _iterator;
/// <summary>
/// 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
/// solver if the user cancels the solve process.
/// </summary>
private IIterativeSolver _currentSolver;
private IIterativeSolver<double> _currentSolver;
/// <summary>
/// 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.
/// </summary>
/// <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;
}
/// <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>
/// <param name="iterator">The iterator.</param>
public void SetIterator(IIterator iterator)
public void SetIterator(IIterator<double> 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="vector">The solution vector, <c>b</c>.</param>
/// <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)
{
throw new ArgumentNullException();
}
Vector result = new DenseVector(matrix.RowCount);
Vector<double> result = new DenseVector(matrix.RowCount);
Solve(matrix, vector, 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="input">The solution vector, <c>b</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
// 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="input">The solution matrix, <c>B</c>.</param>
/// <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)
{
@ -592,7 +594,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution matrix, <c>B</c>.</param>
/// <param name="result">The result matrix, <c>X</c></param>
public void Solve(Matrix matrix, Matrix input, Matrix result)
public void Solve(Matrix<double> matrix, Matrix<double> input, Matrix<double> result)
{
if (matrix == null)
{

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

@ -31,9 +31,12 @@
namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
{
using System;
using Generic;
using Generic.Solvers;
using Generic.Solvers.Preconditioners;
using Generic.Solvers.Status;
using Preconditioners;
using Properties;
using Status;
/// <summary>
/// A Generalized Product Bi-Conjugate Gradient iterative matrix solver.
@ -62,7 +65,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// solver.
/// </para>
/// </remarks>
public sealed class GpBiCg : IIterativeSolver
public sealed class GpBiCg : IIterativeSolver<double>
{
/// <summary>
/// The status used if there is no status, i.e. the solver hasn't run yet and there is no
@ -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
/// pre-conditioner will be used.
/// </summary>
private IPreConditioner _preconditioner;
private IPreConditioner<double> _preconditioner;
/// <summary>
/// The iterative process controller.
/// </summary>
private IIterator _iterator;
private IIterator<double> _iterator;
/// <summary>
/// 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.
/// </summary>
/// <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.
/// </remarks>
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.
/// </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">
/// <item>It is possible to set the desired convergence limits.</item>
/// <item>
/// It is possible to check the reason for which the solver finished
/// the iterative procedure by calling the <see cref="IIterator.Status"/> property.
/// the iterative procedure by calling the <see cref="IIterator{T}.Status"/> property.
/// </item>
/// </list>
/// </para>
/// </remarks>
/// <param name="iterator">The <see cref="IIterator"/> that will be used to monitor the iterative process.</param>
public GpBiCg(IIterator iterator) : this(null, iterator)
/// <param name="iterator">The <see cref="IIterator{T}"/> that will be used to monitor the iterative process.</param>
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.
/// </summary>
/// <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.
/// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner"/> that will be used to precondition the matrix equation.</param>
public GpBiCg(IPreConditioner preconditioner) : this(preconditioner, null)
/// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation.</param>
public GpBiCg(IPreConditioner<double> preconditioner) : this(preconditioner, null)
{
}
@ -149,19 +152,19 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// </summary>
/// <remarks>
/// <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">
/// <item>It is possible to set the desired convergence limits.</item>
/// <item>
/// It is possible to check the reason for which the solver finished
/// the iterative procedure by calling the <see cref="IIterator.Status"/> property.
/// the iterative procedure by calling the <see cref="IIterator{T}.Status"/> property.
/// </item>
/// </list>
/// </para>
/// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner"/> 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>
public GpBiCg(IPreConditioner preconditioner, IIterator iterator)
/// <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{T}"/> that will be used to monitor the iterative process.</param>
public GpBiCg(IPreConditioner<double> preconditioner, IIterator<double> iterator)
{
_iterator = iterator;
_preconditioner = preconditioner;
@ -212,19 +215,19 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
}
/// <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>
/// <param name="preconditioner">The preconditioner.</param>
public void SetPreconditioner(IPreConditioner preconditioner)
public void SetPreconditioner(IPreConditioner<double> preconditioner)
{
_preconditioner = preconditioner;
}
/// <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>
/// <param name="iterator">The iterator.</param>
public void SetIterator(IIterator iterator)
public void SetIterator(IIterator<double> 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="vector">The solution vector, <c>b</c>.</param>
/// <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)
{
throw new ArgumentNullException();
}
Vector result = new DenseVector(matrix.RowCount);
Vector<double> result = new DenseVector(matrix.RowCount);
Solve(matrix, vector, 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="input">The solution vector, <c>b</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
// 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
// Take x_0 = 0
Vector xtemp = new DenseVector(input.Count);
Vector<double> xtemp = new DenseVector(input.Count);
// r_0 = b - Ax_0
// 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);
// Define the temporary scalars
@ -341,24 +344,24 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
// Define the temporary vectors
// rDash_0 = r_0
Vector rdash = new DenseVector(residuals);
Vector<double> rdash = new DenseVector(residuals);
// t_-1 = 0
Vector t = new DenseVector(residuals.Count);
Vector t0 = new DenseVector(residuals.Count);
Vector<double> t = new DenseVector(residuals.Count);
Vector<double> t0 = new DenseVector(residuals.Count);
// w_-1 = 0
Vector w = new DenseVector(residuals.Count);
Vector<double> w = new DenseVector(residuals.Count);
// Define the remaining temporary vectors
Vector c = new DenseVector(residuals.Count);
Vector p = new DenseVector(residuals.Count);
Vector s = new DenseVector(residuals.Count);
Vector u = new DenseVector(residuals.Count);
Vector y = new DenseVector(residuals.Count);
Vector z = new DenseVector(residuals.Count);
Vector temp = new DenseVector(residuals.Count);
Vector<double> c = new DenseVector(residuals.Count);
Vector<double> p = new DenseVector(residuals.Count);
Vector<double> s = new DenseVector(residuals.Count);
Vector<double> u = new DenseVector(residuals.Count);
Vector<double> y = new DenseVector(residuals.Count);
Vector<double> z = new DenseVector(residuals.Count);
Vector<double> temp = new DenseVector(residuals.Count);
// for (k = 0, 1, .... )
var iterationNumber = 0;
@ -499,11 +502,11 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// <summary>
/// Calculates the true residual of the matrix equation Ax = b according to: residual = b - Ax
/// </summary>
/// <param name="matrix">Instance of the <see cref="Matrix"/> A.</param>
/// <param name="residual">Residual values in <see cref="Vector"/>.</param>
/// <param name="x">Instance of the <see cref="Vector"/> x.</param>
/// <param name="b">Instance of the <see cref="Vector"/> b.</param>
private static void CalculateTrueResidual(Matrix matrix, Vector residual, Vector x, Vector b)
/// <param name="matrix">Instance of the <see cref="Matrix{T}"/> A.</param>
/// <param name="residual">Residual values in <see cref="Vector{T}"/>.</param>
/// <param name="x">Instance of the <see cref="Vector{T}"/> x.</param>
/// <param name="b">Instance of the <see cref="Vector{T}"/> b.</param>
private static void CalculateTrueResidual(Matrix<double> matrix, Vector<double> residual, Vector<double> x, Vector<double> b)
{
// -Ax = residual
matrix.Multiply(x, residual);
@ -517,11 +520,11 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// Determine if calculation should continue
/// </summary>
/// <param name="iterationNumber">Number of iterations passed</param>
/// <param name="result">Result <see cref="Vector"/>.</param>
/// <param name="source">Source <see cref="Vector"/>.</param>
/// <param name="residuals">Residual <see cref="Vector"/>.</param>
/// <param name="result">Result <see cref="Vector{T}"/>.</param>
/// <param name="source">Source <see cref="Vector{T}"/>.</param>
/// <param name="residuals">Residual <see cref="Vector{T}"/>.</param>
/// <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)
{
@ -562,7 +565,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution matrix, <c>B</c>.</param>
/// <returns>The result matrix, <c>X</c>.</returns>
public Matrix Solve(Matrix matrix, Matrix input)
public Matrix<double> Solve(Matrix<double> matrix, Matrix<double> input)
{
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="input">The solution matrix, <c>B</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)
{

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

@ -36,9 +36,12 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
using System.Linq;
using Distributions;
using Factorization;
using Generic;
using Generic.Solvers;
using Generic.Solvers.Preconditioners;
using Generic.Solvers.Status;
using Preconditioners;
using Properties;
using Status;
/// <summary>
/// A Multiple-Lanczos Bi-Conjugate Gradient stabilized iterative matrix solver.
@ -63,7 +66,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// solver.
/// </para>
/// </remarks>
public sealed class MlkBiCgStab : IIterativeSolver
public sealed class MlkBiCgStab : IIterativeSolver<double>
{
/// <summary>
/// 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
/// pre-conditioner will be used.
/// </summary>
private IPreConditioner _preconditioner;
private IPreConditioner<double> _preconditioner;
/// <summary>
/// The iterative process controller.
/// </summary>
private IIterator _iterator;
private IIterator<double> _iterator;
/// <summary>
/// The collection of starting vectors which are used as the basis for the Krylov sub-space.
/// </summary>
private IList<Vector> _startingVectors;
private IList<Vector<double>> _startingVectors;
/// <summary>
/// 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.
/// </summary>
/// <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.
/// </remarks>
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.
/// </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">
/// <item>It is possible to set the desired convergence limits.</item>
/// <item>
/// It is possible to check the reason for which the solver finished
/// the iterative procedure by calling the <see cref="IIterator.Status"/> property.
/// the iterative procedure by calling the <see cref="IIterator{T}.Status"/> property.
/// </item>
/// </list>
/// </para>
/// </remarks>
/// <param name="iterator">The <see cref="IIterator"/> that will be used to monitor the iterative process.</param>
public MlkBiCgStab(IIterator iterator) : this(null, iterator)
/// <param name="iterator">The <see cref="IIterator{T}"/> that will be used to monitor the iterative process.</param>
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.
/// </summary>
/// <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.
/// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner"/> that will be used to precondition the matrix equation.</param>
public MlkBiCgStab(IPreConditioner preconditioner) : this(preconditioner, null)
/// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation.</param>
public MlkBiCgStab(IPreConditioner<double> preconditioner) : this(preconditioner, null)
{
}
@ -153,19 +156,19 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// </summary>
/// <remarks>
/// <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">
/// <item>It is possible to set the desired convergence limits.</item>
/// <item>
/// It is possible to check the reason for which the solver finished
/// the iterative procedure by calling the <see cref="IIterator.Status"/> property.
/// the iterative procedure by calling the <see cref="IIterator{T}.Status"/> property.
/// </item>
/// </list>
/// </para>
/// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner"/> 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>
public MlkBiCgStab(IPreConditioner preconditioner, IIterator iterator)
/// <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{T}"/> that will be used to monitor the iterative process.</param>
public MlkBiCgStab(IPreConditioner<double> preconditioner, IIterator<double> iterator)
{
_iterator = iterator;
_preconditioner = preconditioner;
@ -207,19 +210,19 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
}
/// <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>
/// <param name="preconditioner">The preconditioner.</param>
public void SetPreconditioner(IPreConditioner preconditioner)
public void SetPreconditioner(IPreConditioner<double> preconditioner)
{
_preconditioner = preconditioner;
}
/// <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>
/// <param name="iterator">The iterator.</param>
public void SetIterator(IIterator iterator)
public void SetIterator(IIterator<double> 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
/// Krylov sub-space.
/// </summary>
public IList<Vector> StartingVectors
public IList<Vector<double>> StartingVectors
{
[DebuggerStepThrough]
get
@ -280,14 +283,14 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="vector">The solution vector, <c>b</c>.</param>
/// <returns>The result vector, <c>x</c>.</returns>
public Vector Solve(Matrix matrix, Vector vector)
public Vector<double> Solve(Matrix<double> matrix, Vector<double> vector)
{
if (vector == null)
{
throw new ArgumentNullException();
}
Vector result = new DenseVector(matrix.RowCount);
Vector<double> result = new DenseVector(matrix.RowCount);
Solve(matrix, vector, 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="input">The solution vector, <c>b</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
// 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
// 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
// Build a new set if:
@ -377,23 +380,23 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
// r_0 = b - Ax_0
// 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);
// Define the temporary scalars
var c = new double[k];
// Define the temporary vectors
Vector gtemp = new DenseVector(residuals.Count);
Vector<double> gtemp = new DenseVector(residuals.Count);
Vector u = new DenseVector(residuals.Count);
Vector utemp = new DenseVector(residuals.Count);
Vector temp = new DenseVector(residuals.Count);
Vector temp1 = new DenseVector(residuals.Count);
Vector<double> u = new DenseVector(residuals.Count);
Vector<double> utemp = new DenseVector(residuals.Count);
Vector<double> temp = new DenseVector(residuals.Count);
Vector<double> temp1 = new DenseVector(residuals.Count);
Vector zd = new DenseVector(residuals.Count);
Vector zg = new DenseVector(residuals.Count);
Vector zw = new DenseVector(residuals.Count);
Vector<double> zd = new DenseVector(residuals.Count);
Vector<double> zg = new DenseVector(residuals.Count);
Vector<double> zw = new DenseVector(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="maximumNumberOfStartingVectors"/>.
/// </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
// Get random values and then orthogonalize them with
@ -622,7 +625,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
// mean = 0 and sd = 1
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++)
{
var samples = distribution.Samples().Take(matrix.RowCount).ToArray();
@ -636,7 +639,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
var orthogonalMatrix = gs.Q;
// Now transfer this to vectors
var result = new List<Vector>();
var result = new List<Vector<double>>();
for (var i = 0; i < orthogonalMatrix.ColumnCount; 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="vectorSize">Size of each vector</param>
/// <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++)
{
result[i] = new DenseVector(vectorSize);
@ -668,11 +671,11 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// <summary>
/// Calculates the true residual of the matrix equation Ax = b according to: residual = b - Ax
/// </summary>
/// <param name="matrix">Source <see cref="Matrix"/>A.</param>
/// <param name="residual">Residual <see cref="Vector"/> data.</param>
/// <param name="x">x <see cref="Vector"/> data.</param>
/// <param name="b">b <see cref="Vector"/> data.</param>
private static void CalculateTrueResidual(Matrix matrix, Vector residual, Vector x, Vector b)
/// <param name="matrix">Source <see cref="Matrix{T}"/>A.</param>
/// <param name="residual">Residual <see cref="Vector{T}"/> data.</param>
/// <param name="x">x <see cref="Vector{T}"/> data.</param>
/// <param name="b">b <see cref="Vector{T}"/> data.</param>
private static void CalculateTrueResidual(Matrix<double> matrix, Vector<double> residual, Vector<double> x, Vector<double> b)
{
// -Ax = residual
matrix.Multiply(x, residual);
@ -686,11 +689,11 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// Determine if calculation should continue
/// </summary>
/// <param name="iterationNumber">Number of iterations passed</param>
/// <param name="result">Result <see cref="Vector"/>.</param>
/// <param name="source">Source <see cref="Vector"/>.</param>
/// <param name="residuals">Residual <see cref="Vector"/>.</param>
/// <param name="result">Result <see cref="Vector{T}"/>.</param>
/// <param name="source">Source <see cref="Vector{T}"/>.</param>
/// <param name="residuals">Residual <see cref="Vector{T}"/>.</param>
/// <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)
{
@ -714,7 +717,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution matrix, <c>B</c>.</param>
/// <returns>The result matrix, <c>X</c>.</returns>
public Matrix Solve(Matrix matrix, Matrix input)
public Matrix<double> Solve(Matrix<double> matrix, Matrix<double> input)
{
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="input">The solution matrix, <c>B</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)
{

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

@ -31,9 +31,12 @@
namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
{
using System;
using Generic;
using Generic.Solvers;
using Generic.Solvers.Preconditioners;
using Generic.Solvers.Status;
using Preconditioners;
using Properties;
using Status;
/// <summary>
/// A Transpose Free Quasi-Minimal Residual (TFQMR) iterative matrix solver.
@ -52,7 +55,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// solver.
/// </para>
/// </remarks>
public sealed class TFQMR : IIterativeSolver
public sealed class TFQMR : IIterativeSolver<double>
{
/// <summary>
/// The status used if there is no status, i.e. the solver hasn't run yet and there is no
@ -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
/// pre-conditioner will be used.
/// </summary>
private IPreConditioner _preconditioner;
private IPreConditioner<double> _preconditioner;
/// <summary>
/// The iterative process controller.
/// </summary>
private IIterator _iterator;
private IIterator<double> _iterator;
/// <summary>
/// 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.
/// </summary>
/// <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.
/// </remarks>
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.
/// </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">
/// <item>It is possible to set the desired convergence limits.</item>
/// <item>
/// It is possible to check the reason for which the solver finished
/// the iterative procedure by calling the <see cref="IIterator.Status"/> property.
/// the iterative procedure by calling the <see cref="IIterator{T}.Status"/> property.
/// </item>
/// </list>
/// </para>
/// </remarks>
/// <param name="iterator">The <see cref="IIterator"/> that will be used to monitor the iterative process.</param>
public TFQMR(IIterator iterator) : this(null, iterator)
/// <param name="iterator">The <see cref="IIterator{T}"/> that will be used to monitor the iterative process.</param>
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.
/// </summary>
/// <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.
/// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner"/> that will be used to precondition the matrix equation.</param>
public TFQMR(IPreConditioner preconditioner) : this(preconditioner, null)
/// <param name="preconditioner">The <see cref="IPreConditioner{T}"/> that will be used to precondition the matrix equation.</param>
public TFQMR(IPreConditioner<double> preconditioner) : this(preconditioner, null)
{
}
@ -127,38 +130,38 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// </summary>
/// <remarks>
/// <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">
/// <item>It is possible to set the desired convergence limits.</item>
/// <item>
/// It is possible to check the reason for which the solver finished
/// the iterative procedure by calling the <see cref="IIterator.Status"/> property.
/// the iterative procedure by calling the <see cref="IIterator{T}.Status"/> property.
/// </item>
/// </list>
/// </para>
/// </remarks>
/// <param name="preconditioner">The <see cref="IPreConditioner"/> 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>
public TFQMR(IPreConditioner preconditioner, IIterator iterator)
/// <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{T}"/> that will be used to monitor the iterative process.</param>
public TFQMR(IPreConditioner<double> preconditioner, IIterator<double> iterator)
{
_iterator = iterator;
_preconditioner = preconditioner;
}
/// <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>
/// <param name="preconditioner">The preconditioner.</param>
public void SetPreconditioner(IPreConditioner preconditioner)
public void SetPreconditioner(IPreConditioner<double> preconditioner)
{
_preconditioner = preconditioner;
}
/// <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>
/// <param name="iterator">The iterator.</param>
public void SetIterator(IIterator iterator)
public void SetIterator(IIterator<double> 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="vector">The solution vector, <c>b</c>.</param>
/// <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)
{
throw new ArgumentNullException();
}
Vector result = new DenseVector(matrix.RowCount);
Vector<double> result = new DenseVector(matrix.RowCount);
Solve(matrix, vector, 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="input">The solution vector, <c>b</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
// We're doing this at the start of the method to ensure
@ -410,11 +413,11 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// <summary>
/// Calculates the true residual of the matrix equation Ax = b according to: residual = b - Ax
/// </summary>
/// <param name="matrix">Instance of the <see cref="Matrix"/> A.</param>
/// <param name="residual">Residual values in <see cref="Vector"/>.</param>
/// <param name="x">Instance of the <see cref="Vector"/> x.</param>
/// <param name="b">Instance of the <see cref="Vector"/> b.</param>
private static void CalculateTrueResidual(Matrix matrix, Vector residual, Vector x, Vector b)
/// <param name="matrix">Instance of the <see cref="Matrix{T}"/> A.</param>
/// <param name="residual">Residual values in <see cref="Vector{T}"/>.</param>
/// <param name="x">Instance of the <see cref="Vector{T}"/> x.</param>
/// <param name="b">Instance of the <see cref="Vector{T}"/> b.</param>
private static void CalculateTrueResidual(Matrix<double> matrix, Vector<double> residual, Vector<double> x, Vector<double> b)
{
// -Ax = residual
matrix.Multiply(x, residual);
@ -428,11 +431,11 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// Determine if calculation should continue
/// </summary>
/// <param name="iterationNumber">Number of iterations passed</param>
/// <param name="result">Result <see cref="Vector"/>.</param>
/// <param name="source">Source <see cref="Vector"/>.</param>
/// <param name="residuals">Residual <see cref="Vector"/>.</param>
/// <param name="result">Result <see cref="Vector{T}"/>.</param>
/// <param name="source">Source <see cref="Vector{T}"/>.</param>
/// <param name="residuals">Residual <see cref="Vector{T}"/>.</param>
/// <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)
{
@ -466,7 +469,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative
/// <param name="matrix">The coefficient matrix, <c>A</c>.</param>
/// <param name="input">The solution matrix, <c>B</c>.</param>
/// <returns>The result matrix, <c>X</c>.</returns>
public Matrix Solve(Matrix matrix, Matrix input)
public Matrix<double> Solve(Matrix<double> matrix, Matrix<double> input)
{
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="input">The solution matrix, <c>B</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)
{

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

@ -33,14 +33,17 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
using System;
using System.Collections.Generic;
using System.Linq;
using Generic;
using Generic.Solvers;
using Generic.Solvers.Status;
using Generic.Solvers.StopCriterium;
using Properties;
using Status;
using StopCriterium;
/// <summary>
/// An iterator that is used to check if an iterative calculation should continue or stop.
/// </summary>
public sealed class Iterator : IIterator
public sealed class Iterator : IIterator<double>
{
/// <summary>
/// The default status for the iterator.
@ -48,10 +51,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
private static readonly ICalculationStatus DefaultStatus = new CalculationIndetermined();
/// <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>
/// <returns>A new <see cref="IIterator"/> object.</returns>
public static IIterator CreateDefault()
/// <returns>A new <see cref="IIterator{T}"/> object.</returns>
public static IIterator<double> CreateDefault()
{
var iterator = new Iterator();
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
/// to the child iterators.
/// </summary>
private readonly Dictionary<Type, IIterationStopCriterium> _stopCriterias = new Dictionary<Type, IIterationStopCriterium>();
private readonly Dictionary<Type, IIterationStopCriterium<double>> _stopCriterias = new Dictionary<Type, IIterationStopCriterium<double>>();
/// <summary>
/// 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.
/// </param>
/// <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
if (stopCriteria == null)
@ -108,7 +111,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
}
/// <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.
/// </summary>
/// <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
/// stored criterium.
/// </exception>
public void Add(IIterationStopCriterium stopCriterium)
public void Add(IIterationStopCriterium<double> stopCriterium)
{
if (stopCriterium == null)
{
@ -134,10 +137,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
}
/// <summary>
/// Removes the <see cref="IIterationStopCriterium"/> from the internal collection.
/// Removes the <see cref="IIterationStopCriterium{T}"/> from the internal collection.
/// </summary>
/// <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)
{
@ -154,11 +157,11 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
}
/// <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>
/// <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>
public bool Contains(IIterationStopCriterium stopCriterium)
/// <returns><c>true</c> if the <see cref="IIterator{T}"/> contains the stop criterium; otherwise <c>false</c>.</returns>
public bool Contains(IIterationStopCriterium<double> stopCriterium)
{
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.
/// </summary>
/// <remarks>Used for testing only.</remarks>
internal IEnumerator<IIterationStopCriterium> StoredStopCriteria
internal IEnumerator<IIterationStopCriterium<double>> StoredStopCriteria
{
get
{
@ -201,7 +204,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
/// <summary>
/// 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>
/// <param name="iterationNumber">The number of iterations that have passed so far.</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
/// calculation has moved forwards at least one step.
/// </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)
{
@ -284,7 +287,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
}
/// <summary>
/// Resets the <see cref="IIterator"/> to the pre-calculation state.
/// Resets the <see cref="IIterator{T}"/> to the pre-calculation state.
/// </summary>
public void ResetToPrecalculationState()
{
@ -305,9 +308,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
/// Creates a deep clone of the current iterator.
/// </summary>
/// <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);
}

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

@ -31,13 +31,15 @@
namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
{
using System;
using Generic;
using Generic.Solvers.Preconditioners;
using Properties;
/// <summary>
/// A diagonal preconditioner. The preconditioner uses the inverse
/// of the matrix diagonal as preconditioning values.
/// </summary>
public sealed class Diagonal : IPreConditioner
public sealed class Diagonal : IPreConditioner<double>
{
/// <summary>
/// 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.
/// </summary>
/// <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="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)
{
@ -90,7 +92,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
/// </summary>
/// <param name="rhs">The right hand side vector.</param>
/// <returns>The left hand side vector.</returns>
public Vector Approximate(Vector rhs)
public Vector<double> Approximate(Vector<double> rhs)
{
if (rhs == null)
{
@ -107,7 +109,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "rhs");
}
Vector result = new DenseVector(rhs.Count);
Vector<double> result = new DenseVector(rhs.Count);
Approximate(rhs, result);
return result;
}
@ -117,7 +119,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
/// </summary>
/// <param name="rhs">The right hand side vector.</param>
/// <param name="lhs">The left hand side vector. Also known as the result vector.</param>
public void Approximate(Vector rhs, Vector lhs)
public void Approximate(Vector<double> rhs, Vector<double> lhs)
{
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.Collections.Generic;
using Generic;
using Generic.Solvers.Preconditioners;
using Properties;
/// <summary>
@ -51,7 +53,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
/// pp. 20 - 28 <br/>
/// Algorithm is described in Section 2, page 22
/// </remarks>
public sealed class Ilutp : IPreConditioner
public sealed class Ilutp : IPreConditioner<double>
{
/// <summary>
/// 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.
/// </remarks>
/// <returns>A new matrix containing the upper triagonal elements.</returns>
internal Matrix UpperTriangle()
internal Matrix<double> UpperTriangle()
{
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.
/// </remarks>
/// <returns>A new matrix containing the lower triagonal elements.</returns>
internal Matrix LowerTriangle()
internal Matrix<double> LowerTriangle()
{
return _lower.Clone();
}
@ -295,13 +297,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
/// Initializes the preconditioner and loads the internal data structures.
/// </summary>
/// <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
/// as a sparse matrix. Therefore it is not recommended to pass a dense matrix.
/// </param>
/// <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>
public void Initialize(Matrix matrix)
public void Initialize(Matrix<double> matrix)
{
if (matrix == null)
{
@ -373,8 +375,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
_pivots[i] = i;
}
Vector workVector = new DenseVector(sparseMatrix.RowCount);
Vector rowVector = new DenseVector(sparseMatrix.ColumnCount);
Vector<double> workVector = new DenseVector(sparseMatrix.RowCount);
Vector<double> rowVector = new DenseVector(sparseMatrix.ColumnCount);
var indexSorting = new int[sparseMatrix.RowCount];
// spaceLeft = lfilNnz * nnz(A)
@ -529,8 +531,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
/// <summary>
/// Pivot elements in the <paramref name="row"/> according to internal pivot array
/// </summary>
/// <param name="row">Row <see cref="Vector"/> to pivot in</param>
private void PivotRow(Vector row)
/// <param name="row">Row <see cref="Vector{T}"/> to pivot in</param>
private void PivotRow(Vector<double> row)
{
var knownPivots = new Dictionary<int, int>();
@ -577,12 +579,12 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
}
/// <summary>
/// Swap columns in the <see cref="Matrix"/>
/// Swap columns in the <see cref="Matrix{T}"/>
/// </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="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++)
{
@ -598,8 +600,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
/// <param name="lowerBound">Start sort form</param>
/// <param name="upperBound">Sort till upper bound</param>
/// <param name="sortedIndices">Array with sorted vector indicies</param>
/// <param name="values">Source <see cref="Vector"/></param>
private static void FindLargestItems(int lowerBound, int upperBound, int[] sortedIndices, Vector values)
/// <param name="values">Source <see cref="Vector{T}"/></param>
private static void FindLargestItems(int lowerBound, int upperBound, int[] sortedIndices, Vector<double> values)
{
// Copy the indices for the values into the array
for (var i = 0; i < upperBound + 1 - lowerBound; i++)
@ -624,7 +626,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
/// </summary>
/// <param name="rhs">The right hand side vector.</param>
/// <returns>The left hand side vector.</returns>
public Vector Approximate(Vector rhs)
public Vector<double> Approximate(Vector<double> rhs)
{
if (rhs == null)
{
@ -641,7 +643,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "rhs");
}
Vector result = new DenseVector(rhs.Count);
Vector<double> result = new DenseVector(rhs.Count);
Approximate(rhs, result);
return result;
}
@ -651,7 +653,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
/// </summary>
/// <param name="rhs">The right hand side vector.</param>
/// <param name="lhs">The left hand side vector. Also known as the result vector.</param>
public void Approximate(Vector rhs, Vector lhs)
public void Approximate(Vector<double> rhs, Vector<double> lhs)
{
if (rhs == null)
{
@ -676,7 +678,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
// Solve equation here
// Pivot(vector, result);
// 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++)
{
_lower.Row(i, rowValues);
@ -712,11 +714,11 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
}
/// <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>
/// <param name="vector">Source <see cref="Vector"/>.</param>
/// <param name="result">Result <see cref="Vector"/> after pivoting.</param>
private void Pivot(Vector vector, Vector result)
/// <param name="vector">Source <see cref="Vector{T}"/>.</param>
/// <param name="result">Result <see cref="Vector{T}"/> after pivoting.</param>
private void Pivot(Vector<double> vector, Vector<double> result)
{
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
{
using Generic;
/// <summary>
/// An element sort algorithm for the <see cref="Ilutp"/> class.
/// </summary>
@ -46,8 +48,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
/// <param name="lowerBound">The starting 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="values">The <see cref="Vector"/> that contains the values that need to be sorted.</param>
public static void SortDoubleIndicesDecreasing(int lowerBound, int upperBound, int[] sortedIndices, Vector values)
/// <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<double> values)
{
// Move all the indices that we're interested in to the beginning of the
// 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="upperBound">The stopping index.</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>
private static void HeapSortDoublesIndices(int lowerBound, int upperBound, int[] sortedIndices, Vector values)
/// <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<double> values)
{
var start = ((upperBound - lowerBound + 1) / 2) - 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="count">Lenght of <paramref name="values"/></param>
/// <param name="sortedIndices">Indicies of <paramref name="values"/></param>
/// <param name="values">Target <see cref="Vector"/></param>
private static void BuildDoubleIndexHeap(int start, int count, int[] sortedIndices, Vector values)
/// <param name="values">Target <see cref="Vector{T}"/></param>
private static void BuildDoubleIndexHeap(int start, int count, int[] sortedIndices, Vector<double> values)
{
while (start >= 0)
{
@ -108,10 +110,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
/// Sift double indicies
/// </summary>
/// <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="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;
int child;

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

@ -31,6 +31,8 @@
namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
{
using System;
using Generic;
using Generic.Solvers.Preconditioners;
using Properties;
/// <summary>
@ -42,7 +44,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
/// Yousef Saad <br/>
/// Algorithm is described in Chapter 10, section 10.3.2, page 275 <br/>
/// </remarks>
public sealed class IncompleteLU : IPreConditioner
public sealed class IncompleteLU : IPreConditioner<double>
{
/// <summary>
/// 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.
/// </summary>
/// <returns>A new matrix containing the upper triagonal elements.</returns>
internal Matrix UpperTriangle()
internal Matrix<double> UpperTriangle()
{
var result = new SparseMatrix(_decompositionLU.RowCount);
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.
/// </summary>
/// <returns>A new matrix containing the lower triagonal elements.</returns>
internal Matrix LowerTriangle()
internal Matrix<double> LowerTriangle()
{
var result = new SparseMatrix(_decompositionLU.RowCount);
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>
/// <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>
public void Initialize(Matrix matrix)
public void Initialize(Matrix<double> matrix)
{
if (matrix == null)
{
@ -161,7 +163,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
/// </summary>
/// <param name="rhs">The right hand side vector.</param>
/// <returns>The left hand side vector.</returns>
public Vector Approximate(Vector rhs)
public Vector<double> Approximate(Vector<double> rhs)
{
if (rhs == null)
{
@ -178,7 +180,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "rhs");
}
Vector result = new DenseVector(rhs.Count);
Vector<double> result = new DenseVector(rhs.Count);
Approximate(rhs, result);
return result;
}
@ -188,7 +190,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
/// </summary>
/// <param name="rhs">The right hand side vector.</param>
/// <param name="lhs">The left hand side vector. Also known as the result vector.</param>
public void Approximate(Vector rhs, Vector lhs)
public void Approximate(Vector<double> rhs, Vector<double> lhs)
{
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)
// }
// 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++)
{
// Clear the rowValues

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

@ -31,14 +31,17 @@
namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
{
using System;
using Generic;
using Generic.Solvers;
using Generic.Solvers.Preconditioners;
using Properties;
/// <summary>
/// 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.
/// </summary>
internal sealed class UnitPreconditioner : IPreConditioner
internal sealed class UnitPreconditioner : IPreConditioner<double>
{
/// <summary>
/// The coefficient matrix on which this preconditioner operates.
@ -54,7 +57,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
/// </param>
/// <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>
public void Initialize(Matrix matrix)
public void Initialize(Matrix<double> matrix)
{
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.
/// </para>
/// </exception>
public void Approximate(Vector rhs, Vector lhs)
public void Approximate(Vector<double> rhs, Vector<double> lhs)
{
if (rhs == null)
{
@ -116,7 +119,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
/// <exception cref="ArgumentException">
/// If the size of <paramref name="rhs"/> is different the number of rows of the coefficient matrix.
/// </exception>
public Vector Approximate(Vector rhs)
public Vector<double> Approximate(Vector<double> rhs)
{
if (rhs == null)
{
@ -128,7 +131,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
throw new ArgumentException(Resources.ArgumentMatrixDimensions);
}
Vector result = new DenseVector(rhs.Count);
Vector<double> result = new DenseVector(rhs.Count);
Approximate(rhs, 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.Diagnostics;
using Status;
using Generic;
using Generic.Solvers.Status;
using Generic.Solvers.StopCriterium;
/// <summary>
/// Monitors an iterative calculation for signs of divergence.
/// </summary>
public sealed class DivergenceStopCriterium : IIterationStopCriterium
public sealed class DivergenceStopCriterium : IIterationStopCriterium<double>
{
/// <summary>
/// Default value for the maximum relative increase that the
@ -205,7 +207,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium
/// <summary>
/// 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>
/// <param name="iterationNumber">The number of iterations that have passed so far.</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
/// calculation has moved forwards at least one step.
/// </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)
{
@ -345,7 +347,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium
}
/// <summary>
/// Resets the <see cref="IIterationStopCriterium"/> to the pre-calculation state.
/// Resets the <see cref="IIterationStopCriterium{T}"/> to the pre-calculation state.
/// </summary>
public void ResetToPrecalculationState()
{
@ -356,9 +358,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium
/// <summary>
/// Gets the <see cref="StopLevel"/> which indicates what sort of stop criterium this
/// <see cref="IIterationStopCriterium"/> monitors.
/// <see cref="IIterationStopCriterium{T}"/> monitors.
/// </summary>
/// <value>Returns <see cref="StopCriterium.StopLevel.Divergence"/>.</value>
/// <value>Returns <see cref="Generic.Solvers.StopCriterium.StopLevel.Divergence"/>.</value>
public StopLevel StopLevel
{
[DebuggerStepThrough]
@ -372,7 +374,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium
/// Clones the current <see cref="DivergenceStopCriterium"/> and its settings.
/// </summary>
/// <returns>A new instance of the <see cref="DivergenceStopCriterium"/> class.</returns>
public IIterationStopCriterium Clone()
public IIterationStopCriterium<double> Clone()
{
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.Diagnostics;
using Generic;
using Generic.Solvers.Status;
using Generic.Solvers.StopCriterium;
using Properties;
using Status;
/// <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>
public sealed class FailureStopCriterium : IIterationStopCriterium
public sealed class FailureStopCriterium : IIterationStopCriterium<double>
{
/// <summary>
/// Defines the default last iteration number. Set to -1 because iterations normally
@ -63,7 +65,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium
/// <summary>
/// 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>
/// <param name="iterationNumber">The number of iterations that have passed so far.</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
/// calculation has moved forwards at least one step.
/// </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)
{
@ -154,7 +156,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium
}
/// <summary>
/// Resets the <see cref="IIterationStopCriterium"/> to the pre-calculation state.
/// Resets the <see cref="IIterationStopCriterium{T}"/> to the pre-calculation state.
/// </summary>
public void ResetToPrecalculationState()
{
@ -164,7 +166,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium
/// <summary>
/// Gets the <see cref="StopLevel"/>which indicates what sort of stop criterium this
/// <see cref="IIterationStopCriterium"/> monitors.
/// <see cref="IIterationStopCriterium{T}"/> monitors.
/// </summary>
/// <value>Returns <see cref="CalculationFailure"/>.</value>
public StopLevel StopLevel
@ -180,7 +182,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium
/// Clones the current <see cref="FailureStopCriterium"/> and its settings.
/// </summary>
/// <returns>A new instance of the <see cref="FailureStopCriterium"/> class.</returns>
public IIterationStopCriterium Clone()
public IIterationStopCriterium<double> Clone()
{
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.Diagnostics;
using Status;
using Generic;
using Generic.Solvers.Status;
using Generic.Solvers.StopCriterium;
/// <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.
/// </summary>
public sealed class IterationCountStopCriterium : IIterationStopCriterium
public sealed class IterationCountStopCriterium : IIterationStopCriterium<double>
{
/// <summary>
/// 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
/// calculation has moved forwards at least one step.
/// </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)
{
@ -206,7 +208,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium
/// Clones the current <see cref="IterationCountStopCriterium"/> and its settings.
/// </summary>
/// <returns>A new instance of the <see cref="IterationCountStopCriterium"/> class.</returns>
public IIterationStopCriterium Clone()
public IIterationStopCriterium<double> Clone()
{
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.Diagnostics;
using Generic;
using Generic.Solvers.Status;
using Generic.Solvers.StopCriterium;
using Properties;
using Status;
/// <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>
public sealed class ResidualStopCriterium : IIterationStopCriterium
public sealed class ResidualStopCriterium : IIterationStopCriterium<double>
{
/// <summary>
/// The default value for the maximum value of the residual.
@ -210,7 +212,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium
/// <summary>
/// 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>
/// <param name="iterationNumber">The number of iterations that have passed so far.</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
/// calculation has moved forwards at least one step.
/// </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)
{
@ -361,7 +363,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium
}
/// <summary>
/// Resets the <see cref="IIterationStopCriterium"/> to the pre-calculation state.
/// Resets the <see cref="IIterationStopCriterium{T}"/> to the pre-calculation state.
/// </summary>
public void ResetToPrecalculationState()
{
@ -372,7 +374,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium
/// <summary>
/// Gets the <see cref="StopLevel"/> which indicates what sort of stop criterium this
/// <see cref="IIterationStopCriterium"/> monitors.
/// <see cref="IIterationStopCriterium{T}"/> monitors.
/// </summary>
/// <value>Returns <see cref="StopLevel"/>.</value>
public StopLevel StopLevel
@ -388,7 +390,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium
/// Clones the current <see cref="ResidualStopCriterium"/> and its settings.
/// </summary>
/// <returns>A new instance of the <see cref="ResidualStopCriterium"/> class.</returns>
public IIterationStopCriterium Clone()
public IIterationStopCriterium<double> Clone()
{
return new ResidualStopCriterium(_maximum, _minimumIterationsBelowMaximum);
}

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

@ -31,14 +31,16 @@
namespace MathNet.Numerics.LinearAlgebra.Double
{
using System;
using System.Text;
using Distributions;
using Generic;
using Properties;
using Threading;
/// <summary>
/// A Matrix class with sparse storage. The underlying storage scheme is 3-array CSR Format.
/// </summary>
public class SparseMatrix : Matrix
public class SparseMatrix : Matrix<double>
{
/// <summary>
/// Object for use in "lock"
@ -192,7 +194,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>
/// A <c>SparseMatrix</c> with the given dimensions.
/// </returns>
public override Matrix CreateMatrix(int numberOfRows, int numberOfColumns)
public override Matrix<double> CreateMatrix(int numberOfRows, int numberOfColumns)
{
return new SparseMatrix(numberOfRows, numberOfColumns);
}
@ -204,7 +206,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>
/// A <see cref="SparseVector"/> with the given dimension.
/// </returns>
public override Vector CreateVector(int size)
public override Vector<double> CreateVector(int 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.
/// </summary>
/// <returns>The lower triangle of this matrix.</returns>
public override Matrix LowerTriangle()
public override Matrix<double> LowerTriangle()
{
var result = CreateMatrix(RowCount, ColumnCount);
LowerTriangleImpl(result);
@ -226,7 +228,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <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 override void LowerTriangle(Matrix result)
public override void LowerTriangle(Matrix<double> result)
{
if (result == null)
{
@ -255,7 +257,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// Puts the lower triangle of this matrix into the result matrix.
/// </summary>
/// <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++)
{
@ -275,7 +277,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// Returns a new matrix containing the upper triangle of this matrix.
/// </summary>
/// <returns>The upper triangle of this matrix.</returns>
public override Matrix UpperTriangle()
public override Matrix<double> UpperTriangle()
{
var result = CreateMatrix(RowCount, ColumnCount);
UpperTriangleImpl(result);
@ -288,7 +290,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <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 override void UpperTriangle(Matrix result)
public override void UpperTriangle(Matrix<double> result)
{
if (result == null)
{
@ -317,7 +319,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// Puts the upper triangle of this matrix into the result matrix.
/// </summary>
/// <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++)
{
@ -349,7 +351,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <item><c>(rowIndex + rowLength) &gt;= Rows</c></item></list></exception>
/// <exception cref="ArgumentException">If <paramref name="rowLength"/> or <paramref name="columnLength"/>
/// 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)
{
@ -410,7 +412,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// does not contain the diagonal elements of this matrix.
/// </summary>
/// <returns>The lower triangle of this matrix.</returns>
public override Matrix StrictlyLowerTriangle()
public override Matrix<double> StrictlyLowerTriangle()
{
var result = CreateMatrix(RowCount, ColumnCount);
StrictlyLowerTriangleImpl(result);
@ -423,7 +425,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <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 override void StrictlyLowerTriangle(Matrix result)
public override void StrictlyLowerTriangle(Matrix<double> result)
{
if (result == null)
{
@ -452,7 +454,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// Puts the strictly lower triangle of this matrix into the result matrix.
/// </summary>
/// <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++)
{
@ -473,7 +475,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// does not contain the diagonal elements of this matrix.
/// </summary>
/// <returns>The upper triangle of this matrix.</returns>
public override Matrix StrictlyUpperTriangle()
public override Matrix<double> StrictlyUpperTriangle()
{
var result = CreateMatrix(RowCount, ColumnCount);
StrictlyUpperTriangleImpl(result);
@ -486,7 +488,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <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 override void StrictlyUpperTriangle(Matrix result)
public override void StrictlyUpperTriangle(Matrix<double> result)
{
if (result == null)
{
@ -515,7 +517,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// Puts the strictly upper triangle of this matrix into the result matrix.
/// </summary>
/// <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++)
{
@ -762,7 +764,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentException">
/// If this and the target matrix do not have the same dimensions..
/// </exception>
public override void CopyTo(Matrix target)
public override void CopyTo(Matrix<double> target)
{
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>
/// Returns a hash code for this instance.
/// </summary>
@ -860,7 +821,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// Returns the transpose of this matrix.
/// </summary>
/// <returns>The transpose of this matrix.</returns>
public override Matrix Transpose()
public override Matrix<double> Transpose()
{
var ret = new SparseMatrix(ColumnCount, RowCount)
{
@ -957,13 +918,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double
}
/// <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>
/// <param name="rowIndex">The row to copy elements from.</param>
/// <param name="columnIndex">The column to start copying from.</param>
/// <param name="length">The number of elements to copy.</param>
/// <param name="result">The <see cref="Vector"/> to copy the column into.</param>
/// <exception cref="ArgumentNullException">If the result <see cref="Vector"/> is <see langword="null" />.</exception>
/// <param name="result">The <see cref="Vector{T}"/> to copy the column into.</param>
/// <exception cref="ArgumentNullException">If the result <see cref="Vector{T}"/> is <see langword="null" />.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="rowIndex"/> is negative,
/// or greater than or equal to the number of columns.</exception>
/// <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>
/// <exception cref="ArgumentException">If <paramref name="length"/> is not positive.</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)
{
@ -1032,7 +993,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentNullException">If lower 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>
public override void DiagonalStack(Matrix lower, Matrix result)
public override void DiagonalStack(Matrix<double> lower, Matrix<double> result)
{
var lowerSparseMatrix = lower 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>
/// <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>
public override void Add(Matrix other)
public override void Add(Matrix<double> other)
{
if (ReferenceEquals(this, other))
{
@ -1150,7 +1111,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="other">The matrix to subtract.</param>
/// <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>
public override void Subtract(Matrix other)
public override void Subtract(Matrix<double> other)
{
// We are substracting Matrix form itself
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="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>
public override void Multiply(Matrix other, Matrix result)
public override void Multiply(Matrix<double> other, Matrix<double> result)
{
var otherSparseMatrix = other 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="ArgumentNullException">If the other matrix is <see langword="null" />.</exception>
/// <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;
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="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>
public override void TransposeAndMultiply(Matrix other, Matrix result)
public override void TransposeAndMultiply(Matrix<double> other, Matrix<double> result)
{
var otherSparse = other 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="ArgumentNullException">If the other matrix is <see langword="null" />.</exception>
/// <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;
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="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>
public override void PointwiseMultiply(Matrix other, Matrix result)
public override void PointwiseMultiply(Matrix<double> other, Matrix<double> result)
{
if (other == null)
{
@ -1495,7 +1456,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// </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 Random(int numberOfRows, int numberOfColumns, IContinuousDistribution distribution)
public override Matrix<double> Random(int numberOfRows, int numberOfColumns, IContinuousDistribution distribution)
{
if (numberOfRows < 1)
{
@ -1534,7 +1495,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// </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 Random(int numberOfRows, int numberOfColumns, IDiscreteDistribution distribution)
public override Matrix<double> Random(int numberOfRows, int numberOfColumns, IDiscreteDistribution distribution)
{
if (numberOfRows < 1)
{
@ -1592,5 +1553,165 @@ namespace MathNet.Numerics.LinearAlgebra.Double
return m;
}
#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.Globalization;
using Distributions;
using Generic;
using NumberTheory;
using Properties;
using Threading;
@ -37,7 +38,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <summary>
/// A vector with sparse storage.
/// </summary>
public class SparseVector : Vector
public class SparseVector : Vector<double>
{
/// <summary>
/// Lock object for the indexer.
@ -122,7 +123,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="other">
/// The vector to create the new vector from.
/// </param>
public SparseVector(Vector other) : this(other.Count)
public SparseVector(Vector<double> other) : this(other.Count)
{
var vector = other as SparseVector;
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).
/// </summary>
/// <returns>This vector as a column matrix.</returns>
public override Matrix ToColumnMatrix()
public override Matrix<double> ToColumnMatrix()
{
var matrix = new SparseMatrix(Count, 1);
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).
/// </summary>
/// <returns>This vector as a row matrix.</returns>
public override Matrix ToRowMatrix()
public override Matrix<double> ToRowMatrix()
{
var matrix = new SparseMatrix(1, Count);
for (var i = 0; i < NonZerosCount; i++)
@ -263,7 +264,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>
/// A matrix with the given dimensions.
/// </returns>
public override Matrix CreateMatrix(int rows, int columns)
public override Matrix<double> CreateMatrix(int rows, int columns)
{
return new SparseMatrix(rows, columns);
}
@ -278,7 +279,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>
/// The new <c>Vector</c>.
/// </returns>
public override Vector CreateVector(int size)
public override Vector<double> CreateVector(int size)
{
return new SparseVector(size);
}
@ -303,7 +304,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentException">
/// If <paramref name="target"/> is not the same size as this vector.
/// </exception>
public override void CopyTo(Vector target)
public override void CopyTo(Vector<double> target)
{
if (target == null)
{
@ -347,7 +348,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// </summary>
/// <param name="scalar">The scalar to add.</param>
/// <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)
{
@ -370,7 +371,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <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="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)
{
@ -392,7 +393,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <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="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)
{
@ -494,7 +495,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <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="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)
{
@ -545,7 +546,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="rightSide">The vector to get the values from.</param>
/// <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>
public static Vector operator +(SparseVector rightSide)
public static Vector<double> operator +(SparseVector rightSide)
{
if (rightSide == null)
{
@ -563,7 +564,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <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="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)
{
@ -588,7 +589,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// </summary>
/// <param name="scalar">The scalar to subtract.</param>
/// <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)
{
@ -611,7 +612,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <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="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)
{
@ -633,7 +634,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <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="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)
{
@ -666,7 +667,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <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="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)
{
@ -716,7 +717,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="rightSide">The vector to get the values from.</param>
/// <returns>A vector containing the negated values as <paramref name="rightSide"/>.</returns>
/// <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)
{
@ -734,7 +735,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <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="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)
{
@ -759,7 +760,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// </summary>
/// <returns>The negated vector.</returns>
/// <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)
{
@ -785,7 +786,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// </summary>
/// <param name="scalar">The scalar to multiply.</param>
/// <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)
{
@ -813,7 +814,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>The result of the addition.</returns>
/// <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>
public override double DotProduct(Vector other)
public override double DotProduct(Vector<double> other)
{
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>
/// </list></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)
{
@ -1090,7 +1091,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <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="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)
{
@ -1123,7 +1124,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <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 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)
{
@ -1160,7 +1161,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// to the specified random distribution.
/// </returns>
/// <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)
{
@ -1186,7 +1187,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// to the specified random distribution.
/// </returns>
/// <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)
{
@ -1210,7 +1211,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// Matrix M[i,j] = this[i] * v[j].
/// </returns>
/// <seealso cref="OuterProduct"/>
public Matrix TensorMultiply(SparseVector v)
public Matrix<double> TensorMultiply(SparseVector v)
{
return OuterProduct(this, v);
}
@ -1249,6 +1250,33 @@ namespace MathNet.Numerics.LinearAlgebra.Double
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
#region Parse Functions
@ -1515,28 +1543,65 @@ namespace MathNet.Numerics.LinearAlgebra.Double
#region System.Object override
/// <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>
/// <param name="obj">Object to compare</param>
/// <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>
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.
if (ReferenceEquals(this, sparseVector))
if (ReferenceEquals(this, other))
{
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;
}
@ -1553,28 +1618,70 @@ namespace MathNet.Numerics.LinearAlgebra.Double
return true;
}
#region Simple arithmetic of type T
/// <summary>
/// Returns a hash code for this instance.
/// Add two values T+T
/// </summary>
/// <returns>
/// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.
/// </returns>
public override int GetHashCode()
/// <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)
{
var hashNum = Math.Min(NonZerosCount, 20);
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 val1 + val2;
}
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
}
}

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

@ -28,9 +28,11 @@
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
namespace MathNet.Numerics.LinearAlgebra.Generic.Factorization
{
using System;
using System.Numerics;
using Generic;
/// <summary>
/// <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
/// or positive definite, the constructor will throw an exception.
/// </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>
/// Internal method which routes the call to perform the Cholesky factorization to the appropriate class.
/// </summary>
/// <param name="matrix">The matrix to factor.</param>
/// <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 (dense != null)
if (typeof(T) == typeof(double))
{
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>
/// Gets or sets the lower triangular form of the Cholesky matrix
/// </summary>
protected Matrix CholeskyFactor
protected Matrix<T> CholeskyFactor
{
get;
set;
@ -71,7 +80,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <summary>
/// Gets the lower triangular form of the Cholesky matrix.
/// </summary>
public virtual Matrix Factor
public virtual Matrix<T> Factor
{
get
{
@ -82,14 +91,14 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <summary>
/// Gets the determinant of the matrix for which the Cholesky matrix was computed.
/// </summary>
public virtual double Determinant
public virtual T Determinant
{
get
{
var det = 1.0;
var det = OneValueT;
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;
@ -106,7 +115,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
var det = 0.0;
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;
@ -116,9 +125,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <summary>
/// Solves a system of linear equations, <b>AX = B</b>, with A Cholesky factorized.
/// </summary>
/// <param name="input">The right hand side <see cref="Matrix"/>, <b>B</b>.</param>
/// <returns>The left hand side <see cref="Matrix"/>, <b>X</b>.</returns>
public virtual Matrix Solve(Matrix input)
/// <param name="input">The right hand side <see cref="Matrix{T}"/>, <b>B</b>.</param>
/// <returns>The left hand side <see cref="Matrix{T}"/>, <b>X</b>.</returns>
public virtual Matrix<T> Solve(Matrix<T> input)
{
// Check for proper arguments.
if (input == null)
@ -134,16 +143,16 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <summary>
/// Solves a system of linear equations, <b>AX = B</b>, with A Cholesky factorized.
/// </summary>
/// <param name="input">The right hand side <see cref="Matrix"/>, <b>B</b>.</param>
/// <param name="result">The left hand side <see cref="Matrix"/>, <b>X</b>.</param>
public abstract void Solve(Matrix input, Matrix result);
/// <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{T}"/>, <b>X</b>.</param>
public abstract void Solve(Matrix<T> input, Matrix<T> result);
/// <summary>
/// Solves a system of linear equations, <b>Ax = b</b>, with A Cholesky factorized.
/// </summary>
/// <param name="input">The right hand side vector, <b>b</b>.</param>
/// <returns>The left hand side <see cref="Vector"/>, <b>x</b>.</returns>
public virtual Vector Solve(Vector input)
/// <returns>The left hand side <see cref="Vector{T}"/>, <b>x</b>.</returns>
public virtual Vector<T> Solve(Vector<T> input)
{
// Check for proper arguments.
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.
/// </summary>
/// <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>
public abstract void Solve(Vector input, Vector result);
/// <param name="result">The left hand side <see cref="Matrix{T}"/>, <b>x</b>.</param>
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.
// </copyright>
namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
namespace MathNet.Numerics.LinearAlgebra.Generic.Factorization
{
using System;
using System.Numerics;
using Generic;
/// <summary>
/// <para>A class which encapsulates the functionality of an LU factorization.</para>
@ -38,12 +40,14 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <remarks>
/// The computation of the LU factorization is done at construction time.
/// </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>
/// Gets or sets both the L and U factors in the same matrix.
/// </summary>
protected Matrix Factors
protected Matrix<T> Factors
{
get;
set;
@ -63,28 +67,33 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// </summary>
/// <param name="matrix">The matrix to factor.</param>
/// <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 (dense != null)
if (typeof(T) == typeof(double))
{
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>
/// Gets the lower triangular factor.
/// </summary>
public virtual Matrix L
public virtual Matrix<T> L
{
get
{
var result = Factors.LowerTriangle();
for (var i = 0; i < result.RowCount; i++)
{
result.At(i, i, 1);
result.At(i, i, OneValueT);
}
return result;
@ -94,7 +103,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <summary>
/// Gets the upper triangular factor.
/// </summary>
public virtual Matrix U
public virtual Matrix<T> U
{
get
{
@ -116,20 +125,20 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <summary>
/// Gets the determinant of the matrix for which the LU factorization was computed.
/// </summary>
public virtual double Determinant
public virtual T Determinant
{
get
{
var det = 1.0;
var det = OneValueT;
for (var j = 0; j < Factors.RowCount; j++)
{
if (Pivots[j] != j)
{
det = -det * Factors.At(j, j);
det = MultiplyT(MinusOneValueT, MultiplyT(det, Factors.At(j, j)));
}
else
{
det *= Factors.At(j, j);
det = MultiplyT(det, Factors.At(j, j));
}
}
@ -140,9 +149,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <summary>
/// Solves a system of linear equations, <b>AX = B</b>, with A LU factorized.
/// </summary>
/// <param name="input">The right hand side <see cref="Matrix"/>, <b>B</b>.</param>
/// <returns>The left hand side <see cref="Matrix"/>, <b>X</b>.</returns>
public virtual Matrix Solve(Matrix input)
/// <param name="input">The right hand side <see cref="Matrix{T}"/>, <b>B</b>.</param>
/// <returns>The left hand side <see cref="Matrix{T}"/>, <b>X</b>.</returns>
public virtual Matrix<T> Solve(Matrix<T> input)
{
// Check for proper arguments.
if (input == null)
@ -158,16 +167,16 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <summary>
/// Solves a system of linear equations, <b>AX = B</b>, with A LU factorized.
/// </summary>
/// <param name="input">The right hand side <see cref="Matrix"/>, <b>B</b>.</param>
/// <param name="result">The left hand side <see cref="Matrix"/>, <b>X</b>.</param>
public abstract void Solve(Matrix input, Matrix result);
/// <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{T}"/>, <b>X</b>.</param>
public abstract void Solve(Matrix<T> input, Matrix<T> result);
/// <summary>
/// Solves a system of linear equations, <b>Ax = b</b>, with A LU factorized.
/// </summary>
/// <param name="input">The right hand side vector, <b>b</b>.</param>
/// <returns>The left hand side <see cref="Vector"/>, <b>x</b>.</returns>
public virtual Vector Solve(Vector input)
/// <returns>The left hand side <see cref="Vector{T}"/>, <b>x</b>.</returns>
public virtual Vector<T> Solve(Vector<T> input)
{
// Check for proper arguments.
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.
/// </summary>
/// <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>
public abstract void Solve(Vector input, Vector result);
/// <param name="result">The left hand side <see cref="Matrix{T}"/>, <b>x</b>.</param>
public abstract void Solve(Vector<T> input, Vector<T> result);
/// <summary>
/// Returns the inverse of this matrix. The inverse is calculated using LU decomposition.
/// </summary>
/// <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.
// </copyright>
namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
namespace MathNet.Numerics.LinearAlgebra.Generic.Factorization
{
using System;
using System.Numerics;
using Generic;
using Properties;
/// <summary>
@ -38,12 +40,14 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <remarks>
/// The computation of the QR decomposition is done at construction time by Householder transformation.
/// </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>
/// Gets or sets orthogonal Q matrix
/// </summary>
protected Matrix MatrixQ
protected Matrix<T> MatrixQ
{
get;
set;
@ -52,7 +56,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <summary>
/// Gets or sets upper triangular factor R
/// </summary>
protected Matrix MatrixR
protected Matrix<T> MatrixR
{
get;
set;
@ -63,21 +67,26 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// </summary>
/// <param name="matrix">The matrix to factor.</param>
/// <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 (dense != null)
if (typeof(T) == typeof(double))
{
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>
/// Gets orthogonal Q matrix
/// </summary>
public virtual Matrix Q
public virtual Matrix<T> Q
{
get
{
@ -88,7 +97,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <summary>
/// Gets the upper triangular factor R.
/// </summary>
public virtual Matrix R
public virtual Matrix<T> R
{
get
{
@ -108,17 +117,17 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
throw new ArgumentException(Resources.ArgumentMatrixSquare);
}
var det = 1.0;
var det = OneValueT;
for (var i = 0; i < MatrixR.ColumnCount; i++)
{
det *= MatrixR.At(i, i);
if (Math.Abs(MatrixR.At(i, i)).AlmostEqualInDecimalPlaces(0.0, 15))
det = MultiplyT(det, MatrixR.At(i, i));
if (AbsoluteT(MatrixR.At(i, i)).AlmostEqualInDecimalPlaces(0.0, 15))
{
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++)
{
if (Math.Abs(MatrixR.At(i, i)).AlmostEqualInDecimalPlaces(0.0, 15))
if (AbsoluteT(MatrixR.At(i, i)).AlmostEqualInDecimalPlaces(0.0, 15))
{
return false;
}
@ -145,9 +154,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <summary>
/// Solves a system of linear equations, <b>AX = B</b>, with A QR factorized.
/// </summary>
/// <param name="input">The right hand side <see cref="Matrix"/>, <b>B</b>.</param>
/// <returns>The left hand side <see cref="Matrix"/>, <b>X</b>.</returns>
public virtual Matrix Solve(Matrix input)
/// <param name="input">The right hand side <see cref="Matrix{T}"/>, <b>B</b>.</param>
/// <returns>The left hand side <see cref="Matrix{T}"/>, <b>X</b>.</returns>
public virtual Matrix<T> Solve(Matrix<T> input)
{
// Check for proper arguments.
if (input == null)
@ -163,16 +172,16 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <summary>
/// Solves a system of linear equations, <b>AX = B</b>, with A QR factorized.
/// </summary>
/// <param name="input">The right hand side <see cref="Matrix"/>, <b>B</b>.</param>
/// <param name="result">The left hand side <see cref="Matrix"/>, <b>X</b>.</param>
public abstract void Solve(Matrix input, Matrix result);
/// <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{T}"/>, <b>X</b>.</param>
public abstract void Solve(Matrix<T> input, Matrix<T> result);
/// <summary>
/// Solves a system of linear equations, <b>Ax = b</b>, with A QR factorized.
/// </summary>
/// <param name="input">The right hand side vector, <b>b</b>.</param>
/// <returns>The left hand side <see cref="Vector"/>, <b>x</b>.</returns>
public virtual Vector Solve(Vector input)
/// <returns>The left hand side <see cref="Vector{T}"/>, <b>x</b>.</returns>
public virtual Vector<T> Solve(Vector<T> input)
{
// Check for proper arguments.
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.
/// </summary>
/// <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>
public abstract void Solve(Vector input, Vector result);
/// <param name="result">The left hand side <see cref="Matrix{T}"/>, <b>x</b>.</param>
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.
// </copyright>
namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
namespace MathNet.Numerics.LinearAlgebra.Generic.Factorization
{
using System;
using System.Numerics;
using Generic;
using Properties;
/// <summary>
@ -47,7 +49,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <remarks>
/// The computation of the singular value decomposition is done at construction time.
/// </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>
/// 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>
/// Gets or sets the singular values (Σ) of matrix in ascending value.
/// </summary>
protected Vector VectorS
protected Vector<T> VectorS
{
get;
set;
@ -70,7 +74,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <summary>
/// Gets or sets left singular vectors (U - m-by-m unitary matrix)
/// </summary>
protected Matrix MatrixU
protected Matrix<T> MatrixU
{
get;
set;
@ -79,7 +83,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <summary>
/// Gets or sets transpose right singular vectors (transpose of V, an n-by-n unitary matrix
/// </summary>
protected Matrix MatrixVT
protected Matrix<T> MatrixVT
{
get;
set;
@ -94,12 +98,12 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
get
{
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 rank = 0;
for (var h = 0; h < nm; h++)
{
if (VectorS[h] > tol)
if (AbsoluteT(VectorS[h]) > tol)
{
rank++;
}
@ -115,26 +119,31 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <param name="matrix">The matrix to factor.</param>
/// <param name="computeVectors">Compute the singular U and VT vectors or not.</param>
/// <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 (dense != null)
if (typeof(T) == typeof(double))
{
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>
/// Gets the two norm of the <see cref="Matrix"/>.
/// Gets the two norm of the <see cref="Matrix{T}"/>.
/// </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
{
get
{
return VectorS[0];
return AbsoluteT(VectorS[0]);
}
}
@ -147,7 +156,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
get
{
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);
}
var det = 1.0;
var det = OneValueT;
for (var i = 0; i < VectorS.Count; i++)
{
det *= VectorS[i];
if (Math.Abs(VectorS[i]).AlmostEqualInDecimalPlaces(0.0, 15))
det = MultiplyT(det, VectorS[i]);
if (AbsoluteT(VectorS[i]).AlmostEqualInDecimalPlaces(0.0, 15))
{
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>
public Matrix U()
public Matrix<T> U()
{
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>
/// <remarks>This is the transpose of the V matrix.</remarks>
public Matrix VT()
public Matrix<T> VT()
{
return ComputeVectors ? MatrixVT.Clone() : null;
}
/// <summary>Returns the singular values as a diagonal <see cref="Matrix"/>.</summary>
/// <returns>The singular values as a diagonal <see cref="Matrix"/>.</returns>
public Matrix W()
/// <summary>Returns the singular values as a diagonal <see cref="Matrix{T}"/>.</summary>
/// <returns>The singular values as a diagonal <see cref="Matrix{T}"/>.</returns>
public Matrix<T> W()
{
var rows = MatrixU.RowCount;
var columns = MatrixVT.ColumnCount;
@ -213,9 +222,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
return result;
}
/// <summary>Returns the singular values as a <see cref="Vector"/>.</summary>
/// <returns>the singular values as a <see cref="Vector"/>.</returns>
public Vector S()
/// <summary>Returns the singular values as a <see cref="Vector{T}"/>.</summary>
/// <returns>the singular values as a <see cref="Vector{T}"/>.</returns>
public Vector<T> S()
{
return VectorS.Clone();
}
@ -223,9 +232,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <summary>
/// Solves a system of linear equations, <b>AX = B</b>, with A SVD factorized.
/// </summary>
/// <param name="input">The right hand side <see cref="Matrix"/>, <b>B</b>.</param>
/// <returns>The left hand side <see cref="Matrix"/>, <b>X</b>.</returns>
public virtual Matrix Solve(Matrix input)
/// <param name="input">The right hand side <see cref="Matrix{T}"/>, <b>B</b>.</param>
/// <returns>The left hand side <see cref="Matrix{T}"/>, <b>X</b>.</returns>
public virtual Matrix<T> Solve(Matrix<T> input)
{
// Check for proper arguments.
if (input == null)
@ -238,7 +247,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
throw new InvalidOperationException(Resources.SingularVectorsNotComputed);
}
Matrix result = MatrixU.CreateMatrix(MatrixVT.ColumnCount, input.ColumnCount);
var result = MatrixU.CreateMatrix(MatrixVT.ColumnCount, input.ColumnCount);
Solve(input, result);
return result;
}
@ -246,16 +255,16 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Factorization
/// <summary>
/// Solves a system of linear equations, <b>AX = B</b>, with A SVD factorized.
/// </summary>
/// <param name="input">The right hand side <see cref="Matrix"/>, <b>B</b>.</param>
/// <param name="result">The left hand side <see cref="Matrix"/>, <b>X</b>.</param>
public abstract void Solve(Matrix input, Matrix result);
/// <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{T}"/>, <b>X</b>.</param>
public abstract void Solve(Matrix<T> input, Matrix<T> result);
/// <summary>
/// Solves a system of linear equations, <b>Ax = b</b>, with A SVD factorized.
/// </summary>
/// <param name="input">The right hand side vector, <b>b</b>.</param>
/// <returns>The left hand side <see cref="Vector"/>, <b>x</b>.</returns>
public virtual Vector Solve(Vector input)
/// <returns>The left hand side <see cref="Vector{T}"/>, <b>x</b>.</returns>
public virtual Vector<T> Solve(Vector<T> input)
{
// Check for proper arguments.
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.
/// </summary>
/// <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>
public abstract void Solve(Vector input, Vector result);
/// <param name="result">The left hand side <see cref="Matrix{T}"/>, <b>x</b>.</param>
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.
// </copyright>
namespace MathNet.Numerics.LinearAlgebra.Double
namespace MathNet.Numerics.LinearAlgebra.Generic
{
using System;
using System.Numerics;
/// <summary>
/// Classes that solves a system of linear equations, <c>AX = B</c>.
/// </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>
/// Solves a system of linear equations, <c>AX = B</c>.
/// </summary>
/// <param name="input">The right hand side <see cref="Matrix"/>, <c>B</c>.</param>
/// <returns>The left hand side <see cref="Matrix"/>, <c>X</c>.</returns>
Matrix Solve(Matrix input);
/// <param name="input">The right hand side Matrix, <c>B</c>.</param>
/// <returns>The left hand side Matrix, <c>X</c>.</returns>
Matrix<T> Solve(Matrix<T> input);
/// <summary>
/// Solves a system of linear equations, <c>AX = B</c>.
/// </summary>
/// <param name="input">The right hand side <see cref="Matrix"/>, <c>B</c>.</param>
/// <param name="result">The left hand side <see cref="Matrix"/>, <c>X</c>.</param>
void Solve(Matrix input, Matrix result);
/// <param name="input">The right hand side Matrix, <c>B</c>.</param>
/// <param name="result">The left hand side Matrix, <c>X</c>.</param>
void Solve(Matrix<T> input, Matrix<T> result);
/// <summary>
/// Solves a system of linear equations, <c>Ax = b</c>
/// </summary>
/// <param name="input">The right hand side vector, <c>b</c>.</param>
/// <returns>The left hand side <see cref="Vector"/>, <c>x</c>.</returns>
Vector Solve(Vector input);
/// <returns>The left hand side Vector, <c>x</c>.</returns>
Vector<T> Solve(Vector<T> input);
/// <summary>
/// Solves a system of linear equations, <c>Ax = b</c>.
/// </summary>
/// <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>
void Solve(Vector input, Vector result);
/// <param name="result">The left hand side Matrix>, <c>x</c>.</param>
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.
// </copyright>
namespace MathNet.Numerics.LinearAlgebra.Double
namespace MathNet.Numerics.LinearAlgebra.Generic
{
using System;
using System.Numerics;
using Distributions;
using Factorization;
using Properties;
@ -35,7 +36,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <summary>
/// Defines the base class for <c>Matrix</c> classes.
/// </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>
/// 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>
/// <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>
public virtual void Add(Matrix other)
public virtual void Add(Matrix<T> other)
{
if (other == null)
{
@ -56,13 +58,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double
}
CommonParallel.For(
0,
RowCount,
0,
RowCount,
i =>
{
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>
/// <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>
public virtual void Subtract(Matrix other)
public virtual void Subtract(Matrix<T> other)
{
if (other == null)
{
@ -86,13 +88,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double
}
CommonParallel.For(
0,
RowCount,
0,
RowCount,
i =>
{
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.
/// </summary>
/// <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;
}
CommonParallel.For(
0,
RowCount,
0,
RowCount,
i =>
{
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>
/// <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>
public virtual void Multiply(double scalar, Matrix result)
public virtual void Multiply(T scalar, Matrix<T> result)
{
if (result == null)
{
@ -155,7 +157,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>The result of the multiplication.</returns>
/// <exception cref="ArgumentNullException">If <paramref name="rightSide"/> is <see langword="null" />.</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);
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="ArgumentException">If <strong>result.Count != this.RowCount</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)
{
@ -202,14 +204,14 @@ namespace MathNet.Numerics.LinearAlgebra.Double
else
{
CommonParallel.For(
0,
RowCount,
0,
RowCount,
i =>
{
double s = 0;
var s = default(T);
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;
@ -224,7 +226,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>The result of the multiplication.</returns>
/// <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>
public virtual Vector LeftMultiply(Vector leftSide)
public virtual Vector<T> LeftMultiply(Vector<T> leftSide)
{
var ret = CreateVector(ColumnCount);
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="ArgumentException">If <strong>result.Count != this.ColumnCount</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)
{
@ -271,14 +273,14 @@ namespace MathNet.Numerics.LinearAlgebra.Double
else
{
CommonParallel.For(
0,
RowCount,
0,
RowCount,
j =>
{
double s = 0;
var s = default(T);
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;
@ -295,7 +297,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <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 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)
{
@ -326,16 +328,16 @@ namespace MathNet.Numerics.LinearAlgebra.Double
else
{
CommonParallel.For(
0,
RowCount,
0,
RowCount,
j =>
{
for (var i = 0; i != other.ColumnCount; i++)
{
double s = 0;
var s = default(T);
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);
@ -351,7 +353,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentException">If <strong>this.Columns != other.Rows</strong>.</exception>
/// <exception cref="ArgumentNullException">If the other matrix is <see langword="null" />.</exception>
/// <returns>The result of the multiplication.</returns>
public virtual Matrix Multiply(Matrix other)
public virtual Matrix<T> Multiply(Matrix<T> other)
{
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="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>
public virtual void TransposeAndMultiply(Matrix other, Matrix result)
{
public virtual void TransposeAndMultiply(Matrix<T> other, Matrix<T> result)
{
if (other == null)
{
throw new ArgumentNullException("other");
@ -414,13 +416,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double
{
for (var i = 0; i < RowCount; i++)
{
double s = 0;
var s = default(T);
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="ArgumentNullException">If the other matrix is <see langword="null" />.</exception>
/// <returns>The result of the multiplication.</returns>
public virtual Matrix TransposeAndMultiply(Matrix other)
public virtual Matrix<T> TransposeAndMultiply(Matrix<T> other)
{
if (other == null)
{
@ -451,12 +453,11 @@ namespace MathNet.Numerics.LinearAlgebra.Double
}
/// <summary>
/// Negates each element of this matrix.
/// </summary>
public virtual void Negate()
{
Multiply(-1);
}
/// Negate each element of this matrix.
/// </summary>
/// <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>
public abstract void Negate();
/// <summary>
/// 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>
/// <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>
public virtual void Negate(Matrix result)
public virtual void Negate(Matrix<T> result)
{
if (result == null)
{
@ -491,7 +492,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <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="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)
{
@ -519,7 +520,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="rightSide">The matrix to get the values from.</param>
/// <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>
public static Matrix operator +(Matrix rightSide)
public static Matrix<T> operator +(Matrix<T> rightSide)
{
if (rightSide == null)
{
@ -540,7 +541,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <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="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)
{
@ -568,7 +569,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="rightSide">The matrix to negate.</param>
/// <returns>A matrix containing the negated values.</returns>
/// <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)
{
@ -587,7 +588,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="rightSide">The constant to multiply the matrix by.</param>
/// <returns>The result of the multiplication.</returns>
/// <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)
{
@ -606,7 +607,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="rightSide">The constant to multiply the matrix by.</param>
/// <returns>The result of the multiplication.</returns>
/// <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)
{
@ -629,7 +630,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>The result of multiplication.</returns>
/// <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>
public static Matrix operator *(Matrix leftSide, Matrix rightSide)
public static Matrix<T> operator *(Matrix<T> leftSide, Matrix<T> rightSide)
{
if (leftSide == null)
{
@ -650,13 +651,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double
}
/// <summary>
/// Multiplies a <strong>Matrix</strong> and a <see cref="Vector"/>.
/// Multiplies a <strong>Matrix</strong> and a Vector.
/// </summary>
/// <param name="leftSide">The matrix to multiply.</param>
/// <param name="rightSide">The vector to multiply.</param>
/// <returns>The result of multiplication.</returns>
/// <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)
{
@ -667,13 +668,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double
}
/// <summary>
/// Multiplies a <see cref="Vector"/> and a <strong>Matrix</strong>.
/// Multiplies a Vector and a <strong>Matrix</strong>.
/// </summary>
/// <param name="leftSide">The vector to multiply.</param>
/// <param name="rightSide">The matrix to multiply.</param>
/// <returns>The result of multiplication.</returns>
/// <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)
{
@ -690,7 +691,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <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>
/// <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)
{
@ -716,7 +717,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <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="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)
{
@ -739,13 +740,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double
}
CommonParallel.For(
0,
ColumnCount,
0,
ColumnCount,
j =>
{
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="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>
public virtual Matrix PointwiseDivide(Matrix other)
public virtual Matrix<T> PointwiseDivide(Matrix<T> other)
{
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="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>
public virtual void PointwiseDivide(Matrix other, Matrix result)
public virtual void PointwiseDivide(Matrix<T> other, Matrix<T> result)
{
if (other == null)
{
@ -806,13 +807,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double
}
CommonParallel.For(
0,
ColumnCount,
0,
ColumnCount,
j =>
{
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>
/// <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 virtual Matrix 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 abstract Matrix<T> Random(int numberOfRows, int numberOfColumns, IContinuousDistribution distribution);
/// <summary>
/// Generates matrix with random elements.
@ -866,46 +842,23 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// </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 virtual Matrix 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;
}
public abstract Matrix<T> Random(int numberOfRows, int numberOfColumns, IDiscreteDistribution distribution);
/// <summary>
/// Computes the trace of this matrix.
/// </summary>
/// <returns>The trace of this matrix</returns>
/// <exception cref="ArgumentException">If the matrix is not square</exception>
public virtual double Trace()
public virtual T Trace()
{
if (RowCount != ColumnCount)
{
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>
@ -914,8 +867,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>effective numerical rank, obtained from SVD</returns>
public virtual int Rank()
{
var svd = this.Svd(false);
return svd.Rank;
return Svd<T>.Create(this, false).Rank;
}
/// <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>
public virtual double ConditionNumber()
{
var svd = this.Svd(false);
return svd.ConditionNumber;
return Svd<T>.Create(this, false).ConditionNumber;
}
/// <summary>Computes the determinant of this matrix.</summary>
/// <returns>The determinant of this matrix.</returns>
public virtual double Determinant()
public virtual T Determinant()
{
if (RowCount != ColumnCount)
{
throw new ArgumentException(Resources.ArgumentMatrixSquare);
}
var lu = this.LU();
return lu.Determinant;
return LU<T>.Create(this).Determinant;
}
/// <summary>Computes the inverse of this matrix.</summary>
/// <returns>The inverse of this matrix.</returns>
public virtual Matrix Inverse()
public virtual Matrix<T> Inverse()
{
if (RowCount != ColumnCount)
{
throw new ArgumentException(Resources.ArgumentMatrixSquare);
}
var lu = this.LU();
return lu.Inverse();
return LU<T>.Create(this).Inverse();
}
/// <summary>
@ -960,7 +909,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="other">The other matrix.</param>
/// <exception cref="ArgumentNullException">If other is <see langword="null" />.</exception>
/// <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)
{
@ -981,7 +930,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentNullException">If other 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>
public virtual void KroneckerProduct(Matrix other, Matrix result)
public virtual void KroneckerProduct(Matrix<T> other, Matrix<T> result)
{
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>
/// <returns>A normalized version of the matrix.</returns>
/// <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)
{
@ -1025,17 +974,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double
var ret = Clone();
CommonParallel.For(
0,
ColumnCount,
i =>
{
var coli = Column(i);
var norm = coli.Norm(p);
for (var j = 0; j < RowCount; j++)
{
ret[j, i] = coli[j] / norm;
}
});
0,
ColumnCount,
i => ret.SetColumn(i, Column(i).Normalize(p)));
return ret;
}
@ -1045,7 +986,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="p">The norm under which to normalize the rows under.</param>
/// <returns>A normalized version of the matrix.</returns>
/// <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)
{
@ -1054,32 +995,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double
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(
0,
RowCount,
i =>
{
var rowi = Row(i);
var norm = rowi.Norm(p);
for (var j = 0; j < ColumnCount; j++)
{
ret[i, j] = rowi[j] / norm;
}
});
i => ret.SetRow(i, Row(i).Normalize(p)));
return ret;
}
}

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

@ -24,10 +24,11 @@
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
namespace MathNet.Numerics.LinearAlgebra.Double
namespace MathNet.Numerics.LinearAlgebra.Generic
{
using System;
using System.Collections.Generic;
using System.Numerics;
using System.Text;
using Factorization;
using Properties;
@ -36,16 +37,18 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <summary>
/// Defines the base class for <c>Matrix</c> classes.
/// </summary>
/// <typeparam name="T">Supported data types are double, single, <see cref="Complex"/>, and <see cref="Complex32"/>.</typeparam>
[Serializable]
public abstract partial class Matrix :
public abstract partial class Matrix<T> :
#if SILVERLIGHT
IFormattable, IEquatable<Matrix>
IFormattable, IEquatable<Matrix<T>>
#else
IFormattable, IEquatable<Matrix>, ICloneable
IFormattable, IEquatable<Matrix<T>>, ICloneable
#endif
where T : struct, IEquatable<T>, IFormattable
{
/// <summary>
/// Initializes a new instance of the <see cref="Matrix"/> class.
/// Initializes a new instance of the Matrix class.
/// </summary>
/// <param name="rows">
/// The number of rows.
@ -70,7 +73,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
}
/// <summary>
/// Initializes a new instance of the <see cref="Matrix"/> class.
/// Initializes a new instance of the Matrix class.
/// </summary>
/// <param name="order">
/// The order of the matrix.
@ -116,9 +119,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// The column of the element.
/// </param>
/// <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>
public virtual double this[int row, int column]
public virtual T this[int row, int column]
{
get
{
@ -145,7 +148,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>
/// The requested element.
/// </returns>
public abstract double At(int row, int column);
public abstract T At(int row, int column);
/// <summary>
/// Sets the value of the given element.
@ -159,7 +162,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="value">
/// The value to set the element to.
/// </param>
public abstract void At(int row, int column, double value);
public abstract void At(int row, int column, T value);
/// <summary>
/// Creates a clone of this instance.
@ -167,7 +170,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>
/// A clone of the instance.
/// </returns>
public virtual Matrix Clone()
public virtual Matrix<T> Clone()
{
var result = CreateMatrix(RowCount, ColumnCount);
CopyTo(result);
@ -186,7 +189,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentException">
/// If this and the target matrix do not have the same dimensions..
/// </exception>
public virtual void CopyTo(Matrix target)
public virtual void CopyTo(Matrix<T> target)
{
if (target == null)
{
@ -227,19 +230,19 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <remarks>
/// Creates a matrix of the same matrix type as the current matrix.
/// </remarks>
public abstract Matrix CreateMatrix(int numberOfRows, int numberOfColumns);
public abstract Matrix<T> CreateMatrix(int numberOfRows, int numberOfColumns);
/// <summary>
/// Creates a <see cref="Vector"/> with a the given dimension.
/// Creates a Vector with a the given dimension.
/// </summary>
/// <param name="size">The size of the vector.</param>
/// <returns>
/// A <see cref="Vector"/> with the given dimension.
/// A Vector with the given dimension.
/// </returns>
/// <remarks>
/// Creates a vector of the same type as the current matrix.
/// </remarks>
public abstract Vector CreateVector(int size);
public abstract Vector<T> CreateVector(int size);
/// <summary>
/// Returns a <see cref="System.String"/> that represents this instance.
@ -253,13 +256,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double
}
/// <summary>
/// Copies a row into an <see cref="Vector"/>.
/// Copies a row into an Vector.
/// </summary>
/// <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,
/// 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);
Row(index, 0, ColumnCount, ret);
@ -267,26 +270,26 @@ namespace MathNet.Numerics.LinearAlgebra.Double
}
/// <summary>
/// Copies a row into to the given <see cref="Vector"/>.
/// Copies a row into to the given Vector.
/// </summary>
/// <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="ArgumentOutOfRangeException">If <paramref name="index"/> is negative,
/// or greater than or equal to the number of rows.</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);
}
/// <summary>
/// Copies the requested row elements into a new <see cref="Vector"/>.
/// Copies the requested row elements into a new Vector.
/// </summary>
/// <param name="rowIndex">The row to copy elements from.</param>
/// <param name="columnIndex">The column to start copying from.</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:
/// <list><item><paramref name="rowIndex"/> is negative,
/// 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>
/// <item><c>(columnIndex + length) &gt;= Columns.</c></item></list></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);
Row(rowIndex, columnIndex, length, ret);
@ -302,13 +305,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double
}
/// <summary>
/// Copies the requested row elements into a new <see cref="Vector"/>.
/// Copies the requested row elements into a new Vector.
/// </summary>
/// <param name="rowIndex">The row to copy elements from.</param>
/// <param name="columnIndex">The column to start copying from.</param>
/// <param name="length">The number of elements to copy.</param>
/// <param name="result">The <see cref="Vector"/> to copy the column into.</param>
/// <exception cref="ArgumentNullException">If the result <see cref="Vector"/> is <see langword="null" />.</exception>
/// <param name="result">The Vector to copy the column into.</param>
/// <exception cref="ArgumentNullException">If the result Vector is <see langword="null" />.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="rowIndex"/> is negative,
/// or greater than or equal to the number of columns.</exception>
/// <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>
/// <exception cref="ArgumentException">If <paramref name="length"/> is not positive.</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)
{
@ -356,13 +359,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double
}
/// <summary>
/// Copies a column into a new <see cref="Vector"/>.
/// Copies a column into a new Vector>.
/// </summary>
/// <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,
/// 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);
Column(index, 0, RowCount, result);
@ -370,26 +373,26 @@ namespace MathNet.Numerics.LinearAlgebra.Double
}
/// <summary>
/// Copies a column into to the given <see cref="Vector"/>.
/// Copies a column into to the given Vector.
/// </summary>
/// <param name="index">The column to copy.</param>
/// <param name="result">The <see cref="Vector"/> to copy the column into.</param>
/// <exception cref="ArgumentNullException">If the result <see cref="Vector"/> is <see langword="null" />.</exception>
/// <param name="result">The Vector to copy the column into.</param>
/// <exception cref="ArgumentNullException">If the result Vector is <see langword="null" />.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="index"/> is negative,
/// or greater than or equal to the number of columns.</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);
}
/// <summary>
/// Copies the requested column elements into a new <see cref="Vector"/>.
/// Copies the requested column elements into a new Vector.
/// </summary>
/// <param name="columnIndex">The column to copy elements from.</param>
/// <param name="rowIndex">The row to start copying from.</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:
/// <list><item><paramref name="columnIndex"/> is negative,
/// 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>
/// </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);
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="rowIndex">The row to start copying from.</param>
/// <param name="length">The number of elements to copy.</param>
/// <param name="result">The <see cref="Vector"/> to copy the column into.</param>
/// <exception cref="ArgumentNullException">If the result <see cref="Vector"/> is <see langword="null" />.</exception>
/// <param name="result">The Vector to copy the column into.</param>
/// <exception cref="ArgumentNullException">If the result Vector is <see langword="null" />.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="columnIndex"/> is negative,
/// or greater than or equal to the number of columns.</exception>
/// <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>
/// <exception cref="ArgumentException">If <paramref name="length"/> is not positive.</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)
{
@ -463,7 +466,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// Returns a new matrix containing the lower triangle of this matrix.
/// </summary>
/// <returns>The lower triangle of this matrix.</returns>
public virtual Matrix LowerTriangle()
public virtual Matrix<T> LowerTriangle()
{
var ret = CreateMatrix(RowCount, ColumnCount);
CommonParallel.For(
@ -485,7 +488,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <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 LowerTriangle(Matrix result)
public virtual void LowerTriangle(Matrix<T> result)
{
if (result == null)
{
@ -504,7 +507,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
{
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.
/// </summary>
/// <returns>The upper triangle of this matrix.</returns>
public virtual Matrix UpperTriangle()
public virtual Matrix<T> UpperTriangle()
{
var ret = CreateMatrix(RowCount, ColumnCount);
CommonParallel.For(
@ -538,7 +541,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <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 UpperTriangle(Matrix result)
public virtual void UpperTriangle(Matrix<T> result)
{
if (result == null)
{
@ -557,7 +560,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
{
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>
/// <exception cref="ArgumentException">If <paramref name="rowLength"/> or <paramref name="columnLength"/>
/// 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)
{
@ -633,11 +636,11 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// </summary>
/// <returns>An <see cref="IEnumerator{T}"/> that enumerates over the matrix columns</returns>
/// <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++)
{
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>
/// </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)
{
@ -674,7 +677,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
var maxIndex = index + length;
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>
/// <item><c>(index + length) &gt;= Rows.</c></item></list></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)
{
@ -710,7 +713,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
var maxi = index + length;
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>
/// <returns>An <see cref="IEnumerator{T}"/> that enumerates over the matrix rows</returns>
/// <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++)
{
yield return new KeyValuePair<int, Vector>(i, Row(i));
yield return new KeyValuePair<int, Vector<T>>(i, Row(i));
}
}
/// <summary>
/// Returns the elements of the diagonal in a <see cref="Vector"/>.
/// Returns the elements of the diagonal in a Vector.
/// </summary>
/// <returns>The elements of the diagonal.</returns>
/// <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>
public virtual Vector Diagonal()
public virtual Vector<T> Diagonal()
{
var min = Math.Min(RowCount, ColumnCount);
var diagonal = CreateVector(min);
@ -749,7 +752,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// does not contain the diagonal elements of this matrix.
/// </summary>
/// <returns>The lower triangle of this matrix.</returns>
public virtual Matrix StrictlyLowerTriangle()
public virtual Matrix<T> StrictlyLowerTriangle()
{
var result = CreateMatrix(RowCount, ColumnCount);
CommonParallel.For(
@ -774,7 +777,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <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 StrictlyLowerTriangle(Matrix result)
public virtual void StrictlyLowerTriangle(Matrix<T> result)
{
if (result == null)
{
@ -793,7 +796,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
{
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.
/// </summary>
/// <returns>The upper triangle of this matrix.</returns>
public virtual Matrix StrictlyUpperTriangle()
public virtual Matrix<T> StrictlyUpperTriangle()
{
var result = CreateMatrix(RowCount, ColumnCount);
CommonParallel.For(
@ -822,6 +825,36 @@ namespace MathNet.Numerics.LinearAlgebra.Double
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>
/// Creates a new matrix and inserts the given column at the given index.
/// </summary>
@ -831,7 +864,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <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="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)
{
@ -877,7 +910,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// equal the number of rows of this <strong>Matrix</strong>.</exception>
/// <exception cref="ArgumentException">If the size of <paramref name="column"/> does not
/// 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)
{
@ -901,7 +934,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
}
/// <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>
/// <param name="columnIndex">The column to copy the values to.</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>
/// <exception cref="ArgumentException">If the size of <paramref name="column"/> does not
/// 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)
{
@ -942,7 +975,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <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="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)
{
@ -977,7 +1010,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
}
/// <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>
/// <param name="rowIndex">The row to copy the values to.</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>
/// <exception cref="ArgumentException">If the size of <paramref name="row"/> does not
/// 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)
{
@ -1019,7 +1052,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// or greater than or equal to the number of rows.</exception>
/// <exception cref="ArgumentException">If the size of <paramref name="row"/> does not
/// 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)
{
@ -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>
/// <exception cref="ArgumentException">If <paramref name="rowLength"/> or <paramref name="columnLength"/>
/// 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)
{
@ -1123,7 +1156,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
}
/// <summary>
/// Copies the values of the given <see cref="Vector"/> to the diagonal.
/// Copies the values of the given Vector to the diagonal.
/// </summary>
/// <param name="source">The vector to copy the values from. The length of the vector should be
/// Min(Rows, Columns).</param>
@ -1132,7 +1165,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// equal Min(Rows, Columns).</exception>
/// <remarks>For non-square matrices, the elements of <paramref name="source"/> are copied to
/// this[i,i].</remarks>
public virtual void SetDiagonal(Vector source)
public virtual void SetDiagonal(Vector<T> source)
{
if (source == null)
{
@ -1162,7 +1195,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// equal Min(Rows, Columns).</exception>
/// <remarks>For non-square matrices, the elements of <paramref name="source"/> are copied to
/// this[i,i].</remarks>
public virtual void SetDiagonal(double[] source)
public virtual void SetDiagonal(T[] source)
{
if (source == null)
{
@ -1182,43 +1215,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double
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>
/// Returns this matrix as a multidimensional array.
/// </summary>
/// <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(
0,
ColumnCount,
@ -1241,9 +1244,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// 7, 8, 9
/// </pre></example>
/// <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())
{
var columnIndex = column.Key * RowCount;
@ -1265,9 +1268,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// 7, 8, 9
/// </pre></example>
/// <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())
{
@ -1302,7 +1305,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
#endif
#region IEquatable<Matrix>
#region IEquatable<Matrix<T>>
/// <summary>
/// Indicates whether the current object is equal to another object of the same type.
@ -1313,7 +1316,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>
/// <c>true</c> if the current object is equal to the <paramref name="other"/> parameter; otherwise, <c>false</c>.
/// </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.
if (other == null)
@ -1337,7 +1340,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
{
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;
}
@ -1363,7 +1366,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>
/// A <see cref="System.String"/> that represents this instance.
/// </returns>
public string ToString(string format, IFormatProvider formatProvider)
public virtual string ToString(string format, IFormatProvider formatProvider)
{
var stringBuilder = new StringBuilder();
for (var row = 0; row < RowCount; row++)
@ -1423,7 +1426,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// </returns>
public override bool Equals(object obj)
{
return Equals(obj as Matrix);
return Equals(obj as Matrix<T>);
}
/// <summary>
@ -1442,15 +1445,14 @@ namespace MathNet.Numerics.LinearAlgebra.Double
var row = (i - col) / RowCount;
#if SILVERLIGHT
hash ^= Precision.DoubleToInt64Bits(this[row, col]);
hash ^= Precision.DoubleToInt64Bits(this[row, col].GetHashCode());
#else
hash ^= BitConverter.DoubleToInt64Bits(this[row, col]);
hash ^= BitConverter.DoubleToInt64Bits(this[row, col].GetHashCode());
#endif
}
return BitConverter.ToInt32(BitConverter.GetBytes(hash), 4);
}
#endregion
/// <summary>
@ -1462,7 +1464,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
{
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.
/// </summary>
/// <returns>The transpose of this matrix.</returns>
public virtual Matrix Transpose()
public virtual Matrix<T> Transpose()
{
var ret = CreateMatrix(ColumnCount, RowCount);
for (var j = 0; j < ColumnCount; j++)
@ -1548,7 +1550,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// </summary>
/// <param name="right">The matrix to concatenate.</param>
/// <returns>The combined matrix.</returns>
public virtual Matrix Append(Matrix right)
public virtual Matrix<T> Append(Matrix<T> right)
{
if (right == null)
{
@ -1570,7 +1572,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// </summary>
/// <param name="right">The matrix to concatenate.</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)
{
@ -1622,7 +1624,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>The combined matrix.</returns>
/// <exception cref="ArgumentNullException">If lower is <see langword="null" />.</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)
{
@ -1646,7 +1648,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="result">The combined matrix.</param>
/// <exception cref="ArgumentNullException">If lower is <see langword="null" />.</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)
{
@ -1699,7 +1701,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="lower">The lower, right matrix.</param>
/// <exception cref="ArgumentNullException">If lower is <see langword="null" />.</exception>
/// <returns>the combined matrix</returns>
public virtual Matrix DiagonalStack(Matrix lower)
public virtual Matrix<T> DiagonalStack(Matrix<T> lower)
{
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 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>
public virtual void DiagonalStack(Matrix lower, Matrix result)
public virtual void DiagonalStack(Matrix<T> lower, Matrix<T> result)
{
if (lower == null)
{
@ -1769,7 +1771,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
var s = 0.0;
for (var i = 0; i < RowCount; i++)
{
s += Math.Abs(At(i, j));
s += AbsoluteT(At(i, j));
}
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>
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>
@ -1796,11 +1798,11 @@ namespace MathNet.Numerics.LinearAlgebra.Double
// TODO: Replace with multiple Transpose
//// aat.Gemm(1.0, 0.0, false, true, this, this);
var norm = 0.0;
for (var i = 0; i < RowCount; i++)
{
norm += Math.Abs(aat.At(i, i));
norm += AbsoluteT(aat.At(i, i));
}
norm = Math.Sqrt(norm);
@ -1818,13 +1820,62 @@ namespace MathNet.Numerics.LinearAlgebra.Double
var s = 0.0;
for (var j = 0; j < ColumnCount; j++)
{
s += Math.Abs(At(i, j));
s += AbsoluteT(At(i, j));
}
norm = Math.Max(norm, s);
}
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.
// </copyright>
namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
namespace MathNet.Numerics.LinearAlgebra.Generic.Solvers
{
using System;
using System.Numerics;
using Status;
/// <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.
/// </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>
/// Stops the solve process.
@ -47,10 +50,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
void StopSolve();
/// <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>
/// <param name="iterator">The iterator.</param>
void SetIterator(IIterator iterator);
void SetIterator(IIterator<T> iterator);
/// <summary>
/// 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="vector">The solution vector, <c>b</c>.</param>
/// <returns>The result vector, <c>x</c>.</returns>
Vector Solve(Matrix matrix, Vector vector);
Vector<T> Solve(Matrix<T> matrix, Vector<T> vector);
/// <summary>
/// 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="input">The solution vector, <c>b</c></param>
/// <param name="result">The result vector, <c>x</c></param>
void Solve(Matrix matrix, Vector input, Vector result);
void Solve(Matrix<T> matrix, Vector<T> input, Vector<T> result);
/// <summary>
/// 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="input">The solution matrix, <c>B</c>.</param>
/// <returns>The result matrix, <c>X</c>.</returns>
Matrix Solve(Matrix matrix, Matrix input);
Matrix<T> Solve(Matrix<T> matrix, Matrix<T> input);
/// <summary>
/// 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="input">The solution matrix, <c>B</c>.</param>
/// <param name="result">The result matrix, <c>X</c></param>
void Solve(Matrix matrix, Matrix input, Matrix result);
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.
// </copyright>
namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
namespace MathNet.Numerics.LinearAlgebra.Generic.Solvers
{
using System;
using System.Numerics;
/// <summary>
/// Defines the interface for objects that can create an iterative solver with
/// specific settings. This interface is used to pass iterative solver creation
/// setup information around.
/// </summary>
public interface IIterativeSolverSetup
/// <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>
/// 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
/// given by this setup.
/// </summary>
/// <returns>A new <see cref="IIterativeSolver"/>.</returns>
IIterativeSolver CreateNew();
/// <returns>A new <see cref="IIterativeSolver{T}"/>.</returns>
IIterativeSolver<T> CreateNew();
/// <summary>
/// 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.
// </copyright>
namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
namespace MathNet.Numerics.LinearAlgebra.Generic.Solvers
{
using System;
using System.Numerics;
using Status;
using StopCriterium;
/// <summary>
/// Defines the base interface for iterators that help control an iterative calculation.
/// </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
: ICloneable
#endif
where T : struct, IEquatable<T>, IFormattable
{
/// <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.
/// </summary>
/// <param name="stopCriterium">The stop criterium to add.</param>
/// <exception cref="ArgumentNullException">Thrown if <paramref name="stopCriterium"/> is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">Thrown if <paramref name="stopCriterium"/> is of the same type as an already stored criterium.</exception>
void Add(IIterationStopCriterium stopCriterium);
void Add(IIterationStopCriterium<T> stopCriterium);
/// <summary>
/// Removes the <see cref="IIterationStopCriterium"/> from the internal collection.
/// Removes the <see cref="IIterationStopCriterium{T}"/> from the internal collection.
/// </summary>
/// <param name="stopCriterium">The stop criterium that must be removed.</param>
void Remove(IIterationStopCriterium stopCriterium);
void Remove(IIterationStopCriterium<T> stopCriterium);
/// <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>
/// <param name="stopCriterium">The stop criterium.</param>
/// <returns><c>true</c> if the <see cref="IIterator"/> contains the stop criterium; otherwise <c>false</c>.</returns>
bool Contains(IIterationStopCriterium stopCriterium);
/// <returns><c>true</c> if the <see cref="IIterator{T}"/> contains the stop criterium; otherwise <c>false</c>.</returns>
bool Contains(IIterationStopCriterium<T> stopCriterium);
/// <summary>
/// Indicates to the iterator that the iterative process has been cancelled.
@ -72,7 +75,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
/// <summary>
/// Determines the status of the iterative calculation based on the stop criteria stored
/// by the current <see cref="IIterator"/>. Status is set to <c>Status</c> field of current object.
/// by the current <see cref="IIterator{T}"/>. Status is set to <c>Status</c> field of current object.
/// </summary>
/// <param name="iterationNumber">The number of iterations that have passed so far.</param>
/// <param name="solutionVector">The vector containing the current solution values.</param>
@ -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
/// calculation has moved forwards at least one step.
/// </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>
/// Gets the current calculation status.
@ -92,7 +95,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
ICalculationStatus Status { get; }
/// <summary>
/// Resets the <c>IIterator</c> to the pre-calculation state.
/// Resets the <see cref="IIterator{T}"/> to the pre-calculation state.
/// </summary>
/// <remarks>
/// Note to implementers: Invoking this method should not clear the user defined
@ -102,7 +105,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers
void ResetToPrecalculationState();
#if SILVERLIGHT
IIterator Clone();
IIterator<double> Clone();
#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.
// </copyright>
namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
namespace MathNet.Numerics.LinearAlgebra.Generic.Solvers.Preconditioners
{
using System;
using System.Numerics;
/// <summary>
/// The base interface for preconditioner classes.
/// </summary>
@ -48,26 +51,27 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners
/// if the changes occur after creating the preconditioner.
/// </para>
/// </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>
/// Initializes the preconditioner and loads the internal data structures.
/// </summary>
/// <param name="matrix">The matrix on which the preconditioner is based.</param>
void Initialize(Matrix matrix);
void Initialize(Matrix<T> matrix);
/// <summary>
/// Approximates the solution to the matrix equation <b>Mx = b</b>.
/// </summary>
/// <param name="rhs">The right hand side vector.</param>
/// <returns>The left hand side vector.</returns>
Vector Approximate(Vector rhs);
Vector<double> Approximate(Vector<T> rhs);
/// <summary>
/// Approximates the solution to the matrix equation <b>Mx = b</b>.
/// </summary>
/// <param name="rhs">The right hand side vector.</param>
/// <param name="lhs">The left hand side vector. Also known as the result vector.</param>
void Approximate(Vector rhs, Vector lhs);
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.
// </copyright>
namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Status
namespace MathNet.Numerics.LinearAlgebra.Generic.Solvers.Status
{
/// <summary>
/// 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.
// </copyright>
namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Status
namespace MathNet.Numerics.LinearAlgebra.Generic.Solvers.Status
{
/// <summary>
/// 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.
// </copyright>
namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Status
namespace MathNet.Numerics.LinearAlgebra.Generic.Solvers.Status
{
/// <summary>
/// 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.
// </copyright>
namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Status
namespace MathNet.Numerics.LinearAlgebra.Generic.Solvers.Status
{
/// <summary>
/// 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.
// </copyright>
namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Status
namespace MathNet.Numerics.LinearAlgebra.Generic.Solvers.Status
{
/// <summary>
/// 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.
// </copyright>
namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Status
namespace MathNet.Numerics.LinearAlgebra.Generic.Solvers.Status
{
/// <summary>
/// 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.
// </copyright>
namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Status
namespace MathNet.Numerics.LinearAlgebra.Generic.Solvers.Status
{
/// <summary>
/// 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.
// </copyright>
namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Status
namespace MathNet.Numerics.LinearAlgebra.Generic.Solvers.Status
{
/// <summary>
/// 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.
// </copyright>
namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium
namespace MathNet.Numerics.LinearAlgebra.Generic.Solvers.StopCriterium
{
using System;
using System.Numerics;
using Status;
/// <summary>
/// The base interface for classes that provide stop criteria for iterative calculations.
/// </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
: ICloneable
#endif
where T : struct, IEquatable<T>, IFormattable
{
/// <summary>
/// Determines the status of the iterative calculation based on the stop criteria stored
/// by the current <see cref="IIterationStopCriterium"/>. Status is set to <c>Status</c> field of current object.
/// by the current <see cref="IIterationStopCriterium{T}"/>. Status is set to <c>Status</c> field of current object.
/// </summary>
/// <param name="iterationNumber">The number of iterations that have passed so far.</param>
/// <param name="solutionVector">The vector containing the current solution values.</param>
@ -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
/// calculation has moved forwards at least one step.
/// </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>
/// Gets the current calculation status.
@ -59,7 +62,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium
ICalculationStatus Status { get; }
/// <summary>
/// Resets the <see cref="IIterationStopCriterium"/> to the pre-calculation state.
/// Resets the <see cref="IIterationStopCriterium{T}"/> to the pre-calculation state.
/// </summary>
/// <remarks>To implementers: Invoking this method should not clear the user defined
/// property values, only the state that is used to track the progress of the
@ -68,12 +71,12 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium
/// <summary>
/// Gets the <see cref="StopLevel"/> which indicates what sort of stop criterium this
/// <see cref="IIterationStopCriterium"/> monitors.
/// <see cref="IIterationStopCriterium{T}"/> monitors.
/// </summary>
StopLevel StopLevel { get; }
#if SILVERLIGHT
IIterationStopCriterium Clone();
IIterationStopCriterium<double> Clone();
#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.
// </copyright>
namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.StopCriterium
namespace MathNet.Numerics.LinearAlgebra.Generic.Solvers.StopCriterium
{
/// <summary>
/// Indicates what an <c>IIterationStopCriterium</c> monitors for stop criteria.
/// Indicates what an <see cref="IIterationStopCriterium{T}"/> monitors for stop criteria.
/// </summary>
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.
// </copyright>
namespace MathNet.Numerics.LinearAlgebra.Double
namespace MathNet.Numerics.LinearAlgebra.Generic
{
using System;
using System.Collections;
using System.Collections.Generic;
using System.Numerics;
using System.Text;
using Distributions;
using Properties;
using Threading;
/// <summary>
/// Defines the base class for <c>Vector</c> classes.
/// Defines the generic class for <c>Vector</c> classes.
/// </summary>
/// <typeparam name="T">Supported data types are double, single, <see cref="Complex"/>, and <see cref="Complex32"/>.</typeparam>
[Serializable]
public abstract class Vector :
public abstract class Vector<T> :
#if SILVERLIGHT
IFormattable, IEnumerable<double>, IEquatable<Vector>
IFormattable, IEnumerable<T>, IEquatable<Vector<T>>
#else
IFormattable, IEnumerable<double>, IEquatable<Vector>, ICloneable
IFormattable, IEnumerable<T>, IEquatable<Vector<T>>, ICloneable
#endif
where T : struct, IEquatable<T>, IFormattable
{
/// <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.
/// </summary>
/// <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>
/// <exception cref="IndexOutOfRangeException">If <paramref name="index"/> is negative or
/// greater than the size of the vector.</exception>
public abstract double this[int index]
public abstract T this[int index]
{
get;
set;
@ -98,7 +101,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>
/// A matrix with the given dimensions.
/// </returns>
public abstract Matrix CreateMatrix(int rows, int columns);
public abstract Matrix<T> CreateMatrix(int rows, int columns);
/// <summary>
/// Creates a <strong>Vector</strong> of the given size using the same storage type
@ -110,7 +113,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>
/// The new <c>Vector</c>.
/// </returns>
public abstract Vector CreateVector(int size);
public abstract Vector<T> CreateVector(int size);
#region Elementary operations
@ -121,18 +124,15 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// The scalar to add.
/// </param>
/// <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();
}
var copy = Clone();
CommonParallel.For(
0,
Count,
index => copy[index] += scalar);
Add(scalar, copy);
return copy;
}
@ -151,7 +151,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentException">
/// If this vector and <paramref name="result"/> are not the same size.
/// </exception>
public virtual void Add(double scalar, Vector result)
public virtual void Add(T scalar, Vector<T> result)
{
if (result == null)
{
@ -171,7 +171,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
CommonParallel.For(
0,
Count,
index => result[index] += scalar);
index => result[index] = AddT(result[index], scalar));
}
/// <summary>
@ -183,7 +183,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <remarks>
/// Added as an alternative to the unary addition operator.
/// </remarks>
public virtual Vector Plus()
public virtual Vector<T> Plus()
{
return Clone();
}
@ -201,7 +201,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentException">
/// If this vector and <paramref name="other"/> are not the same size.
/// </exception>
public virtual Vector Add(Vector other)
public virtual Vector<T> Add(Vector<T> other)
{
if (other == null)
{
@ -214,10 +214,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
}
var copy = Clone();
CommonParallel.For(
0,
Count,
index => copy[index] += other[index]);
Add(other, copy);
return copy;
}
@ -242,7 +239,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentException">
/// If this vector and <paramref name="result"/> are not the same size.
/// </exception>
public virtual void Add(Vector other, Vector result)
public virtual void Add(Vector<T> other, Vector<T> result)
{
if (result == null)
{
@ -264,7 +261,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
CommonParallel.For(
0,
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.
/// </param>
/// <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();
}
var copy = Clone();
CommonParallel.For(
0,
Count,
index => copy[index] -= scalar);
Subtract(scalar, copy);
return copy;
}
@ -305,7 +299,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentException">
/// If this vector and <paramref name="result"/> are not the same size.
/// </exception>
public virtual void Subtract(double scalar, Vector result)
public virtual void Subtract(T scalar, Vector<T> result)
{
if (result == null)
{
@ -325,7 +319,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
CommonParallel.For(
0,
Count,
index => result[index] -= scalar);
index => result[index] = SubtractT(result[index], scalar));
}
/// <summary>
@ -337,10 +331,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <remarks>
/// Added as an alternative to the unary negation operator.
/// </remarks>
public virtual Vector Negate()
{
return this * -1;
}
public abstract Vector<T> Negate();
/// <summary>
/// Subtracts another vector from this vector.
@ -355,7 +346,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentException">
/// If this vector and <paramref name="other"/> are not the same size.
/// </exception>
public virtual Vector Subtract(Vector other)
public virtual Vector<T> Subtract(Vector<T> other)
{
if (other == null)
{
@ -368,10 +359,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
}
var copy = Clone();
CommonParallel.For(
0,
Count,
index => copy[index] -= other[index]);
Subtract(other, copy);
return copy;
}
@ -396,7 +384,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentException">
/// If this vector and <paramref name="result"/> are not the same size.
/// </exception>
public virtual void Subtract(Vector other, Vector result)
public virtual void Subtract(Vector<T> other, Vector<T> result)
{
if (result == null)
{
@ -419,7 +407,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
CommonParallel.For(
0,
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.
/// </param>
/// <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();
}
var copy = Clone();
CommonParallel.For(
0,
Count,
index => copy[index] *= scalar);
Multiply(scalar, copy);
return copy;
}
@ -460,7 +445,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentException">
/// If this vector and <paramref name="result"/> are not the same size.
/// </exception>
public virtual void Multiply(double scalar, Vector result)
public virtual void Multiply(T scalar, Vector<T> result)
{
if (result == null)
{
@ -480,7 +465,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
CommonParallel.For(
0,
Count,
index => result[index] *= scalar);
index => result[index] = MultiplyT(result[index], scalar));
}
/// <summary>
@ -498,7 +483,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentNullException">
/// If <paramref name="other"/> is <see langword="null"/>.
/// </exception>
public virtual double DotProduct(Vector other)
public virtual T DotProduct(Vector<T> other)
{
if (other == null)
{
@ -510,10 +495,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "other");
}
var dot = 0.0;
var dot = default(T);
for (var i = 0; i < Count; i++)
{
dot += this[i] * other[i];
dot = AddT(dot, MultiplyT(this[i], other[i]));
}
return dot;
@ -526,14 +511,16 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// The scalar to divide with.
/// </param>
/// <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 Multiply(1.0 / scalar);
var copy = Clone();
Divide(scalar, copy);
return copy;
}
/// <summary>
@ -551,7 +538,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentException">
/// If this vector and <paramref name="result"/> are not the same size.
/// </exception>
public virtual void Divide(double scalar, Vector result)
public virtual void Divide(T scalar, Vector<T> result)
{
if (result == null)
{
@ -567,11 +554,11 @@ namespace MathNet.Numerics.LinearAlgebra.Double
{
CopyTo(result);
}
CommonParallel.For(
0,
Count,
index => result[index] /= scalar);
index => result[index] = DivideT(result[index], scalar));
}
/// <summary>
@ -581,7 +568,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <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="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)
{
@ -594,10 +581,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
}
var copy = Clone();
CommonParallel.For(
0,
Count,
index => copy[index] *= other[index]);
PointwiseMultiply(other, 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="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>
public virtual void PointwiseMultiply(Vector other, Vector result)
public virtual void PointwiseMultiply(Vector<T> other, Vector<T> result)
{
if (result == null)
{
@ -642,7 +626,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
CommonParallel.For(
0,
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>
/// <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>
public virtual Vector PointwiseDivide(Vector other)
public virtual Vector<T> PointwiseDivide(Vector<T> other)
{
if (other == null)
{
@ -666,10 +650,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
}
var copy = Clone();
CommonParallel.For(
0,
Count,
index => copy[index] /= other[index]);
PointwiseDivide(other, 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="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>
public virtual void PointwiseDivide(Vector other, Vector result)
public virtual void PointwiseDivide(Vector<T> other, Vector<T> result)
{
if (result == null)
{
@ -714,7 +695,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
CommonParallel.For(
0,
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>
/// <exception cref="ArgumentNullException">If the u 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)
{
@ -738,17 +719,11 @@ namespace MathNet.Numerics.LinearAlgebra.Double
throw new ArgumentNullException("v");
}
var matrix = new DenseMatrix(u.Count, v.Count);
var matrix = u.CreateMatrix(u.Count, v.Count);
CommonParallel.For(
0,
u.Count,
i =>
{
for (var j = 0; j < v.Count; j++)
{
matrix.At(i, j, u[i] * v[j]);
}
});
0,
u.Count,
i => matrix.SetRow(i, v.Multiply(u[i])));
return matrix;
}
@ -762,21 +737,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// to the specified random distribution.
/// </returns>
/// <exception cref="ArgumentException">If the n vector is non-positive.</exception>
public virtual Vector 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;
}
public abstract Vector<T> Random(int length, IContinuousDistribution randomDistribution);
/// <summary>
/// Generates a vector with random elements
@ -788,21 +749,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// to the specified random distribution.
/// </returns>
/// <exception cref="ArgumentException">If the n vector is not positive.</exception>
public virtual Vector 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;
}
public abstract Vector<T> Random(int length, IDiscreteDistribution randomDistribution);
/// <summary>
/// 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].
/// </returns>
/// <seealso cref="OuterProduct"/>
public Matrix TensorMultiply(Vector v)
public Matrix<T> TensorMultiply(Vector<T> v)
{
return OuterProduct(this, v);
}
@ -823,7 +770,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>The value of the absolute minimum element.</returns>
public virtual double AbsoluteMinimum()
{
return Math.Abs(this[AbsoluteMinimumIndex()]);
return AbsoluteT(this[AbsoluteMinimumIndex()]);
}
/// <summary>
@ -833,10 +780,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double
public virtual int AbsoluteMinimumIndex()
{
var index = 0;
var min = Math.Abs(this[index]);
var min = AbsoluteT(this[index]);
for (var i = 1; i < Count; i++)
{
var test = Math.Abs(this[i]);
var test = AbsoluteT(this[i]);
if (test < min)
{
index = i;
@ -846,14 +793,14 @@ namespace MathNet.Numerics.LinearAlgebra.Double
return index;
}
/// <summary>
/// Returns the value of the absolute maximum element.
/// </summary>
/// <returns>The value of the absolute maximum element.</returns>
public virtual double AbsoluteMaximum()
{
return Math.Abs(this[AbsoluteMaximumIndex()]);
return AbsoluteT(this[AbsoluteMaximumIndex()]);
}
/// <summary>
@ -863,10 +810,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double
public virtual int AbsoluteMaximumIndex()
{
var index = 0;
var max = Math.Abs(this[index]);
var max = AbsoluteT(this[index]);
for (var i = 1; i < Count; i++)
{
var test = Math.Abs(this[i]);
var test = AbsoluteT(this[i]);
if (test > max)
{
index = i;
@ -881,7 +828,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// Returns the value of maximum element.
/// </summary>
/// <returns>The value of maximum element.</returns>
public virtual double Maximum()
public virtual T Maximum()
{
return this[MaximumIndex()];
}
@ -890,27 +837,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// Returns the index of the absolute maximum element.
/// </summary>
/// <returns>The index of absolute maximum element.</returns>
public virtual 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;
}
public abstract int MaximumIndex();
/// <summary>
/// Returns the value of the minimum element.
/// </summary>
/// <returns>The value of the minimum element.</returns>
public virtual double Minimum()
public virtual T Minimum()
{
return this[MinimumIndex()];
}
@ -919,32 +852,18 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// Returns the index of the minimum element.
/// </summary>
/// <returns>The index of minimum element.</returns>
public virtual 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;
}
public abstract int MinimumIndex();
/// <summary>
/// Computes the sum of the vector's elements.
/// </summary>
/// <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++)
{
result += this[i];
result = AddT(result, this[i]);
}
return result;
@ -959,7 +878,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
double result = 0;
for (var i = 0; i < Count; i++)
{
result += Math.Abs(this[i]);
result += AbsoluteT(this[i]);
}
return result;
@ -976,7 +895,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="rightSide">The vector to get the values from.</param>
/// <returns>A vector containing the same values as <paramref name="rightSide"/>.</returns>
/// <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)
{
@ -994,7 +913,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <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="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)
{
@ -1020,7 +939,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="rightSide">The vector to get the values from.</param>
/// <returns>A vector containing the negated values as <paramref name="rightSide"/>.</returns>
/// <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)
{
@ -1038,7 +957,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <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="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)
{
@ -1065,7 +984,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="rightSide">The scalar value.</param>
/// <returns>The result of the multiplication.</returns>
/// <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)
{
@ -1082,7 +1001,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="rightSide">The vector to scale.</param>
/// <returns>The result of the multiplication.</returns>
/// <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)
{
@ -1100,7 +1019,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <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="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)
{
@ -1127,14 +1046,14 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="rightSide">The scalar value.</param>
/// <returns>The result of the division.</returns>
/// <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)
{
throw new ArgumentNullException("leftSide");
}
return leftSide.Multiply(1.0 / rightSide);
return leftSide.Divide(rightSide);
}
#endregion
@ -1162,14 +1081,14 @@ namespace MathNet.Numerics.LinearAlgebra.Double
return CommonParallel.Select(
0,
Count,
(index, localData) => Math.Max(localData, Math.Abs(this[index])),
(index, localData) => Math.Max(localData, AbsoluteT(this[index])),
Math.Max);
}
var sum = CommonParallel.Aggregate(
0,
Count,
index => Math.Pow(Math.Abs(this[index]), p));
index => Math.Pow(AbsoluteT(this[index]), p));
return Math.Pow(sum, 1.0 / p);
}
@ -1183,24 +1102,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>
/// This vector normalized to a unit vector with respect to the p-norm.
/// </returns>
public virtual Vector 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;
}
public abstract Vector<T> Normalize(double p);
#endregion
@ -1212,7 +1114,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>
/// A deep-copy clone of the vector.
/// </returns>
public Vector Clone()
public Vector<T> Clone()
{
var retrunVector = CreateVector(Count);
CopyTo(retrunVector);
@ -1231,7 +1133,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentException">
/// If <paramref name="target"/> is not the same size as this vector.
/// </exception>
public virtual void CopyTo(Vector target)
public virtual void CopyTo(Vector<T> target)
{
if (target == null)
{
@ -1269,7 +1171,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="count">
/// The number of elements to copy.
/// </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)
{
@ -1321,9 +1223,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>
/// The vector's data as an array.
/// </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++)
{
ret[i] = this[i];
@ -1338,7 +1240,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>
/// This vector as a column matrix.
/// </returns>
public virtual Matrix ToColumnMatrix()
public virtual Matrix<T> ToColumnMatrix()
{
var matrix = CreateMatrix(Count, 1);
for (var i = 0; i < Count; i++)
@ -1355,7 +1257,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>
/// This vector as a row matrix.
/// </returns>
public virtual Matrix ToRowMatrix()
public virtual Matrix<T> ToRowMatrix()
{
var matrix = CreateMatrix(1, Count);
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>
/// </list></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)
{
@ -1409,7 +1311,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <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="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)
{
@ -1465,7 +1367,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
#endregion
#region IEnumerable<double>
#region IEnumerable<T>
/// <summary>
/// Returns an enumerator that iterates through the collection.
@ -1473,7 +1375,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>
/// A <see cref="T:System.Collections.Generic.IEnumerator`1"/> that can be used to iterate through the collection.
/// </returns>
public virtual IEnumerator<double> GetEnumerator()
public virtual IEnumerator<T> GetEnumerator()
{
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
/// with a zero value.
/// </remarks>
public virtual IEnumerable<KeyValuePair<int, double>> GetIndexedEnumerator()
public virtual IEnumerable<KeyValuePair<int, T>> GetIndexedEnumerator()
{
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>
/// <c>true</c> if the current object is equal to the <paramref name="other"/> parameter; otherwise, <c>false</c>.
/// </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.
if (other == null)
@ -1538,7 +1440,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
// If all else fails, perform element wise comparison.
for (var index = 0; index < Count; index++)
{
if (!this[index].AlmostEqual(other[index]))
if (!this[index].Equals(other[index]))
{
return false;
}
@ -1577,7 +1479,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>
/// A <see cref="System.String"/> that represents this instance.
/// </returns>
public string ToString(string format, IFormatProvider formatProvider)
public virtual string ToString(string format, IFormatProvider formatProvider)
{
var stringBuilder = new StringBuilder();
for (var index = 0; index < Count; index++)
@ -1591,7 +1493,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double
return stringBuilder.ToString();
}
#endregion
#endregion
@ -1609,7 +1510,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// </returns>
public override bool Equals(object obj)
{
return Equals(obj as Vector);
return Equals(obj as Vector<T>);
}
/// <summary>
@ -1625,9 +1526,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double
for (var i = 0; i < hashNum; i++)
{
#if SILVERLIGHT
hash ^= Precision.DoubleToInt64Bits(this[i]);
hash ^= Precision.DoubleToInt64Bits(AbsoluteT(this[i]));
#else
hash ^= BitConverter.DoubleToInt64Bits(this[i]);
hash ^= BitConverter.DoubleToInt64Bits(this[i].GetHashCode());
#endif
}
@ -1652,7 +1553,56 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// </summary>
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\DenseVector.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\DenseLU.cs" />
<Compile Include="LinearAlgebra\Double\Factorization\DenseQR.cs" />
<Compile Include="LinearAlgebra\Double\Factorization\DenseSvd.cs" />
<Compile Include="LinearAlgebra\Double\Factorization\ExtensionMethods.cs" />
<Compile Include="LinearAlgebra\Double\Factorization\GramSchmidt.cs" />
<Compile Include="LinearAlgebra\Double\Factorization\LU.cs" />
<Compile Include="LinearAlgebra\Double\Factorization\QR.cs" />
<Compile Include="LinearAlgebra\Generic\Factorization\LU.cs" />
<Compile Include="LinearAlgebra\Generic\Factorization\QR.cs" />
<Compile Include="LinearAlgebra\Double\Factorization\SparseCholesky.cs" />
<Compile Include="LinearAlgebra\Double\Factorization\SparseLU.cs" />
<Compile Include="LinearAlgebra\Double\Factorization\SparseQR.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\UserLU.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\MatrixReader.cs" />
<Compile Include="LinearAlgebra\Double\IO\MatrixWriter.cs" />
<Compile Include="LinearAlgebra\Double\ISolver.cs" />
<Compile Include="LinearAlgebra\Double\Matrix.Arithmetic.cs" />
<Compile Include="LinearAlgebra\Double\Matrix.cs" />
<Compile Include="LinearAlgebra\Double\Solvers\IIterativeSolver.cs" />
<Compile Include="LinearAlgebra\Double\Solvers\IIterativeSolverSetup.cs" />
<Compile Include="LinearAlgebra\Double\Solvers\IIterator.cs" />
<Compile Include="LinearAlgebra\Generic\ISolver.cs" />
<Compile Include="LinearAlgebra\Generic\Solvers\IIterativeSolver.cs" />
<Compile Include="LinearAlgebra\Generic\Solvers\IIterativeSolverSetup.cs" />
<Compile Include="LinearAlgebra\Generic\Solvers\IIterator.cs" />
<Compile Include="LinearAlgebra\Double\Solvers\Iterative\BiCgStab.cs" />
<Compile Include="LinearAlgebra\Double\Solvers\Iterative\CompositeSolver.cs" />
<Compile Include="LinearAlgebra\Double\Solvers\Iterative\GpBiCg.cs" />
@ -153,25 +151,27 @@
<Compile Include="LinearAlgebra\Double\Solvers\Preconditioners\IncompleteLU.cs">
<SubType>Code</SubType>
</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\Status\CalculationCancelled.cs" />
<Compile Include="LinearAlgebra\Double\Solvers\Status\CalculationConverged.cs" />
<Compile Include="LinearAlgebra\Double\Solvers\Status\CalculationDiverged.cs" />
<Compile Include="LinearAlgebra\Double\Solvers\Status\CalculationFailure.cs" />
<Compile Include="LinearAlgebra\Double\Solvers\Status\CalculationIndetermined.cs" />
<Compile Include="LinearAlgebra\Double\Solvers\Status\CalculationRunning.cs" />
<Compile Include="LinearAlgebra\Double\Solvers\Status\CalculationStoppedWithoutConvergence.cs" />
<Compile Include="LinearAlgebra\Double\Solvers\Status\ICalculationStatus.cs" />
<Compile Include="LinearAlgebra\Generic\Solvers\Status\CalculationCancelled.cs" />
<Compile Include="LinearAlgebra\Generic\Solvers\Status\CalculationConverged.cs" />
<Compile Include="LinearAlgebra\Generic\Solvers\Status\CalculationDiverged.cs" />
<Compile Include="LinearAlgebra\Generic\Solvers\Status\CalculationFailure.cs" />
<Compile Include="LinearAlgebra\Generic\Solvers\Status\CalculationIndetermined.cs" />
<Compile Include="LinearAlgebra\Generic\Solvers\Status\CalculationRunning.cs" />
<Compile Include="LinearAlgebra\Generic\Solvers\Status\CalculationStoppedWithoutConvergence.cs" />
<Compile Include="LinearAlgebra\Generic\Solvers\Status\ICalculationStatus.cs" />
<Compile Include="LinearAlgebra\Double\Solvers\StopCriterium\DivergenceStopCriterium.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\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\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="Distributions\Continuous\Beta.cs" />
<Compile Include="Distributions\Continuous\ContinuousUniform.cs" />

130
src/Silverlight/Silverlight.csproj

@ -224,9 +224,6 @@
<Compile Include="..\Numerics\LinearAlgebra\Double\DiagonalMatrix.cs">
<Link>LinearAlgebra\Double\DiagonalMatrix.cs</Link>
</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">
<Link>LinearAlgebra\Double\Factorization\DenseCholesky.cs</Link>
</Compile>
@ -245,12 +242,6 @@
<Compile Include="..\Numerics\LinearAlgebra\Double\Factorization\GramSchmidt.cs">
<Link>LinearAlgebra\Double\Factorization\GramSchmidt.cs</Link>
</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">
<Link>LinearAlgebra\Double\Factorization\SparseCholesky.cs</Link>
</Compile>
@ -263,9 +254,6 @@
<Compile Include="..\Numerics\LinearAlgebra\Double\Factorization\SparseSvd.cs">
<Link>LinearAlgebra\Double\Factorization\SparseSvd.cs</Link>
</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">
<Link>LinearAlgebra\Double\Factorization\UserCholesky.cs</Link>
</Compile>
@ -290,24 +278,6 @@
<Compile Include="..\Numerics\LinearAlgebra\Double\IO\MatrixWriter.cs">
<Link>LinearAlgebra\Double\IO\MatrixWriter.cs</Link>
</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">
<Link>LinearAlgebra\Double\Solvers\Iterative\BiCgStab.cs</Link>
</Compile>
@ -338,62 +308,92 @@
<Compile Include="..\Numerics\LinearAlgebra\Double\Solvers\Preconditioners\IncompleteLU.cs">
<Link>LinearAlgebra\Double\Solvers\Preconditioners\IncompleteLU.cs</Link>
</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">
<Link>LinearAlgebra\Double\Solvers\Preconditioners\UnitPreconditioner.cs</Link>
</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">
<Link>LinearAlgebra\Double\Solvers\StopCriterium\DivergenceStopCriterium.cs</Link>
</Compile>
<Compile Include="..\Numerics\LinearAlgebra\Double\Solvers\StopCriterium\FailureStopCriterium.cs">
<Link>LinearAlgebra\Double\Solvers\StopCriterium\FailureStopCriterium.cs</Link>
</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">
<Link>LinearAlgebra\Double\Solvers\StopCriterium\IterationCountStopCriterium.cs</Link>
</Compile>
<Compile Include="..\Numerics\LinearAlgebra\Double\Solvers\StopCriterium\ResidualStopCriterium.cs">
<Link>LinearAlgebra\Double\Solvers\StopCriterium\ResidualStopCriterium.cs</Link>
</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">
<Link>LinearAlgebra\Double\SparseMatrix.cs</Link>
</Compile>
<Compile Include="..\Numerics\LinearAlgebra\Double\SparseVector.cs">
<Link>LinearAlgebra\Double\SparseVector.cs</Link>
</Compile>
<Compile Include="..\Numerics\LinearAlgebra\Double\Vector.cs">
<Link>LinearAlgebra\Double\Vector.cs</Link>
<Compile Include="..\Numerics\LinearAlgebra\Generic\Factorization\Cholesky.cs">
<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 Include="..\Numerics\NumberTheory\IntegerTheory.cs">
<Link>NumberTheory\IntegerTheory.cs</Link>

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

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

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

@ -27,7 +27,7 @@
namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
{
using System;
using LinearAlgebra.Double;
using LinearAlgebra.Generic;
using MbUnit.Framework;
[TestFixture]
@ -42,7 +42,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[MultipleAsserts]
public void CanCloneMatrix(string name)
{
var matrix = this.CreateMatrix(this.TestData2D[name]);
var matrix = CreateMatrix(TestData2D[name]);
var clone = matrix.Clone();
Assert.AreNotSame(matrix, clone);
@ -66,8 +66,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[MultipleAsserts]
public void CanCloneMatrixUsingICloneable(string name)
{
var matrix = this.TestMatrices[name];
var clone = (Matrix)((ICloneable)matrix).Clone();
var matrix = TestMatrices[name];
var clone = (Matrix<double>)((ICloneable)matrix).Clone();
Assert.AreNotSame(matrix, clone);
Assert.AreEqual(matrix.RowCount, clone.RowCount);
@ -90,8 +90,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[MultipleAsserts]
public void CanCopyTo(string name)
{
var matrix = this.TestMatrices[name];
var copy = this.CreateMatrix(matrix.RowCount, matrix.ColumnCount);
var matrix = TestMatrices[name];
var copy = CreateMatrix(matrix.RowCount, matrix.ColumnCount);
matrix.CopyTo(copy);
Assert.AreNotSame(matrix, copy);
@ -108,8 +108,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentNullException]
public void CopyToFailsWhenTargetIsNull()
{
var matrix = this.TestMatrices["Singular3x3"];
Matrix target = null;
var matrix = TestMatrices["Singular3x3"];
Matrix<double> target = null;
matrix.CopyTo(target);
}
@ -117,8 +117,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentException]
public void CopyToFailsWhenTargetHasMoreRows()
{
var matrix = this.TestMatrices["Singular3x3"];
var target = this.CreateMatrix(matrix.RowCount + 1, matrix.ColumnCount);
var matrix = TestMatrices["Singular3x3"];
var target = CreateMatrix(matrix.RowCount + 1, matrix.ColumnCount);
matrix.CopyTo(target);
}
@ -126,8 +126,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentException]
public void CopyToFailsWhenTargetHasMoreColumns()
{
var matrix = this.TestMatrices["Singular3x3"];
var target = this.CreateMatrix(matrix.RowCount + 1, matrix.ColumnCount);
var matrix = TestMatrices["Singular3x3"];
var target = CreateMatrix(matrix.RowCount + 1, matrix.ColumnCount);
matrix.CopyTo(target);
}
@ -140,7 +140,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Test]
public void CanCreateMatrix()
{
var expected = this.CreateMatrix(5, 6);
var expected = CreateMatrix(5, 6);
var actual = expected.CreateMatrix(5, 6);
Assert.AreEqual(expected.GetType(), actual.GetType(), "Matrices are same type.");
}
@ -154,9 +154,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[MultipleAsserts]
public void CanEquateMatrices(string name)
{
var matrix1 = this.CreateMatrix(this.TestData2D[name]);
var matrix2 = this.CreateMatrix(this.TestData2D[name]);
var matrix3 = this.CreateMatrix(this.TestData2D[name].GetLength(0), this.TestData2D[name].GetLength(1));
var matrix1 = CreateMatrix(TestData2D[name]);
var matrix2 = CreateMatrix(TestData2D[name]);
var matrix3 = CreateMatrix(TestData2D[name].GetLength(0), TestData2D[name].GetLength(1));
Assert.IsTrue(matrix1.Equals(matrix1));
Assert.IsTrue(matrix1.Equals(matrix2));
Assert.IsFalse(matrix1.Equals(matrix3));
@ -172,7 +172,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentOutOfRangeException]
public void ThrowsArgumentExceptionIfSizeIsNotPositive(int rows, int columns)
{
var A = this.CreateMatrix(rows, columns);
var A = CreateMatrix(rows, columns);
}
[Test]
@ -183,7 +183,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Row("Wide2x3")]
public void TestingForEqualityWithNonMatrixReturnsFalse(string name)
{
var matrix = this.CreateMatrix(this.TestData2D[name]);
var matrix = CreateMatrix(TestData2D[name]);
Assert.IsFalse(matrix.Equals(2));
}
@ -195,8 +195,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Row("Wide2x3")]
public void CanTestForEqualityUsingObjectEquals(string name)
{
var matrix1 = this.CreateMatrix(this.TestData2D[name]);
var matrix2 = this.CreateMatrix(this.TestData2D[name]);
var matrix1 = CreateMatrix(TestData2D[name]);
var matrix2 = CreateMatrix(TestData2D[name]);
Assert.IsTrue(matrix1.Equals((object)matrix2));
}
@ -207,7 +207,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentOutOfRangeException))]
public void RangeCheckFails(int i, int j, string name)
{
var d = this.TestMatrices[name][i, j];
var d = TestMatrices[name][i, j];
}
[Test]
@ -219,7 +219,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Test]
public void CanClearMatrix()
{
var matrix = this.TestMatrices["Singular3x3"].Clone();
var matrix = TestMatrices["Singular3x3"].Clone();
matrix.Clear();
for (var i = 0; i < matrix.RowCount; i++)
{
@ -237,7 +237,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Row(2, "Square3x3")]
public void CanGetRow(int rowIndex, string name)
{
var matrix = this.TestMatrices[name];
var matrix = TestMatrices[name];
var row = matrix.Row(rowIndex);
Assert.AreEqual(matrix.ColumnCount, row.Count);
@ -251,7 +251,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentOutOfRangeException))]
public void GetRowThrowsArgumentOutOfRangeWithNegativeIndex()
{
var matrix = this.TestMatrices["Singular3x3"];
var matrix = TestMatrices["Singular3x3"];
matrix.Row(-1);
}
@ -259,7 +259,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentOutOfRangeException))]
public void GetRowThrowsArgumentOutOfRangeWithOverflowingRowIndex()
{
var matrix = this.TestMatrices["Singular3x3"];
var matrix = TestMatrices["Singular3x3"];
matrix.Row(matrix.RowCount);
}
@ -270,7 +270,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Row(2, "Square3x3")]
public void CanGetRowWithResult(int rowIndex, string name)
{
var matrix = this.TestMatrices[name];
var matrix = TestMatrices[name];
var row = CreateVector(matrix.ColumnCount);
matrix.Row(rowIndex, row);
@ -285,7 +285,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentNullException))]
public void GetRowWithResultFailsWhenResultIsNull()
{
var matrix = this.TestMatrices["Singular3x3"];
var matrix = TestMatrices["Singular3x3"];
matrix.Row(0, null);
}
@ -293,7 +293,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentOutOfRangeException))]
public void GetRowWithResultThrowsArgumentOutOfRangeWithNegativeIndex()
{
var matrix = this.TestMatrices["Singular3x3"];
var matrix = TestMatrices["Singular3x3"];
var row = CreateVector(matrix.ColumnCount);
matrix.Row(-1, row);
}
@ -302,7 +302,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentOutOfRangeException))]
public void GetRowWithResultThrowsArgumentOutOfRangeWithOverflowingRowIndex()
{
var matrix = this.TestMatrices["Singular3x3"];
var matrix = TestMatrices["Singular3x3"];
var row = CreateVector(matrix.ColumnCount);
matrix.Row(matrix.RowCount, row);
}
@ -314,7 +314,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Row(2, 0, 3, "Square3x3")]
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);
Assert.AreEqual(length, row.Count);
@ -328,7 +328,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentException))]
public void GetRowWithRangeResultArgumentExeptionWhenLengthIsZero()
{
var matrix = this.TestMatrices["Singular3x3"];
var matrix = TestMatrices["Singular3x3"];
var result = CreateVector(matrix.ColumnCount);
matrix.Row(0, 0, 0, result);
}
@ -337,8 +337,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentException))]
public void GetRowWithRangeFailsWithTooSmallResultVector()
{
var matrix = this.TestMatrices["Singular3x3"];
var result = this.CreateVector(matrix.ColumnCount - 1);
var matrix = TestMatrices["Singular3x3"];
var result = CreateVector(matrix.ColumnCount - 1);
matrix.Row(0, 0, 0, result);
}
@ -349,7 +349,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Row(2, "Square3x3")]
public void CanGetColumn(int colIndex, string name)
{
var matrix = this.TestMatrices[name];
var matrix = TestMatrices[name];
var col = matrix.Column(colIndex);
Assert.AreEqual(matrix.RowCount, col.Count);
@ -363,7 +363,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentOutOfRangeException))]
public void GetColumnThrowsArgumentOutOfRangeWithNegativeIndex()
{
var matrix = this.TestMatrices["Singular3x3"];
var matrix = TestMatrices["Singular3x3"];
matrix.Column(-1);
}
@ -371,7 +371,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentOutOfRangeException))]
public void GetColumnThrowsArgumentOutOfRangeWithOverflowingRowIndex()
{
var matrix = this.TestMatrices["Singular3x3"];
var matrix = TestMatrices["Singular3x3"];
matrix.Column(matrix.ColumnCount);
}
@ -382,7 +382,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Row(2, "Square3x3")]
public void CanGetColumnWithResult(int colIndex, string name)
{
var matrix = this.TestMatrices[name];
var matrix = TestMatrices[name];
var col = CreateVector(matrix.RowCount);
matrix.Column(colIndex, col);
@ -397,7 +397,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentNullException))]
public void GetColumnFailsWhenResultIsNull()
{
var matrix = this.TestMatrices["Singular3x3"];
var matrix = TestMatrices["Singular3x3"];
matrix.Column(0, null);
}
@ -405,7 +405,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentOutOfRangeException))]
public void GetColumnWithResultThrowsArgumentOutOfRangeWithNegativeIndex()
{
var matrix = this.TestMatrices["Singular3x3"];
var matrix = TestMatrices["Singular3x3"];
var column = CreateVector(matrix.ColumnCount);
matrix.Column(-1, column);
}
@ -414,7 +414,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentOutOfRangeException))]
public void GetColumnWithResultThrowsArgumentOutOfRangeWithOverflowingRowIndex()
{
var matrix = this.TestMatrices["Singular3x3"];
var matrix = TestMatrices["Singular3x3"];
var column = CreateVector(matrix.RowCount);
matrix.Row(matrix.ColumnCount, column);
}
@ -426,7 +426,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Row(2, 0, 3, "Square3x3")]
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);
Assert.AreEqual(length, col.Count);
@ -440,7 +440,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentException))]
public void GetColumnWithRangeResultArgumentExeptionWhenLengthIsZero()
{
var matrix = this.TestMatrices["Singular3x3"];
var matrix = TestMatrices["Singular3x3"];
var col = CreateVector(matrix.RowCount);
matrix.Column(0, 0, 0, col);
}
@ -449,8 +449,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentException))]
public void GetColumnWithRangeFailsWithTooSmallResultVector()
{
var matrix = this.TestMatrices["Singular3x3"];
var result = this.CreateVector(matrix.RowCount - 1);
var matrix = TestMatrices["Singular3x3"];
var result = CreateVector(matrix.RowCount - 1);
matrix.Column(0, 0, matrix.RowCount, result);
}
@ -461,7 +461,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Row(2, "Square3x3")]
public void CanSetRow(int rowIndex, string name)
{
var matrix = this.TestMatrices[name].Clone();
var matrix = TestMatrices[name].Clone();
matrix.SetRow(rowIndex, CreateVector(matrix.ColumnCount));
for (var i = 0; i < matrix.RowCount; i++)
@ -474,7 +474,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
}
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")]
public void CanSetColumn(int colIndex, string name)
{
var matrix = this.TestMatrices[name].Clone();
var matrix = TestMatrices[name].Clone();
matrix.SetColumn(colIndex, CreateVector(matrix.ColumnCount));
for (var i = 0; i < matrix.RowCount; i++)
@ -500,7 +500,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
}
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]
public void UpperTriangleResult(string name)
{
var data = this.TestMatrices[name];
var result = this.CreateMatrix(data.RowCount, data.ColumnCount);
var data = TestMatrices[name];
var result = CreateMatrix(data.RowCount, data.ColumnCount);
var lower = data.UpperTriangle();
for (var i = 0; i < data.RowCount; i++)
{
@ -539,8 +539,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentNullException]
public void UpperTriangleWithResultNullShouldThrowException()
{
var data = this.TestMatrices["Square3x3"];
Matrix result = null;
var data = TestMatrices["Square3x3"];
Matrix<double> result = null;
data.UpperTriangle(result);
}
@ -548,8 +548,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentException]
public void UpperTriangleWithUnEqualRowsShouldThrowException()
{
var data = this.TestMatrices["Square3x3"];
var result = this.CreateMatrix(data.RowCount + 1, data.ColumnCount);
var data = TestMatrices["Square3x3"];
var result = CreateMatrix(data.RowCount + 1, data.ColumnCount);
data.UpperTriangle(result);
}
@ -557,15 +557,15 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentException]
public void UpperTriangleWithUnEqualColumnsShouldThrowException()
{
var data = this.TestMatrices["Square3x3"];
var result = this.CreateMatrix(data.RowCount, data.ColumnCount + 1);
var data = TestMatrices["Square3x3"];
var result = CreateMatrix(data.RowCount, data.ColumnCount + 1);
data.UpperTriangle(result);
}
[Test]
public void StrictlyLowerTriangle()
{
foreach (var data in this.TestMatrices.Values)
foreach (var data in TestMatrices.Values)
{
var lower = data.StrictlyLowerTriangle();
for (var i = 0; i < data.RowCount; i++)
@ -588,9 +588,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Test]
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);
for (var i = 0; i < data.RowCount; i++)
{
@ -613,8 +613,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentNullException]
public void StrictlyLowerTriangleWithNullParameterShouldThrowException()
{
var data = this.TestMatrices["Square3x3"];
Matrix lower = null;
var data = TestMatrices["Square3x3"];
Matrix<double> lower = null;
data.StrictlyLowerTriangle(lower);
}
@ -622,8 +622,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentException]
public void StrictlyLowerTriangleWithInvalidColumnNumberShouldThrowException()
{
var data = this.TestMatrices["Square3x3"];
var lower = this.CreateMatrix(data.RowCount, data.ColumnCount + 1);
var data = TestMatrices["Square3x3"];
var lower = CreateMatrix(data.RowCount, data.ColumnCount + 1);
data.StrictlyLowerTriangle(lower);
}
@ -631,8 +631,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentException]
public void StrictlyLowerTriangleWithInvalidRowNumberShouldThrowException()
{
var data = this.TestMatrices["Square3x3"];
var lower = this.CreateMatrix(data.RowCount + 1, data.ColumnCount);
var data = TestMatrices["Square3x3"];
var lower = CreateMatrix(data.RowCount + 1, data.ColumnCount);
data.StrictlyLowerTriangle(lower);
}
@ -640,7 +640,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Test]
public void StrictlyUpperTriangle()
{
foreach (var data in this.TestMatrices.Values)
foreach (var data in TestMatrices.Values)
{
var lower = data.StrictlyUpperTriangle();
for (var i = 0; i < data.RowCount; i++)
@ -663,9 +663,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Test]
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);
for (var i = 0; i < data.RowCount; i++)
{
@ -688,8 +688,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentNullException]
public void StrictlyUpperTriangleWithNullParameterShouldThrowException()
{
var data = this.TestMatrices["Square3x3"];
Matrix lower = null;
var data = TestMatrices["Square3x3"];
Matrix<double> lower = null;
data.StrictlyUpperTriangle(lower);
}
@ -697,8 +697,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentException]
public void StrictlyUpperTriangleWithInvalidColumnNumberShouldThrowException()
{
var data = this.TestMatrices["Square3x3"];
var lower = this.CreateMatrix(data.RowCount, data.ColumnCount + 1);
var data = TestMatrices["Square3x3"];
var lower = CreateMatrix(data.RowCount, data.ColumnCount + 1);
data.StrictlyUpperTriangle(lower);
}
@ -706,8 +706,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentException]
public void StrictlyUpperTriangleWithInvalidRowNumberShouldThrowException()
{
var data = this.TestMatrices["Square3x3"];
var lower = this.CreateMatrix(data.RowCount + 1, data.ColumnCount);
var data = TestMatrices["Square3x3"];
var lower = CreateMatrix(data.RowCount + 1, data.ColumnCount);
data.StrictlyUpperTriangle(lower);
}
@ -720,7 +720,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[MultipleAsserts]
public void CanTransposeMatrix(string name)
{
var matrix = this.CreateMatrix(this.TestData2D[name]);
var matrix = CreateMatrix(TestData2D[name]);
var transpose = 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))]
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++)
{
matrix.SetColumn(i, column);
@ -759,7 +759,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentOutOfRangeException]
public void SetColumnArrayWithInvalidColumnIndexShouldThrowException()
{
var matrix = this.TestMatrices["Square3x3"];
var matrix = TestMatrices["Square3x3"];
double[] column = { 1, 2, 3 };
matrix.SetColumn(-1, column);
}
@ -768,7 +768,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentOutOfRangeException]
public void SetColumnArrayWithInvalidColumnIndexShouldThrowException2()
{
var matrix = this.TestMatrices["Square3x3"];
var matrix = TestMatrices["Square3x3"];
double[] column = { 1, 2, 3 };
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))]
public virtual void SetColumnWithVector(string name, double[] column)
{
var matrix = this.TestMatrices[name];
var matrix = TestMatrices[name];
var columnVector = CreateVector(column);
for (var i = 0; i < matrix.ColumnCount; i++)
{
@ -797,8 +797,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentNullException]
public void SetColumnWithNullVectorShouldThrowException()
{
var matrix = this.TestMatrices["Square3x3"];
Vector columnVector = null;
var matrix = TestMatrices["Square3x3"];
Vector<double> columnVector = null;
matrix.SetColumn(1, columnVector);
}
@ -806,8 +806,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentOutOfRangeException]
public void SetColumnVectorWithInvalidColumnIndexShouldThrowException()
{
var matrix = this.TestMatrices["Square3x3"];
var column = this.CreateVector(new double[] { 1, 2, 3 });
var matrix = TestMatrices["Square3x3"];
var column = CreateVector(new double[] { 1, 2, 3 });
matrix.SetColumn(-1, column);
}
@ -815,15 +815,15 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentOutOfRangeException]
public void SetColumnVectorWithInvalidColumnIndexShouldThrowException2()
{
var matrix = this.TestMatrices["Square3x3"];
var column = this.CreateVector(new double[] { 1, 2, 3 });
var matrix = TestMatrices["Square3x3"];
var column = CreateVector(new double[] { 1, 2, 3 });
matrix.SetColumn(matrix.ColumnCount + 1, column);
}
[Test]
public void InsertColumn()
{
var matrix = this.CreateMatrix(3, 3);
var matrix = CreateMatrix(3, 3);
var column = CreateVector(matrix.RowCount);
for (var i = 0; i < column.Count; i++)
{
@ -855,7 +855,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentNullException))]
public void InsertNullColumnShouldThrowExecption()
{
var matrix = this.TestMatrices["Square3x3"];
var matrix = TestMatrices["Square3x3"];
matrix.InsertColumn(0, null);
}
@ -864,15 +864,15 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Row(5, ExpectedException = typeof(ArgumentOutOfRangeException))]
public void InsertColumnWithInvalidColumnIndexShouldThrowExceptiopn(int columnIndex)
{
var matrix = this.CreateMatrix(3, 3);
var matrix = CreateMatrix(3, 3);
var column = CreateVector(matrix.RowCount);
matrix.InsertColumn(columnIndex, column);
}
public void InsertColumnWithInvalidNumberOfElementsShouldThrowException()
{
var matrix = this.CreateMatrix(3, 3);
var column = this.CreateVector(matrix.RowCount + 1);
var matrix = CreateMatrix(3, 3);
var column = CreateVector(matrix.RowCount + 1);
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))]
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++)
{
matrix.SetRow(i, row);
@ -900,7 +900,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentOutOfRangeException]
public void SetRowArrayWithInvalidRowIndexShouldThrowException()
{
var matrix = this.TestMatrices["Square3x3"];
var matrix = TestMatrices["Square3x3"];
double[] row = { 1, 2, 3 };
matrix.SetRow(-1, row);
}
@ -909,7 +909,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentOutOfRangeException]
public void SetRowArrayWithInvalidRowIndexShouldThrowException2()
{
var matrix = this.TestMatrices["Square3x3"];
var matrix = TestMatrices["Square3x3"];
double[] row = { 1, 2, 3 };
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))]
public virtual void SetRowWithVector(string name, double[] row)
{
var matrix = this.TestMatrices[name];
var matrix = TestMatrices[name];
var rowVector = CreateVector(row);
for (var i = 0; i < matrix.RowCount; i++)
{
@ -938,8 +938,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentNullException]
public void SetRowWithNullVectorShouldThrowException()
{
var matrix = this.TestMatrices["Square3x3"];
Vector rowVector = null;
var matrix = TestMatrices["Square3x3"];
Vector<double> rowVector = null;
matrix.SetRow(1, rowVector);
}
@ -947,8 +947,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentOutOfRangeException]
public void SetRowVectorWithInvalidRowIndexShouldThrowException()
{
var matrix = this.TestMatrices["Square3x3"];
var row = this.CreateVector(new double[] { 1, 2, 3 });
var matrix = TestMatrices["Square3x3"];
var row = CreateVector(new double[] { 1, 2, 3 });
matrix.SetRow(-1, row);
}
@ -956,8 +956,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentOutOfRangeException]
public void SetRowVectorWithInvalidRowIndexShouldThrowException2()
{
var matrix = this.TestMatrices["Square3x3"];
var row = this.CreateVector(new double[] { 1, 2, 3 });
var matrix = TestMatrices["Square3x3"];
var row = CreateVector(new double[] { 1, 2, 3 });
matrix.SetRow(matrix.RowCount + 1, row);
}
@ -974,7 +974,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Row(0, 2, 0, -1, ExpectedException = typeof(ArgumentException))]
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);
subMatrix[0, 0] = 10.0;
@ -997,8 +997,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentNullException]
public void SetSubMatrixWithNullSubMatrixShouldThrowException()
{
var data = this.TestMatrices["Square3x3"];
Matrix subMatrix = null;
var data = TestMatrices["Square3x3"];
Matrix<double> subMatrix = null;
data.SetSubMatrix(0, 2, 0, 2, subMatrix);
}
@ -1009,7 +1009,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Row("Tall3x2", new double[] { 1, 2 })]
public void SetDiagonalVector(string name, double[] diagonal)
{
var matrix = this.TestMatrices[name];
var matrix = TestMatrices[name];
var vector = CreateVector(diagonal);
matrix.SetDiagonal(vector);
@ -1026,8 +1026,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentNullException]
public void SetDiagonalWithNullVectorParameterShouldThrowException()
{
var matrix = this.TestMatrices["Square3x3"];
Vector vector = null;
var matrix = TestMatrices["Square3x3"];
Vector<double> vector = null;
matrix.SetDiagonal(vector);
}
@ -1039,7 +1039,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Row("Square3x3", null, ExpectedException = typeof(ArgumentNullException))]
public void SetDiagonalArray(string name, double[] diagonal)
{
var matrix = this.TestMatrices[name];
var matrix = TestMatrices[name];
matrix.SetDiagonal(diagonal);
var min = Math.Min(matrix.ColumnCount, matrix.RowCount);
Assert.AreEqual(diagonal.Length, min);
@ -1052,7 +1052,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Test]
public void InsertRow()
{
var matrix = this.CreateMatrix(3, 3);
var matrix = CreateMatrix(3, 3);
var row = CreateVector(matrix.ColumnCount);
for (var i = 0; i < row.Count; i++)
{
@ -1084,7 +1084,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedException(typeof(ArgumentNullException))]
public void InsertNullRowShouldThrowExecption()
{
var matrix = this.TestMatrices["Square3x3"];
var matrix = TestMatrices["Square3x3"];
matrix.InsertRow(0, null);
}
@ -1093,22 +1093,22 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Row(5, ExpectedException = typeof(ArgumentOutOfRangeException))]
public void InsertRowWithInvalidRowIndexShouldThrowExceptiopn(int rowIndex)
{
var matrix = this.CreateMatrix(3, 3);
var matrix = CreateMatrix(3, 3);
var row = CreateVector(matrix.ColumnCount);
matrix.InsertRow(rowIndex, row);
}
public void InsertRowWithInvalidNumberOfElementsShouldThrowException()
{
var matrix = this.CreateMatrix(3, 3);
var row = this.CreateVector(matrix.ColumnCount + 1);
var matrix = CreateMatrix(3, 3);
var row = CreateVector(matrix.ColumnCount + 1);
matrix.InsertRow(0, row);
}
[Test]
public void ToArray()
{
foreach (var data in this.TestMatrices.Values)
foreach (var data in TestMatrices.Values)
{
var array = data.ToArray();
Assert.AreEqual(data.RowCount, array.GetLength(0));
@ -1127,7 +1127,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Test]
public void ToColumnWiseArray()
{
foreach (var data in this.TestMatrices.Values)
foreach (var data in TestMatrices.Values)
{
var array = data.ToColumnWiseArray();
Assert.AreEqual(data.RowCount * data.ColumnCount, array.Length);
@ -1145,7 +1145,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Test]
public void ToRowWiseArray()
{
foreach (var data in this.TestMatrices.Values)
foreach (var data in TestMatrices.Values)
{
var array = data.ToRowWiseArray();
Assert.AreEqual(data.RowCount * data.ColumnCount, array.Length);
@ -1168,8 +1168,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[MultipleAsserts]
public virtual void CanPermuteMatrixRows(string name)
{
var matrix = this.CreateMatrix(this.TestData2D[name]);
var matrixp = this.CreateMatrix(this.TestData2D[name]);
var matrix = CreateMatrix(TestData2D[name]);
var matrixp = CreateMatrix(TestData2D[name]);
var permutation = new Permutation(new[] { 2, 0, 1 });
matrixp.PermuteRows(permutation);
@ -1193,8 +1193,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[MultipleAsserts]
public virtual void CanPermuteMatrixColumns(string name)
{
var matrix = this.CreateMatrix(this.TestData2D[name]);
var matrixp = this.CreateMatrix(this.TestData2D[name]);
var matrix = CreateMatrix(TestData2D[name]);
var matrixp = CreateMatrix(TestData2D[name]);
var permutation = new Permutation(new[] { 2, 0, 1 });
matrixp.PermuteColumns(permutation);
@ -1214,8 +1214,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Test]
public void CanAppendMatrices()
{
var left = this.CreateMatrix(this.TestData2D["Singular3x3"]);
var right = this.CreateMatrix(this.TestData2D["Tall3x2"]);
var left = CreateMatrix(TestData2D["Singular3x3"]);
var right = CreateMatrix(TestData2D["Tall3x2"]);
var result = left.Append(right);
Assert.AreEqual(left.ColumnCount + right.ColumnCount, result.ColumnCount);
Assert.AreEqual(left.RowCount, right.RowCount);
@ -1240,8 +1240,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentNullException]
public void CanAppendWithRightParameterNullShouldThrowException()
{
var left = this.TestMatrices["Square3x3"];
Matrix right = null;
var left = TestMatrices["Square3x3"];
Matrix<double> right = null;
left.Append(right);
}
@ -1249,9 +1249,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentNullException]
public void CanAppendWithResultParameterNullShouldThrowException()
{
var left = this.TestMatrices["Square3x3"];
var right = this.TestMatrices["Tall3x2"];
Matrix result = null;
var left = TestMatrices["Square3x3"];
var right = TestMatrices["Tall3x2"];
Matrix<double> result = null;
left.Append(right, result);
}
@ -1259,8 +1259,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentException]
public void AppendingTwoMatricesWithDifferentRowCountShouldThrowException()
{
var left = this.TestMatrices["Square3x3"];
var right = this.TestMatrices["Wide2x3"];
var left = TestMatrices["Square3x3"];
var right = TestMatrices["Wide2x3"];
var result = left.Append(right);
}
@ -1268,17 +1268,17 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentException]
public void AppendingWithInvalidResultMatrixColumnsShouldThrowException()
{
var left = this.TestMatrices["Square3x3"];
var right = this.TestMatrices["Tall3x2"];
var result = this.CreateMatrix(3, 2);
var left = TestMatrices["Square3x3"];
var right = TestMatrices["Tall3x2"];
var result = CreateMatrix(3, 2);
left.Append(right, result);
}
[Test]
public void CanStackMatrices()
{
var top = this.TestMatrices["Square3x3"];
var bottom = this.TestMatrices["Wide2x3"];
var top = TestMatrices["Square3x3"];
var bottom = TestMatrices["Wide2x3"];
var result = top.Stack(bottom);
Assert.AreEqual(top.RowCount + bottom.RowCount, result.RowCount);
Assert.AreEqual(top.ColumnCount, result.ColumnCount);
@ -1303,9 +1303,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentNullException]
public void StackingWithBottomParameterNullShouldThrowException()
{
var top = this.TestMatrices["Square3x3"];
Matrix bottom = null;
var result = this.CreateMatrix(top.RowCount + top.RowCount, top.ColumnCount);
var top = TestMatrices["Square3x3"];
Matrix<double> bottom = null;
var result = CreateMatrix(top.RowCount + top.RowCount, top.ColumnCount);
top.Stack(bottom, result);
}
@ -1313,9 +1313,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentNullException]
public void StackingWithResultParameterNullShouldThrowException()
{
var top = this.TestMatrices["Square3x3"];
var bottom = this.TestMatrices["Square3x3"];
Matrix result = null;
var top = TestMatrices["Square3x3"];
var bottom = TestMatrices["Square3x3"];
Matrix<double> result = null;
top.Stack(bottom, result);
}
@ -1323,9 +1323,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentException]
public void StackingTwoMatricesWithDifferentColumnsShouldThrowException()
{
var top = this.TestMatrices["Square3x3"];
var lower = this.TestMatrices["Tall3x2"];
var result = this.CreateMatrix(top.RowCount + lower.RowCount, top.ColumnCount);
var top = TestMatrices["Square3x3"];
var lower = TestMatrices["Tall3x2"];
var result = CreateMatrix(top.RowCount + lower.RowCount, top.ColumnCount);
top.Stack(lower, result);
}
@ -1333,17 +1333,17 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentException]
public void StackingWithInvalidResultMatrixRowsShouldThrowException()
{
var top = this.TestMatrices["Square3x3"];
var bottom = this.TestMatrices["Wide2x3"];
var result = this.CreateMatrix(1, 3);
var top = TestMatrices["Square3x3"];
var bottom = TestMatrices["Wide2x3"];
var result = CreateMatrix(1, 3);
top.Stack(bottom, result);
}
[Test]
public void CanDiagonallyStackMatrics()
{
var top = this.TestMatrices["Tall3x2"];
var bottom = this.TestMatrices["Wide2x3"];
var top = TestMatrices["Tall3x2"];
var bottom = TestMatrices["Wide2x3"];
var result = top.DiagonalStack(bottom);
Assert.AreEqual(top.RowCount + bottom.RowCount, result.RowCount);
Assert.AreEqual(top.ColumnCount + bottom.ColumnCount, result.ColumnCount);
@ -1372,17 +1372,17 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentNullException]
public void DiagonalStackWithLowerNullShouldThrowException()
{
var top = this.TestMatrices["Square3x3"];
Matrix lower = null;
var top = TestMatrices["Square3x3"];
Matrix<double> lower = null;
top.DiagonalStack(lower);
}
[Test]
public virtual void CanDiagonallyStackMatricesWithPassingResult()
{
var top = this.TestMatrices["Tall3x2"];
var bottom = this.TestMatrices["Wide2x3"];
var result = this.CreateMatrix(top.RowCount + bottom.RowCount, top.ColumnCount + bottom.ColumnCount);
var top = TestMatrices["Tall3x2"];
var bottom = TestMatrices["Wide2x3"];
var result = CreateMatrix(top.RowCount + bottom.RowCount, top.ColumnCount + bottom.ColumnCount);
top.DiagonalStack(bottom, result);
Assert.AreEqual(top.RowCount + bottom.RowCount, result.RowCount);
Assert.AreEqual(top.ColumnCount + bottom.ColumnCount, result.ColumnCount);
@ -1411,9 +1411,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentNullException]
public void DiagonalStackWithResultNullShouldThrowException()
{
var top = this.TestMatrices["Square3x3"];
var lower = this.TestMatrices["Wide2x3"];
Matrix result = null;
var top = TestMatrices["Square3x3"];
var lower = TestMatrices["Wide2x3"];
Matrix<double> result = null;
top.DiagonalStack(lower, result);
}
@ -1421,9 +1421,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentException]
public void DiagonalStackWithInvalidResultMatrixShouldThrowException()
{
var top = this.TestMatrices["Square3x3"];
var lower = this.TestMatrices["Wide2x3"];
var result = this.CreateMatrix(top.RowCount + lower.RowCount + 2, top.ColumnCount + lower.ColumnCount);
var top = TestMatrices["Square3x3"];
var lower = TestMatrices["Wide2x3"];
var result = CreateMatrix(top.RowCount + lower.RowCount + 2, top.ColumnCount + lower.ColumnCount);
top.DiagonalStack(lower, result);
}
@ -1443,7 +1443,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Test]
public virtual void InfinityNorm()
{
Matrix matrix = TestMatrices["Square3x3"];
var matrix = TestMatrices["Square3x3"];
Assert.AreEqual(16.5, matrix.InfinityNorm());
matrix = TestMatrices["Wide2x3"];
@ -1456,7 +1456,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Test]
public virtual void L1Norm()
{
Matrix matrix = TestMatrices["Square3x3"];
var matrix = TestMatrices["Square3x3"];
Assert.AreEqual(12.1, matrix.L1Norm());
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.Solvers;
using LinearAlgebra.Double.Solvers.Iterative;
using LinearAlgebra.Double.Solvers.Status;
using LinearAlgebra.Double.Solvers.StopCriterium;
using LinearAlgebra.Generic;
using LinearAlgebra.Generic.Solvers.Status;
using LinearAlgebra.Generic.Solvers.StopCriterium;
using MbUnit.Framework;
[TestFixture]
@ -18,7 +20,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
public void SolveWideMatrix()
{
var matrix = new SparseMatrix(2, 3);
Vector input = new DenseVector(2);
Vector<double> input = new DenseVector(2);
var solver = new BiCgStab();
solver.Solve(matrix, input);
@ -29,7 +31,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
public void SolveLongMatrix()
{
var matrix = new SparseMatrix(3, 2);
Vector input = new DenseVector(3);
Vector<double> input = new DenseVector(3);
var solver = new BiCgStab();
solver.Solve(matrix, input);
@ -40,13 +42,13 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
public void SolveUnitMatrixAndBackMultiply()
{
// Create the identity matrix
Matrix matrix = SparseMatrix.Identity(100);
Matrix<double> matrix = SparseMatrix.Identity(100);
// 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
var monitor = new Iterator(new IIterationStopCriterium[]
var monitor = new Iterator(new IIterationStopCriterium<double>[]
{
new IterationCountStopCriterium(MaximumIterations),
new ResidualStopCriterium(ConvergenceBoundary),
@ -80,16 +82,16 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
public void SolveScaledUnitMatrixAndBackMultiply()
{
// Create the identity matrix
Matrix matrix = SparseMatrix.Identity(100);
Matrix<double> matrix = SparseMatrix.Identity(100);
// Scale it with a funny number
matrix.Multiply(System.Math.PI);
// 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
var monitor = new Iterator(new IIterationStopCriterium[]
var monitor = new Iterator(new IIterationStopCriterium<double>[]
{
new IterationCountStopCriterium(MaximumIterations),
new ResidualStopCriterium(ConvergenceBoundary),
@ -162,10 +164,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
}
// 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
var monitor = new Iterator(new IIterationStopCriterium[]
var monitor = new Iterator(new IIterationStopCriterium<double>[]
{
new IterationCountStopCriterium(MaximumIterations),
new ResidualStopCriterium(ConvergenceBoundary),
@ -204,7 +206,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order);
var vectorb = MatrixLoader.GenerateRandomDenseVector(order);
var monitor = new Iterator(new IIterationStopCriterium[]
var monitor = new Iterator(new IIterationStopCriterium<double>[]
{
new IterationCountStopCriterium(1000),
new ResidualStopCriterium(1e-10),
@ -233,7 +235,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
var matrixA = 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 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.Solvers;
using LinearAlgebra.Double.Solvers.Iterative;
using LinearAlgebra.Double.Solvers.Status;
using LinearAlgebra.Double.Solvers.StopCriterium;
using LinearAlgebra.Generic;
using LinearAlgebra.Generic.Solvers.Status;
using LinearAlgebra.Generic.Solvers.StopCriterium;
using MbUnit.Framework;
[TestFixture]
@ -18,7 +20,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
public void SolveWideMatrix()
{
var matrix = new SparseMatrix(2, 3);
Vector input = new DenseVector(2);
Vector<double> input = new DenseVector(2);
var solver = new GpBiCg();
solver.Solve(matrix, input);
@ -29,7 +31,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
public void SolveLongMatrix()
{
var matrix = new SparseMatrix(3, 2);
Vector input = new DenseVector(3);
Vector<double> input = new DenseVector(3);
var solver = new GpBiCg();
solver.Solve(matrix, input);
@ -40,13 +42,13 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
public void SolveUnitMatrixAndBackMultiply()
{
// Create the identity matrix
Matrix matrix = SparseMatrix.Identity(100);
Matrix<double> matrix = SparseMatrix.Identity(100);
// 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
var monitor = new Iterator(new IIterationStopCriterium[]
var monitor = new Iterator(new IIterationStopCriterium<double>[]
{
new IterationCountStopCriterium(MaximumIterations),
new ResidualStopCriterium(ConvergenceBoundary),
@ -80,16 +82,16 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
public void SolveScaledUnitMatrixAndBackMultiply()
{
// Create the identity matrix
Matrix matrix = SparseMatrix.Identity(100);
Matrix<double> matrix = SparseMatrix.Identity(100);
// Scale it with a funny number
matrix.Multiply(System.Math.PI);
// 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
var monitor = new Iterator(new IIterationStopCriterium[]
var monitor = new Iterator(new IIterationStopCriterium<double>[]
{
new IterationCountStopCriterium(MaximumIterations),
new ResidualStopCriterium(ConvergenceBoundary),
@ -163,10 +165,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
}
// 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
var monitor = new Iterator(new IIterationStopCriterium[]
var monitor = new Iterator(new IIterationStopCriterium<double>[]
{
new IterationCountStopCriterium(MaximumIterations),
new ResidualStopCriterium(ConvergenceBoundary),
@ -206,7 +208,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order);
var vectorb = MatrixLoader.GenerateRandomDenseVector(order);
var monitor = new Iterator(new IIterationStopCriterium[]
var monitor = new Iterator(new IIterationStopCriterium<double>[]
{
new IterationCountStopCriterium(1000),
new ResidualStopCriterium(1e-10),
@ -235,7 +237,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
var matrixA = 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 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.Solvers;
using LinearAlgebra.Double.Solvers.Iterative;
using LinearAlgebra.Double.Solvers.Status;
using LinearAlgebra.Double.Solvers.StopCriterium;
using LinearAlgebra.Generic;
using LinearAlgebra.Generic.Solvers.Status;
using LinearAlgebra.Generic.Solvers.StopCriterium;
using MbUnit.Framework;
[TestFixture]
@ -18,7 +20,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
public void SolveWideMatrix()
{
var matrix = new SparseMatrix(2, 3);
Vector input = new DenseVector(2);
Vector<double> input = new DenseVector(2);
var solver = new MlkBiCgStab();
solver.Solve(matrix, input);
@ -29,7 +31,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
public void SolveLongMatrix()
{
var matrix = new SparseMatrix(3, 2);
Vector input = new DenseVector(3);
Vector<double> input = new DenseVector(3);
var solver = new MlkBiCgStab();
solver.Solve(matrix, input);
@ -40,13 +42,13 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
public void SolveUnitMatrixAndBackMultiply()
{
// Create the identity matrix
Matrix matrix = SparseMatrix.Identity(100);
Matrix<double> matrix = SparseMatrix.Identity(100);
// 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
var monitor = new Iterator(new IIterationStopCriterium[]
var monitor = new Iterator(new IIterationStopCriterium<double>[]
{
new IterationCountStopCriterium(MaximumIterations),
new ResidualStopCriterium(ConvergenceBoundary),
@ -81,16 +83,16 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
public void SolveScaledUnitMatrixAndBackMultiply()
{
// Create the identity matrix
Matrix matrix = SparseMatrix.Identity(100);
Matrix<double> matrix = SparseMatrix.Identity(100);
// Scale it with a funny number
matrix.Multiply(System.Math.PI);
// 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
var monitor = new Iterator(new IIterationStopCriterium[]
var monitor = new Iterator(new IIterationStopCriterium<double>[]
{
new IterationCountStopCriterium(MaximumIterations),
new ResidualStopCriterium(ConvergenceBoundary),
@ -162,10 +164,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
}
// 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
var monitor = new Iterator(new IIterationStopCriterium[]
var monitor = new Iterator(new IIterationStopCriterium<double>[]
{
new IterationCountStopCriterium(MaximumIterations),
new ResidualStopCriterium(ConvergenceBoundary),
@ -204,7 +206,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order);
var vectorb = MatrixLoader.GenerateRandomDenseVector(order);
var monitor = new Iterator(new IIterationStopCriterium[]
var monitor = new Iterator(new IIterationStopCriterium<double>[]
{
new IterationCountStopCriterium(1000),
new ResidualStopCriterium(1e-10),
@ -233,7 +235,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
var matrixA = 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 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.Solvers;
using LinearAlgebra.Double.Solvers.Iterative;
using LinearAlgebra.Double.Solvers.Status;
using LinearAlgebra.Double.Solvers.StopCriterium;
using LinearAlgebra.Generic;
using LinearAlgebra.Generic.Solvers.Status;
using LinearAlgebra.Generic.Solvers.StopCriterium;
using MbUnit.Framework;
[TestFixture]
@ -18,7 +20,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
public void SolveWideMatrix()
{
var matrix = new SparseMatrix(2, 3);
Vector input = new DenseVector(2);
Vector<double> input = new DenseVector(2);
var solver = new TFQMR();
solver.Solve(matrix, input);
@ -29,7 +31,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
public void SolveLongMatrix()
{
var matrix = new SparseMatrix(3, 2);
Vector input = new DenseVector(3);
Vector<double> input = new DenseVector(3);
var solver = new TFQMR();
solver.Solve(matrix, input);
@ -40,13 +42,13 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
public void SolveUnitMatrixAndBackMultiply()
{
// Create the identity matrix
Matrix matrix = SparseMatrix.Identity(100);
Matrix<double> matrix = SparseMatrix.Identity(100);
// 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
var monitor = new Iterator(new IIterationStopCriterium[]
var monitor = new Iterator(new IIterationStopCriterium<double>[]
{
new IterationCountStopCriterium(MaximumIterations),
new ResidualStopCriterium(ConvergenceBoundary),
@ -81,16 +83,16 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
public void SolveScaledUnitMatrixAndBackMultiply()
{
// Create the identity matrix
Matrix matrix = SparseMatrix.Identity(100);
Matrix<double> matrix = SparseMatrix.Identity(100);
// Scale it with a funny number
matrix.Multiply(System.Math.PI);
// 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
var monitor = new Iterator(new IIterationStopCriterium[]
var monitor = new Iterator(new IIterationStopCriterium<double>[]
{
new IterationCountStopCriterium(MaximumIterations),
new ResidualStopCriterium(ConvergenceBoundary),
@ -162,10 +164,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
}
// 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
var monitor = new Iterator(new IIterationStopCriterium[]
var monitor = new Iterator(new IIterationStopCriterium<double>[]
{
new IterationCountStopCriterium(MaximumIterations),
new ResidualStopCriterium(ConvergenceBoundary),
@ -204,7 +206,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order);
var vectorb = MatrixLoader.GenerateRandomDenseVector(order);
var monitor = new Iterator(new IIterationStopCriterium[]
var monitor = new Iterator(new IIterationStopCriterium<double>[]
{
new IterationCountStopCriterium(1000),
new ResidualStopCriterium(1e-10),
@ -233,7 +235,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Iterative
var matrixA = 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 ResidualStopCriterium(1e-10)

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

@ -4,8 +4,9 @@
using System.Collections.Generic;
using LinearAlgebra.Double;
using LinearAlgebra.Double.Solvers;
using LinearAlgebra.Double.Solvers.Status;
using LinearAlgebra.Double.Solvers.StopCriterium;
using LinearAlgebra.Generic.Solvers.Status;
using LinearAlgebra.Generic.Solvers.StopCriterium;
using MbUnit.Framework;
[TestFixture]
@ -24,7 +25,7 @@
[MultipleAsserts]
public void CreateWithEmptyCollection()
{
var iterator = new Iterator(new IIterationStopCriterium[] { });
var iterator = new Iterator(new IIterationStopCriterium<double>[] { });
Assert.IsNotNull(iterator, "Should have an iterator");
Assert.AreEqual(0, iterator.NumberOfCriteria, "There shouldn't be any criteria");
}
@ -33,7 +34,7 @@
[MultipleAsserts]
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.AreEqual(0, iterator.NumberOfCriteria, "There shouldn't be any criteria");
}
@ -42,7 +43,7 @@
[ExpectedArgumentException]
public void CreateWithDuplicates()
{
new Iterator(new IIterationStopCriterium[]
new Iterator(new IIterationStopCriterium<double>[]
{
new FailureStopCriterium(),
new FailureStopCriterium()
@ -53,7 +54,7 @@
[MultipleAsserts]
public void CreateWithCollection()
{
var criteria = new List<IIterationStopCriterium>
var criteria = new List<IIterationStopCriterium<double>>
{
new FailureStopCriterium(),
new DivergenceStopCriterium(),
@ -96,7 +97,7 @@
[MultipleAsserts]
public void Add()
{
var criteria = new List<IIterationStopCriterium>
var criteria = new List<IIterationStopCriterium<double>>
{
new FailureStopCriterium(),
new DivergenceStopCriterium(),
@ -126,7 +127,7 @@
[ExpectedArgumentNullException]
public void RemoveWithNullStopCriterium()
{
var criteria = new List<IIterationStopCriterium>
var criteria = new List<IIterationStopCriterium<double>>
{
new FailureStopCriterium(),
new DivergenceStopCriterium(),
@ -143,7 +144,7 @@
[MultipleAsserts]
public void RemoveWithNonExistingStopCriterium()
{
var criteria = new List<IIterationStopCriterium>
var criteria = new List<IIterationStopCriterium<double>>
{
new FailureStopCriterium(),
new DivergenceStopCriterium(),
@ -160,7 +161,7 @@
[MultipleAsserts]
public void Remove()
{
var criteria = new List<IIterationStopCriterium>
var criteria = new List<IIterationStopCriterium<double>>
{
new FailureStopCriterium(),
new DivergenceStopCriterium(),
@ -192,7 +193,7 @@
[ExpectedException(typeof(ArgumentOutOfRangeException))]
public void DetermineStatusWithNegativeIterationNumber()
{
var criteria = new List<IIterationStopCriterium>
var criteria = new List<IIterationStopCriterium<double>>
{
new FailureStopCriterium(),
new DivergenceStopCriterium(),
@ -211,7 +212,7 @@
[ExpectedArgumentNullException]
public void DetermineStatusWithNullSolutionVector()
{
var criteria = new List<IIterationStopCriterium>
var criteria = new List<IIterationStopCriterium<double>>
{
new FailureStopCriterium(),
new DivergenceStopCriterium(),
@ -230,7 +231,7 @@
[ExpectedArgumentNullException]
public void DetermineStatusWithNullSourceVector()
{
var criteria = new List<IIterationStopCriterium>
var criteria = new List<IIterationStopCriterium<double>>
{
new FailureStopCriterium(),
new DivergenceStopCriterium(),
@ -249,7 +250,7 @@
[ExpectedArgumentNullException]
public void DetermineStatusWithNullResidualVector()
{
var criteria = new List<IIterationStopCriterium>
var criteria = new List<IIterationStopCriterium<double>>
{
new FailureStopCriterium(),
new DivergenceStopCriterium(),
@ -268,7 +269,7 @@
[MultipleAsserts]
public void DetermineStatus()
{
var criteria = new List<IIterationStopCriterium>
var criteria = new List<IIterationStopCriterium<double>>
{
new FailureStopCriterium(),
new DivergenceStopCriterium(),
@ -296,7 +297,7 @@
[MultipleAsserts]
public void ResetToPrecalculationState()
{
var criteria = new List<IIterationStopCriterium>
var criteria = new List<IIterationStopCriterium<double>>
{
new FailureStopCriterium(),
new DivergenceStopCriterium(),
@ -323,7 +324,7 @@
[MultipleAsserts]
public void Clone()
{
var criteria = new List<IIterationStopCriterium>
var criteria = new List<IIterationStopCriterium<double>>
{
new FailureStopCriterium(),
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.Solvers.Preconditioners;
using LinearAlgebra.Generic;
using LinearAlgebra.Generic.Solvers.Preconditioners;
using MbUnit.Framework;
[TestFixture]
public sealed class DiagonalTest : PreconditionerTest
{
internal override IPreConditioner CreatePreconditioner()
internal override IPreConditioner<double> CreatePreconditioner()
{
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");
// Compute M * result = product
// compare vector and product. Should be equal
Vector product = new DenseVector(result.Count);
Vector<double> product = new DenseVector(result.Count);
matrix.Multiply(result, product);
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 LinearAlgebra.Double;
using LinearAlgebra.Double.Solvers.Preconditioners;
using LinearAlgebra.Generic;
using LinearAlgebra.Generic.Solvers.Preconditioners;
using MbUnit.Framework;
[TestFixture]
@ -71,7 +73,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Precondit
return result;
}
internal override IPreConditioner CreatePreconditioner()
internal override IPreConditioner<double> CreatePreconditioner()
{
_pivotTolerance = 0;
_dropTolerance = 0.0;
@ -79,13 +81,13 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Precondit
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");
// Compute M * result = product
// compare vector and product. Should be equal
Vector product = new DenseVector(result.Count);
Vector<double> product = new DenseVector(result.Count);
matrix.Multiply(result, product);
for (var i = 0; i < product.Count; i++)
{
@ -108,7 +110,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Precondit
_fillLevel = 100;
var preconditioner = CreatePreconditioner();
preconditioner.Initialize(newMatrix);
Vector result = new DenseVector(vector.Count);
Vector<double> result = new DenseVector(vector.Count);
preconditioner.Approximate(vector, result);
CheckResult(preconditioner, newMatrix, vector, result);
}
@ -127,7 +129,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Precondit
_fillLevel = 100;
var preconditioner = CreatePreconditioner();
preconditioner.Initialize(newMatrix);
Vector result = new DenseVector(vector.Count);
Vector<double> result = new DenseVector(vector.Count);
preconditioner.Approximate(vector, result);
CheckResult(preconditioner, newMatrix, vector, result);
}
@ -240,7 +242,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Precondit
FillLevel = 10
};
preconditioner.Initialize(newMatrix);
Vector result = new DenseVector(vector.Count);
Vector<double> result = new DenseVector(vector.Count);
preconditioner.Approximate(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 LinearAlgebra.Double;
using LinearAlgebra.Double.Solvers.Preconditioners;
using LinearAlgebra.Generic;
using LinearAlgebra.Generic.Solvers.Preconditioners;
using MbUnit.Framework;
[TestFixture]
@ -22,28 +24,28 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Precondit
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();
}
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");
// Compute M * result = product
// compare vector and product. Should be equal
Vector product = new DenseVector(result.Count);
Vector<double> product = new DenseVector(result.Count);
matrix.Multiply(result, product);
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
{
using LinearAlgebra.Double;
using LinearAlgebra.Double.Solvers.Preconditioners;
using LinearAlgebra.Generic;
using LinearAlgebra.Generic.Solvers.Preconditioners;
using MbUnit.Framework;
public abstract class PreconditionerTest
@ -19,9 +20,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Precondit
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++)
{
vector[i] = i + 1;
@ -30,9 +31,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Precondit
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]
[MultipleAsserts]
@ -62,7 +63,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Precondit
var preconditioner = CreatePreconditioner();
preconditioner.Initialize(newMatrix);
Vector result = new DenseVector(vector.Count);
Vector<double> result = new DenseVector(vector.Count);
preconditioner.Approximate(vector, result);
CheckResult(preconditioner, newMatrix, vector, result);
@ -79,7 +80,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Precondit
var preconditioner = CreatePreconditioner();
preconditioner.Initialize(newMatrix);
Vector result = new DenseVector(vector.Count + 10);
Vector<double> result = new DenseVector(vector.Count + 10);
preconditioner.Approximate(vector, result);
}
@ -94,7 +95,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Precondit
var preconditioner = CreatePreconditioner();
preconditioner.Initialize(newMatrix);
Vector result = new DenseVector(vector.Count + 10);
Vector<double> result = new DenseVector(vector.Count + 10);
preconditioner.Approximate(null, result);
}
@ -109,7 +110,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Solvers.Precondit
var preconditioner = CreatePreconditioner();
preconditioner.Initialize(newMatrix);
Vector result = null;
Vector<double> result = null;
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.Solvers.Preconditioners;
using LinearAlgebra.Generic;
using LinearAlgebra.Generic.Solvers.Preconditioners;
using MbUnit.Framework;
[TestFixture]
public sealed class UnitPreconditionerTest : PreconditionerTest
{
internal override IPreConditioner CreatePreconditioner()
internal override IPreConditioner<double> CreatePreconditioner()
{
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");

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

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

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

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

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

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

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

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

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

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

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

@ -30,9 +30,14 @@
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;
@ -61,12 +66,12 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
_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);
}
public override Vector CreateVector(int size)
public override Vector<double> CreateVector(int size)
{
return new UserDefinedVector(size);
}
@ -81,26 +86,115 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
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
{
protected override Matrix CreateMatrix(int rows, int columns)
protected override Matrix<double> CreateMatrix(int rows, int columns)
{
return new UserDefinedMatrix(rows, columns);
}
protected override Matrix CreateMatrix(double[,] data)
protected override Matrix<double> CreateMatrix(double[,] data)
{
return new UserDefinedMatrix(data);
}
protected override Vector CreateVector(int size)
protected override Vector<double> CreateVector(int size)
{
return new UserDefinedVector(size);
}
protected override Vector CreateVector(double[] data)
protected override Vector<double> CreateVector(double[] data)
{
return new UserDefinedVector(data);
}

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

@ -30,10 +30,15 @@
namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
{
using System;
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;
@ -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);
}
public override Vector CreateVector(int size)
public override Vector<double> CreateVector(int 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
{
protected override Vector CreateVector(int size)
protected override Vector<double> CreateVector(int 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);
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 LinearAlgebra.Double;
using LinearAlgebra.Generic;
using MbUnit.Framework;
public abstract partial class VectorTests
@ -47,8 +48,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Test]
public void OperatorPlusThrowsArgumentNullExceptionWhenCallOnNullVector()
{
Vector vector = null;
Vector other = null;
Vector<double> vector = null;
Vector<double> other = null;
Assert.Throws<ArgumentNullException>(() => other = +vector);
}
@ -154,7 +155,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Test]
public void AdditionOperatorThrowsArgumentNullExpectionIfAVectorIsNull()
{
Vector a = null;
Vector<double> a = null;
var b = CreateVector(Data.Length);
Assert.Throws<ArgumentNullException>(() => a += b);
@ -273,8 +274,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Test]
public void OperatorNegateThrowsArgumentNullExceptionWhenCallOnNullVector()
{
Vector vector = null;
Vector other = null;
Vector<double> vector = null;
Vector<double> other = null;
Assert.Throws<ArgumentNullException>(() => other = -vector);
}
@ -379,7 +380,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Test]
public void SubtractionOperatorThrowsArgumentNullExpectionIfAVectorIsNull()
{
Vector a = null;
Vector<double> a = null;
var b = CreateVector(Data.Length);
Assert.Throws<ArgumentNullException>(() => a -= b);
@ -650,8 +651,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[MultipleAsserts]
public void OperatorMultiplyThrowsArgumentNullExceptionWhenVectorIsNull()
{
Vector vector = null;
Vector result = null;
Vector<double> vector = null;
Vector<double> result = null;
Assert.Throws<ArgumentNullException>(() => result = vector * 2.0);
Assert.Throws<ArgumentNullException>(() => result = 2.0 * vector);
}
@ -659,7 +660,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Test]
public void OperatorDivideThrowsArgumentNullExceptionWhenVectorIsNull()
{
Vector vector = null;
Vector<double> vector = null;
Assert.Throws<ArgumentNullException>(() => vector = vector / 2.0);
}
@ -677,7 +678,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
public void DotProductThrowsExceptionWhenArgumentIsNull()
{
var dataA = CreateVector(Data);
Vector dataB = null;
Vector<double> dataB = null;
dataA.DotProduct(dataB);
}
@ -706,7 +707,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
public void OperatorDotProductThrowsExceptionWhenLeftArgumentIsNull()
{
var dataA = CreateVector(Data);
Vector dataB = null;
Vector<double> dataB = null;
var d = dataA * dataB;
}
@ -715,7 +716,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentNullException]
public void OperatorDotProductThrowsExceptionWhenRightArgumentIsNull()
{
Vector dataA = null;
Vector<double> dataA = null;
var dataB = CreateVector(Data);
var d = dataA * dataB;
@ -761,7 +762,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
public void PointwiseMultiplyWithOtherNullShouldThrowException()
{
var vector1 = CreateVector(Data);
Vector vector2 = null;
Vector<double> vector2 = null;
var result = CreateVector(vector1.Count);
vector1.PointwiseMultiply(vector2, result);
}
@ -772,7 +773,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
{
var vector1 = CreateVector(Data);
var vector2 = vector1.Clone();
Vector result = null;
Vector<double> result = null;
vector1.PointwiseMultiply(vector2, result);
}
@ -816,7 +817,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
public void PointwiseDivideWithOtherNullShouldThrowException()
{
var vector1 = CreateVector(Data);
Vector vector2 = null;
Vector<double> vector2 = null;
var result = CreateVector(vector1.Count);
vector1.PointwiseDivide(vector2, result);
}
@ -827,7 +828,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
{
var vector1 = CreateVector(Data);
var vector2 = vector1.Clone();
Vector result = null;
Vector<double> result = null;
vector1.PointwiseDivide(vector2, result);
}
@ -846,7 +847,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
{
var vector1 = 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 j = 0; j < vector2.Count; j++)
@ -860,9 +861,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[ExpectedArgumentNullException]
public void OuterProductWithFirstParameterNullShouldThrowException()
{
Vector vector1 = null;
Vector<double> vector1 = null;
var vector2 = CreateVector(Data);
Vector.OuterProduct(vector1, vector2);
Vector<double>.OuterProduct(vector1, vector2);
}
[Test]
@ -870,8 +871,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
public void OutercProductWithSecondParameterNullShouldThrowException()
{
var vector1 = CreateVector(Data);
Vector vector2 = null;
Vector.OuterProduct(vector1, vector2);
Vector<double> vector2 = null;
Vector<double>.OuterProduct(vector1, vector2);
}
[Test]
@ -894,7 +895,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
public void TensorMultiplyWithNullParameterNullShouldThrowException()
{
var vector1 = CreateVector(Data);
Vector vector2 = null;
Vector<double> vector2 = null;
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.Globalization;
using Distributions;
using LinearAlgebra.Double;
using LinearAlgebra.Generic;
using MbUnit.Framework;
[TestFixture]
@ -59,7 +59,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
public void CanCloneVectorUsingICloneable()
{
var vector = CreateVector(Data);
var clone = (Vector)((ICloneable)vector).Clone();
var clone = (Vector<double>)((ICloneable)vector).Clone();
Assert.AreNotSame(vector, clone);
Assert.AreEqual(vector.Count, clone.Count);
@ -196,7 +196,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
public void VectorGetHashCode()
{
var vector = CreateVector(new double[] { 1, 2, 3, 4 });
Assert.AreEqual(2145910784, vector.GetHashCode());
Assert.AreEqual(2096640, vector.GetHashCode());
}
[Test]
@ -433,7 +433,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
}
}
protected abstract Vector CreateVector(int size);
protected abstract Vector CreateVector(IList<double> data);
protected abstract Vector<double> CreateVector(int size);
protected abstract Vector<double> CreateVector(IList<double> data);
}
}
Loading…
Cancel
Save