Browse Source

LA: Create sparse matrix from row/col vectors; rework creation in F#

optimization-1
Christoph Ruegg 13 years ago
parent
commit
72439d00ff
  1. 2
      src/FSharp/Fit.fs
  2. 108
      src/FSharp/LinearAlgebra.Double.Matrix.fs
  3. 15
      src/FSharp/LinearAlgebra.Double.Vector.fs
  4. 20
      src/FSharpExamples/Matrices.fsx
  5. 36
      src/FSharpUnitTests/DenseMatrixTests.fs
  6. 2
      src/FSharpUnitTests/DenseVectorTests.fs
  7. 18
      src/FSharpUnitTests/SparseMatrixTests.fs
  8. 30
      src/Numerics/LinearAlgebra/Complex/SparseMatrix.cs
  9. 30
      src/Numerics/LinearAlgebra/Complex32/SparseMatrix.cs
  10. 30
      src/Numerics/LinearAlgebra/Double/SparseMatrix.cs
  11. 30
      src/Numerics/LinearAlgebra/Single/SparseMatrix.cs
  12. 66
      src/Numerics/LinearAlgebra/Storage/DenseColumnMajorMatrixStorage.cs
  13. 77
      src/Numerics/LinearAlgebra/Storage/SparseCompressedRowMatrixStorage.cs

2
src/FSharp/Fit.fs

@ -62,7 +62,7 @@ module Fit =
let linear functions (x:_[]) (y:float[]) =
functions
|> List.map (fun f -> List.init (Array.length x) (fun i -> f x.[i]))
|> DenseMatrix.ofColumnsList (Array.length x) (List.length functions)
|> DenseMatrix.ofColumnList (Array.length x) (List.length functions)
|> fun m -> m.QR(QRMethod.Thin).Solve(DenseVector(y)).ToArray()
|> List.ofArray

108
src/FSharp/LinearAlgebra.Double.Matrix.fs

@ -36,6 +36,8 @@ open MathNet.Numerics.LinearAlgebra
[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
module Matrix =
// TODO: generalize or reconsider
/// Returns the sum of all elements of a matrix.
let inline sum (A: #Matrix<float>) = A |> Matrix.foldnz (+) 0.0
@ -75,19 +77,28 @@ module DenseMatrix =
/// Create a matrix with the given dimension and set all values to x.
let inline create (rows: int) (cols: int) x = DenseMatrix.Create(rows, cols, fun i j -> x) :> _ Matrix
/// Create a matrix with the given dimension and set all diagonal values to x. All other values are zero.
let inline createDiag (rows: int) (cols: int) x =
let A = DenseMatrix(rows,cols)
for i=0 to min (rows-1) (cols-1) do A.At(i,i,x)
A :> _ Matrix
/// Initialize a matrix by calling a construction function for every element.
let inline init (rows: int) (cols: int) (f: int -> int -> float) = DenseMatrix.Create(rows, cols, fun i j -> f i j) :> _ Matrix
/// Initialize a matrix by calling a construction function for every diagonal element. All other values are zero.
let inline initDiag (rows: int) (cols: int) (f: int -> float) =
let A = DenseMatrix(rows,cols)
for i=0 to min (rows-1) (cols-1) do A.At(i,i,f i)
A :> _ Matrix
/// Create an identity matrix with the given dimension.
let inline identity (rows: int) (cols: int) = createDiag rows cols 1.0
/// Create a matrix from a 2D array of floating point numbers.
let inline ofArray2 array = DenseMatrix.OfArray(array) :> _ Matrix
/// Create a matrix from a list of sequences. Every sequence in the master sequence specifies a row.
/// If the dimensions are known, consider to use ofRowSeq instead to avoid multiple enumeration.
let inline ofSeq (fss: #seq<#seq<float>>) =
let n = Seq.length fss
let m = Seq.length (Seq.head fss)
DenseMatrix.OfRowsCovariant(n, m, fss) :> _ Matrix
/// Create a matrix from a list of float lists. Every list in the master list specifies a row.
/// If the dimensions are known, consider to use ofRowList instead to avoid multiple enumeration.
let inline ofList (fll: float list list) =
@ -96,38 +107,39 @@ module DenseMatrix =
DenseMatrix.OfRowsCovariant(n, m, fll) :> _ Matrix
/// Create a matrix from a list of sequences. Every sequence in the master sequence specifies a row.
let inline ofRows (rows: int) (cols: int) (fss: #seq<#seq<float>>) = DenseMatrix.OfRowsCovariant(rows, cols, fss) :> _ Matrix
/// If the dimensions are known, consider to use ofRowSeq instead to avoid multiple enumeration.
let inline ofSeq (fss: #seq<#seq<float>>) =
let n = Seq.length fss
let m = Seq.length (Seq.head fss)
DenseMatrix.OfRowsCovariant(n, m, fss) :> _ Matrix
/// Create a matrix from a list of float lists. Every list in the master list specifies a row.
let inline ofRowsList (rows: int) (cols: int) (fll: float list list) = DenseMatrix.OfRowsCovariant(rows, cols, fll) :> _ Matrix
/// Create a matrix from a list of row vectors.
let inline ofRowVectors (vectors: #Vector<float> list) = DenseMatrix.OfRowVectors(vectors |> Array.ofList |> box |> unbox) :> _ Matrix
let inline ofRows (vectors: #Vector<float> list) = DenseMatrix.OfRowVectors(vectors |> Array.ofList |> box |> unbox) :> _ Matrix
/// Create a matrix from a list of sequences. Every sequence in the master sequence specifies a column.
let inline ofColumns (rows: int) (cols: int) (fss: #seq<#seq<float>>) = DenseMatrix.OfColumnsCovariant(rows, cols, fss) :> _ Matrix
/// Create a matrix from a list of float lists. Every list in the master list specifies a row.
let inline ofRowList (rows: int) (cols: int) (fll: float list list) = DenseMatrix.OfRowsCovariant(rows, cols, fll) :> _ Matrix
/// Create a matrix from a list of float lists. Every list in the master list specifies a column.
let inline ofColumnsList (rows: int) (cols: int) (fll: float list list) = DenseMatrix.OfColumnsCovariant(rows, cols, fll) :> _ Matrix
/// Create a matrix from a list of sequences. Every sequence in the master sequence specifies a row.
let inline ofRowSeq (rows: int) (cols: int) (fss: #seq<#seq<float>>) = DenseMatrix.OfRowsCovariant(rows, cols, fss) :> _ Matrix
/// Create a matrix from a list of column vectors.
let inline ofColumnVectors (vectors: #Vector<float> list) = DenseMatrix.OfColumnVectors(vectors |> Array.ofList |> box |> unbox) :> _ Matrix
let inline ofColumns (vectors: #Vector<float> list) = DenseMatrix.OfColumnVectors(vectors |> Array.ofList |> box |> unbox) :> _ Matrix
/// Create a matrix with a given dimension from an indexed sequences of row, column, value tuples.
let inline ofSeqi (rows: int) (cols: int) (fs: #seq<int * int * float>) = DenseMatrix.OfIndexed(rows, cols, fs) :> _ Matrix
/// Create a matrix from a list of float lists. Every list in the master list specifies a column.
let inline ofColumnList (rows: int) (cols: int) (fll: float list list) = DenseMatrix.OfColumnsCovariant(rows, cols, fll) :> _ Matrix
/// Create a matrix from a list of sequences. Every sequence in the master sequence specifies a column.
let inline ofColumnSeq (rows: int) (cols: int) (fss: #seq<#seq<float>>) = DenseMatrix.OfColumnsCovariant(rows, cols, fss) :> _ Matrix
/// Create a matrix with a given dimension from an indexed list of row, column, value tuples.
let inline ofListi (rows: int) (cols: int) (fl: list<int * int * float>) = DenseMatrix.OfIndexed(rows, cols, Seq.ofList fl) :> _ Matrix
/// Create a square matrix with constant diagonal entries.
let inline constDiag (n: int) (f: float) =
let A = DenseMatrix(n,n)
for i=0 to n-1 do
A.At(i,i,f)
A :> _ Matrix
/// Create a matrix with a given dimension from an indexed sequences of row, column, value tuples.
let inline ofSeqi (rows: int) (cols: int) (fs: #seq<int * int * float>) = DenseMatrix.OfIndexed(rows, cols, fs) :> _ Matrix
/// Create a square matrix with the vector elements on the diagonal.
let inline diag (v: #Vector<float>) =
let inline ofDiag (v: #Vector<float>) =
let n = v.Count
let A = DenseMatrix(n,n)
A.SetDiagonal(v)
@ -152,9 +164,25 @@ module SparseMatrix =
/// Create an all-zero matrix with the given dimension.
let inline zeroCreate (rows: int) (cols: int) = SparseMatrix(rows, cols) :> _ Matrix
/// Create a matrix with the given dimension and set all diagonal values to x. All other values are zero.
let inline createDiag (rows: int) (cols: int) x =
let A = SparseMatrix(rows,cols)
for i=0 to min (rows-1) (cols-1) do A.At(i,i,x)
A :> _ Matrix
/// Initialize a matrix by calling a construction function for every element.
let inline init (rows: int) (cols: int) (f: int -> int -> float) = SparseMatrix.Create(rows, cols, fun n m -> f n m) :> _ Matrix
/// Initialize a matrix by calling a construction function for every diagonal element. All other values are zero.
let inline initDiag (rows: int) (cols: int) (f: int -> float) =
let A = SparseMatrix(rows,cols)
for i=0 to min (rows-1) (cols-1) do A.At(i,i,f i)
A :> _ Matrix
/// Create an identity matrix with the given dimension.
let inline identity (rows: int) (cols: int) = createDiag rows cols 1.0
/// Create a matrix from a 2D array of floating point numbers.
let inline ofArray2 array = SparseMatrix.OfArray(array) :> _ Matrix
@ -166,33 +194,33 @@ module SparseMatrix =
[<System.ObsoleteAttribute("Use ofListi instead. Will be changed to expect a non-indexed list in a future version.")>]
let inline ofList (rows: int) (cols: int) (fl: list<int * int * float>) = SparseMatrix.OfIndexed(rows, cols, Seq.ofList fl) :> _ Matrix
/// Create a matrix from a list of sequences. Every sequence in the master sequence specifies a row.
let inline ofRows (rows: int) (cols: int) (fss: #seq<#seq<float>>) = SparseMatrix.OfRowsCovariant(rows, cols, fss) :> _ Matrix
/// Create a matrix from a list of row vectors.
let inline ofRows (vectors: #Vector<float> list) = SparseMatrix.OfRowVectors(vectors |> Array.ofList |> box |> unbox) :> _ Matrix
/// Create a matrix from a list of float lists. Every list in the master list specifies a row.
let inline ofRowsList (rows: int) (cols: int) (fll: float list list) = SparseMatrix.OfRowsCovariant(rows, cols, fll) :> _ Matrix
let inline ofRowList (rows: int) (cols: int) (fll: float list list) = SparseMatrix.OfRowsCovariant(rows, cols, fll) :> _ Matrix
/// Create a matrix from a list of sequences. Every sequence in the master sequence specifies a column.
let inline ofColumns (rows: int) (cols: int) (fss: #seq<#seq<float>>) = SparseMatrix.OfColumnsCovariant(rows, cols, fss) :> _ Matrix
/// Create a matrix from a list of sequences. Every sequence in the master sequence specifies a row.
let inline ofRowSeq (rows: int) (cols: int) (fss: #seq<#seq<float>>) = SparseMatrix.OfRowsCovariant(rows, cols, fss) :> _ Matrix
/// Create a matrix from a list of column vectors.
let inline ofColumns (vectors: #Vector<float> list) = SparseMatrix.OfColumnVectors(vectors |> Array.ofList |> box |> unbox) :> _ Matrix
/// Create a matrix from a list of float lists. Every list in the master list specifies a column.
let inline ofColumnsList (rows: int) (cols: int) (fll: float list list) = SparseMatrix.OfColumnsCovariant(rows, cols, fll) :> _ Matrix
let inline ofColumnList (rows: int) (cols: int) (fll: float list list) = SparseMatrix.OfColumnsCovariant(rows, cols, fll) :> _ Matrix
/// Create a matrix with a given dimension from an indexed sequences of row, column, value tuples.
let inline ofSeqi (rows: int) (cols: int) (fs: #seq<int * int * float>) = SparseMatrix.OfIndexed(rows, cols, fs) :> _ Matrix
/// Create a matrix from a list of sequences. Every sequence in the master sequence specifies a column.
let inline ofColumnSeq (rows: int) (cols: int) (fss: #seq<#seq<float>>) = SparseMatrix.OfColumnsCovariant(rows, cols, fss) :> _ Matrix
/// Create a matrix with a given dimension from an indexed list of row, column, value tuples.
let inline ofListi (rows: int) (cols: int) (fl: list<int * int * float>) = SparseMatrix.OfIndexed(rows, cols, Seq.ofList fl) :> _ Matrix
/// Create a square matrix with constant diagonal entries.
let inline constDiag (n: int) (f: float) =
let A = SparseMatrix(n,n)
for i=0 to n-1 do
A.At(i,i,f)
A :> _ Matrix
/// Create a matrix with a given dimension from an indexed sequences of row, column, value tuples.
let inline ofSeqi (rows: int) (cols: int) (fs: #seq<int * int * float>) = SparseMatrix.OfIndexed(rows, cols, fs) :> _ Matrix
/// Create a square matrix with the vector elements on the diagonal.
let inline diag (v: #Vector<float>) =
let inline ofDiag (v: #Vector<float>) =
let n = v.Count
let A = SparseMatrix(n,n)
A.SetDiagonal(v)

15
src/FSharp/LinearAlgebra.Double.Vector.fs

@ -36,6 +36,8 @@ open MathNet.Numerics.LinearAlgebra
[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
module Vector =
// TODO: generalize or reconsider
/// Creates a new vector and inserts the given value at the given index.
let inline insert index value (v: #Vector<float>) =
let newV = new DenseVector(v.Count + 1)
@ -77,17 +79,12 @@ module DenseVector =
/// Create a vector with a given dimension from an indexed sequences of index, value pairs.
let inline ofSeqi (n: int) (fs: #seq<int * float>) = DenseVector.OfIndexedEnumerable(n, fs) :> _ Vector
/// Create a vector with integer entries in the given range.
let inline range (start: int) (step: int) (stop: int) = raw [| for i in start..step..stop -> float i |]
/// Create a vector with evenly spaced entries: e.g. rangef -1.0 0.5 1.0 = [-1.0 -0.5 0.0 0.5 1.0]
let inline rangef (start: float) (step: float) (stop: float) =
let n = (int ((stop - start) / step)) + 1
let v = DenseVector(n)
for i=0 to n-1 do
v.At(i, (float i) * step + start)
v :> _ Vector
let inline rangef (start: float) (step: float) (stop: float) = raw [| start..step..stop |]
/// Create a vector with integer entries in the given range.
let inline range (start: int) (stop: int) =
DenseVector([| for i in [start .. stop] -> float i |]) :> _ Vector
/// A module which implements functional sparse vector operations.
[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]

20
src/FSharpExamples/Matrices.fsx

@ -53,16 +53,20 @@ let d1 = DenseMatrix.init 3 4 (fun i j -> float i / 100.0 + float j)
let d2 = SparseMatrix.init 3 4 (fun i j -> if i=j then float i / 100.0 + float j else 0.0)
// Matrices can also be constructed from sequences of rows or of columns
let e1 = DenseMatrix.ofRows 20 10 (seq { for i in 1 .. 20 do yield Array.init 10 (fun j -> float j + 100.0 * float i) })
let e2 = SparseMatrix.ofRows 20 10 (seq { for i in 1 .. 20 do yield Array.init 10 (fun j -> if i%5 = 0 then float j + 100.0 * float i else 0.0) })
let e3 = DenseMatrix.ofColumns 20 10 (seq { for j in 1 .. 10 do yield Array.init 20 (fun i -> float j + 100.0 * float i) })
let e4 = SparseMatrix.ofColumns 20 10 (seq { for j in 1 .. 10 do yield Array.init 20 (fun i -> if i%5 = 0 then float j + 100.0 * float i else 0.0) })
let e1 = DenseMatrix.ofRowSeq 20 10 (seq { for i in 1 .. 20 do yield Array.init 10 (fun j -> float j + 100.0 * float i) })
let e2 = SparseMatrix.ofRowSeq 20 10 (seq { for i in 1 .. 20 do yield Array.init 10 (fun j -> if i%5 = 0 then float j + 100.0 * float i else 0.0) })
let e3 = DenseMatrix.ofColumnSeq 20 10 (seq { for j in 1 .. 10 do yield Array.init 20 (fun i -> float j + 100.0 * float i) })
let e4 = SparseMatrix.ofColumnSeq 20 10 (seq { for j in 1 .. 10 do yield Array.init 20 (fun i -> if i%5 = 0 then float j + 100.0 * float i else 0.0) })
// Or from F# lists
let f1 = DenseMatrix.ofRowsList 20 10 [ for i in 1 .. 20 -> List.init 10 (fun j -> float j + 100.0 * float i) ]
let f2 = SparseMatrix.ofRowsList 20 10 [ for i in 1 .. 20 -> List.init 10 (fun j -> if i%5 = 0 then float j + 100.0 * float i else 0.0) ]
let f3 = DenseMatrix.ofColumnsList 20 10 [ for j in 1 .. 10 -> List.init 20 (fun i -> float j + 100.0 * float i) ]
let f4 = SparseMatrix.ofColumnsList 20 10 [ for j in 1 .. 10 -> List.init 20 (fun i -> if i%5 = 0 then float j + 100.0 * float i else 0.0) ]
let f1 = DenseMatrix.ofRowList 20 10 [ for i in 1 .. 20 -> List.init 10 (fun j -> float j + 100.0 * float i) ]
let f2 = SparseMatrix.ofRowList 20 10 [ for i in 1 .. 20 -> List.init 10 (fun j -> if i%5 = 0 then float j + 100.0 * float i else 0.0) ]
let f3 = DenseMatrix.ofColumnList 20 10 [ for j in 1 .. 10 -> List.init 20 (fun i -> float j + 100.0 * float i) ]
let f4 = SparseMatrix.ofColumnList 20 10 [ for j in 1 .. 10 -> List.init 20 (fun i -> if i%5 = 0 then float j + 100.0 * float i else 0.0) ]
// Or from row or column vectors
let m1 = DenseMatrix.ofRows [DenseVector.create 3 1.0; DenseVector.create 3 2.0]
let m2 = DenseMatrix.ofColumns [DenseVector.create 3 1.0; DenseVector.create 3 2.0]
// Or from indexed lists or sequences where all other values are zero (useful mostly for sparse data)
let g1 = DenseMatrix.ofListi 20 10 [(4,3,20.0); (18,9,3.0); (2,1,100.0)]

36
src/FSharpUnitTests/DenseMatrixTests.fs

@ -53,28 +53,28 @@ module DenseMatrixTests =
DenseMatrix.ofList [[0.3;0.3];[0.3;0.3];[0.3;0.3]] |> should equal smallM
[<Test>]
let ``DenseMatrix.ofRows`` () =
DenseMatrix.ofRows 3 2 (Seq.ofList [[0.3;0.3];[0.3;0.3];[0.3;0.3]]) |> should equal smallM
let ``DenseMatrix.ofRowSeq`` () =
DenseMatrix.ofRowSeq 3 2 (Seq.ofList [[0.3;0.3];[0.3;0.3];[0.3;0.3]]) |> should equal smallM
[<Test>]
let ``DenseMatrix.ofRowsList`` () =
DenseMatrix.ofRowsList 3 2 [[0.3;0.3];[0.3;0.3];[0.3;0.3]] |> should equal smallM
let ``DenseMatrix.ofRowList`` () =
DenseMatrix.ofRowList 3 2 [[0.3;0.3];[0.3;0.3];[0.3;0.3]] |> should equal smallM
[<Test>]
let ``DenseMatrix.ofRowVectors`` () =
DenseMatrix.ofRowVectors [vector [0.3;0.3]; vector [0.3;0.3]; vector [0.3;0.3]] |> should equal smallM
let ``DenseMatrix.ofRows`` () =
DenseMatrix.ofRows [vector [0.3;0.3]; vector [0.3;0.3]; vector [0.3;0.3]] |> should equal smallM
[<Test>]
let ``DenseMatrix.ofColumn`` () =
DenseMatrix.ofColumns 3 2 (Seq.ofList [[0.3;0.3;0.3];[0.3;0.3;0.3]]) |> should equal smallM
let ``DenseMatrix.ofColumnSeq`` () =
DenseMatrix.ofColumnSeq 3 2 (Seq.ofList [[0.3;0.3;0.3];[0.3;0.3;0.3]]) |> should equal smallM
[<Test>]
let ``DenseMatrix.ofColumnsList`` () =
DenseMatrix.ofColumnsList 3 2 [[0.3;0.3;0.3];[0.3;0.3;0.3]] |> should equal smallM
let ``DenseMatrix.ofColumnList`` () =
DenseMatrix.ofColumnList 3 2 [[0.3;0.3;0.3];[0.3;0.3;0.3]] |> should equal smallM
[<Test>]
let ``DenseMatrix.ofColumnVectors`` () =
DenseMatrix.ofColumnVectors [vector [0.3;0.3;0.3]; vector [0.3;0.3;0.3]] |> should equal smallM
let ``DenseMatrix.ofColumns`` () =
DenseMatrix.ofColumns [vector [0.3;0.3;0.3]; vector [0.3;0.3;0.3]] |> should equal smallM
[<Test>]
let ``DenseMatrix.ofSeqi`` () =
@ -87,17 +87,17 @@ module DenseMatrixTests =
|> DenseMatrix.ofListi 100 120 |> should equal largeM
[<Test>]
let ``DenseMatrix.constDiag`` () =
DenseMatrix.constDiag 100 2.0 |> should equal (2.0 * (DenseMatrix.Identity 100))
let ``DenseMatrix.createDiag`` () =
DenseMatrix.createDiag 100 100 2.0 |> should equal (2.0 * (DenseMatrix.Identity 100))
[<Test>]
let ``DenseMatrix.diag`` () =
DenseMatrix.diag (DenseVector.Create(100, fun i -> 2.0)) |> should equal (2.0 * (DenseMatrix.Identity 100))
let ``DenseMatrix.ofDiag`` () =
DenseMatrix.ofDiag (DenseVector.Create(100, fun i -> 2.0)) |> should equal (2.0 * (DenseMatrix.Identity 100))
[<Test>]
let ``DenseMatrix.init_row`` () =
let ``DenseMatrix.initRow`` () =
DenseMatrix.initRow 100 120 (fun i -> (DenseVector.init 120 (fun j -> float i * 100.0 + float j))) |> should equal largeM
[<Test>]
let ``DenseMatrix.init_col`` () =
let ``DenseMatrix.initCol`` () =
DenseMatrix.initCol 100 120 (fun j -> (DenseVector.init 100 (fun i -> float i * 100.0 + float j))) |> should equal largeM

2
src/FSharpUnitTests/DenseVectorTests.fs

@ -57,4 +57,4 @@ module DenseVectorTests =
[<Test>]
let ``DenseVector.range`` () =
DenseVector.range 0 99 |> should equal (new DenseVector( [| for i in 0 .. 99 -> float i |] ) )
DenseVector.range 0 1 99 |> should equal (new DenseVector( [| for i in 0 .. 99 -> float i |] ) )

18
src/FSharpUnitTests/SparseMatrixTests.fs

@ -25,20 +25,20 @@ module SparseMatrixTests =
SparseMatrix.ofArray2 (Array2D.init 4 6 (fun i j -> if i = 1 && j = 2 then 1.0 else 0.0)) |> should equal smallM
[<Test>]
let ``SparseMatrix.ofRows`` () =
SparseMatrix.ofRows 4 6 (Seq.ofList [[0.;0.;0.;0.;0.;0.];[0.;0.;1.;0.;0.;0.];[0.;0.;0.;0.;0.;0.];[0.;0.;0.;0.;0.;0.]]) |> should equal smallM
let ``SparseMatrix.ofRowSeq`` () =
SparseMatrix.ofRowSeq 4 6 (Seq.ofList [[0.;0.;0.;0.;0.;0.];[0.;0.;1.;0.;0.;0.];[0.;0.;0.;0.;0.;0.];[0.;0.;0.;0.;0.;0.]]) |> should equal smallM
[<Test>]
let ``SparseMatrix.ofRowsList`` () =
SparseMatrix.ofRowsList 4 6 [[0.;0.;0.;0.;0.;0.];[0.;0.;1.;0.;0.;0.];[0.;0.;0.;0.;0.;0.];[0.;0.;0.;0.;0.;0.]] |> should equal smallM
let ``SparseMatrix.ofRowList`` () =
SparseMatrix.ofRowList 4 6 [[0.;0.;0.;0.;0.;0.];[0.;0.;1.;0.;0.;0.];[0.;0.;0.;0.;0.;0.];[0.;0.;0.;0.;0.;0.]] |> should equal smallM
[<Test>]
let ``SparseMatrix.ofColumns`` () =
SparseMatrix.ofColumns 4 6 (Seq.ofList [[0.;0.;0.;0.];[0.;0.;0.;0.];[0.;1.;0.;0.];[0.;0.;0.;0.];[0.;0.;0.;0.];[0.;0.;0.;0.]]) |> should equal smallM
let ``SparseMatrix.ofColumnSeq`` () =
SparseMatrix.ofColumnSeq 4 6 (Seq.ofList [[0.;0.;0.;0.];[0.;0.;0.;0.];[0.;1.;0.;0.];[0.;0.;0.;0.];[0.;0.;0.;0.];[0.;0.;0.;0.]]) |> should equal smallM
[<Test>]
let ``SparseMatrix.ofColumnList`` () =
SparseMatrix.ofColumnsList 4 6 [[0.;0.;0.;0.];[0.;0.;0.;0.];[0.;1.;0.;0.];[0.;0.;0.;0.];[0.;0.;0.;0.];[0.;0.;0.;0.]] |> should equal smallM
SparseMatrix.ofColumnList 4 6 [[0.;0.;0.;0.];[0.;0.;0.;0.];[0.;1.;0.;0.];[0.;0.;0.;0.];[0.;0.;0.;0.];[0.;0.;0.;0.]] |> should equal smallM
[<Test>]
let ``SparseMatrix.ofSeqi`` () =
@ -50,11 +50,11 @@ module SparseMatrixTests =
[<Test>]
let ``SparseMatrix.constDiag`` () =
SparseMatrix.constDiag 100 2.0 |> should equal (2.0 * (SparseMatrix.Identity 100))
SparseMatrix.createDiag 100 100 2.0 |> should equal (2.0 * (SparseMatrix.Identity 100))
[<Test>]
let ``SparseMatrix.diag`` () =
SparseMatrix.diag (DenseVector.Create(100, fun i -> 2.0)) |> should equal (2.0 * (SparseMatrix.Identity 100))
SparseMatrix.ofDiag (DenseVector.Create(100, fun i -> 2.0)) |> should equal (2.0 * (SparseMatrix.Identity 100))
[<Test>]
let ``SparseMatrix.init_row`` () =

30
src/Numerics/LinearAlgebra/Complex/SparseMatrix.cs

@ -162,6 +162,21 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
return new SparseMatrix(SparseCompressedRowMatrixStorage<Complex>.OfColumnEnumerables(rows, columns, data));
}
/// <summary>
/// Create a new sparse matrix as a copy of the given column vectors.
/// This new matrix will be independent from the vectors.
/// A new memory block will be allocated for storing the matrix.
/// </summary>
public static SparseMatrix OfColumnVectors(params Vector<Complex>[] columns)
{
var storage = new VectorStorage<Complex>[columns.Length];
for (int i = 0; i < columns.Length; i++)
{
storage[i] = columns[i].Storage;
}
return new SparseMatrix(SparseCompressedRowMatrixStorage<Complex>.OfColumnVectors(storage));
}
/// <summary>
/// Create a new sparse matrix as a copy of the given enumerable of enumerable columns.
/// Each enumerable in the master enumerable specifies a column.
@ -186,6 +201,21 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
return new SparseMatrix(SparseCompressedRowMatrixStorage<Complex>.OfRowEnumerables(rows, columns, data));
}
/// <summary>
/// Create a new sparse matrix as a copy of the given row vectors.
/// This new matrix will be independent from the vectors.
/// A new memory block will be allocated for storing the matrix.
/// </summary>
public static SparseMatrix OfRowVectors(params Vector<Complex>[] rows)
{
var storage = new VectorStorage<Complex>[rows.Length];
for (int i = 0; i < rows.Length; i++)
{
storage[i] = rows[i].Storage;
}
return new SparseMatrix(SparseCompressedRowMatrixStorage<Complex>.OfRowVectors(storage));
}
/// <summary>
/// Create a new sparse matrix as a copy of the given enumerable of enumerable rows.
/// Each enumerable in the master enumerable specifies a row.

30
src/Numerics/LinearAlgebra/Complex32/SparseMatrix.cs

@ -157,6 +157,21 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
return new SparseMatrix(SparseCompressedRowMatrixStorage<Complex32>.OfColumnEnumerables(rows, columns, data));
}
/// <summary>
/// Create a new sparse matrix as a copy of the given column vectors.
/// This new matrix will be independent from the vectors.
/// A new memory block will be allocated for storing the matrix.
/// </summary>
public static SparseMatrix OfColumnVectors(params Vector<Complex32>[] columns)
{
var storage = new VectorStorage<Complex32>[columns.Length];
for (int i = 0; i < columns.Length; i++)
{
storage[i] = columns[i].Storage;
}
return new SparseMatrix(SparseCompressedRowMatrixStorage<Complex32>.OfColumnVectors(storage));
}
/// <summary>
/// Create a new sparse matrix as a copy of the given enumerable of enumerable columns.
/// Each enumerable in the master enumerable specifies a column.
@ -181,6 +196,21 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
return new SparseMatrix(SparseCompressedRowMatrixStorage<Complex32>.OfRowEnumerables(rows, columns, data));
}
/// <summary>
/// Create a new sparse matrix as a copy of the given row vectors.
/// This new matrix will be independent from the vectors.
/// A new memory block will be allocated for storing the matrix.
/// </summary>
public static SparseMatrix OfRowVectors(params Vector<Complex32>[] rows)
{
var storage = new VectorStorage<Complex32>[rows.Length];
for (int i = 0; i < rows.Length; i++)
{
storage[i] = rows[i].Storage;
}
return new SparseMatrix(SparseCompressedRowMatrixStorage<Complex32>.OfRowVectors(storage));
}
/// <summary>
/// Create a new sparse matrix as a copy of the given enumerable of enumerable rows.
/// Each enumerable in the master enumerable specifies a row.

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

@ -155,6 +155,21 @@ namespace MathNet.Numerics.LinearAlgebra.Double
return new SparseMatrix(SparseCompressedRowMatrixStorage<double>.OfColumnEnumerables(rows, columns, data));
}
/// <summary>
/// Create a new sparse matrix as a copy of the given column vectors.
/// This new matrix will be independent from the vectors.
/// A new memory block will be allocated for storing the matrix.
/// </summary>
public static SparseMatrix OfColumnVectors(params Vector<double>[] columns)
{
var storage = new VectorStorage<double>[columns.Length];
for (int i = 0; i < columns.Length; i++)
{
storage[i] = columns[i].Storage;
}
return new SparseMatrix(SparseCompressedRowMatrixStorage<double>.OfColumnVectors(storage));
}
/// <summary>
/// Create a new sparse matrix as a copy of the given enumerable of enumerable columns.
/// Each enumerable in the master enumerable specifies a column.
@ -179,6 +194,21 @@ namespace MathNet.Numerics.LinearAlgebra.Double
return new SparseMatrix(SparseCompressedRowMatrixStorage<double>.OfRowEnumerables(rows, columns, data));
}
/// <summary>
/// Create a new sparse matrix as a copy of the given row vectors.
/// This new matrix will be independent from the vectors.
/// A new memory block will be allocated for storing the matrix.
/// </summary>
public static SparseMatrix OfRowVectors(params Vector<double>[] rows)
{
var storage = new VectorStorage<double>[rows.Length];
for (int i = 0; i < rows.Length; i++)
{
storage[i] = rows[i].Storage;
}
return new SparseMatrix(SparseCompressedRowMatrixStorage<double>.OfRowVectors(storage));
}
/// <summary>
/// Create a new sparse matrix as a copy of the given enumerable of enumerable rows.
/// Each enumerable in the master enumerable specifies a row.

30
src/Numerics/LinearAlgebra/Single/SparseMatrix.cs

@ -155,6 +155,21 @@ namespace MathNet.Numerics.LinearAlgebra.Single
return new SparseMatrix(SparseCompressedRowMatrixStorage<float>.OfColumnEnumerables(rows, columns, data));
}
/// <summary>
/// Create a new sparse matrix as a copy of the given column vectors.
/// This new matrix will be independent from the vectors.
/// A new memory block will be allocated for storing the matrix.
/// </summary>
public static SparseMatrix OfColumnVectors(params Vector<float>[] columns)
{
var storage = new VectorStorage<float>[columns.Length];
for (int i = 0; i < columns.Length; i++)
{
storage[i] = columns[i].Storage;
}
return new SparseMatrix(SparseCompressedRowMatrixStorage<float>.OfColumnVectors(storage));
}
/// <summary>
/// Create a new sparse matrix as a copy of the given enumerable of enumerable columns.
/// Each enumerable in the master enumerable specifies a column.
@ -179,6 +194,21 @@ namespace MathNet.Numerics.LinearAlgebra.Single
return new SparseMatrix(SparseCompressedRowMatrixStorage<float>.OfRowEnumerables(rows, columns, data));
}
/// <summary>
/// Create a new sparse matrix as a copy of the given row vectors.
/// This new matrix will be independent from the vectors.
/// A new memory block will be allocated for storing the matrix.
/// </summary>
public static SparseMatrix OfRowVectors(params Vector<float>[] rows)
{
var storage = new VectorStorage<float>[rows.Length];
for (int i = 0; i < rows.Length; i++)
{
storage[i] = rows[i].Storage;
}
return new SparseMatrix(SparseCompressedRowMatrixStorage<float>.OfRowVectors(storage));
}
/// <summary>
/// Create a new sparse matrix as a copy of the given enumerable of enumerable rows.
/// Each enumerable in the master enumerable specifies a row.

66
src/Numerics/LinearAlgebra/Storage/DenseColumnMajorMatrixStorage.cs

@ -138,43 +138,8 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
return storage;
}
public static DenseColumnMajorMatrixStorage<T> OfIndexedEnumerable(int rows, int columns, IEnumerable<Tuple<int, int, T>> data)
{
if (data == null)
{
throw new ArgumentNullException("data");
}
var array = new T[rows * columns];
foreach (var item in data)
{
array[(item.Item2 * rows) + item.Item1] = item.Item3;
}
return new DenseColumnMajorMatrixStorage<T>(rows, columns, array);
}
public static DenseColumnMajorMatrixStorage<T> OfColumnMajorEnumerable(int rows, int columns, IEnumerable<T> data)
{
if (data == null)
{
throw new ArgumentNullException("data");
}
var arrayData = data as T[];
if (arrayData != null)
{
var copy = new T[arrayData.Length];
Array.Copy(arrayData, copy, arrayData.Length);
return new DenseColumnMajorMatrixStorage<T>(rows, columns, copy);
}
var array = System.Linq.Enumerable.ToArray(data);
return new DenseColumnMajorMatrixStorage<T>(rows, columns, array);
}
public static DenseColumnMajorMatrixStorage<T> OfColumnVectors(VectorStorage<T>[] data)
{
if (data == null) throw new ArgumentNullException("data");
int columns = data.Length;
int rows = data[0].Length;
var array = new T[rows * columns];
@ -189,7 +154,7 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
else
{
// FALL BACK
int offset = j*rows;
int offset = j * rows;
for (int i = 0; i < rows; i++)
{
array[offset + i] = column.At(i);
@ -201,13 +166,12 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
public static DenseColumnMajorMatrixStorage<T> OfRowVectors(VectorStorage<T>[] data)
{
if (data == null) throw new ArgumentNullException("data");
int rows = data.Length;
int columns = data[0].Length;
var array = new T[rows * columns];
for (int j = 0; j < columns; j++)
{
int offset = j*rows;
int offset = j * rows;
for (int i = 0; i < rows; i++)
{
array[offset + i] = data[i].At(j);
@ -216,11 +180,34 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
return new DenseColumnMajorMatrixStorage<T>(rows, columns, array);
}
public static DenseColumnMajorMatrixStorage<T> OfIndexedEnumerable(int rows, int columns, IEnumerable<Tuple<int, int, T>> data)
{
var array = new T[rows * columns];
foreach (var item in data)
{
array[(item.Item2 * rows) + item.Item1] = item.Item3;
}
return new DenseColumnMajorMatrixStorage<T>(rows, columns, array);
}
public static DenseColumnMajorMatrixStorage<T> OfColumnMajorEnumerable(int rows, int columns, IEnumerable<T> data)
{
var arrayData = data as T[];
if (arrayData != null)
{
var copy = new T[arrayData.Length];
Array.Copy(arrayData, copy, arrayData.Length);
return new DenseColumnMajorMatrixStorage<T>(rows, columns, copy);
}
var array = System.Linq.Enumerable.ToArray(data);
return new DenseColumnMajorMatrixStorage<T>(rows, columns, array);
}
public static DenseColumnMajorMatrixStorage<T> OfColumnEnumerables<TColumn>(int rows, int columns, IEnumerable<TColumn> data)
// NOTE: flexible typing to 'backport' generic covariance.
where TColumn : IEnumerable<T>
{
if (data == null) throw new ArgumentNullException("data");
var array = new T[rows*columns];
using (var columnIterator = data.GetEnumerator())
{
@ -255,7 +242,6 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
// NOTE: flexible typing to 'backport' generic covariance.
where TRow : IEnumerable<T>
{
if (data == null) throw new ArgumentNullException("data");
var array = new T[rows*columns];
using (var rowIterator = data.GetEnumerator())
{

77
src/Numerics/LinearAlgebra/Storage/SparseCompressedRowMatrixStorage.cs

@ -31,6 +31,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using MathNet.Numerics.Properties;
namespace MathNet.Numerics.LinearAlgebra.Storage
@ -373,11 +374,6 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
public static SparseCompressedRowMatrixStorage<T> OfArray(T[,] array)
{
if (array == null)
{
throw new ArgumentNullException("array");
}
var storage = new SparseCompressedRowMatrixStorage<T>(array.GetLength(0), array.GetLength(1));
var rowPointers = storage.RowPointers;
var columnIndices = new List<int>();
@ -429,13 +425,65 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
return storage;
}
public static SparseCompressedRowMatrixStorage<T> OfIndexedEnumerable(int rows, int columns, IEnumerable<Tuple<int, int, T>> data)
public static SparseCompressedRowMatrixStorage<T> OfRowVectors(VectorStorage<T>[] data)
{
if (data == null)
var storage = new SparseCompressedRowMatrixStorage<T>(data.Length, data[0].Length);
var rowPointers = storage.RowPointers;
var columnIndices = new List<int>();
var values = new List<T>();
// TODO PERF: Optimize for sparse and dense cases
for (int row = 0; row < storage.RowCount; row++)
{
throw new ArgumentNullException("data");
var vector = data[row];
rowPointers[row] = values.Count;
for (int col = 0; col < storage.ColumnCount; col++)
{
var x = vector.At(col);
if (!Zero.Equals(x))
{
values.Add(x);
columnIndices.Add(col);
}
}
}
storage.ColumnIndices = columnIndices.ToArray();
storage.Values = values.ToArray();
storage.ValueCount = values.Count;
return storage;
}
public static SparseCompressedRowMatrixStorage<T> OfColumnVectors(VectorStorage<T>[] data)
{
var storage = new SparseCompressedRowMatrixStorage<T>(data[0].Length, data.Length);
var rowPointers = storage.RowPointers;
var columnIndices = new List<int>();
var values = new List<T>();
// TODO PERF: Optimize for sparse and dense cases
for (int row = 0; row < storage.RowCount; row++)
{
rowPointers[row] = values.Count;
for (int col = 0; col < storage.ColumnCount; col++)
{
var x = data[col].At(row);
if (!Zero.Equals(x))
{
values.Add(x);
columnIndices.Add(col);
}
}
}
storage.ColumnIndices = columnIndices.ToArray();
storage.Values = values.ToArray();
storage.ValueCount = values.Count;
return storage;
}
public static SparseCompressedRowMatrixStorage<T> OfIndexedEnumerable(int rows, int columns, IEnumerable<Tuple<int, int, T>> data)
{
var trows = new List<Tuple<int, T>>[rows];
foreach (var item in data)
{
@ -478,8 +526,6 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
// NOTE: flexible typing to 'backport' generic covariance.
where TRow : IEnumerable<T>
{
if (data == null) throw new ArgumentNullException("data");
var storage = new SparseCompressedRowMatrixStorage<T>(rows, columns);
var rowPointers = storage.RowPointers;
var columnIndices = new List<int>();
@ -517,8 +563,6 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
// NOTE: flexible typing to 'backport' generic covariance.
where TColumn : IEnumerable<T>
{
if (data == null) throw new ArgumentNullException("data");
var trows = new List<Tuple<int, T>>[rows];
using (var columnIterator = data.GetEnumerator())
{
@ -570,11 +614,6 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
public static SparseCompressedRowMatrixStorage<T> OfRowMajorEnumerable(int rows, int columns, IEnumerable<T> data)
{
if (data == null)
{
throw new ArgumentNullException("data");
}
var storage = new SparseCompressedRowMatrixStorage<T>(rows, columns);
var rowPointers = storage.RowPointers;
var columnIndices = new List<int>();
@ -605,10 +644,6 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
public static SparseCompressedRowMatrixStorage<T> OfColumnMajorList(int rows, int columns, IList<T> data)
{
if (data == null)
{
throw new ArgumentNullException("data");
}
if (rows * columns != data.Count)
{
throw new ArgumentOutOfRangeException(Resources.ArgumentMatrixDimensions);

Loading…
Cancel
Save