1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
|
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE DeriveDataTypeable, DeriveGeneric #-}
-- |
-- Module : Statistics.Distribution.Poisson
-- Copyright : (c) 2009, 2011 Bryan O'Sullivan
-- License : BSD3
--
-- Maintainer : bos@serpentine.com
-- Stability : experimental
-- Portability : portable
--
-- The Poisson distribution. This is the discrete probability
-- distribution of a number of events occurring in a fixed interval if
-- these events occur with a known average rate, and occur
-- independently from each other within that interval.
module Statistics.Distribution.Poisson
(
PoissonDistribution
-- * Constructors
, poisson
, poissonE
-- * Accessors
, poissonLambda
-- * References
-- $references
) where
import Control.Applicative
import Data.Aeson (FromJSON(..), ToJSON, Value(..), (.:))
import Data.Binary (Binary(..))
import Data.Data (Data, Typeable)
import GHC.Generics (Generic)
import Numeric.SpecFunctions (incompleteGamma,logFactorial)
import Numeric.MathFunctions.Constants (m_neg_inf)
import qualified Statistics.Distribution as D
import qualified Statistics.Distribution.Poisson.Internal as I
import Statistics.Internal
newtype PoissonDistribution = PD {
poissonLambda :: Double
} deriving (Eq, Typeable, Data, Generic)
instance Show PoissonDistribution where
showsPrec i (PD l) = defaultShow1 "poisson" l i
instance Read PoissonDistribution where
readPrec = defaultReadPrecM1 "poisson" poissonE
instance ToJSON PoissonDistribution
instance FromJSON PoissonDistribution where
parseJSON (Object v) = do
l <- v .: "poissonLambda"
maybe (fail $ errMsg l) return $ poissonE l
parseJSON _ = empty
instance Binary PoissonDistribution where
put = put . poissonLambda
get = do
l <- get
maybe (fail $ errMsg l) return $ poissonE l
instance D.Distribution PoissonDistribution where
cumulative (PD lambda) x
| x < 0 = 0
| isInfinite x = 1
| isNaN x = error "Statistics.Distribution.Poisson.cumulative: NaN input"
| otherwise = 1 - incompleteGamma (fromIntegral (floor x + 1 :: Int)) lambda
instance D.DiscreteDistr PoissonDistribution where
probability (PD lambda) x = I.probability lambda (fromIntegral x)
logProbability (PD lambda) i
| i < 0 = m_neg_inf
| otherwise = log lambda * fromIntegral i - logFactorial i - lambda
instance D.Variance PoissonDistribution where
variance = poissonLambda
instance D.Mean PoissonDistribution where
mean = poissonLambda
instance D.MaybeMean PoissonDistribution where
maybeMean = Just . D.mean
instance D.MaybeVariance PoissonDistribution where
maybeStdDev = Just . D.stdDev
instance D.Entropy PoissonDistribution where
entropy (PD lambda) = I.poissonEntropy lambda
instance D.MaybeEntropy PoissonDistribution where
maybeEntropy = Just . D.entropy
-- | Create Poisson distribution.
poisson :: Double -> PoissonDistribution
poisson l = maybe (error $ errMsg l) id $ poissonE l
-- | Create Poisson distribution.
poissonE :: Double -> Maybe PoissonDistribution
poissonE l
| l >= 0 = Just (PD l)
| otherwise = Nothing
errMsg :: Double -> String
errMsg l = "Statistics.Distribution.Poisson.poisson: lambda must be non-negative. Got "
++ show l
-- $references
--
-- * Loader, C. (2000) Fast and Accurate Computation of Binomial
-- Probabilities. <http://projects.scipy.org/scipy/raw-attachment/ticket/620/loader2000Fast.pdf>
-- * Adell, J., Lekuona, A., and Yu, Y. (2010) Sharp Bounds on the
-- Entropy of the Poisson Law and Related Quantities
-- <http://arxiv.org/pdf/1001.2897.pdf>
|