Skip to content

Commit

Permalink
Add functions to create sparse matrices from other matrices or array2d
Browse files Browse the repository at this point in the history
  • Loading branch information
caroott committed Oct 9, 2019
1 parent 9cdfc26 commit 94d2d30
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 0 deletions.
39 changes: 39 additions & 0 deletions src/FSharp.Stats/AlgTypes.fs
Expand Up @@ -285,6 +285,23 @@ namespace FSharp.Stats
| _ -> raise (new System.NotSupportedException("The element type '"+(typeof<'T>.ToString())+"' carried by this vector or matrix does not support the INormFloat<_> operation (i.e. does not have a registered numeric association that supports this type)"))

let mkDenseMatrixGU ops arr = DenseMatrix(ops,arr)
let mkSparseMatrixGU ops (arr: 'a[,]) =
let m = arr |> Array2D.length1
let n = arr |> Array2D.length2

let mutable nnz = 0
let a = FSharp.Collections.ResizeArray<'a>()
let ja = FSharp.Collections.ResizeArray<int>()
let ia = FSharp.Collections.ResizeArray<int>()
ia.Add(0)
for i = 0 to (m - 1) do
for j = 0 to (n - 1) do
if ((Array2D.get arr i j) |> System.Convert.ToDouble) >= 0.000001 || ((Array2D.get arr i j)|> System.Convert.ToDouble) <= -0.000001 then
a.Add((Array2D.get arr i j))
ja.Add(j)
nnz <- nnz + 1
ia.Add(nnz)
SparseMatrix(ops, a.ToArray(), ia.ToArray(), n, ja.ToArray())
let mkRowVecGU ops arr = RowVector(ops, arr)
let mkVecGU ops arr = Vector(ops,arr)

Expand Down Expand Up @@ -1373,6 +1390,7 @@ namespace FSharp.Stats
let listRV xss : RowVector<'T> = GU.listRowVecGU opsdata<'T> xss

let arrayM xss : Matrix<'T> = GU.mkDenseMatrixGU opsdata<'T> (Array2D.copy xss) |> dense
let arraySM xss : Matrix<'T> = GU.mkSparseMatrixGU opsdata<'T> (Array2D.copy xss) |> sparse
let arrayV xss : Vector<'T> = GU.mkVecGU opsdata<'T> (Array.copy xss)
let arrayRV xss : RowVector<'T> = GU.mkRowVecGU opsdata<'T> (Array.copy xss)

Expand Down Expand Up @@ -1821,6 +1839,27 @@ namespace FSharp.Stats
match a with
| SparseRepr a -> GU.toDenseSparseMatrixGU a |> dense
| DenseRepr _ -> a
let toSparseM (a: Matrix<'T>) =
match a with
| SparseRepr _ -> a
| DenseRepr a ->
let m = a.NumRows
let n = a.NumCols

let mutable nnz = 0
let ar = FSharp.Collections.ResizeArray<'T>()
let ja = FSharp.Collections.ResizeArray<int>()
let ia = FSharp.Collections.ResizeArray<int>()
ia.Add(0)

for i = 0 to (m - 1) do
for j = 0 to (n - 1) do
if (a.Item(i, j)|> System.Convert.ToDouble) >= 0.000001 || (a.Item(i, j)|> System.Convert.ToDouble) <= -0.000001 then
ar.Add(a.Item(i, j))
ja.Add(j)
nnz <- nnz + 1
ia.Add(nnz)
SparseRepr (SparseMatrix(opsdata<'T>, ar.ToArray(), ia.ToArray(), n, ja.ToArray()))

let initSparseM i j x : Matrix<'T> =
let opsData = opsdata<'T>
Expand Down
3 changes: 3 additions & 0 deletions src/FSharp.Stats/Matrix.fs
Expand Up @@ -34,6 +34,7 @@ module Matrix = begin
let ofSeq sources = MS.seqM sources
let init length1 length2 initializer = MS.initM length1 length2 initializer
let ofArray2D (array: 'T[,]) : Matrix<'T> = MS.arrayM array
let sparseOfArray2D (array: 'T[,]) : Matrix<'T> = MS.arraySM array
let toArray2D (matrix:Matrix<_>) = Array2D.init matrix.NumRows matrix.NumCols (fun i j -> get matrix i j)
let toJaggedArray (m:Matrix<_>) = [|for i=0 to m.NumRows-1 do yield (Array.init m.NumCols (fun j -> get m i j))|]
let initNumeric length1 length2 initializer = MS.initNumericM length1 length2 initializer
Expand Down Expand Up @@ -128,6 +129,8 @@ module Matrix = begin
///
let toDense matrix = MS.toDenseM matrix
///
let toSparse matrix = MS.toSparseM matrix
///
let initDense length1 length2 source = MS.initDenseM length1 length2 source
///
let initSparse length1 length2 source = MS.initSparseM length1 length2 source
Expand Down

0 comments on commit 94d2d30

Please sign in to comment.