Permalink
Browse files

Fix cumulative for distributions

Properly handle infinities and NaNs
  • Loading branch information...
1 parent 111b20b commit 07c955552c5fbc4f1ced4b64f5774c8bbfb8068f @Shimuuar Shimuuar committed Oct 3, 2012
@@ -67,13 +67,15 @@ probability (BD n p) k
-- Summation from different sides required to reduce roundoff errors
cumulative :: BinomialDistribution -> Double -> Double
cumulative d@(BD n _) x
- | k < 0 = 0
- | k >= n = 1
- | k < m = D.sumProbabilities d 0 k
- | otherwise = 1 - D.sumProbabilities d (k+1) n
- where
- m = floor (mean d)
- k = floor x
+ | isNaN x = error "Statistics.Distribution.Binomial.cumulative: NaN input"
+ | isInfinite x = if x > 0 then 1 else 0
+ | k < 0 = 0
+ | k >= n = 1
+ | k < m = D.sumProbabilities d 0 k
+ | otherwise = 1 - D.sumProbabilities d (k+1) n
+ where
+ m = floor (mean d)
+ k = floor x
{-# INLINE cumulative #-}
mean :: BinomialDistribution -> Double
@@ -70,6 +70,9 @@ probability (GD s) n | n < 1 = 0
{-# INLINE probability #-}
cumulative :: GeometricDistribution -> Double -> Double
-cumulative (GD s) x | x < 1 = 0
- | otherwise = 1 - (1-s) ^ (floor x :: Int)
+cumulative (GD s) x
+ | x < 1 = 0
+ | isInfinite x = 1
+ | isNaN x = error "Statistics.Distribution.Geometric.cumulative: NaN input"
+ | otherwise = 1 - (1-s) ^ (floor x :: Int)
{-# INLINE cumulative #-}
@@ -93,10 +93,12 @@ probability (HD mi li ki) n
cumulative :: HypergeometricDistribution -> Double -> Double
cumulative d@(HD mi li ki) x
- | n < minN = 0
- | n >= maxN = 1
- | otherwise = D.sumProbabilities d minN n
- where
- n = floor x
- minN = max 0 (mi+ki-li)
- maxN = min mi ki
+ | isNaN x = error "Statistics.Distribution.Hypergeometric.cumulative: NaN argument"
+ | isInfinite x = if x > 0 then 1 else 0
+ | n < minN = 0
+ | n >= maxN = 1
+ | otherwise = D.sumProbabilities d minN n
+ where
+ n = floor x
+ minN = max 0 (mi+ki-li)
+ maxN = min mi ki
@@ -37,8 +37,10 @@ newtype PoissonDistribution = PD {
instance D.Distribution PoissonDistribution where
cumulative (PD lambda) x
- | x < 0 = 0
- | otherwise = 1 - incompleteGamma (fromIntegral (floor x + 1 :: Int)) lambda
+ | x < 0 = 0
+ | isInfinite x = 1
+ | isNaN x = error "Statistics.Distribution.Poisson.cumulative: NaN input"
+ | otherwise = 1 - incompleteGamma (fromIntegral (floor x + 1 :: Int)) lambda
{-# INLINE cumulative #-}
instance D.DiscreteDistr PoissonDistribution where

0 comments on commit 07c9555

Please sign in to comment.