probability-dist-0.1.0.0: src/Probability/Continuous.hs
module Probability.Continuous
(
normalPDF
,normalLogPDF
,normalCDF
,normalMean
,normalVar
,exponentialLogPDF
,exponentialPDF
,exponentialCDF
,exponentialMean
,exponentialVar
,gammaLogPDF
,gammaPDF
,gammaMean
,gammaVar
,uniformLogPDF
,uniformPDF
,uniformCDF
,uniformMean
,uniformVar
)where
import Probability.Error (ProbabilityError(..))
import Probability.Math
(logFactorial
, logCombination
, logGamma
, logBeta
,erf
,expm1)
normalLogPDF
:: Double
-> Double
-> Double
-> Either ProbabilityError Double
normalLogPDF x mu sigma
| sigma <= 0 =
Left (InvalidStandardDeviation sigma)
| otherwise =
let z = (x - mu) / sigma
logP =
- log sigma
- 0.5 * log (2.0 * pi)
- 0.5 * z * z
in Right logP
normalPDF
:: Double
-> Double
-> Double
-> Either ProbabilityError Double
normalPDF x mu sigma
| sigma <= 0 =
Left (InvalidStandardDeviation sigma)
| otherwise = do
logP <- normalLogPDF x mu sigma
pure (exp logP)
normalCDF
:: Double
-> Double
-> Double
-> Either ProbabilityError Double
normalCDF x mu sigma
| sigma <= 0 =
Left (InvalidStandardDeviation sigma)
| otherwise =
let z = (x - mu) / (sigma * sqrt 2.0)
in Right
(0.5 * (1.0 + erf z))
normalMean
:: Double
-> Double
-> Either ProbabilityError Double
normalMean mu sigma
| sigma <= 0 =
Left (InvalidStandardDeviation sigma)
| otherwise =
Right mu
normalVar
:: Double
-> Double
-> Either ProbabilityError Double
normalVar mu sigma
| sigma <= 0 =
Left (InvalidStandardDeviation sigma)
| otherwise =
Right (sigma * sigma)
exponentialLogPDF
:: Double
-> Double
-> Either ProbabilityError Double
exponentialLogPDF x lambda
| lambda <= 0 =
Left (InvalidRate lambda)
| x < 0 =
Right (-1.0 / 0.0)
| otherwise =
Right (log lambda - lambda * x)
exponentialPDF
:: Double
-> Double
-> Either ProbabilityError Double
exponentialPDF x lambda
| lambda <= 0 =
Left (InvalidRate lambda)
| x < 0 =
Right 0.0
| otherwise = do
logP <- exponentialLogPDF x lambda
pure (exp logP)
exponentialCDF
:: Double
-> Double
-> Either ProbabilityError Double
exponentialCDF x lambda
| lambda <= 0 =
Left (InvalidRate lambda)
| x < 0 =
Right 0.0
| otherwise =
Right (- expm1 (-lambda * x))
exponentialMean
:: Double
-> Either ProbabilityError Double
exponentialMean lambda
| lambda <= 0 =
Left (InvalidRate lambda)
| otherwise =
Right (1.0 / lambda)
exponentialVar
:: Double
-> Either ProbabilityError Double
exponentialVar lambda
| lambda <= 0 =
Left (InvalidRate lambda)
| otherwise =
Right (1.0 / (lambda * lambda))
gammaLogPDF
:: Double
-> Double
-> Double
-> Either ProbabilityError Double
gammaLogPDF x alpha lambda
| alpha <= 0 =
Left (InvalidShape alpha)
| lambda <= 0 =
Left (InvalidRate lambda)
| x < 0 =
Right (-1.0 / 0.0)
| x == 0 && alpha < 1 =
Right (1.0 / 0.0)
| x == 0 && alpha == 1 =
Right (log lambda)
| x == 0 =
Right (-1.0 / 0.0)
| otherwise = do
logG <- logGamma alpha
let logP =
alpha * log lambda
- logG
+ (alpha - 1.0) * log x
- lambda * x
pure logP
gammaPDF
:: Double
-> Double
-> Double
-> Either ProbabilityError Double
gammaPDF x alpha lambda
| alpha <= 0 =
Left (InvalidShape alpha)
| lambda <= 0 =
Left (InvalidRate lambda)
| x < 0 =
Right 0.0
| x == 0 && alpha < 1 =
Right (1.0 / 0.0)
| x == 0 && alpha == 1 =
Right lambda
| x == 0 =
Right 0.0
| otherwise = do
logP <- gammaLogPDF x alpha lambda
pure (exp logP)
gammaMean
:: Double
-> Double
-> Either ProbabilityError Double
gammaMean alpha lambda
| alpha <= 0 =
Left (InvalidShape alpha)
| lambda <= 0 =
Left (InvalidRate lambda)
| otherwise =
Right (alpha / lambda)
gammaVar
:: Double
-> Double
-> Either ProbabilityError Double
gammaVar alpha lambda
| alpha <= 0 =
Left (InvalidShape alpha)
| lambda <= 0 =
Left (InvalidRate lambda)
| otherwise =
Right (alpha / (lambda * lambda))
uniformLogPDF
:: Double
-> Double
-> Double
-> Either ProbabilityError Double
uniformLogPDF x a b
| b <= a =
Left (InvalidBounds a b)
| x < a || x > b =
Right (-1.0 / 0.0)
| otherwise =
Right (- log (b - a))
uniformPDF
:: Double
-> Double
-> Double
-> Either ProbabilityError Double
uniformPDF x a b
| b <= a =
Left (InvalidBounds a b)
| x < a || x > b =
Right 0.0
| otherwise =
Right (1.0 / (b - a))
uniformCDF
:: Double
-> Double
-> Double
-> Either ProbabilityError Double
uniformCDF x a b
| b <= a =
Left (InvalidBounds a b)
| x < a =
Right 0.0
| x > b =
Right 1.0
| otherwise =
Right ((x - a) / (b - a))
uniformMean
:: Double
-> Double
-> Either ProbabilityError Double
uniformMean a b
| b <= a =
Left (InvalidBounds a b)
| otherwise =
Right ((a + b) / 2.0)
uniformVar
:: Double
-> Double
-> Either ProbabilityError Double
uniformVar a b
| b <= a =
Left (InvalidBounds a b)
| otherwise =
let width = b - a
in Right (width * width / 12.0)