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

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

    module Data.Random.Distribution.Rayleigh where

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

    floatingRayleigh :: (Floating a, Eq a, Distribution StdUniform a) => a -> RVarT m a
    floatingRayleigh :: forall a (m :: * -> *).
    (Floating a, Eq a, Distribution StdUniform a) =>
    a -> RVarT m a
    floatingRayleigh a
    s = do
        u <- RVarT m a
    forall a (m :: * -> *).
    (Distribution StdUniform a, Num a, Eq a) =>
    RVarT m a
    stdUniformPosT
        return (s * sqrt (-2 * log u))

    -- |The rayleigh distribution with a specified mode (\"sigma\") parameter.
    -- Its mean will be @sigma*sqrt(pi/2)@ and its variance will be @sigma^2*(4-pi)/2@
    --
    -- (therefore if you want one with a particular mean @m@, @sigma@ should be @m*sqrt(2/pi)@)
    newtype Rayleigh a = Rayleigh a

    rayleigh :: Distribution Rayleigh a => a -> RVar a
    rayleigh :: forall a. Distribution Rayleigh a => a -> RVar a
    rayleigh = Rayleigh a -> RVar a
    forall (d :: * -> *) t. Distribution d t => d t -> RVar t
    rvar (Rayleigh a -> RVar a) -> (a -> Rayleigh a) -> a -> RVar a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . a -> Rayleigh a
    forall a. a -> Rayleigh a
    Rayleigh

    rayleighT :: Distribution Rayleigh a => a -> RVarT m a
    rayleighT :: forall a (m :: * -> *). Distribution Rayleigh a => a -> RVarT m a
    rayleighT = Rayleigh a -> RVarT m a
    forall (n :: * -> *). Rayleigh a -> RVarT n a
    forall (d :: * -> *) t (n :: * -> *).
    Distribution d t =>
    d t -> RVarT n t
    rvarT (Rayleigh a -> RVarT m a) -> (a -> Rayleigh a) -> a -> RVarT m a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . a -> Rayleigh a
    forall a. a -> Rayleigh a
    Rayleigh

    rayleighCDF :: Real a => a -> a -> Double
    rayleighCDF :: forall a. Real a => a -> a -> Double
    rayleighCDF a
    s a
    x = Double
    1 Double -> Double -> Double
    forall a. Num a => a -> a -> a
    - Double -> Double
    forall a. Floating a => a -> a
    exp ((-Double
    0.5)Double -> Double -> Double
    forall a. Num a => a -> a -> a
    * a -> Double
    forall a b. (Real a, Fractional b) => a -> b
    realToFrac (a
    xa -> a -> a
    forall a. Num a => a -> a -> a
    *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
    sa -> a -> a
    forall a. Num a => a -> a -> a
    *a
    s))

    instance (RealFloat a, Distribution StdUniform a) => Distribution Rayleigh a where
        rvarT :: forall (n :: * -> *). Rayleigh a -> RVarT n a
    rvarT (Rayleigh a
    s) = a -> RVarT n a
    forall a (m :: * -> *).
    (Floating a, Eq a, Distribution StdUniform a) =>
    a -> RVarT m a
    floatingRayleigh a
    s

    instance (Real a, Distribution Rayleigh a) => CDF Rayleigh a where
        cdf :: Rayleigh a -> a -> Double
    cdf  (Rayleigh a
    s) a
    x = a -> a -> Double
    forall a. Real a => a -> a -> Double
    rayleighCDF a
    s a
    x