Browse Source

LA: F# create/init functions should always return generic types

pull/163/head
Christoph Ruegg 13 years ago
parent
commit
8ec3597664
  1. 94
      src/FSharp/LinearAlgebra.Double.Matrix.fs
  2. 36
      src/FSharp/LinearAlgebra.Double.Vector.fs
  3. 2
      src/FSharpUnitTests/DenseMatrixTests.fs
  4. 2
      src/FSharpUnitTests/DenseVectorTests.fs
  5. 4
      src/FSharpUnitTests/MatrixTests.fs
  6. 6
      src/FSharpUnitTests/SparseMatrixTests.fs
  7. 6
      src/FSharpUnitTests/SparseVectorTests.fs

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

@ -239,7 +239,7 @@ module Matrix =
for i=0 to A.RowCount-1 do
macc <- f macc (A.At(i,k))
v.At(k, macc)
v :> Vector<float>
v :> _ Vector
/// Fold all rows into one column vector.
let inline foldByRow (f: float -> float -> float) acc (A: #Matrix<float>) =
@ -249,159 +249,155 @@ module Matrix =
for i=0 to A.ColumnCount-1 do
macc <- f macc (A.At(k,i))
v.At(k, macc)
v :> Vector<float>
v :> _ Vector
/// A module which implements functional dense vector operations.
[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
module DenseMatrix =
/// Create a matrix that directly binds to a raw storage array in column-major (column by column) format, without copying.
let inline raw (rows: int) (cols: int) (columnMajor: float[]) = DenseMatrix(rows, cols, columnMajor)
let inline raw (rows: int) (cols: int) (columnMajor: float[]) = DenseMatrix(rows, cols, columnMajor) :> _ Matrix
/// Create an all-zero matrix with the given dimension.
let inline zeroCreate (rows: int) (cols: int) = DenseMatrix(rows, cols)
let inline zeroCreate (rows: int) (cols: int) = DenseMatrix(rows, cols) :> _ Matrix
/// Create a random matrix with the given dimension and value distribution.
let inline randomCreate (rows: int) (cols: int) dist = DenseMatrix.CreateRandom(rows, cols, dist)
let inline randomCreate (rows: int) (cols: int) dist = DenseMatrix.CreateRandom(rows, cols, dist) :> _ Matrix
/// 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)
let inline create (rows: int) (cols: int) x = DenseMatrix.Create(rows, cols, fun i j -> x) :> _ 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)
let inline init (rows: int) (cols: int) (f: int -> int -> float) = DenseMatrix.Create(rows, cols, fun i j -> f i j) :> _ Matrix
/// Create a matrix from a 2D array of floating point numbers.
let inline ofArray2 array = DenseMatrix.OfArray(array)
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)
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) =
let n = List.length fll
let m = List.length (List.head fll)
DenseMatrix.OfRowsCovariant(n, m, fll)
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)
let inline ofRows (rows: int) (cols: int) (fss: #seq<#seq<float>>) = DenseMatrix.OfRowsCovariant(rows, cols, 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)
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)
let inline ofRowVectors (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)
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 column.
let inline ofColumnsList (rows: int) (cols: int) (fll: float list list) = DenseMatrix.OfColumnsCovariant(rows, cols, fll)
let inline ofColumnsList (rows: int) (cols: int) (fll: float list list) = DenseMatrix.OfColumnsCovariant(rows, cols, fll) :> _ Matrix
/// Create a matrix from a list of column vectors.
let inline ofColumnVectors (vectors: #Vector<float> list) = DenseMatrix.OfColumnVectors(vectors |> Array.ofList |> box |> unbox)
let inline ofColumnVectors (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)
let inline ofSeqi (rows: int) (cols: int) (fs: #seq<int * int * float>) = DenseMatrix.OfIndexed(rows, cols, fs) :> _ 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)
/// Create a matrix with the given entries.
[<System.ObsoleteAttribute("Use ofSeqi instead. Scheduled for removal in v3.0.")>]
let inline initDense (rows: int) (cols: int) (es: #seq<int * int * float>) = ofSeqi rows cols es
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 = new DenseMatrix(n,n)
let A = DenseMatrix(n,n)
for i=0 to n-1 do
A.At(i,i,f)
A
A :> _ Matrix
/// Create a square matrix with the vector elements on the diagonal.
let inline diag (v: #Vector<float>) =
let n = v.Count
let A = new DenseMatrix(n,n)
let A = DenseMatrix(n,n)
A.SetDiagonal(v)
A
A :> _ Matrix
/// Initialize a matrix by calling a construction function for every row.
let inline initRow (rows: int) (cols: int) (f: int -> #Vector<float>) =
let A = new DenseMatrix(rows,cols)
let A = DenseMatrix(rows,cols)
for i=0 to rows-1 do A.SetRow(i, f i)
A
A :> _ Matrix
/// Initialize a matrix by calling a construction function for every column.
let inline initCol (rows: int) (cols: int) (f: int -> #Vector<float>) =
let A = new DenseMatrix(rows,cols)
let A = DenseMatrix(rows,cols)
for i=0 to cols-1 do A.SetColumn(i, f i)
A
A :> _ Matrix
/// A module which implements functional sparse vector operations.
[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
module SparseMatrix =
/// Create an all-zero matrix with the given dimension.
let inline zeroCreate (rows: int) (cols: int) = SparseMatrix(rows, cols)
let inline zeroCreate (rows: int) (cols: int) = SparseMatrix(rows, cols) :> _ 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)
let inline init (rows: int) (cols: int) (f: int -> int -> float) = SparseMatrix.Create(rows, cols, fun n m -> f n m) :> _ Matrix
/// Create a matrix from a 2D array of floating point numbers.
let inline ofArray2 array = SparseMatrix.OfArray(array)
let inline ofArray2 array = SparseMatrix.OfArray(array) :> _ Matrix
/// Create a matrix with a given dimension from an indexed sequences of row, column, value tuples.
[<System.ObsoleteAttribute("Use ofSeqi instead. Will be changed to expect a non-indexed seq in a future version.")>]
let inline ofSeq (rows: int) (cols: int) (fs: #seq<int * int * float>) = SparseMatrix.OfIndexed(rows, cols, fs)
let inline ofSeq (rows: int) (cols: int) (fs: #seq<int * int * float>) = SparseMatrix.OfIndexed(rows, cols, fs) :> _ Matrix
/// Create a matrix with a given dimension from an indexed list of row, column, value tuples.
[<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)
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)
let inline ofRows (rows: int) (cols: int) (fss: #seq<#seq<float>>) = SparseMatrix.OfRowsCovariant(rows, cols, 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) = SparseMatrix.OfRowsCovariant(rows, cols, fll)
let inline ofRowsList (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)
let inline ofColumns (rows: int) (cols: int) (fss: #seq<#seq<float>>) = SparseMatrix.OfColumnsCovariant(rows, cols, fss) :> _ 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)
let inline ofColumnsList (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)
let inline ofSeqi (rows: int) (cols: int) (fs: #seq<int * int * float>) = SparseMatrix.OfIndexed(rows, cols, fs) :> _ 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)
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 = new SparseMatrix(n,n)
let A = SparseMatrix(n,n)
for i=0 to n-1 do
A.At(i,i,f)
A
A :> _ Matrix
/// Create a square matrix with the vector elements on the diagonal.
let inline diag (v: #Vector<float>) =
let n = v.Count
let A = new SparseMatrix(n,n)
let A = SparseMatrix(n,n)
A.SetDiagonal(v)
A
A :> _ Matrix
/// Initialize a matrix by calling a construction function for every row.
let inline initRow (rows: int) (cols: int) (f: int -> #Vector<float>) =
let A = new SparseMatrix(rows,cols)
let A = SparseMatrix(rows,cols)
for i=0 to rows-1 do A.SetRow(i, f i)
A
A :> _ Matrix
/// Initialize a matrix by calling a construction function for every column.
let inline initCol (rows: int) (cols: int) (f: int -> #Vector<float>) =
let A = new SparseMatrix(rows,cols)
let A = SparseMatrix(rows,cols)
for i=0 to cols-1 do A.SetColumn(i, f i)
A
A :> _ Matrix

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

@ -207,62 +207,62 @@ module Vector =
module DenseVector =
/// Create a vector that directly binds to a raw storage array, without copying.
let inline raw (raw: float[]) = DenseVector(raw)
let inline raw (raw: float[]) = DenseVector(raw) :> _ Vector
/// Initialize an all-zero vector with the given dimension.
let inline zeroCreate (n: int) = DenseVector(n)
let inline zeroCreate (n: int) = DenseVector(n) :> _ Vector
/// Initialize a random vector with the given dimension and distribution.
let inline randomCreate (n: int) dist = DenseVector.CreateRandom(n, dist)
let inline randomCreate (n: int) dist = DenseVector.CreateRandom(n, dist) :> _ Vector
/// Initialize an x-valued vector with the given dimension.
let inline create (n: int) x = DenseVector.Create(n, fun i -> x)
let inline create (n: int) x = DenseVector.Create(n, fun i -> x) :> _ Vector
/// Initialize a vector by calling a construction function for every element.
let inline init (n: int) (f: int -> float) = DenseVector.Create(n, fun i -> f i)
let inline init (n: int) (f: int -> float) = DenseVector.Create(n, fun i -> f i) :> _ Vector
/// Create a vector from a float list.
let inline ofList (fl: float list) = DenseVector(Array.ofList fl)
let inline ofList (fl: float list) = DenseVector(Array.ofList fl) :> _ Vector
/// Create a vector from a float sequence.
let inline ofSeq (fs: #seq<float>) = DenseVector.OfEnumerable(fs)
let inline ofSeq (fs: #seq<float>) = DenseVector.OfEnumerable(fs) :> _ Vector
/// Create a vector with a given dimension from an indexed list of index, value pairs.
let inline ofListi (n: int) (fl: list<int * float>) = DenseVector.OfIndexedEnumerable(n, Seq.ofList fl)
let inline ofListi (n: int) (fl: list<int * float>) = DenseVector.OfIndexedEnumerable(n, Seq.ofList fl) :> _ Vector
/// 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)
let inline ofSeqi (n: int) (fs: #seq<int * float>) = DenseVector.OfIndexedEnumerable(n, fs) :> _ Vector
/// 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 = new DenseVector(n)
let v = DenseVector(n)
for i=0 to n-1 do
v.At(i, (float i) * step + start)
v
v :> _ Vector
/// Create a vector with integer entries in the given range.
let inline range (start: int) (stop: int) =
new DenseVector([| for i in [start .. stop] -> float i |])
DenseVector([| for i in [start .. stop] -> float i |]) :> _ Vector
/// A module which implements functional sparse vector operations.
[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
module SparseVector =
/// Initialize an all-zero vector with the given dimension.
let inline zeroCreate (n: int) = SparseVector(n)
let inline zeroCreate (n: int) = SparseVector(n) :> _ Vector
/// Initialize a vector by calling a construction function for every element.
let inline init (n: int) (f: int -> float) = SparseVector.Create(n, fun i -> f i)
let inline init (n: int) (f: int -> float) = SparseVector.Create(n, fun i -> f i) :> _ Vector
/// Create a sparse vector from a float list.
let inline ofList (n: int) (fl: float list) = SparseVector.OfEnumerable(Seq.ofList fl)
let inline ofList (n: int) (fl: float list) = SparseVector.OfEnumerable(Seq.ofList fl) :> _ Vector
/// Create a sparse vector from a float sequence.
let inline ofSeq (n: int) (fs: #seq<float>) = SparseVector.OfEnumerable(fs)
let inline ofSeq (n: int) (fs: #seq<float>) = SparseVector.OfEnumerable(fs) :> _ Vector
/// Create a sparse vector with a given dimension from an indexed list of index, value pairs.
let inline ofListi (n: int) (fl: list<int * float>) = SparseVector.OfIndexedEnumerable(n, Seq.ofList fl)
let inline ofListi (n: int) (fl: list<int * float>) = SparseVector.OfIndexedEnumerable(n, Seq.ofList fl) :> _ Vector
/// Create a sparse vector with a given dimension from an indexed sequence of index, value pairs.
let inline ofSeqi (n: int) (fs: #seq<int * float>) = SparseVector.OfIndexedEnumerable(n, fs)
let inline ofSeqi (n: int) (fs: #seq<int * float>) = SparseVector.OfIndexedEnumerable(n, fs) :> _ Vector

2
src/FSharpUnitTests/DenseMatrixTests.fs

@ -25,7 +25,7 @@ module DenseMatrixTests =
[<Test>]
let ``DenseMatrix.randomCreate`` () =
let m = DenseMatrix.randomCreate 100 120 (Normal.WithMeanStdDev(100.0,0.1))
m.Values |> ArrayStatistics.Mean |> should (equalWithin 10.0) 100.0
(m :?> DenseMatrix).Values |> ArrayStatistics.Mean |> should (equalWithin 10.0) 100.0
m.RowCount |> should equal 100
m.ColumnCount |> should equal 120

2
src/FSharpUnitTests/DenseVectorTests.fs

@ -23,7 +23,7 @@ module DenseVectorTests =
[<Test>]
let ``DenseVector.randomCreate`` () =
let m = DenseVector.randomCreate 100 (Normal.WithMeanStdDev(100.0,0.1))
m.Values |> ArrayStatistics.Mean |> should (equalWithin 10.0) 100.0
(m :?> DenseVector).Values |> ArrayStatistics.Mean |> should (equalWithin 10.0) 100.0
m.Count |> should equal 100
[<Test>]

4
src/FSharpUnitTests/MatrixTests.fs

@ -174,11 +174,11 @@ module MatrixTests =
[<Test>]
let ``Matrix.foldByCol`` () =
Matrix.foldByCol (+) 0.0 smallM |> should equal (DenseVector.ofList [0.6;0.6] :> Vector<float>)
Matrix.foldByCol (+) 0.0 smallM |> should equal (DenseVector.ofList [0.6;0.6])
[<Test>]
let ``Matrix.foldByRow`` () =
Matrix.foldByRow (+) 0.0 smallM |> should equal (DenseVector.ofList [0.6;0.6] :> Vector<float>)
Matrix.foldByRow (+) 0.0 smallM |> should equal (DenseVector.ofList [0.6;0.6])
[<Test>]
let ``Pointwise Multiplication using .* Operator`` () =

6
src/FSharpUnitTests/SparseMatrixTests.fs

@ -9,7 +9,7 @@ open MathNet.Numerics.LinearAlgebra.Double
module SparseMatrixTests =
/// A small uniform matrix.
let smallM = DenseMatrix.init 4 6 (fun i j -> if i = 1 && j = 2 then 1.0 else 0.0) :> Matrix<float>
let smallM = DenseMatrix.init 4 6 (fun i j -> if i = 1 && j = 2 then 1.0 else 0.0)
[<Test>]
let ``SparseMatrix.zeroCreate`` () =
@ -58,8 +58,8 @@ module SparseMatrixTests =
[<Test>]
let ``SparseMatrix.init_row`` () =
SparseMatrix.initRow 4 6 (fun i -> if i=1 then DenseVector([|0.;0.;1.;0.;0.;0.|]) else DenseVector.zeroCreate 6) |> should equal smallM
SparseMatrix.initRow 4 6 (fun i -> if i=1 then DenseVector.raw [|0.;0.;1.;0.;0.;0.|] else DenseVector.zeroCreate 6) |> should equal smallM
[<Test>]
let ``SparseMatrix.init_col`` () =
SparseMatrix.initCol 4 6 (fun j -> if j=2 then DenseVector([|0.;1.;0.;0.|]) else DenseVector.zeroCreate 4) |> should equal smallM
SparseMatrix.initCol 4 6 (fun j -> if j=2 then DenseVector.raw [|0.;1.;0.;0.|] else DenseVector.zeroCreate 4) |> should equal smallM

6
src/FSharpUnitTests/SparseVectorTests.fs

@ -12,10 +12,8 @@ module SparseVectorTests =
let smallv = new DenseVector( [|0.0;0.3;0.0;0.0;0.0|] ) :> Vector<float>
[<Test>]
let ``SparseVector.ofListi`` () =
(SparseVector.ofListi 5 [ (1,0.3) ] :> Vector<float>) |> should equal smallv
let ``SparseVector.ofListi`` () = SparseVector.ofListi 5 [ (1,0.3) ] |> should equal smallv
[<Test>]
let ``SparseVector.ofSeqi`` () =
(SparseVector.ofSeqi 5 (List.toSeq [ (1,0.3) ]) :> Vector<float>) |> should equal smallv
let ``SparseVector.ofSeqi`` () = SparseVector.ofSeqi 5 (List.toSeq [ (1,0.3) ]) |> should equal smallv

Loading…
Cancel
Save