diff --git a/src/FSharp.Stats/Array.fs b/src/FSharp.Stats/Array.fs index c4e436df..ebaed80d 100644 --- a/src/FSharp.Stats/Array.fs +++ b/src/FSharp.Stats/Array.fs @@ -260,6 +260,9 @@ module Array = /// /// let inline weightedMean (weights:array<'T>) (items:array<'T>) = + // throws an exception if the collection is empty and the file type is not float (returns nan if float collection) + if items.Length = 0 && not (box items :? float[]) then + failwithf "Array.weightedMean is undefined for an empty non float sequence!" // DimensionMismatchException if (items.Length <> weights.Length) then failwithf "The items and weights must have the same length" @@ -305,6 +308,10 @@ module Array = /// /// let inline weightedVariance mean (weights:array<'T>) (items:array<'T>) = + // throws an exception if the collection is empty and the file type is not float (returns nan if float collection) + if items.Length = 0 && not (box items :? float[]) then + failwithf "Array.weightedVariance is undefined for an empty non float sequence!" + // DimensionMismatchException if (items.Length <> weights.Length) then failwithf "The items and weights must have the same length" @@ -334,7 +341,10 @@ module Array = /// /// /// - let inline median (items:array<'T>) = + let inline median (items: array<'T>) = + // throws an exception if the collection is empty and the file type is not float (returns nan if float collection) + if items.Length = 0 && not (box items :? float[]) then + failwithf "Array.median is undefined for an empty non float sequence!" let zero = LanguagePrimitives.GenericZero< 'T > let one = LanguagePrimitives.GenericOne< 'T > diff --git a/tests/FSharp.Stats.Tests/Array.fs b/tests/FSharp.Stats.Tests/Array.fs index b0728f8f..ed66bbc5 100644 --- a/tests/FSharp.Stats.Tests/Array.fs +++ b/tests/FSharp.Stats.Tests/Array.fs @@ -13,6 +13,9 @@ let testArrayNegInfinity = [|10000.;-0.1;14.;-10.;5.;Double.NegativeInfinity|] let testArrayEvenCountsInt = [|10000;-50;14;-9|] let testArrayOddCountsInt = [|10000;-50;14;-10;5|] +let testArrayEmptyInt : int array = [||] +let testArrayEmptyFloat : float array = [||] +let testArrayEmptyDec : decimal array = [||] [] let medianTests = @@ -33,12 +36,21 @@ let medianTests = let median = Array.median testArrayNegInfinity Expect.floatClose Accuracy.high median 2.45 "Median should be 2.45" - testCase "testListEvenCountsInt" <| fun () -> + testCase "testArrayEvenCountsInt" <| fun () -> let median = Array.median testArrayEvenCountsInt Expect.equal median 2 "Median should be 2" - testCase "testListOddCountsInt" <| fun () -> + testCase "testArrayOddCountsInt" <| fun () -> let median = Array.median testArrayOddCountsInt Expect.equal median 5 "Median should be 5" + testCase "testArrayEmptyFloat" <| fun () -> + let median = Array.median testArrayEmptyFloat + Expect.isTrue (Ops.isNan median) "Median of empty float array should be nan" + testCase "testArrayEmptyInt" <| fun () -> + let median() = Array.median testArrayEmptyInt + Expect.throws (fun () -> median () |> ignore) "Median for empty non-float sequences is not defined" + testCase "testArrayEmptyDec" <| fun () -> + let median() = Array.median testArrayEmptyDec + Expect.throws (fun () -> median () |> ignore) "Median for empty non-float sequences is not defined" ] []