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
|
{-# LANGUAGE DeriveDataTypeable #-}
-----------------------------------------------------------------------------
-- |
-- Module : Statistics.Distribution.Beta
-- Copyright : (C) 2012 Edward Kmett,
-- License : BSD-style (see the file LICENSE)
--
-- Maintainer : Edward Kmett <ekmett@gmail.com>
-- Stability : provisional
-- Portability : DeriveDataTypeable
--
----------------------------------------------------------------------------
module Statistics.Distribution.Beta
( BetaDistribution
-- * Constructor
, betaDistr
, improperBetaDistr
-- * Accessors
, bdAlpha
, bdBeta
) where
import Numeric.SpecFunctions (incompleteBeta, invIncompleteBeta, logBeta)
import Numeric.MathFunctions.Constants (m_NaN)
import qualified Statistics.Distribution as D
import Data.Typeable
-- | The beta distribution
data BetaDistribution = BD
{ bdAlpha :: {-# UNPACK #-} !Double
-- ^ Alpha shape parameter
, bdBeta :: {-# UNPACK #-} !Double
-- ^ Beta shape parameter
} deriving (Eq,Read,Show,Typeable)
-- | Create beta distribution. Both shape parameters must be positive.
betaDistr :: Double -- ^ Shape parameter alpha
-> Double -- ^ Shape parameter beta
-> BetaDistribution
betaDistr a b
| a > 0 && b > 0 = improperBetaDistr a b
| otherwise =
error $ "Statistics.Distribution.Beta.betaDistr: "
++ "shape parameters must be positive. Got a = "
++ show a
++ " b = "
++ show b
{-# INLINE betaDistr #-}
-- | Create beta distribution. This construtor doesn't check parameters.
improperBetaDistr :: Double -- ^ Shape parameter alpha
-> Double -- ^ Shape parameter beta
-> BetaDistribution
improperBetaDistr = BD
{-# INLINE improperBetaDistr #-}
instance D.Distribution BetaDistribution where
cumulative (BD a b) x
| x <= 0 = 0
| x >= 1 = 1
| otherwise = incompleteBeta a b x
{-# INLINE cumulative #-}
instance D.Mean BetaDistribution where
mean (BD a b) = a / (a + b)
{-# INLINE mean #-}
instance D.MaybeMean BetaDistribution where
maybeMean = Just . D.mean
{-# INLINE maybeMean #-}
instance D.Variance BetaDistribution where
variance (BD a b) = a*b / (apb*apb*(apb+1))
where apb = a + b
{-# INLINE variance #-}
instance D.MaybeVariance BetaDistribution where
maybeVariance = Just . D.variance
{-# INLINE maybeVariance #-}
instance D.ContDistr BetaDistribution where
density (BD a b) x
| a <= 0 || b <= 0 = m_NaN
| x <= 0 = 0
| x >= 1 = 0
| otherwise = exp $ (a-1)*log x + (b-1)*log (1-x) - logBeta a b
{-# INLINE density #-}
quantile (BD a b) p
| p == 0 = 0
| p == 1 = 1
| p > 0 && p < 1 = invIncompleteBeta a b p
| otherwise =
error $ "Statistics.Distribution.Gamma.quantile: p must be in [0,1] range. Got: "++show p
{-# INLINE quantile #-}
instance D.ContGen BetaDistribution where
genContVar = D.genContinous
|