{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}
module ELynx.Distribution.TimeOfOrigin
( TimeOfOriginDistribution (..),
cumulative,
density,
quantile,
)
where
import Data.Data
( Data,
Typeable,
)
import ELynx.Distribution.Types
import GHC.Generics (Generic)
import qualified Statistics.Distribution as D
data TimeOfOriginDistribution = TOD
{
todTN :: Int,
todLa :: Rate,
todMu :: Rate
}
deriving (Eq, Typeable, Data, Generic)
instance D.Distribution TimeOfOriginDistribution where
cumulative = cumulative
cumulative :: TimeOfOriginDistribution -> Time -> Double
cumulative (TOD n l m) x
| x <= 0 = 0
| otherwise = te ** fromIntegral n
where
d = l - m
te = l * (1.0 - exp (- d * x)) / (l - m * exp (- d * x))
instance D.ContDistr TimeOfOriginDistribution where
density = density
quantile = quantile
density :: TimeOfOriginDistribution -> Time -> Double
density (TOD nn l m) x
| x < 0 = 0
| otherwise = n * l ** n * d ** 2 * t1 ** (n - 1.0) * ex / (t2 ** (n + 1.0))
where
d = l - m
n = fromIntegral nn
ex = exp (- d * x)
t1 = 1.0 - ex
t2 = l - m * ex
quantile :: TimeOfOriginDistribution -> Double -> Time
quantile (TOD n' l m) p
| p >= 0 && p <= 1 =
-1.0 / d * log (t1 / t2)
| otherwise =
error $
"PointProcess.quantile: p must be in [0,1] range. Got: "
++ show p
++ "."
where
d = l - m
n = fromIntegral n'
t1 = l * (1.0 - p ** (1.0 / n))
t2 = l - p ** (1.0 / n) * m
instance D.ContGen TimeOfOriginDistribution where
genContVar = D.genContinuous