{-# 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 :: a -> a -> RVarT m a
floatingStretchedExponential a
beta a
lambdaRecip = do
    a
x <- RVarT m a
forall a (m :: * -> *). Distribution StdUniform a => RVarT m a
stdUniformT
    a -> RVarT m a
forall (m :: * -> *) a. Monad m => a -> m a
return (a -> a
forall a. Num a => a -> a
negate (a -> a
forall a. Floating a => a -> a
log (a
1a -> a -> a
forall a. Num a => a -> a -> a
-a
x))a -> a -> a
forall a. Floating a => a -> a -> a
**(a
1a -> a -> a
forall a. Fractional a => a -> a -> a
/a
beta) a -> a -> a
forall a. Num a => a -> a -> a
* a
lambdaRecip)

floatingStretchedExponentialCDF :: Real a => a -> a -> a -> Double
floatingStretchedExponentialCDF :: 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 :: 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 :: a -> a -> RVarT m a
stretchedExponentialT a
beta a
lambdaRecip = StretchedExponential a -> RVarT m 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 :: 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