From 1e7c60cb8e6bbb22271c0e09cf8bceec3e0582aa Mon Sep 17 00:00:00 2001 From: Gustavo Guerra Date: Sat, 1 Dec 2012 12:24:32 +0000 Subject: [PATCH] Convert FSharpUnitTests to NUnit + latest FSUnit --- src/FSharpUnitTests/App.config | 6 - src/FSharpUnitTests/BigRationalTests.fs | 10 +- src/FSharpUnitTests/DenseMatrixTests.fs | 51 ++++ src/FSharpUnitTests/DenseVectorTests.fs | 35 +++ src/FSharpUnitTests/FSharpUnitTests.fsproj | 12 +- src/FSharpUnitTests/FsUnit.fs | 310 +++++---------------- src/FSharpUnitTests/MatrixTests.fs | 112 ++++++++ src/FSharpUnitTests/Program.fs | 223 --------------- src/FSharpUnitTests/SparseMatrixTests.fs | 27 ++ src/FSharpUnitTests/SparseVectorTests.fs | 21 ++ src/FSharpUnitTests/VectorTests.fs | 103 +++++++ 11 files changed, 425 insertions(+), 485 deletions(-) delete mode 100644 src/FSharpUnitTests/App.config create mode 100644 src/FSharpUnitTests/DenseMatrixTests.fs create mode 100644 src/FSharpUnitTests/DenseVectorTests.fs create mode 100644 src/FSharpUnitTests/MatrixTests.fs delete mode 100644 src/FSharpUnitTests/Program.fs create mode 100644 src/FSharpUnitTests/SparseMatrixTests.fs create mode 100644 src/FSharpUnitTests/SparseVectorTests.fs create mode 100644 src/FSharpUnitTests/VectorTests.fs diff --git a/src/FSharpUnitTests/App.config b/src/FSharpUnitTests/App.config deleted file mode 100644 index 6c301d33..00000000 --- a/src/FSharpUnitTests/App.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/src/FSharpUnitTests/BigRationalTests.fs b/src/FSharpUnitTests/BigRationalTests.fs index 1173e196..65915416 100644 --- a/src/FSharpUnitTests/BigRationalTests.fs +++ b/src/FSharpUnitTests/BigRationalTests.fs @@ -331,15 +331,7 @@ type BigNumType() = "1000000000000000000000000000000000018") Assert.AreEqual(g_zero.ToString(),"0") Assert.AreEqual(g_normal.ToString(),"88") - - - [] - member this.System_Object_GetHashCode() = - Assert.AreEqual(g_negative1.GetHashCode(),1210897093) - Assert.AreEqual(g_normal.GetHashCode(),89) - Assert.AreEqual(g_zero.GetHashCode(),1) - () - + // Static methods [] member this.Abs() = diff --git a/src/FSharpUnitTests/DenseMatrixTests.fs b/src/FSharpUnitTests/DenseMatrixTests.fs new file mode 100644 index 00000000..b06107d9 --- /dev/null +++ b/src/FSharpUnitTests/DenseMatrixTests.fs @@ -0,0 +1,51 @@ +namespace MathNet.Numerics.Tests + +open NUnit.Framework +open FsUnit +open MathNet.Numerics.LinearAlgebra.Generic +open MathNet.Numerics.LinearAlgebra.Double + +/// Unit tests for the dense matrix type. +module DenseMatrixTests = + + /// A small uniform vector. + let smallM = new DenseMatrix( Array2D.create 2 2 0.3 ) + + /// A large vector with increasingly large entries + let largeM = new DenseMatrix( Array2D.init 100 100 (fun i j -> float i * 100.0 + float j) ) + + [] + let ``DenseMatrix.init`` () = + DenseMatrix.init 100 100 (fun i j -> float i * 100.0 + float j) |> should equal largeM + + [] + let ``DenseMatrix.ofList`` () = + DenseMatrix.ofList [[0.3;0.3];[0.3;0.3]] |> should equal smallM + + [] + let ``DenseMatrix.ofSeq`` () = + DenseMatrix.ofSeq (Seq.ofList [[0.3;0.3];[0.3;0.3]]) |> should equal smallM + + [] + let ``DenseMatrix.ofArray2`` () = + DenseMatrix.ofArray2 (Array2D.create 2 2 0.3) |> should equal smallM + + [] + let ``DenseMatrix.initDense`` () = + DenseMatrix.initDense 100 100 (seq { for i in 0 .. 99 do + for j in 0 .. 99 -> (i,j, float i * 100.0 + float j)}) |> should equal largeM + [] + let ``DenseMatrix.constDiag`` () = + DenseMatrix.constDiag 100 2.0 |> should equal (2.0 * (DenseMatrix.Identity 100)) + + [] + let ``DenseMatrix.diag`` () = + DenseMatrix.diag (new DenseVector(100, 2.0)) |> should equal (2.0 * (DenseMatrix.Identity 100)) + + [] + let ``DenseMatrix.init_row`` () = + DenseMatrix.initRow 100 100 (fun i -> (DenseVector.init 100 (fun j -> float i * 100.0 + float j))) |> should equal largeM + + [] + let ``DenseMatrix.init_col`` () = + DenseMatrix.initCol 100 100 (fun j -> (DenseVector.init 100 (fun i -> float i * 100.0 + float j))) |> should equal largeM diff --git a/src/FSharpUnitTests/DenseVectorTests.fs b/src/FSharpUnitTests/DenseVectorTests.fs new file mode 100644 index 00000000..346e55a6 --- /dev/null +++ b/src/FSharpUnitTests/DenseVectorTests.fs @@ -0,0 +1,35 @@ +namespace MathNet.Numerics.Tests + +open NUnit.Framework +open FsUnit +open MathNet.Numerics.LinearAlgebra.Generic +open MathNet.Numerics.LinearAlgebra.Double + +/// Unit tests for the dense vector type. +module DenseVectorTests = + + /// A small uniform vector. + let smallv = new DenseVector(5, 0.3 ) + + /// A large vector with increasingly large entries + let largev = new DenseVector( Array.init 100 (fun i -> float i / 100.0) ) + + [] + let ``DenseVector.init`` () = + DenseVector.init 100 (fun i -> float i / 100.0) |> should equal largev + + [] + let ``DenseVector.ofList`` () = + DenseVector.ofList [ for i in 0 .. 99 -> float i / 100.0 ] |> should equal largev + + [] + let ``DenseVector.ofSeq`` () = + DenseVector.ofSeq (seq { for i in 0 .. 99 -> float i / 100.0 }) |> should equal largev + + [] + let ``DenseVector.rangef`` () = + DenseVector.rangef 0.0 0.01 0.99 |> should equal (new DenseVector( [| for i in 0 .. 99 -> 0.01 * float i |] ) ) + + [] + let ``DenseVector.range`` () = + DenseVector.range 0 99 |> should equal (new DenseVector( [| for i in 0 .. 99 -> float i |] ) ) diff --git a/src/FSharpUnitTests/FSharpUnitTests.fsproj b/src/FSharpUnitTests/FSharpUnitTests.fsproj index 6a51226a..9859d024 100644 --- a/src/FSharpUnitTests/FSharpUnitTests.fsproj +++ b/src/FSharpUnitTests/FSharpUnitTests.fsproj @@ -6,7 +6,7 @@ 8.0.30703 2.0 {f2f8032b-a31d-4e33-a05e-f2cdcbfaa75d} - Exe + Library FSharpUnitTests MathNet.Numerics.FSharp.UnitTests v4.0 @@ -46,14 +46,16 @@ + + + + + + - - - Always - diff --git a/src/FSharpUnitTests/FsUnit.fs b/src/FSharpUnitTests/FsUnit.fs index a4f7b89c..d5c8a7a7 100644 --- a/src/FSharpUnitTests/FsUnit.fs +++ b/src/FSharpUnitTests/FsUnit.fs @@ -1,244 +1,70 @@ -(* -Copyright (c) 2008, Raymond W. Vernagus (R.Vernagus@gmail.com) -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of Raymond W. Vernagus nor the names of FsUnit's - contributors may be used to endorse or promote products derived from this - software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*) -namespace FsUnit - -open MathNet.Numerics -open MathNet.Numerics.LinearAlgebra.Double -open MathNet.Numerics.LinearAlgebra.Generic - -type Result = - | Pass - | Fail of string - | Error of string - -type Expectation = - | True - | False - | Empty - | NullOrEmpty - | Null - | SameAs of obj - -type Spec = - abstract Check : unit -> Result - abstract NegatedMessage : string - -[] -module SpecOps = - let internal safeCheck f = - try - f() - with ex -> Error (ex.ToString()) - - let make f nmsg = - { new Spec with - member this.Check() = safeCheck f - member this.NegatedMessage = nmsg } - - let check (s: Spec) = s.Check() - - let not' f x = - let s = f x - match check s with - | Pass -> make (fun () -> Fail s.NegatedMessage) "" - | Fail msg -> make (fun () -> Pass) msg - | Error msg -> make (fun () -> Error msg) msg - - let equal expected actual = - make (fun () -> - if actual.Equals(expected) - then Pass - else Fail (sprintf "Expected: %A\nActual: %A" expected actual)) - (sprintf "NOT Expected: %A\nActual: %A" expected actual) - - let have n lbl s = - make (fun() -> - let len = Seq.length s - if len = n - then Pass - else Fail (sprintf "Expected: %d %s\nActual: %d %s" n lbl len lbl)) - (sprintf "NOT Expected: %d %s\nActual: %d %s" n lbl n lbl) - - let contain x s = - make (fun () -> - let exists = s |> Seq.exists (fun x' -> x' = x) - if exists - then Pass - else Fail (sprintf "Expected %A to contain %A" s x)) - (sprintf "Did NOT expect %A to contain %A" s x) - - let raise'<'a when 'a :> System.Exception> f = - let expType = typeof<'a> - make (fun () -> - try - f() - Fail (sprintf "Expected %s but no exception was raised" expType.FullName) - with ex -> - let actualExType = ex.GetType() - if expType = actualExType - then Pass - else Fail (sprintf "Expected: %s\nActual: %s" expType.FullName actualExType.FullName)) - (sprintf "Did NOT expect %s to be raised" expType.FullName) - - let be expectation x = - let x = box x - let msg = sprintf "Expected: %A\nActual: %A" expectation x - let negmsg = sprintf "NOT Expected: %A\nActual: %A" expectation x - match expectation with - | True -> - make (fun () -> - if x = box true - then Pass - else Fail msg) - negmsg - | False -> - make (fun () -> - if x = box false - then Pass - else Fail msg) - negmsg - | Empty -> - make (fun () -> - if x = box System.String.Empty - then Pass - else Fail msg) - negmsg - | NullOrEmpty -> - make (fun () -> - if System.String.IsNullOrEmpty(x :?> string) - then Pass - else Fail msg) - negmsg - | Null -> - make (fun () -> - if x = null - then Pass - else Fail msg) - negmsg - | SameAs other -> - make (fun () -> - if System.Object.ReferenceEquals(x, other) - then Pass - else Fail (sprintf "Expected actual to be same reference as expected %A" other)) - (sprintf "Expected %A to have different reference than %A" x other) - - let array_equal (expected: float []) (actual: float []) = - make (fun () -> - let mutable f = true - for i=0 to expected.Length-1 do - f <- f && (expected.[i] = actual.[i]) - if f - then Pass - else Fail (sprintf "Expected: %A\nActual: %A" expected actual)) - (sprintf "NOT Expected: %A\nActual: %A" expected actual) - - let array2_equal (expected: float [,]) (actual: float [,]) = - make (fun () -> - let mutable f = true - for i=0 to expected.GetLength(0)-1 do - for j=0 to expected.GetLength(1)-1 do - f <- f && (expected.[i,j] = actual.[i,j]) - if f - then Pass - else Fail (sprintf "Expected: %A\nActual: %A" expected actual)) - (sprintf "NOT Expected: %A\nActual: %A" expected actual) - - let approximately_equal (places : int) (expected: float) (actual: float) = - make (fun () -> - if Precision.AlmostEqualInDecimalPlaces(actual, expected, places) - then Pass - 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) = - make (fun () -> - let mutable f = true - for i=0 to expected.Count-1 do - f <- f && Precision.AlmostEqualInDecimalPlaces(expected.[i], actual.[i], places) - if f - then Pass - 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) = - make (fun () -> - let mutable f = true - for i=0 to expected.RowCount-1 do - for j=0 to expected.ColumnCount-1 do - f <- f && Precision.AlmostEqualInDecimalPlaces(expected.[i,j], actual.[i,j], places) - if f - then Pass - else Fail (sprintf "Expected: %A\nActual: %A" expected actual)) - (sprintf "NOT Expected: %A\nActual: %A" expected actual) - -module Results = - open Microsoft.FSharp.Text - - let internal currentResults = new ResizeArray() - - let add = currentResults.Add - - let passedCount () = - currentResults - |> Seq.filter (function _,Pass -> true | _ -> false) - |> Seq.length - - let failed () = - currentResults - |> Seq.filter (function _,Fail _ -> true | _ -> false) - - let failedCount () = - failed() - |> Seq.length - - let erred () = - currentResults - |> Seq.filter (function _,Error _ -> true | _ -> false) - - let erredCount () = - erred() - |> Seq.length - - let summary () = - let buff = new System.Text.StringBuilder() - buff.AppendFormat("{0} passed.\n{1} failed.\n{2} erred.", passedCount(), failedCount(), erredCount()) |> ignore - failed() - |> Seq.iter (function (lbl,Fail msg) -> buff.AppendFormat("\n----\nFailed: {0}\n{1}", lbl, msg) |> ignore | _ -> ()) - erred() - |> Seq.iter (function (lbl,Error msg) -> buff.AppendFormat("\n----\nErred: {0}\n{1}", lbl, msg) |> ignore | _ -> ()) - buff.ToString() +module FsUnit +open NUnit.Framework +open NUnit.Framework.Constraints + +let should (f : 'a -> #Constraint) x (y : obj) = + let c = f x + let y = + match y with + | :? (unit -> unit) -> box (TestDelegate(y :?> unit -> unit)) + | _ -> y + Assert.That(y, c) +let equal x = EqualConstraint(x) -[] -module SpecHelpers = - let spec lbl s = (lbl, check s) - - let should f x = f x - - let specs lbl (results: seq) = - results |> Seq.iter (fun x -> Results.add x) +let equalWithin tolerance x = equal(x).Within tolerance + +let contain x = ContainsConstraint(x) + +let haveLength n = Has.Length.EqualTo(n) + +let haveCount n = Has.Count.EqualTo(n) + +let be = id + +let Null = NullConstraint() + +let Empty = EmptyConstraint() + +let EmptyString = EmptyStringConstraint() + +let NullOrEmptyString = NullOrEmptyStringConstraint() + +let True = TrueConstraint() + +let False = FalseConstraint() + +let sameAs x = SameAsConstraint(x) + +let throw = Throws.TypeOf + +let greaterThan x = GreaterThanConstraint(x) + +let greaterThanOrEqualTo x = GreaterThanOrEqualConstraint(x) + +let lessThan x = LessThanConstraint(x) + +let lessThanOrEqualTo x = LessThanOrEqualConstraint(x) + +let shouldFail (f : unit -> unit) = + TestDelegate(f) |> should throw typeof + +let endWith (s:string) = EndsWithConstraint s + +let startWith (s:string) = StartsWithConstraint s + +let ofExactType<'a> = ExactTypeConstraint(typeof<'a>) + +let instanceOfType<'a> = InstanceOfTypeConstraint(typeof<'a>) + +let NaN = NaNConstraint() + +let unique = UniqueItemsConstraint() + +let not' x = NotConstraint(x) + +let array_equal = equal +let array2_equal = equal +let approximately_equal tolerance = equalWithin (10.0 ** (float -tolerance)) +let approximately_vector_equal = approximately_equal +let approximately_matrix_equal = approximately_equal diff --git a/src/FSharpUnitTests/MatrixTests.fs b/src/FSharpUnitTests/MatrixTests.fs new file mode 100644 index 00000000..bea3a6c9 --- /dev/null +++ b/src/FSharpUnitTests/MatrixTests.fs @@ -0,0 +1,112 @@ +namespace MathNet.Numerics.Tests + +open NUnit.Framework +open FsUnit +open MathNet.Numerics.LinearAlgebra.Generic +open MathNet.Numerics.LinearAlgebra.Double + +/// Unit tests for the matrix type. +module MatrixTests = + + /// A small uniform vector. + let smallM = new DenseMatrix( Array2D.create 2 2 0.3 ) + let failingFoldBackM = DenseMatrix.init 2 3 (fun i j -> 1.0) + + /// A large vector with increasingly large entries + let largeM = new DenseMatrix( Array2D.init 100 100 (fun i j -> float i * 100.0 + float j) ) + + [] + let ``Matrix.fold`` () = + Matrix.fold (fun a b -> a - b) 0.0 smallM |> should equal -1.2 + + [] + let ``Matrix.foldBack`` () = + Matrix.foldBack (fun a b -> a - b) 0.0 smallM |> should equal 0.0 + + [] + let ``Matrix.foldBackSummation`` () = + Matrix.foldBack( fun a b -> a + b) 0.0 failingFoldBackM |> should equal 6.0 + + [] + let ``Matrix.foldi`` () = + Matrix.foldi (fun i j acc x -> acc + x + float (i+j)) 0.0 smallM |> should equal 5.2 + + [] + let ``Matrix.toArray2`` () = + Matrix.toArray2 smallM |> should array2_equal (Array2D.create 2 2 0.3) + + [] + let ``Matrix.forall`` () = + Matrix.forall (fun x -> x = 0.3) smallM |> should equal true + + [] + let ``Matrix.exists`` () = + Matrix.exists (fun x -> x = 0.5) smallM |> should equal false + + [] + let ``Matrix.foralli`` () = + Matrix.foralli (fun i j x -> x = float i * 100.0 + float j) largeM |> should equal true + + [] + let ``Matrix.existsi`` () = + Matrix.existsi (fun i j x -> x = float i * 100.0 + float j) largeM |> should equal true + + [] + let ``Matrix.map`` () = + Matrix.map (fun x -> 2.0 * x) smallM |> should equal (2.0 * smallM) + + [] + let ``Matrix.mapi`` () = + Matrix.mapi (fun i j x -> float i * 100.0 + float j + x) largeM |> should equal (2.0 * largeM) + + [] + let ``Matrix.mapCols`` () = + Matrix.mapCols (fun j col -> col.Add(float j)) smallM |> should (approximately_matrix_equal 14) (matrix [[0.3;1.3];[0.3;1.3]]) + + [] + let ``Matrix.mapRows`` () = + Matrix.mapRows (fun i row -> row.Add(float i)) smallM |> should (approximately_matrix_equal 14) (matrix [[0.3;0.3];[1.3;1.3]]) + + [] + let ``Matrix.inplaceAssign`` () = + let N = smallM.Clone() + Matrix.inplaceAssign (fun i j -> 0.0) N + N |> should equal (0.0 * smallM) + + [] + let ``Matrix.inplaceMapi`` () = + let N = largeM.Clone() + Matrix.inplaceMapi (fun i j x -> 2.0 * (float i * 100.0 + float j) + x) N + N |> should equal (3.0 * largeM) + + [] + let ``Matrix.nonZeroEntries`` () = + Seq.length (Matrix.nonZeroEntries smallM) |> should equal 4 + + [] + let ``Matrix.sum`` () = + Matrix.sum smallM |> should equal 1.2 + + [] + let ``Matrix.sumColsBy`` () = + Matrix.sumColsBy (fun j col -> col.[0] * col.[1]) (matrix [[1.0; 2.0]; [3.0; 4.0]]) |> should equal 11.0 + + [] + let ``Matrix.sumRowsBy`` () = + Matrix.sumRowsBy (fun i row -> row.[0] * row.[1]) (matrix [[1.0; 2.0]; [3.0; 4.0]]) |> should equal 14.0 + + [] + let ``Matrix.foldCol`` () = + Matrix.foldCol (+) 0.0 largeM 0 |> should equal 495000.0 + + [] + let ``Matrix.foldRow`` () = + Matrix.foldRow (+) 0.0 largeM 0 |> should equal 4950.0 + + [] + let ``Matrix.foldByCol`` () = + Matrix.foldByCol (+) 0.0 smallM |> should equal (DenseVector.ofList [0.6;0.6] :> Vector) + + [] + let ``Matrix.foldByRow`` () = + Matrix.foldByRow (+) 0.0 smallM |> should equal (DenseVector.ofList [0.6;0.6] :> Vector) diff --git a/src/FSharpUnitTests/Program.fs b/src/FSharpUnitTests/Program.fs deleted file mode 100644 index 79780a5a..00000000 --- a/src/FSharpUnitTests/Program.fs +++ /dev/null @@ -1,223 +0,0 @@ -open FsUnit -open MathNet.Numerics.LinearAlgebra.Generic -open MathNet.Numerics.LinearAlgebra.Double - -/// Unit tests for the dense vector type. -let DenseVectorTests = - - /// A small uniform vector. - let smallv = new DenseVector(5, 0.3 ) - - /// A large vector with increasingly large entries - let largev = new DenseVector( Array.init 100 (fun i -> float i / 100.0) ) - - specs "DenseVector" [ - spec "DenseVector.init" - (DenseVector.init 100 (fun i -> float i / 100.0) |> should equal largev) - spec "DenseVector.ofList" - (DenseVector.ofList [ for i in 0 .. 99 -> float i / 100.0 ] |> should equal largev) - spec "DenseVector.ofSeq" - (DenseVector.ofSeq (seq { for i in 0 .. 99 -> float i / 100.0 }) |> should equal largev) - spec "DenseVector.rangef" - (DenseVector.rangef 0.0 0.01 0.99 |> should equal (new DenseVector( [| for i in 0 .. 99 -> 0.01 * float i |] ) )) - spec "DenseVector.range" - (DenseVector.range 0 99 |> should equal (new DenseVector( [| for i in 0 .. 99 -> float i |] ) )) - ] - - -/// Unit tests for the sparse vector type. -let SparseVectorTests = - - /// A small uniform vector. - let smallv = new DenseVector( [|0.0;0.3;0.0;0.0;0.0|] ) :> Vector - - specs "SparseVector" [ - spec "SparseVector.ofList" - ((SparseVector.ofList 5 [ (1,0.3) ] :> Vector) |> should equal smallv) - spec "SparseVector.ofSeq" - ((SparseVector.ofSeq 5 (List.toSeq [ (1,0.3) ]) :> Vector) |> should equal smallv) - ] - - -/// Unit tests for the vector type. -let VectorTests = - - /// A small uniform vector. - let smallv = new DenseVector( [|0.3;0.3;0.3;0.3;0.3|] ) :> Vector - - /// A large vector with increasingly large entries - let largev = new DenseVector( Array.init 100 (fun i -> float i / 100.0) ) :> Vector - - specs "Vector" [ - spec "Vector.toArray" - (Vector.toArray smallv |> should array_equal [|0.3;0.3;0.3;0.3;0.3|]) - spec "Vector.toList" - (Vector.toList smallv |> should equal [0.3;0.3;0.3;0.3;0.3]) - spec "Vector.mapInPlace" - ( let w = smallv.Clone() - Vector.mapInPlace (fun x -> 2.0 * x) w - w |> should equal (2.0 * smallv)) - spec "Vector.mapiInPlace" - ( let w = largev.Clone() - Vector.mapiInPlace (fun i x -> float i / 100.0) w - w |> should equal (largev)) - spec "Vector.addInPlace" - ( let w = largev.Clone() - Vector.addInPlace w largev - w |> should equal (2.0 * largev)) - spec "Vector.subInPlace" - ( let w = largev.Clone() - Vector.subInPlace w largev - w |> should equal (0.0 * largev)) - spec "Vector.map" - (Vector.map (fun x -> 2.0 * x) largev |> should equal (2.0 * largev)) - spec "Vector.mapi" - (Vector.mapi (fun i x -> float i / 100.0) largev |> should equal largev) - spec "Vector.fold" - (Vector.fold (fun a b -> a - b) 0.0 smallv |> should equal -1.5) - spec "Vector.foldBack" - (Vector.foldBack (fun a b -> a - b) 0.0 smallv |> should equal 0.0) - spec "Vector.foldi" - (Vector.foldi (fun i a b -> a + b) 0.0 smallv |> should equal 1.5) - spec "Vector.forall" - (Vector.forall (fun x -> x = 0.3) smallv |> should equal true) - spec "Vector.exists" - (Vector.exists (fun x -> x = 0.3) smallv |> should equal true) - spec "Vector.foralli" - (Vector.foralli (fun i x -> x = 0.3 && i < 5) smallv |> should equal true) - 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) ) - 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) ) - spec "Vector.reduce" - (Vector.reduce (fun acc x -> acc ** x) smallv |> should approximately_equal 14 0.990295218585507) - spec "Vector.reduceBack" - (Vector.reduceBack (fun x acc -> x ** acc) smallv |> should approximately_equal 14 0.488911287726319) - spec "Vector.insert" - (Vector.insert 2 0.5 smallv |> should approximately_vector_equal 14 (new DenseVector ( [|0.3;0.3;0.5;0.3;0.3;0.3|] ) :> Vector) ) - ] - - -/// Unit tests for the matrix type. -let MatrixTests = - - /// A small uniform vector. - let smallM = new DenseMatrix( Array2D.create 2 2 0.3 ) - let failingFoldBackM = DenseMatrix.init 2 3 (fun i j -> 1.0) - - - /// A large vector with increasingly large entries - let largeM = new DenseMatrix( Array2D.init 100 100 (fun i j -> float i * 100.0 + float j) ) - - specs "Matrix" [ - spec "Matrix.fold" - (Matrix.fold (fun a b -> a - b) 0.0 smallM |> should equal -1.2) - spec "Matrix.foldBack" - (Matrix.foldBack (fun a b -> a - b) 0.0 smallM |> should equal 0.0) - spec "Matrix.foldBackSummation" - (Matrix.foldBack( fun a b -> a + b) 0.0 failingFoldBackM |> should equal 6.0) - spec "Matrix.foldi" - (Matrix.foldi (fun i j acc x -> acc + x + float (i+j)) 0.0 smallM |> should equal 5.2) - spec "Matrix.toArray2" - (Matrix.toArray2 smallM |> should array2_equal (Array2D.create 2 2 0.3)) - spec "Matrix.forall" - (Matrix.forall (fun x -> x = 0.3) smallM |> should equal true) - spec "Matrix.exists" - (Matrix.exists (fun x -> x = 0.5) smallM |> should equal false) - spec "Matrix.foralli" - (Matrix.foralli (fun i j x -> x = float i * 100.0 + float j) largeM |> should equal true) - spec "Matrix.existsi" - (Matrix.existsi (fun i j x -> x = float i * 100.0 + float j) largeM |> should equal true) - spec "Matrix.map" - (Matrix.map (fun x -> 2.0 * x) smallM |> should equal (2.0 * smallM)) - spec "Matrix.mapi" - (Matrix.mapi (fun i j x -> float i * 100.0 + float j + x) largeM |> should equal (2.0 * largeM)) - spec "Matrix.mapCols" - (Matrix.mapCols (fun j col -> col.Add(float j)) smallM |> should approximately_matrix_equal 14 (matrix [[0.3;1.3];[0.3;1.3]])) - spec "Matrix.mapRows" - (Matrix.mapRows (fun i row -> row.Add(float i)) smallM |> should approximately_matrix_equal 14 (matrix [[0.3;0.3];[1.3;1.3]])) - spec "Matrix.inplaceAssign" - ( let N = smallM.Clone() - Matrix.inplaceAssign (fun i j -> 0.0) N - N |> should equal (0.0 * smallM)) - spec "Matrix.inplaceMapi" - ( let N = largeM.Clone() - Matrix.inplaceMapi (fun i j x -> 2.0 * (float i * 100.0 + float j) + x) N - N |> should equal (3.0 * largeM)) - spec "Matrix.nonZeroEntries" - (Seq.length (Matrix.nonZeroEntries smallM) |> should equal 4) - spec "Matrix.sum" - (Matrix.sum smallM |> should equal 1.2) - spec "Matrix.sumColsBy" - (Matrix.sumColsBy (fun j col -> col.[0] * col.[1]) (matrix [[1.0; 2.0]; [3.0; 4.0]]) |> should equal 11.0) - spec "Matrix.sumRowsBy" - (Matrix.sumRowsBy (fun i row -> row.[0] * row.[1]) (matrix [[1.0; 2.0]; [3.0; 4.0]]) |> should equal 14.0) - spec "Matrix.foldCol" - (Matrix.foldCol (+) 0.0 largeM 0 |> should equal 495000.0) - 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)) - spec "Matrix.foldByRow" - (Matrix.foldByRow (+) 0.0 smallM |> should equal (DenseVector.ofList [0.6;0.6] :> Vector)) - ] - - -/// Unit tests for the dense matrix type. -let DenseMatrixTests = - - /// A small uniform vector. - let smallM = new DenseMatrix( Array2D.create 2 2 0.3 ) - - /// A large vector with increasingly large entries - let largeM = new DenseMatrix( Array2D.init 100 100 (fun i j -> float i * 100.0 + float j) ) - - specs "DenseMatrix" [ - spec "DenseMatrix.init" - (DenseMatrix.init 100 100 (fun i j -> float i * 100.0 + float j) |> should equal largeM) - spec "DenseMatrix.ofList" - (DenseMatrix.ofList [[0.3;0.3];[0.3;0.3]] |> should equal smallM) - spec "DenseMatrix.ofSeq" - (DenseMatrix.ofSeq (Seq.ofList [[0.3;0.3];[0.3;0.3]]) |> should equal smallM) - spec "DenseMatrix.ofArray2" - (DenseMatrix.ofArray2 (Array2D.create 2 2 0.3) |> should equal smallM) - spec "DenseMatrix.initDense" - (DenseMatrix.initDense 100 100 (seq { for i in 0 .. 99 do - for j in 0 .. 99 -> (i,j, float i * 100.0 + float j)}) |> should equal largeM) - spec "DenseMatrix.constDiag" - (DenseMatrix.constDiag 100 2.0 |> should equal (2.0 * (DenseMatrix.Identity 100))) - spec "DenseMatrix.diag" - (DenseMatrix.diag (new DenseVector(100, 2.0)) |> should equal (2.0 * (DenseMatrix.Identity 100))) - spec "DenseMatrix.init_row" - (DenseMatrix.initRow 100 100 (fun i -> (DenseVector.init 100 (fun j -> float i * 100.0 + float j))) |> should equal largeM) - spec "DenseMatrix.init_col" - (DenseMatrix.initCol 100 100 (fun j -> (DenseVector.init 100 (fun i -> float i * 100.0 + float j))) |> should equal largeM) - ] - - -/// Unit tests for the sparse matrix type. -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 - - specs "SparseMatrix" [ - spec "SparseMatrix.ofList" - ((SparseMatrix.ofList 4 4 [(1,2,1.0)] :> Matrix) |> should equal smallM) - spec "SparseMatrix.ofSeq" - ((SparseMatrix.ofSeq 4 4 (Seq.ofList [(1,2,1.0)]) :> Matrix) |> should equal smallM) - spec "SparseMatrix.constDiag" - (SparseMatrix.constDiag 100 2.0 |> should equal (2.0 * (SparseMatrix.Identity 100))) - spec "SparseMatrix.diag" - (SparseMatrix.diag (new DenseVector(100, 2.0)) |> should equal (2.0 * (SparseMatrix.Identity 100))) - ] - - -/// Report on errors and success and exit. -printfn "F# Test Results:" -printfn "%s" (Results.summary()) - -let code = if Results.erredCount() > 0 || Results.failedCount() > 0 then -1 else 0;; -exit code;; \ No newline at end of file diff --git a/src/FSharpUnitTests/SparseMatrixTests.fs b/src/FSharpUnitTests/SparseMatrixTests.fs new file mode 100644 index 00000000..c572a26e --- /dev/null +++ b/src/FSharpUnitTests/SparseMatrixTests.fs @@ -0,0 +1,27 @@ +namespace MathNet.Numerics.Tests + +open NUnit.Framework +open FsUnit +open MathNet.Numerics.LinearAlgebra.Generic +open MathNet.Numerics.LinearAlgebra.Double + +/// Unit tests for the sparse matrix type. +module 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 ``SparseMatrix.ofList`` () = + (SparseMatrix.ofList 4 4 [(1,2,1.0)] :> Matrix) |> should equal smallM + + [] + let ``SparseMatrix.ofSeq`` () = + (SparseMatrix.ofSeq 4 4 (Seq.ofList [(1,2,1.0)]) :> Matrix) |> should equal smallM + + [] + let ``SparseMatrix.constDiag`` () = + SparseMatrix.constDiag 100 2.0 |> should equal (2.0 * (SparseMatrix.Identity 100)) + + [] let ``SparseMatrix.diag`` () = + SparseMatrix.diag (new DenseVector(100, 2.0)) |> should equal (2.0 * (SparseMatrix.Identity 100)) diff --git a/src/FSharpUnitTests/SparseVectorTests.fs b/src/FSharpUnitTests/SparseVectorTests.fs new file mode 100644 index 00000000..9526695d --- /dev/null +++ b/src/FSharpUnitTests/SparseVectorTests.fs @@ -0,0 +1,21 @@ +namespace MathNet.Numerics.Tests + +open NUnit.Framework +open FsUnit +open MathNet.Numerics.LinearAlgebra.Generic +open MathNet.Numerics.LinearAlgebra.Double + +/// Unit tests for the sparse vector type. +module SparseVectorTests = + + /// A small uniform vector. + let smallv = new DenseVector( [|0.0;0.3;0.0;0.0;0.0|] ) :> Vector + + [] + let ``SparseVector.ofList`` () = + (SparseVector.ofList 5 [ (1,0.3) ] :> Vector) |> should equal smallv + + [] + let ``SparseVector.ofSeq`` () = + (SparseVector.ofSeq 5 (List.toSeq [ (1,0.3) ]) :> Vector) |> should equal smallv + diff --git a/src/FSharpUnitTests/VectorTests.fs b/src/FSharpUnitTests/VectorTests.fs new file mode 100644 index 00000000..b0f0294b --- /dev/null +++ b/src/FSharpUnitTests/VectorTests.fs @@ -0,0 +1,103 @@ +namespace MathNet.Numerics.Tests + +open NUnit.Framework +open FsUnit +open MathNet.Numerics.LinearAlgebra.Generic +open MathNet.Numerics.LinearAlgebra.Double + +/// Unit tests for the vector type. +module VectorTests = + + /// A small uniform vector. + let smallv = new DenseVector([|0.3;0.3;0.3;0.3;0.3|]) :> Vector + + /// A large vector with increasingly large entries + let largev = new DenseVector(Array.init 100 (fun i -> float i / 100.0)) :> Vector + + [] + let ``Vector.toArray`` () = + Vector.toArray smallv |> should array_equal [|0.3;0.3;0.3;0.3;0.3|] + + [] + let ``Vector.toList`` () = + Vector.toList smallv |> should equal [0.3;0.3;0.3;0.3;0.3] + + [] + let ``Vector.mapInPlace`` () = + let w = smallv.Clone() + Vector.mapInPlace (fun x -> 2.0 * x) w + w |> should equal (2.0 * smallv) + + [] + let ``Vector.mapiInPlace`` () = + let w = largev.Clone() + Vector.mapiInPlace (fun i x -> float i / 100.0) w + w |> should equal (largev) + + [] + let ``Vector.addInPlace`` () = + let w = largev.Clone() + Vector.addInPlace w largev + w |> should equal (2.0 * largev) + + [] + let ``Vector.subInPlace`` () = + let w = largev.Clone() + Vector.subInPlace w largev + w |> should equal (0.0 * largev) + + [] + let ``Vector.map`` () = + Vector.map (fun x -> 2.0 * x) largev |> should equal (2.0 * largev) + + [] + let ``Vector.mapi`` () = + Vector.mapi (fun i x -> float i / 100.0) largev |> should equal largev + + [] + let ``Vector.fold`` () = + Vector.fold (fun a b -> a - b) 0.0 smallv |> should equal -1.5 + + [] + let ``Vector.foldBack`` () = + Vector.foldBack (fun a b -> a - b) 0.0 smallv |> should equal 0.0 + + [] + let ``Vector.foldi`` () = + Vector.foldi (fun i a b -> a + b) 0.0 smallv |> should equal 1.5 + + [] + let ``Vector.forall`` () = + Vector.forall (fun x -> x = 0.3) smallv |> should equal true + + [] + let ``Vector.exists`` () = + Vector.exists (fun x -> x = 0.3) smallv |> should equal true + + [] + let ``Vector.foralli`` () = + Vector.foralli (fun i x -> x = 0.3 && i < 5) smallv |> should equal true + + [] + let ``Vector.existsi`` () = + Vector.existsi (fun i x -> x = 0.3 && i = 2) smallv |> should equal true + + [] + let ``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) + + [] + let ``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) + + [] + let ``Vector.reduce`` () = + Vector.reduce (fun acc x -> acc ** x) smallv |> should (approximately_equal 14) 0.990295218585507 + + [] + let ``Vector.reduceBack`` () = + Vector.reduceBack (fun x acc -> x ** acc) smallv |> should (approximately_equal 14) 0.488911287726319 + + [] + let ``Vector.insert`` () = + Vector.insert 2 0.5 smallv |> should (approximately_vector_equal 14) (new DenseVector ( [|0.3;0.3;0.5;0.3;0.3;0.3|] ) :> Vector)