    {-# LANGUAGE
        MultiParamTypeClasses,
        FlexibleInstances, FlexibleContexts,
        UndecidableInstances
      #-}

    {-# OPTIONS_GHC -fno-warn-simplifiable-class-constraints #-}

    module Data.Random.Distribution.Exponential where

    import Data.Random.RVar
    import Data.Random.Distribution
    import Data.Random.Distribution.Uniform

    {-|
    A definition of the exponential distribution over the type @a@.

    @'Exp' mu@ models an exponential distribution with mean @mu@. This can
    alternatively be viewed as an exponential distribution with parameter @lambda =
    1 / mu@.

    See also 'exponential'.
    -}
    newtype Exponential a = Exp a

    floatingExponential :: (Floating a, Distribution StdUniform a) => a -> RVarT m a
    floatingExponential :: forall a (m :: * -> *).
    (Floating a, Distribution StdUniform a) =>
    a -> RVarT m a
    floatingExponential a
    lambdaRecip = do
        x <- RVarT m a
    forall a (m :: * -> *). Distribution StdUniform a => RVarT m a
    stdUniformT
        return (negate (log x) * lambdaRecip)

    floatingExponentialCDF :: Real a => a -> a -> Double
    floatingExponentialCDF :: forall a. Real a => a -> a -> Double
    floatingExponentialCDF a
    lambdaRecip a
    x = Double
    1 Double -> Double -> Double
    forall a. Num a => a -> a -> a
    - Double -> Double
    forall a. Floating a => a -> a
    exp (Double -> Double
    forall a. Num a => a -> a
    negate (a -> Double
    forall a b. (Real a, Fractional b) => a -> b
    realToFrac a
    x) Double -> Double -> Double
    forall a. Fractional a => a -> a -> a
    / a -> Double
    forall a b. (Real a, Fractional b) => a -> b
    realToFrac a
    lambdaRecip)

    {-|
    A random variable which samples from the exponential distribution.

    @'exponential' mu@ is an exponential random variable with mean @mu@. This can
    alternatively be viewed as an exponential random variable with parameter @lambda
    = 1 / mu@.
    -}
    exponential :: Distribution Exponential a => a -> RVar a
    exponential :: forall a. Distribution Exponential a => a -> RVar a
    exponential = Exponential a -> RVar a
    forall (d :: * -> *) t. Distribution d t => d t -> RVar t
    rvar (Exponential a -> RVar a) -> (a -> Exponential a) -> a -> RVar a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . a -> Exponential a
    forall a. a -> Exponential a
    Exp

    {-|
    A random variable transformer which samples from the exponential distribution.

    @'exponentialT' mu@ is an exponential random variable with mean @mu@. This can
    alternatively be viewed as an exponential random variable with parameter @lambda
    = 1 / mu@.
    -}
    exponentialT :: Distribution Exponential a => a -> RVarT m a
    exponentialT :: forall a (m :: * -> *).
    Distribution Exponential a =>
    a -> RVarT m a
    exponentialT = Exponential a -> RVarT m a
    forall (n :: * -> *). Exponential a -> RVarT n a
    forall (d :: * -> *) t (n :: * -> *).
    Distribution d t =>
    d t -> RVarT n t
    rvarT (Exponential a -> RVarT m a)
    -> (a -> Exponential a) -> a -> RVarT m a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . a -> Exponential a
    forall a. a -> Exponential a
    Exp

    instance (Floating a, Distribution StdUniform a) => Distribution Exponential a where
        rvarT :: forall (n :: * -> *). Exponential a -> RVarT n a
    rvarT (Exp a
    lambdaRecip) = a -> RVarT n a
    forall a (m :: * -> *).
    (Floating a, Distribution StdUniform a) =>
    a -> RVarT m a
    floatingExponential a
    lambdaRecip
    instance (Real a, Distribution Exponential a) => CDF Exponential a where
        cdf :: Exponential a -> a -> Double
    cdf  (Exp a
    lambdaRecip) = a -> a -> Double
    forall a. Real a => a -> a -> Double
    floatingExponentialCDF a
    lambdaRecip