{-# LANGUAGE
    MultiParamTypeClasses, FunctionalDependencies,
    FlexibleContexts, FlexibleInstances,
    UndecidableInstances, EmptyDataDecls,
    TemplateHaskell,
    BangPatterns
  #-}

module Data.Random.Distribution.Uniform
    ( Uniform(..)
    , uniform
    , uniformT

    , StdUniform(..)
    , stdUniform
    , stdUniformT
    , stdUniformPos
    , stdUniformPosT

    , integralUniform
    , realFloatUniform
    , floatUniform
    , doubleUniform
    , fixedUniform
    , enumUniform

    , boundedStdUniform
    , boundedEnumStdUniform
    , realFloatStdUniform
    , fixedStdUniform
    , floatStdUniform
    , doubleStdUniform

    , boundedStdUniformCDF
    , realStdUniformCDF
    , realUniformCDF
    , enumUniformCDF
    ) where

import Data.Random.Internal.TH
import Data.Random.Internal.Words
import Data.Random.Internal.Fixed

import Data.Random.Source
import Data.Random.Distribution
import Data.Random.RVar

import Data.Fixed
import Data.Word
import Data.Int

import Control.Monad.Loops

-- |Compute a random 'Integral' value between the 2 values provided (inclusive).
{-# INLINE integralUniform #-}
integralUniform :: (Integral a) => a -> a -> RVarT m a
integralUniform :: a -> a -> RVarT m a
integralUniform !a
x !a
y = if a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< a
y then a -> a -> RVarT m a
forall a (m :: * -> *). Integral a => a -> a -> RVarT m a
integralUniform' a
x a
y else a -> a -> RVarT m a
forall a (m :: * -> *). Integral a => a -> a -> RVarT m a
integralUniform' a
y a
x

{-# SPECIALIZE integralUniform' :: Int     -> Int     -> RVarT m Int   #-}
{-# SPECIALIZE integralUniform' :: Int8    -> Int8    -> RVarT m Int8  #-}
{-# SPECIALIZE integralUniform' :: Int16   -> Int16   -> RVarT m Int16 #-}
{-# SPECIALIZE integralUniform' :: Int32   -> Int32   -> RVarT m Int32 #-}
{-# SPECIALIZE integralUniform' :: Int64   -> Int64   -> RVarT m Int64 #-}
{-# SPECIALIZE integralUniform' :: Word    -> Word    -> RVarT m Word   #-}
{-# SPECIALIZE integralUniform' :: Word8   -> Word8   -> RVarT m Word8  #-}
{-# SPECIALIZE integralUniform' :: Word16  -> Word16  -> RVarT m Word16 #-}
{-# SPECIALIZE integralUniform' :: Word32  -> Word32  -> RVarT m Word32 #-}
{-# SPECIALIZE integralUniform' :: Word64  -> Word64  -> RVarT m Word64 #-}
{-# SPECIALIZE integralUniform' :: Integer -> Integer -> RVarT m Integer #-}
integralUniform' :: (Integral a) => a -> a -> RVarT m a
integralUniform' :: a -> a -> RVarT m a
integralUniform' !a
l !a
u
    | Integer
nReject Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== 0  = (Integer -> a) -> RVarT m Integer -> RVarT m a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Integer -> a
shift RVarT m Integer
prim
    | Bool
otherwise     = (Integer -> a) -> RVarT m Integer -> RVarT m a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Integer -> a
shift RVarT m Integer
loop
    where
        m :: Integer
m = 1 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ a -> Integer
forall a. Integral a => a -> Integer
toInteger a
u Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- a -> Integer
forall a. Integral a => a -> Integer
toInteger a
l
        (bytes :: Int
bytes, nPossible :: Integer
nPossible) = Integer -> (Int, Integer)
bytesNeeded Integer
m
        nReject :: Integer
nReject = Integer
nPossible Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
`mod` Integer
m

        !prim :: RVarT m Integer
prim = Int -> RVarT m Integer
forall (m :: * -> *).
(MonadRandom m, MonadRandom m) =>
Int -> m Integer
getRandomNByteInteger Int
bytes
        !shift :: Integer -> a
shift = \(!Integer
z) -> a
l a -> a -> a
forall a. Num a => a -> a -> a
+ (Integer -> a
forall a. Num a => Integer -> a
fromInteger (Integer -> a) -> Integer -> a
forall a b. (a -> b) -> a -> b
$! (Integer
z Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
`mod` Integer
m))

        loop :: RVarT m Integer
loop = do
            Integer
z <- RVarT m Integer
prim
            if Integer
z Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
< Integer
nReject
                then RVarT m Integer
loop
                else Integer -> RVarT m Integer
forall (m :: * -> *) a. Monad m => a -> m a
return Integer
z

integralUniformCDF :: (Integral a, Fractional b) => a -> a -> a -> b
integralUniformCDF :: a -> a -> a -> b
integralUniformCDF a :: a
a b :: a
b x :: a
x
    | a
b a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< a
a     = a -> a -> a -> b
forall a b. (Integral a, Fractional b) => a -> a -> a -> b
integralUniformCDF a
b a
a a
x
    | a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< a
a     = 0
    | a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
> a
b     = 1
    | Bool
otherwise = (a -> b
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
x b -> b -> b
forall a. Num a => a -> a -> a
- a -> b
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
a) b -> b -> b
forall a. Fractional a => a -> a -> a
/ (a -> b
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
b b -> b -> b
forall a. Num a => a -> a -> a
- a -> b
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
a)

-- TODO: come up with a decent, fast heuristic to decide whether to return an extra
-- byte.  May involve moving calculation of nReject into this function, and then
-- accepting first if 4*nReject < nPossible or something similar.
bytesNeeded :: Integer -> (Int, Integer)
bytesNeeded :: Integer -> (Int, Integer)
bytesNeeded x :: Integer
x = [(Int, Integer)] -> (Int, Integer)
forall a. [a] -> a
head (((Int, Integer) -> Bool) -> [(Int, Integer)] -> [(Int, Integer)]
forall a. (a -> Bool) -> [a] -> [a]
dropWhile ((Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
<= Integer
x)(Integer -> Bool)
-> ((Int, Integer) -> Integer) -> (Int, Integer) -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
.(Int, Integer) -> Integer
forall a b. (a, b) -> b
snd) [(Int, Integer)]
powersOf256)

powersOf256 :: [(Int, Integer)]
powersOf256 :: [(Int, Integer)]
powersOf256 = [Int] -> [Integer] -> [(Int, Integer)]
forall a b. [a] -> [b] -> [(a, b)]
zip [0..] ((Integer -> Integer) -> Integer -> [Integer]
forall a. (a -> a) -> a -> [a]
iterate (256 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
*) 1)

-- |Compute a random value for a 'Bounded' type, between 'minBound' and 'maxBound'
-- (inclusive for 'Integral' or 'Enum' types, in ['minBound', 'maxBound') for Fractional types.)
boundedStdUniform :: (Distribution Uniform a, Bounded a) => RVar a
boundedStdUniform :: RVar a
boundedStdUniform = a -> a -> RVar a
forall a. Distribution Uniform a => a -> a -> RVar a
uniform a
forall a. Bounded a => a
minBound a
forall a. Bounded a => a
maxBound

boundedStdUniformCDF :: (CDF Uniform a, Bounded a) => a -> Double
boundedStdUniformCDF :: a -> Double
boundedStdUniformCDF = Uniform a -> a -> Double
forall (d :: * -> *) t. CDF d t => d t -> t -> Double
cdf (a -> a -> Uniform a
forall t. t -> t -> Uniform t
Uniform a
forall a. Bounded a => a
minBound a
forall a. Bounded a => a
maxBound)

-- |Compute a random value for a 'Bounded' 'Enum' type, between 'minBound' and
-- 'maxBound' (inclusive)
boundedEnumStdUniform :: (Enum a, Bounded a) => RVarT m a
boundedEnumStdUniform :: RVarT m a
boundedEnumStdUniform = a -> a -> RVarT m a
forall a (m :: * -> *). Enum a => a -> a -> RVarT m a
enumUniform a
forall a. Bounded a => a
minBound a
forall a. Bounded a => a
maxBound

boundedEnumStdUniformCDF :: (Enum a, Bounded a, Ord a) => a -> Double
boundedEnumStdUniformCDF :: a -> Double
boundedEnumStdUniformCDF = a -> a -> a -> Double
forall a. (Enum a, Ord a) => a -> a -> a -> Double
enumUniformCDF a
forall a. Bounded a => a
minBound a
forall a. Bounded a => a
maxBound

-- |Compute a uniform random 'Float' value in the range [0,1)
floatStdUniform :: RVarT m Float
floatStdUniform :: RVarT m Float
floatStdUniform = do
    Word32
x <- RVarT m Word32
forall (m :: * -> *). MonadRandom m => m Word32
getRandomWord32
    Float -> RVarT m Float
forall (m :: * -> *) a. Monad m => a -> m a
return (Word32 -> Float
word32ToFloat Word32
x)

-- |Compute a uniform random 'Double' value in the range [0,1)
{-# INLINE doubleStdUniform #-}
doubleStdUniform :: RVarT m Double
doubleStdUniform :: RVarT m Double
doubleStdUniform = RVarT m Double
forall (m :: * -> *). MonadRandom m => m Double
getRandomDouble

-- |Compute a uniform random value in the range [0,1) for any 'RealFloat' type
realFloatStdUniform :: RealFloat a => RVarT m a
realFloatStdUniform :: RVarT m a
realFloatStdUniform = do
    let (b :: Integer
b, e :: Int
e) = a -> (Integer, Int)
forall a. RealFloat a => a -> (Integer, Int)
decodeFloat a
one

    Integer
x <- Integer -> Integer -> RVarT m Integer
forall a (m :: * -> *).
Distribution Uniform a =>
a -> a -> RVarT m a
uniformT 0 (Integer
bInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
-1)
    if Integer
x Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== 0
        then a -> RVarT m a
forall (m :: * -> *) a. Monad m => a -> m a
return (0 a -> a -> a
forall a. a -> a -> a
`asTypeOf` a
one)
        else a -> RVarT m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Integer -> Int -> a
forall a. RealFloat a => Integer -> Int -> a
encodeFloat Integer
x Int
e)

    where one :: a
one = 1

-- |Compute a uniform random 'Fixed' value in the range [0,1), with any
-- desired precision.
fixedStdUniform :: HasResolution r => RVarT m (Fixed r)
fixedStdUniform :: RVarT m (Fixed r)
fixedStdUniform = RVarT m (Fixed r)
forall (m :: * -> *). RVarT m (Fixed r)
x
    where
        res :: Integer
res = RVarT m (Fixed r) -> Integer
forall r (f :: * -> *) (g :: * -> *).
HasResolution r =>
f (g r) -> Integer
resolutionOf2 RVarT m (Fixed r)
x
        x :: RVarT m (Fixed r)
x = do
            Integer
u <- Integer -> Integer -> RVarT m Integer
forall a (m :: * -> *).
Distribution Uniform a =>
a -> a -> RVarT m a
uniformT 0 (Integer
res)
            Fixed r -> RVarT m (Fixed r)
forall (m :: * -> *) a. Monad m => a -> m a
return (Integer -> Fixed r
forall r. Integer -> Fixed r
mkFixed Integer
u)

-- |The CDF of the random variable 'realFloatStdUniform'.
realStdUniformCDF :: Real a => a -> Double
realStdUniformCDF :: a -> Double
realStdUniformCDF x :: a
x
    | a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= 0    = 0
    | a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
>= 1    = 1
    | Bool
otherwise = a -> Double
forall a b. (Real a, Fractional b) => a -> b
realToFrac a
x

-- |The PDF of the random variable 'realFloatStdUniform'.
realStdUniformPDF :: Real a => a -> Double
realStdUniformPDF :: a -> Double
realStdUniformPDF x :: a
x
    | a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= 0    = 0
    | a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
>= 1    = 0
    | Bool
otherwise = 1

-- |(internal) basic linear interpolation; @lerp x y@ is a linear function whose
-- value is @x@ at 0 and @y@ at 1
lerp :: Num a => a -> a -> a -> a
lerp :: a -> a -> a -> a
lerp x :: a
x y :: a
y a :: a
a = (1a -> a -> a
forall a. Num a => a -> a -> a
-a
a)a -> a -> a
forall a. Num a => a -> a -> a
*a
x a -> a -> a
forall a. Num a => a -> a -> a
+ a
aa -> a -> a
forall a. Num a => a -> a -> a
*a
y

-- |@floatUniform a b@ computes a uniform random 'Float' value in the range [a,b)
floatUniform :: Float -> Float -> RVarT m Float
floatUniform :: Float -> Float -> RVarT m Float
floatUniform 0 1 = RVarT m Float
forall (m :: * -> *). RVarT m Float
floatStdUniform
floatUniform a :: Float
a b :: Float
b = do
    Float
x <- RVarT m Float
forall (m :: * -> *). RVarT m Float
floatStdUniform
    Float -> RVarT m Float
forall (m :: * -> *) a. Monad m => a -> m a
return (Float -> Float -> Float -> Float
forall a. Num a => a -> a -> a -> a
lerp Float
a Float
b Float
x)

-- |@doubleUniform a b@ computes a uniform random 'Double' value in the range [a,b)
{-# INLINE doubleUniform #-}
doubleUniform :: Double -> Double -> RVarT m Double
doubleUniform :: Double -> Double -> RVarT m Double
doubleUniform 0 1 = RVarT m Double
forall (m :: * -> *). RVarT m Double
doubleStdUniform
doubleUniform a :: Double
a b :: Double
b = do
    Double
x <- RVarT m Double
forall (m :: * -> *). RVarT m Double
doubleStdUniform
    Double -> RVarT m Double
forall (m :: * -> *) a. Monad m => a -> m a
return (Double -> Double -> Double -> Double
forall a. Num a => a -> a -> a -> a
lerp Double
a Double
b Double
x)

-- |@realFloatUniform a b@ computes a uniform random value in the range [a,b) for
-- any 'RealFloat' type
realFloatUniform :: RealFloat a => a -> a -> RVarT m a
realFloatUniform :: a -> a -> RVarT m a
realFloatUniform 0 1 = RVarT m a
forall a (m :: * -> *). RealFloat a => RVarT m a
realFloatStdUniform
realFloatUniform a :: a
a b :: a
b = do
    a
x <- RVarT m a
forall a (m :: * -> *). RealFloat a => RVarT m a
realFloatStdUniform
    a -> RVarT m a
forall (m :: * -> *) a. Monad m => a -> m a
return (a -> a -> a -> a
forall a. Num a => a -> a -> a -> a
lerp a
a a
b a
x)

-- |@fixedUniform a b@ computes a uniform random 'Fixed' value in the range
-- [a,b), with any desired precision.
fixedUniform :: HasResolution r => Fixed r -> Fixed r -> RVarT m (Fixed r)
fixedUniform :: Fixed r -> Fixed r -> RVarT m (Fixed r)
fixedUniform a :: Fixed r
a b :: Fixed r
b = do
    Integer
u <- Integer -> Integer -> RVarT m Integer
forall a (m :: * -> *). Integral a => a -> a -> RVarT m a
integralUniform (Fixed r -> Integer
forall r. Fixed r -> Integer
unMkFixed Fixed r
a) (Fixed r -> Integer
forall r. Fixed r -> Integer
unMkFixed Fixed r
b)
    Fixed r -> RVarT m (Fixed r)
forall (m :: * -> *) a. Monad m => a -> m a
return (Integer -> Fixed r
forall r. Integer -> Fixed r
mkFixed Integer
u)

-- |@realUniformCDF a b@ is the CDF of the random variable @realFloatUniform a b@.
realUniformCDF :: RealFrac a => a -> a -> a -> Double
realUniformCDF :: a -> a -> a -> Double
realUniformCDF a :: a
a b :: a
b x :: a
x
    | a
b a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< a
a     = a -> a -> a -> Double
forall a. RealFrac a => a -> a -> a -> Double
realUniformCDF a
b a
a a
x
    | a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= a
a    = 0
    | a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
>= a
b    = 1
    | Bool
otherwise = a -> Double
forall a b. (Real a, Fractional b) => a -> b
realToFrac ((a
xa -> a -> a
forall a. Num a => a -> a -> a
-a
a) a -> a -> a
forall a. Fractional a => a -> a -> a
/ (a
ba -> a -> a
forall a. Num a => a -> a -> a
-a
a))

-- |@realFloatUniform a b@ computes a uniform random value in the range [a,b) for
-- any 'Enum' type
enumUniform :: Enum a => a -> a -> RVarT m a
enumUniform :: a -> a -> RVarT m a
enumUniform a :: a
a b :: a
b = do
    Int
x <- Int -> Int -> RVarT m Int
forall a (m :: * -> *). Integral a => a -> a -> RVarT m a
integralUniform (a -> Int
forall a. Enum a => a -> Int
fromEnum a
a) (a -> Int
forall a. Enum a => a -> Int
fromEnum a
b)
    a -> RVarT m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Int -> a
forall a. Enum a => Int -> a
toEnum Int
x)

enumUniformCDF :: (Enum a, Ord a) => a -> a -> a -> Double
enumUniformCDF :: a -> a -> a -> Double
enumUniformCDF a :: a
a b :: a
b x :: a
x
    | a
b a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< a
a     = a -> a -> a -> Double
forall a. (Enum a, Ord a) => a -> a -> a -> Double
enumUniformCDF a
b a
a a
x
    | a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= a
a    = 0
    | a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
>= a
b    = 1
    | Bool
otherwise = (a -> Double
e2f a
x Double -> Double -> Double
forall a. Num a => a -> a -> a
- a -> Double
e2f a
a) Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ (a -> Double
e2f a
b Double -> Double -> Double
forall a. Num a => a -> a -> a
- a -> Double
e2f a
a)

    where e2f :: a -> Double
e2f = Int -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Double) -> (a -> Int) -> a -> Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Int
forall a. Enum a => a -> Int
fromEnum

-- @uniform a b@ is a uniformly distributed random variable in the range
-- [a,b] for 'Integral' or 'Enum' types and in the range [a,b) for 'Fractional'
-- types.  Requires a @Distribution Uniform@ instance for the type.
uniform :: Distribution Uniform a => a -> a -> RVar a
uniform :: a -> a -> RVar a
uniform a :: a
a b :: a
b = Uniform a -> RVar a
forall (d :: * -> *) t. Distribution d t => d t -> RVar t
rvar (a -> a -> Uniform a
forall t. t -> t -> Uniform t
Uniform a
a a
b)

-- @uniformT a b@ is a uniformly distributed random process in the range
-- [a,b] for 'Integral' or 'Enum' types and in the range [a,b) for 'Fractional'
-- types.  Requires a @Distribution Uniform@ instance for the type.
uniformT :: Distribution Uniform a => a -> a -> RVarT m a
uniformT :: a -> a -> RVarT m a
uniformT a :: a
a b :: a
b = Uniform a -> RVarT m a
forall (d :: * -> *) t (n :: * -> *).
Distribution d t =>
d t -> RVarT n t
rvarT (a -> a -> Uniform a
forall t. t -> t -> Uniform t
Uniform a
a a
b)

-- |Get a \"standard\" uniformly distributed variable.
-- For integral types, this means uniformly distributed over the full range
-- of the type (there is no support for 'Integer').  For fractional
-- types, this means uniformly distributed on the interval [0,1).
{-# SPECIALIZE stdUniform :: RVar Double #-}
{-# SPECIALIZE stdUniform :: RVar Float #-}
stdUniform :: (Distribution StdUniform a) => RVar a
stdUniform :: RVar a
stdUniform = StdUniform a -> RVar a
forall (d :: * -> *) t. Distribution d t => d t -> RVar t
rvar StdUniform a
forall t. StdUniform t
StdUniform

-- |Get a \"standard\" uniformly distributed process.
-- For integral types, this means uniformly distributed over the full range
-- of the type (there is no support for 'Integer').  For fractional
-- types, this means uniformly distributed on the interval [0,1).
{-# SPECIALIZE stdUniformT :: RVarT m Double #-}
{-# SPECIALIZE stdUniformT :: RVarT m Float #-}
stdUniformT :: (Distribution StdUniform a) => RVarT m a
stdUniformT :: RVarT m a
stdUniformT = StdUniform a -> RVarT m a
forall (d :: * -> *) t (n :: * -> *).
Distribution d t =>
d t -> RVarT n t
rvarT StdUniform a
forall t. StdUniform t
StdUniform

-- |Like 'stdUniform', but returns only positive or zero values.  Not
-- exported because it is not truly uniform: nonzero values are twice
-- as likely as zero on signed types.
stdUniformNonneg :: (Distribution StdUniform a, Num a, Eq a) => RVarT m a
stdUniformNonneg :: RVarT m a
stdUniformNonneg = (a -> a) -> RVarT m a -> RVarT m a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> a
forall a. Num a => a -> a
abs RVarT m a
forall a (m :: * -> *). Distribution StdUniform a => RVarT m a
stdUniformT

-- |Like 'stdUniform' but only returns positive values.
stdUniformPos :: (Distribution StdUniform a, Num a, Eq a) => RVar a
stdUniformPos :: RVar a
stdUniformPos = RVar a
forall a (m :: * -> *).
(Distribution StdUniform a, Num a, Eq a) =>
RVarT m a
stdUniformPosT

-- |Like 'stdUniform' but only returns positive values.
stdUniformPosT :: (Distribution StdUniform a, Num a, Eq a) => RVarT m a
stdUniformPosT :: RVarT m a
stdUniformPosT = (a -> Bool) -> RVarT m a -> RVarT m a
forall (m :: * -> *) a. Monad m => (a -> Bool) -> m a -> m a
iterateUntil (a -> a -> Bool
forall a. Eq a => a -> a -> Bool
/= 0) RVarT m a
forall a (m :: * -> *).
(Distribution StdUniform a, Num a, Eq a) =>
RVarT m a
stdUniformNonneg

-- |A definition of a uniform distribution over the type @t@.  See also 'uniform'.
data Uniform t =
    -- |A uniform distribution defined by a lower and upper range bound.
    -- For 'Integral' and 'Enum' types, the range is inclusive.  For 'Fractional'
    -- types the range includes the lower bound but not the upper.
    Uniform !t !t

-- |A name for the \"standard\" uniform distribution over the type @t@,
-- if one exists.  See also 'stdUniform'.
--
-- For 'Integral' and 'Enum' types that are also 'Bounded', this is
-- the uniform distribution over the full range of the type.
-- For un-'Bounded' 'Integral' types this is not defined.
-- For 'Fractional' types this is a random variable in the range [0,1)
-- (that is, 0 to 1 including 0 but not including 1).
data StdUniform t = StdUniform

$( replicateInstances ''Int integralTypes [d|
        instance Distribution Uniform Int   where rvarT (Uniform a b) = integralUniform a b
        instance CDF Uniform Int            where cdf   (Uniform a b) = integralUniformCDF a b
    |])

instance Distribution StdUniform Word8      where rvarT :: StdUniform Word8 -> RVarT n Word8
rvarT _ = RVarT n Word8
forall (m :: * -> *). MonadRandom m => m Word8
getRandomWord8
instance Distribution StdUniform Word16     where rvarT :: StdUniform Word16 -> RVarT n Word16
rvarT _ = RVarT n Word16
forall (m :: * -> *). MonadRandom m => m Word16
getRandomWord16
instance Distribution StdUniform Word32     where rvarT :: StdUniform Word32 -> RVarT n Word32
rvarT _ = RVarT n Word32
forall (m :: * -> *). MonadRandom m => m Word32
getRandomWord32
instance Distribution StdUniform Word64     where rvarT :: StdUniform Word64 -> RVarT n Word64
rvarT _ = RVarT n Word64
forall (m :: * -> *). MonadRandom m => m Word64
getRandomWord64

instance Distribution StdUniform Int8       where rvarT :: StdUniform Int8 -> RVarT n Int8
rvarT _ = Word8 -> Int8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8 -> Int8) -> RVarT n Word8 -> RVarT n Int8
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` RVarT n Word8
forall (m :: * -> *). MonadRandom m => m Word8
getRandomWord8
instance Distribution StdUniform Int16      where rvarT :: StdUniform Int16 -> RVarT n Int16
rvarT _ = Word16 -> Int16
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word16 -> Int16) -> RVarT n Word16 -> RVarT n Int16
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` RVarT n Word16
forall (m :: * -> *). MonadRandom m => m Word16
getRandomWord16
instance Distribution StdUniform Int32      where rvarT :: StdUniform Int32 -> RVarT n Int32
rvarT _ = Word32 -> Int32
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word32 -> Int32) -> RVarT n Word32 -> RVarT n Int32
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` RVarT n Word32
forall (m :: * -> *). MonadRandom m => m Word32
getRandomWord32
instance Distribution StdUniform Int64      where rvarT :: StdUniform Int64 -> RVarT n Int64
rvarT _ = Word64 -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64 -> Int64) -> RVarT n Word64 -> RVarT n Int64
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` RVarT n Word64
forall (m :: * -> *). MonadRandom m => m Word64
getRandomWord64

instance Distribution StdUniform Int where
    rvar :: StdUniform Int -> RVar Int
rvar _ =
        $(if toInteger (maxBound :: Int) > toInteger (maxBound :: Int32)
            then [|fromIntegral `fmap` getRandomWord64 :: RVar Int|]
            else [|fromIntegral `fmap` getRandomWord32 :: RVar Int|])

instance Distribution StdUniform Word where
    rvar :: StdUniform Word -> RVar Word
rvar _ =
        $(if toInteger (maxBound :: Word) > toInteger (maxBound :: Word32)
            then [|fromIntegral `fmap` getRandomWord64 :: RVar Word|]
            else [|fromIntegral `fmap` getRandomWord32 :: RVar Word|])

-- Integer has no StdUniform...

instance CDF StdUniform Word8   where cdf :: StdUniform Word8 -> Word8 -> Double
cdf _ = Word8 -> Word8 -> Word8 -> Double
forall a b. (Integral a, Fractional b) => a -> a -> a -> b
integralUniformCDF Word8
forall a. Bounded a => a
minBound Word8
forall a. Bounded a => a
maxBound
instance CDF StdUniform Word16  where cdf :: StdUniform Word16 -> Word16 -> Double
cdf _ = Word16 -> Word16 -> Word16 -> Double
forall a b. (Integral a, Fractional b) => a -> a -> a -> b
integralUniformCDF Word16
forall a. Bounded a => a
minBound Word16
forall a. Bounded a => a
maxBound
instance CDF StdUniform Word32  where cdf :: StdUniform Word32 -> Word32 -> Double
cdf _ = Word32 -> Word32 -> Word32 -> Double
forall a b. (Integral a, Fractional b) => a -> a -> a -> b
integralUniformCDF Word32
forall a. Bounded a => a
minBound Word32
forall a. Bounded a => a
maxBound
instance CDF StdUniform Word64  where cdf :: StdUniform Word64 -> Word64 -> Double
cdf _ = Word64 -> Word64 -> Word64 -> Double
forall a b. (Integral a, Fractional b) => a -> a -> a -> b
integralUniformCDF Word64
forall a. Bounded a => a
minBound Word64
forall a. Bounded a => a
maxBound
instance CDF StdUniform Word    where cdf :: StdUniform Word -> Word -> Double
cdf _ = Word -> Word -> Word -> Double
forall a b. (Integral a, Fractional b) => a -> a -> a -> b
integralUniformCDF Word
forall a. Bounded a => a
minBound Word
forall a. Bounded a => a
maxBound
instance CDF StdUniform Int8    where cdf :: StdUniform Int8 -> Int8 -> Double
cdf _ = Int8 -> Int8 -> Int8 -> Double
forall a b. (Integral a, Fractional b) => a -> a -> a -> b
integralUniformCDF Int8
forall a. Bounded a => a
minBound Int8
forall a. Bounded a => a
maxBound
instance CDF StdUniform Int16   where cdf :: StdUniform Int16 -> Int16 -> Double
cdf _ = Int16 -> Int16 -> Int16 -> Double
forall a b. (Integral a, Fractional b) => a -> a -> a -> b
integralUniformCDF Int16
forall a. Bounded a => a
minBound Int16
forall a. Bounded a => a
maxBound
instance CDF StdUniform Int32   where cdf :: StdUniform Int32 -> Int32 -> Double
cdf _ = Int32 -> Int32 -> Int32 -> Double
forall a b. (Integral a, Fractional b) => a -> a -> a -> b
integralUniformCDF Int32
forall a. Bounded a => a
minBound Int32
forall a. Bounded a => a
maxBound
instance CDF StdUniform Int64   where cdf :: StdUniform Int64 -> Int64 -> Double
cdf _ = Int64 -> Int64 -> Int64 -> Double
forall a b. (Integral a, Fractional b) => a -> a -> a -> b
integralUniformCDF Int64
forall a. Bounded a => a
minBound Int64
forall a. Bounded a => a
maxBound
instance CDF StdUniform Int     where cdf :: StdUniform Int -> Int -> Double
cdf _ = Int -> Int -> Int -> Double
forall a b. (Integral a, Fractional b) => a -> a -> a -> b
integralUniformCDF Int
forall a. Bounded a => a
minBound Int
forall a. Bounded a => a
maxBound


instance Distribution Uniform Float         where rvarT :: Uniform Float -> RVarT n Float
rvarT (Uniform a :: Float
a b :: Float
b) = Float -> Float -> RVarT n Float
forall (m :: * -> *). Float -> Float -> RVarT m Float
floatUniform  Float
a Float
b
instance Distribution Uniform Double        where rvarT :: Uniform Double -> RVarT n Double
rvarT (Uniform a :: Double
a b :: Double
b) = Double -> Double -> RVarT n Double
forall (m :: * -> *). Double -> Double -> RVarT m Double
doubleUniform Double
a Double
b
instance CDF Uniform Float                  where cdf :: Uniform Float -> Float -> Double
cdf   (Uniform a :: Float
a b :: Float
b) = Float -> Float -> Float -> Double
forall a. RealFrac a => a -> a -> a -> Double
realUniformCDF Float
a Float
b
instance CDF Uniform Double                 where cdf :: Uniform Double -> Double -> Double
cdf   (Uniform a :: Double
a b :: Double
b) = Double -> Double -> Double -> Double
forall a. RealFrac a => a -> a -> a -> Double
realUniformCDF Double
a Double
b

instance Distribution StdUniform Float      where rvarT :: StdUniform Float -> RVarT n Float
rvarT _ = RVarT n Float
forall (m :: * -> *). RVarT m Float
floatStdUniform
instance Distribution StdUniform Double     where rvarT :: StdUniform Double -> RVarT n Double
rvarT _ = RVarT n Double
forall (m :: * -> *). MonadRandom m => m Double
getRandomDouble
instance CDF StdUniform Float               where cdf :: StdUniform Float -> Float -> Double
cdf   _ = Float -> Double
forall a. Real a => a -> Double
realStdUniformCDF
instance CDF StdUniform Double              where cdf :: StdUniform Double -> Double -> Double
cdf   _ = Double -> Double
forall a. Real a => a -> Double
realStdUniformCDF
instance PDF StdUniform Float               where pdf :: StdUniform Float -> Float -> Double
pdf   _ = Float -> Double
forall a. Real a => a -> Double
realStdUniformPDF
instance PDF StdUniform Double              where pdf :: StdUniform Double -> Double -> Double
pdf   _ = Double -> Double
forall a. Real a => a -> Double
realStdUniformPDF


instance HasResolution r =>
         Distribution Uniform (Fixed r)     where rvarT :: Uniform (Fixed r) -> RVarT n (Fixed r)
rvarT (Uniform a :: Fixed r
a b :: Fixed r
b) = Fixed r -> Fixed r -> RVarT n (Fixed r)
forall r (m :: * -> *).
HasResolution r =>
Fixed r -> Fixed r -> RVarT m (Fixed r)
fixedUniform  Fixed r
a Fixed r
b
instance HasResolution r =>
         CDF Uniform (Fixed r)              where cdf :: Uniform (Fixed r) -> Fixed r -> Double
cdf   (Uniform a :: Fixed r
a b :: Fixed r
b) = Fixed r -> Fixed r -> Fixed r -> Double
forall a. RealFrac a => a -> a -> a -> Double
realUniformCDF Fixed r
a Fixed r
b
instance HasResolution r =>
         Distribution StdUniform (Fixed r)  where rvarT :: StdUniform (Fixed r) -> RVarT n (Fixed r)
rvarT ~StdUniform (Fixed r)
StdUniform = RVarT n (Fixed r)
forall r (m :: * -> *). HasResolution r => RVarT m (Fixed r)
fixedStdUniform
instance HasResolution r =>
         CDF StdUniform (Fixed r)           where cdf :: StdUniform (Fixed r) -> Fixed r -> Double
cdf   ~StdUniform (Fixed r)
StdUniform = Fixed r -> Double
forall a. Real a => a -> Double
realStdUniformCDF

instance Distribution Uniform ()            where rvarT :: Uniform () -> RVarT n ()
rvarT (Uniform _ _) = () -> RVarT n ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
instance CDF Uniform ()                     where cdf :: Uniform () -> () -> Double
cdf   (Uniform _ _) = Double -> () -> Double
forall (m :: * -> *) a. Monad m => a -> m a
return 1
$( replicateInstances ''Char [''Char, ''Bool, ''Ordering] [d|
        instance Distribution Uniform Char  where rvarT (Uniform a b) = enumUniform a b
        instance CDF Uniform Char           where cdf   (Uniform a b) = enumUniformCDF a b

    |])

instance Distribution StdUniform ()         where rvarT :: StdUniform () -> RVarT n ()
rvarT ~StdUniform ()
StdUniform = () -> RVarT n ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
instance CDF StdUniform ()                  where cdf :: StdUniform () -> () -> Double
cdf   ~StdUniform ()
StdUniform = Double -> () -> Double
forall (m :: * -> *) a. Monad m => a -> m a
return 1
instance Distribution StdUniform Bool       where rvarT :: StdUniform Bool -> RVarT n Bool
rvarT ~StdUniform Bool
StdUniform = (Word8 -> Bool) -> RVarT n Word8 -> RVarT n Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Word8 -> Bool
forall a. Integral a => a -> Bool
even (RVarT n Word8
forall (m :: * -> *). MonadRandom m => m Word8
getRandomWord8)
instance CDF StdUniform Bool                where cdf :: StdUniform Bool -> Bool -> Double
cdf   ~StdUniform Bool
StdUniform = Bool -> Double
forall a. (Enum a, Bounded a, Ord a) => a -> Double
boundedEnumStdUniformCDF

instance Distribution StdUniform Char       where rvarT :: StdUniform Char -> RVarT n Char
rvarT ~StdUniform Char
StdUniform = RVarT n Char
forall a (m :: * -> *). (Enum a, Bounded a) => RVarT m a
boundedEnumStdUniform
instance CDF StdUniform Char                where cdf :: StdUniform Char -> Char -> Double
cdf   ~StdUniform Char
StdUniform = Char -> Double
forall a. (Enum a, Bounded a, Ord a) => a -> Double
boundedEnumStdUniformCDF
instance Distribution StdUniform Ordering   where rvarT :: StdUniform Ordering -> RVarT n Ordering
rvarT ~StdUniform Ordering
StdUniform = RVarT n Ordering
forall a (m :: * -> *). (Enum a, Bounded a) => RVarT m a
boundedEnumStdUniform
instance CDF StdUniform Ordering            where cdf :: StdUniform Ordering -> Ordering -> Double
cdf   ~StdUniform Ordering
StdUniform = Ordering -> Double
forall a. (Enum a, Bounded a, Ord a) => a -> Double
boundedEnumStdUniformCDF