forked from tsai/mathnet-numerics
11 changed files with 425 additions and 485 deletions
@ -1,6 +0,0 @@ |
|||||
<?xml version="1.0" encoding="utf-8"?> |
|
||||
<configuration> |
|
||||
<startup> |
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0" /> |
|
||||
</startup> |
|
||||
</configuration> |
|
||||
@ -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) ) |
||||
|
|
||||
|
[<Test>] |
||||
|
let ``DenseMatrix.init`` () = |
||||
|
DenseMatrix.init 100 100 (fun i j -> float i * 100.0 + float j) |> should equal largeM |
||||
|
|
||||
|
[<Test>] |
||||
|
let ``DenseMatrix.ofList`` () = |
||||
|
DenseMatrix.ofList [[0.3;0.3];[0.3;0.3]] |> should equal smallM |
||||
|
|
||||
|
[<Test>] |
||||
|
let ``DenseMatrix.ofSeq`` () = |
||||
|
DenseMatrix.ofSeq (Seq.ofList [[0.3;0.3];[0.3;0.3]]) |> should equal smallM |
||||
|
|
||||
|
[<Test>] |
||||
|
let ``DenseMatrix.ofArray2`` () = |
||||
|
DenseMatrix.ofArray2 (Array2D.create 2 2 0.3) |> should equal smallM |
||||
|
|
||||
|
[<Test>] |
||||
|
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 |
||||
|
[<Test>] |
||||
|
let ``DenseMatrix.constDiag`` () = |
||||
|
DenseMatrix.constDiag 100 2.0 |> should equal (2.0 * (DenseMatrix.Identity 100)) |
||||
|
|
||||
|
[<Test>] |
||||
|
let ``DenseMatrix.diag`` () = |
||||
|
DenseMatrix.diag (new DenseVector(100, 2.0)) |> should equal (2.0 * (DenseMatrix.Identity 100)) |
||||
|
|
||||
|
[<Test>] |
||||
|
let ``DenseMatrix.init_row`` () = |
||||
|
DenseMatrix.initRow 100 100 (fun i -> (DenseVector.init 100 (fun j -> float i * 100.0 + float j))) |> should equal largeM |
||||
|
|
||||
|
[<Test>] |
||||
|
let ``DenseMatrix.init_col`` () = |
||||
|
DenseMatrix.initCol 100 100 (fun j -> (DenseVector.init 100 (fun i -> float i * 100.0 + float j))) |> should equal largeM |
||||
@ -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) ) |
||||
|
|
||||
|
[<Test>] |
||||
|
let ``DenseVector.init`` () = |
||||
|
DenseVector.init 100 (fun i -> float i / 100.0) |> should equal largev |
||||
|
|
||||
|
[<Test>] |
||||
|
let ``DenseVector.ofList`` () = |
||||
|
DenseVector.ofList [ for i in 0 .. 99 -> float i / 100.0 ] |> should equal largev |
||||
|
|
||||
|
[<Test>] |
||||
|
let ``DenseVector.ofSeq`` () = |
||||
|
DenseVector.ofSeq (seq { for i in 0 .. 99 -> float i / 100.0 }) |> should equal largev |
||||
|
|
||||
|
[<Test>] |
||||
|
let ``DenseVector.rangef`` () = |
||||
|
DenseVector.rangef 0.0 0.01 0.99 |> should equal (new DenseVector( [| for i in 0 .. 99 -> 0.01 * float i |] ) ) |
||||
|
|
||||
|
[<Test>] |
||||
|
let ``DenseVector.range`` () = |
||||
|
DenseVector.range 0 99 |> should equal (new DenseVector( [| for i in 0 .. 99 -> float i |] ) ) |
||||
@ -1,244 +1,70 @@ |
|||||
(* |
module FsUnit |
||||
Copyright (c) 2008, Raymond W. Vernagus (R.Vernagus@gmail.com) |
open NUnit.Framework |
||||
All rights reserved. |
open NUnit.Framework.Constraints |
||||
|
|
||||
Redistribution and use in source and binary forms, with or without modification, |
let should (f : 'a -> #Constraint) x (y : obj) = |
||||
are permitted provided that the following conditions are met: |
let c = f x |
||||
|
let y = |
||||
* Redistributions of source code must retain the above copyright notice, |
match y with |
||||
this list of conditions and the following disclaimer. |
| :? (unit -> unit) -> box (TestDelegate(y :?> unit -> unit)) |
||||
* Redistributions in binary form must reproduce the above copyright notice, |
| _ -> y |
||||
this list of conditions and the following disclaimer in the documentation |
Assert.That(y, c) |
||||
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 |
|
||||
|
|
||||
[<AutoOpen>] |
|
||||
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<float>) (actual: #Vector<float>) = |
|
||||
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<float>) (actual: #Matrix<float>) = |
|
||||
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<string * Result>() |
|
||||
|
|
||||
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() |
|
||||
|
|
||||
|
let equal x = EqualConstraint(x) |
||||
|
|
||||
[<AutoOpen>] |
let equalWithin tolerance x = equal(x).Within tolerance |
||||
module SpecHelpers = |
|
||||
let spec lbl s = (lbl, check s) |
let contain x = ContainsConstraint(x) |
||||
|
|
||||
let should f x = f x |
let haveLength n = Has.Length.EqualTo(n) |
||||
|
|
||||
let specs lbl (results: seq<string * Result>) = |
let haveCount n = Has.Count.EqualTo(n) |
||||
results |> Seq.iter (fun x -> Results.add x) |
|
||||
|
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<AssertionException> |
||||
|
|
||||
|
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 |
||||
|
|||||
@ -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) ) |
||||
|
|
||||
|
[<Test>] |
||||
|
let ``Matrix.fold`` () = |
||||
|
Matrix.fold (fun a b -> a - b) 0.0 smallM |> should equal -1.2 |
||||
|
|
||||
|
[<Test>] |
||||
|
let ``Matrix.foldBack`` () = |
||||
|
Matrix.foldBack (fun a b -> a - b) 0.0 smallM |> should equal 0.0 |
||||
|
|
||||
|
[<Test>] |
||||
|
let ``Matrix.foldBackSummation`` () = |
||||
|
Matrix.foldBack( fun a b -> a + b) 0.0 failingFoldBackM |> should equal 6.0 |
||||
|
|
||||
|
[<Test>] |
||||
|
let ``Matrix.foldi`` () = |
||||
|
Matrix.foldi (fun i j acc x -> acc + x + float (i+j)) 0.0 smallM |> should equal 5.2 |
||||
|
|
||||
|
[<Test>] |
||||
|
let ``Matrix.toArray2`` () = |
||||
|
Matrix.toArray2 smallM |> should array2_equal (Array2D.create 2 2 0.3) |
||||
|
|
||||
|
[<Test>] |
||||
|
let ``Matrix.forall`` () = |
||||
|
Matrix.forall (fun x -> x = 0.3) smallM |> should equal true |
||||
|
|
||||
|
[<Test>] |
||||
|
let ``Matrix.exists`` () = |
||||
|
Matrix.exists (fun x -> x = 0.5) smallM |> should equal false |
||||
|
|
||||
|
[<Test>] |
||||
|
let ``Matrix.foralli`` () = |
||||
|
Matrix.foralli (fun i j x -> x = float i * 100.0 + float j) largeM |> should equal true |
||||
|
|
||||
|
[<Test>] |
||||
|
let ``Matrix.existsi`` () = |
||||
|
Matrix.existsi (fun i j x -> x = float i * 100.0 + float j) largeM |> should equal true |
||||
|
|
||||
|
[<Test>] |
||||
|
let ``Matrix.map`` () = |
||||
|
Matrix.map (fun x -> 2.0 * x) smallM |> should equal (2.0 * smallM) |
||||
|
|
||||
|
[<Test>] |
||||
|
let ``Matrix.mapi`` () = |
||||
|
Matrix.mapi (fun i j x -> float i * 100.0 + float j + x) largeM |> should equal (2.0 * largeM) |
||||
|
|
||||
|
[<Test>] |
||||
|
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]]) |
||||
|
|
||||
|
[<Test>] |
||||
|
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]]) |
||||
|
|
||||
|
[<Test>] |
||||
|
let ``Matrix.inplaceAssign`` () = |
||||
|
let N = smallM.Clone() |
||||
|
Matrix.inplaceAssign (fun i j -> 0.0) N |
||||
|
N |> should equal (0.0 * smallM) |
||||
|
|
||||
|
[<Test>] |
||||
|
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) |
||||
|
|
||||
|
[<Test>] |
||||
|
let ``Matrix.nonZeroEntries`` () = |
||||
|
Seq.length (Matrix.nonZeroEntries smallM) |> should equal 4 |
||||
|
|
||||
|
[<Test>] |
||||
|
let ``Matrix.sum`` () = |
||||
|
Matrix.sum smallM |> should equal 1.2 |
||||
|
|
||||
|
[<Test>] |
||||
|
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 |
||||
|
|
||||
|
[<Test>] |
||||
|
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 |
||||
|
|
||||
|
[<Test>] |
||||
|
let ``Matrix.foldCol`` () = |
||||
|
Matrix.foldCol (+) 0.0 largeM 0 |> should equal 495000.0 |
||||
|
|
||||
|
[<Test>] |
||||
|
let ``Matrix.foldRow`` () = |
||||
|
Matrix.foldRow (+) 0.0 largeM 0 |> should equal 4950.0 |
||||
|
|
||||
|
[<Test>] |
||||
|
let ``Matrix.foldByCol`` () = |
||||
|
Matrix.foldByCol (+) 0.0 smallM |> should equal (DenseVector.ofList [0.6;0.6] :> Vector<float>) |
||||
|
|
||||
|
[<Test>] |
||||
|
let ``Matrix.foldByRow`` () = |
||||
|
Matrix.foldByRow (+) 0.0 smallM |> should equal (DenseVector.ofList [0.6;0.6] :> Vector<float>) |
||||
@ -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<float> |
|
||||
|
|
||||
specs "SparseVector" [ |
|
||||
spec "SparseVector.ofList" |
|
||||
((SparseVector.ofList 5 [ (1,0.3) ] :> Vector<float>) |> should equal smallv) |
|
||||
spec "SparseVector.ofSeq" |
|
||||
((SparseVector.ofSeq 5 (List.toSeq [ (1,0.3) ]) :> Vector<float>) |> 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<float> |
|
||||
|
|
||||
/// A large vector with increasingly large entries |
|
||||
let largev = new DenseVector( Array.init 100 (fun i -> float i / 100.0) ) :> Vector<float> |
|
||||
|
|
||||
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<float>) ) |
|
||||
spec "Vector.scanBack" |
|
||||
(Vector.scanBack (fun x acc -> acc + x) smallv |> should approximately_vector_equal 14 (new DenseVector( [|1.5;1.2;0.9;0.6;0.3|] ) :> Vector<float>) ) |
|
||||
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<float>) ) |
|
||||
] |
|
||||
|
|
||||
|
|
||||
/// 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<float>)) |
|
||||
spec "Matrix.foldByRow" |
|
||||
(Matrix.foldByRow (+) 0.0 smallM |> should equal (DenseVector.ofList [0.6;0.6] :> Vector<float>)) |
|
||||
] |
|
||||
|
|
||||
|
|
||||
/// 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<float> |
|
||||
|
|
||||
specs "SparseMatrix" [ |
|
||||
spec "SparseMatrix.ofList" |
|
||||
((SparseMatrix.ofList 4 4 [(1,2,1.0)] :> Matrix<float>) |> should equal smallM) |
|
||||
spec "SparseMatrix.ofSeq" |
|
||||
((SparseMatrix.ofSeq 4 4 (Seq.ofList [(1,2,1.0)]) :> Matrix<float>) |> 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;; |
|
||||
@ -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<float> |
||||
|
|
||||
|
[<Test>] |
||||
|
let ``SparseMatrix.ofList`` () = |
||||
|
(SparseMatrix.ofList 4 4 [(1,2,1.0)] :> Matrix<float>) |> should equal smallM |
||||
|
|
||||
|
[<Test>] |
||||
|
let ``SparseMatrix.ofSeq`` () = |
||||
|
(SparseMatrix.ofSeq 4 4 (Seq.ofList [(1,2,1.0)]) :> Matrix<float>) |> should equal smallM |
||||
|
|
||||
|
[<Test>] |
||||
|
let ``SparseMatrix.constDiag`` () = |
||||
|
SparseMatrix.constDiag 100 2.0 |> should equal (2.0 * (SparseMatrix.Identity 100)) |
||||
|
|
||||
|
[<Test>] let ``SparseMatrix.diag`` () = |
||||
|
SparseMatrix.diag (new DenseVector(100, 2.0)) |> should equal (2.0 * (SparseMatrix.Identity 100)) |
||||
@ -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<float> |
||||
|
|
||||
|
[<Test>] |
||||
|
let ``SparseVector.ofList`` () = |
||||
|
(SparseVector.ofList 5 [ (1,0.3) ] :> Vector<float>) |> should equal smallv |
||||
|
|
||||
|
[<Test>] |
||||
|
let ``SparseVector.ofSeq`` () = |
||||
|
(SparseVector.ofSeq 5 (List.toSeq [ (1,0.3) ]) :> Vector<float>) |> should equal smallv |
||||
|
|
||||
@ -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<float> |
||||
|
|
||||
|
/// A large vector with increasingly large entries |
||||
|
let largev = new DenseVector(Array.init 100 (fun i -> float i / 100.0)) :> Vector<float> |
||||
|
|
||||
|
[<Test>] |
||||
|
let ``Vector.toArray`` () = |
||||
|
Vector.toArray smallv |> should array_equal [|0.3;0.3;0.3;0.3;0.3|] |
||||
|
|
||||
|
[<Test>] |
||||
|
let ``Vector.toList`` () = |
||||
|
Vector.toList smallv |> should equal [0.3;0.3;0.3;0.3;0.3] |
||||
|
|
||||
|
[<Test>] |
||||
|
let ``Vector.mapInPlace`` () = |
||||
|
let w = smallv.Clone() |
||||
|
Vector.mapInPlace (fun x -> 2.0 * x) w |
||||
|
w |> should equal (2.0 * smallv) |
||||
|
|
||||
|
[<Test>] |
||||
|
let ``Vector.mapiInPlace`` () = |
||||
|
let w = largev.Clone() |
||||
|
Vector.mapiInPlace (fun i x -> float i / 100.0) w |
||||
|
w |> should equal (largev) |
||||
|
|
||||
|
[<Test>] |
||||
|
let ``Vector.addInPlace`` () = |
||||
|
let w = largev.Clone() |
||||
|
Vector.addInPlace w largev |
||||
|
w |> should equal (2.0 * largev) |
||||
|
|
||||
|
[<Test>] |
||||
|
let ``Vector.subInPlace`` () = |
||||
|
let w = largev.Clone() |
||||
|
Vector.subInPlace w largev |
||||
|
w |> should equal (0.0 * largev) |
||||
|
|
||||
|
[<Test>] |
||||
|
let ``Vector.map`` () = |
||||
|
Vector.map (fun x -> 2.0 * x) largev |> should equal (2.0 * largev) |
||||
|
|
||||
|
[<Test>] |
||||
|
let ``Vector.mapi`` () = |
||||
|
Vector.mapi (fun i x -> float i / 100.0) largev |> should equal largev |
||||
|
|
||||
|
[<Test>] |
||||
|
let ``Vector.fold`` () = |
||||
|
Vector.fold (fun a b -> a - b) 0.0 smallv |> should equal -1.5 |
||||
|
|
||||
|
[<Test>] |
||||
|
let ``Vector.foldBack`` () = |
||||
|
Vector.foldBack (fun a b -> a - b) 0.0 smallv |> should equal 0.0 |
||||
|
|
||||
|
[<Test>] |
||||
|
let ``Vector.foldi`` () = |
||||
|
Vector.foldi (fun i a b -> a + b) 0.0 smallv |> should equal 1.5 |
||||
|
|
||||
|
[<Test>] |
||||
|
let ``Vector.forall`` () = |
||||
|
Vector.forall (fun x -> x = 0.3) smallv |> should equal true |
||||
|
|
||||
|
[<Test>] |
||||
|
let ``Vector.exists`` () = |
||||
|
Vector.exists (fun x -> x = 0.3) smallv |> should equal true |
||||
|
|
||||
|
[<Test>] |
||||
|
let ``Vector.foralli`` () = |
||||
|
Vector.foralli (fun i x -> x = 0.3 && i < 5) smallv |> should equal true |
||||
|
|
||||
|
[<Test>] |
||||
|
let ``Vector.existsi`` () = |
||||
|
Vector.existsi (fun i x -> x = 0.3 && i = 2) smallv |> should equal true |
||||
|
|
||||
|
[<Test>] |
||||
|
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<float>) |
||||
|
|
||||
|
[<Test>] |
||||
|
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<float>) |
||||
|
|
||||
|
[<Test>] |
||||
|
let ``Vector.reduce`` () = |
||||
|
Vector.reduce (fun acc x -> acc ** x) smallv |> should (approximately_equal 14) 0.990295218585507 |
||||
|
|
||||
|
[<Test>] |
||||
|
let ``Vector.reduceBack`` () = |
||||
|
Vector.reduceBack (fun x acc -> x ** acc) smallv |> should (approximately_equal 14) 0.488911287726319 |
||||
|
|
||||
|
[<Test>] |
||||
|
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<float>) |
||||
Loading…
Reference in new issue