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

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

    module Data.Random.Distribution.StretchedExponential where

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

    newtype StretchedExponential a = StretchedExp (a,a)

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

    floatingStretchedExponentialCDF :: Real a => a -> a -> a -> Double
    floatingStretchedExponentialCDF :: forall a. Real a => a -> a -> a -> Double
    floatingStretchedExponentialCDF a
    beta 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)Double -> Double -> Double
    forall a. Floating a => a -> a -> a
    **(a -> Double
    forall a b. (Real a, Fractional b) => a -> b
    realToFrac a
    beta))

    stretchedExponential :: Distribution StretchedExponential a => a -> a -> RVar a
    stretchedExponential :: forall a. Distribution StretchedExponential a => a -> a -> RVar a
    stretchedExponential a
    beta a
    lambdaRecip = StretchedExponential a -> RVar a
    forall (d :: * -> *) t. Distribution d t => d t -> RVar t
    rvar (StretchedExponential a -> RVar a)
    -> StretchedExponential a -> RVar a
    forall a b. (a -> b) -> a -> b
    $ (a, a) -> StretchedExponential a
    forall a. (a, a) -> StretchedExponential a
    StretchedExp (a
    beta, a
    lambdaRecip)

    stretchedExponentialT :: Distribution StretchedExponential a => a -> a -> RVarT m a
    stretchedExponentialT :: forall a (m :: * -> *).
    Distribution StretchedExponential a =>
    a -> a -> RVarT m a
    stretchedExponentialT a
    beta a
    lambdaRecip = StretchedExponential a -> RVarT m a
    forall (n :: * -> *). StretchedExponential a -> RVarT n a
    forall (d :: * -> *) t (n :: * -> *).
    Distribution d t =>
    d t -> RVarT n t
    rvarT (StretchedExponential a -> RVarT m a)
    -> StretchedExponential a -> RVarT m a
    forall a b. (a -> b) -> a -> b
    $ (a, a) -> StretchedExponential a
    forall a. (a, a) -> StretchedExponential a
    StretchedExp (a
    beta, a
    lambdaRecip)

    instance (Floating a, Distribution StdUniform a) => Distribution StretchedExponential a where
        rvarT :: forall (n :: * -> *). StretchedExponential a -> RVarT n a
    rvarT (StretchedExp (a
    beta,a
    lambdaRecip)) = a -> a -> RVarT n a
    forall a (m :: * -> *).
    (Floating a, Distribution StdUniform a) =>
    a -> a -> RVarT m a
    floatingStretchedExponential a
    beta a
    lambdaRecip
    instance (Real a, Distribution StretchedExponential a) => CDF StretchedExponential a where
        cdf :: StretchedExponential a -> a -> Double
    cdf  (StretchedExp (a
    beta,a
    lambdaRecip)) = a -> a -> a -> Double
    forall a. Real a => a -> a -> a -> Double
    floatingStretchedExponentialCDF a
    beta a
    lambdaRecip