    {-# LANGUAGE DeriveDataTypeable, DeriveGeneric, OverloadedStrings #-}
    -- |
    -- Module    : Statistics.Distribution.DiscreteUniform
    -- Copyright : (c) 2016 André Szabolcs Szelp
    -- License   : BSD3
    --
    -- Maintainer  : a.sz.szelp@gmail.com
    -- Stability   : experimental
    -- Portability : portable
    --
    -- The discrete uniform distribution. There are two parametrizations of
    -- this distribution. First is the probability distribution on an
    -- inclusive interval {1, ..., n}. This is parametrized with n only,
    -- where p_1, ..., p_n = 1/n. ('discreteUniform').
    --
    -- The second parametrization is the uniform distribution on {a, ..., b} with
    -- probabilities p_a, ..., p_b = 1/(a-b+1). This is parametrized with
    -- /a/ and /b/. ('discreteUniformAB')

    module Statistics.Distribution.DiscreteUniform
        (
          DiscreteUniform
        -- * Constructors
        , discreteUniform
        , discreteUniformAB
        -- * Accessors
        , rangeFrom
        , rangeTo
        ) where

    import Control.Applicative (empty)
    import Data.Aeson   (FromJSON(..), ToJSON, Value(..), (.:))
    import Data.Binary  (Binary(..))
    import Data.Data    (Data, Typeable)
    import System.Random.Stateful (uniformRM)
    import GHC.Generics (Generic)

    import qualified Statistics.Distribution as D
    import Statistics.Internal

    -- | The discrete uniform distribution.
    data DiscreteUniform = U {
          DiscreteUniform -> Int
    rangeFrom  :: {-# UNPACK #-} !Int
        -- ^ /a/, the lower bound of the support {a, ..., b}
        , DiscreteUniform -> Int
    rangeTo    :: {-# UNPACK #-} !Int
        -- ^ /b/, the upper bound of the support {a, ..., b}
        } deriving (DiscreteUniform -> DiscreteUniform -> Bool
    (DiscreteUniform -> DiscreteUniform -> Bool)
    -> (DiscreteUniform -> DiscreteUniform -> Bool)
    -> Eq DiscreteUniform
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: DiscreteUniform -> DiscreteUniform -> Bool
    == :: DiscreteUniform -> DiscreteUniform -> Bool
    $c/= :: DiscreteUniform -> DiscreteUniform -> Bool
    /= :: DiscreteUniform -> DiscreteUniform -> Bool
    Eq, Typeable, Typeable DiscreteUniform
    Typeable DiscreteUniform =>
    (forall (c :: * -> *).
     (forall d b. Data d => c (d -> b) -> d -> c b)
     -> (forall g. g -> c g) -> DiscreteUniform -> c DiscreteUniform)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c DiscreteUniform)
    -> (DiscreteUniform -> Constr)
    -> (DiscreteUniform -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c DiscreteUniform))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e))
        -> Maybe (c DiscreteUniform))
    -> ((forall b. Data b => b -> b)
        -> DiscreteUniform -> DiscreteUniform)
    -> (forall r r'.
        (r -> r' -> r)
        -> r -> (forall d. Data d => d -> r') -> DiscreteUniform -> r)
    -> (forall r r'.
        (r' -> r -> r)
        -> r -> (forall d. Data d => d -> r') -> DiscreteUniform -> r)
    -> (forall u.
        (forall d. Data d => d -> u) -> DiscreteUniform -> [u])
    -> (forall u.
        Int -> (forall d. Data d => d -> u) -> DiscreteUniform -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d)
        -> DiscreteUniform -> m DiscreteUniform)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d)
        -> DiscreteUniform -> m DiscreteUniform)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d)
        -> DiscreteUniform -> m DiscreteUniform)
    -> Data DiscreteUniform
    DiscreteUniform -> Constr
    DiscreteUniform -> DataType
    (forall b. Data b => b -> b) -> DiscreteUniform -> DiscreteUniform
    forall a.
    Typeable a =>
    (forall (c :: * -> *).
     (forall d b. Data d => c (d -> b) -> d -> c b)
     -> (forall g. g -> c g) -> a -> c a)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c a)
    -> (a -> Constr)
    -> (a -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c a))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
    -> ((forall b. Data b => b -> b) -> a -> a)
    -> (forall r r'.
        (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall r r'.
        (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall u. (forall d. Data d => d -> u) -> a -> [u])
    -> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> Data a
    forall u.
    Int -> (forall d. Data d => d -> u) -> DiscreteUniform -> u
    forall u. (forall d. Data d => d -> u) -> DiscreteUniform -> [u]
    forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> DiscreteUniform -> r
    forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> DiscreteUniform -> r
    forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d)
    -> DiscreteUniform -> m DiscreteUniform
    forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> DiscreteUniform -> m DiscreteUniform
    forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c DiscreteUniform
    forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> DiscreteUniform -> c DiscreteUniform
    forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c DiscreteUniform)
    forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c DiscreteUniform)
    $cgfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> DiscreteUniform -> c DiscreteUniform
    gfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> DiscreteUniform -> c DiscreteUniform
    $cgunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c DiscreteUniform
    gunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c DiscreteUniform
    $ctoConstr :: DiscreteUniform -> Constr
    toConstr :: DiscreteUniform -> Constr
    $cdataTypeOf :: DiscreteUniform -> DataType
    dataTypeOf :: DiscreteUniform -> DataType
    $cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c DiscreteUniform)
    dataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c DiscreteUniform)
    $cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c DiscreteUniform)
    dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c DiscreteUniform)
    $cgmapT :: (forall b. Data b => b -> b) -> DiscreteUniform -> DiscreteUniform
    gmapT :: (forall b. Data b => b -> b) -> DiscreteUniform -> DiscreteUniform
    $cgmapQl :: forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> DiscreteUniform -> r
    gmapQl :: forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> DiscreteUniform -> r
    $cgmapQr :: forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> DiscreteUniform -> r
    gmapQr :: forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> DiscreteUniform -> r
    $cgmapQ :: forall u. (forall d. Data d => d -> u) -> DiscreteUniform -> [u]
    gmapQ :: forall u. (forall d. Data d => d -> u) -> DiscreteUniform -> [u]
    $cgmapQi :: forall u.
    Int -> (forall d. Data d => d -> u) -> DiscreteUniform -> u
    gmapQi :: forall u.
    Int -> (forall d. Data d => d -> u) -> DiscreteUniform -> u
    $cgmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d)
    -> DiscreteUniform -> m DiscreteUniform
    gmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d)
    -> DiscreteUniform -> m DiscreteUniform
    $cgmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> DiscreteUniform -> m DiscreteUniform
    gmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> DiscreteUniform -> m DiscreteUniform
    $cgmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> DiscreteUniform -> m DiscreteUniform
    gmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> DiscreteUniform -> m DiscreteUniform
    Data, (forall x. DiscreteUniform -> Rep DiscreteUniform x)
    -> (forall x. Rep DiscreteUniform x -> DiscreteUniform)
    -> Generic DiscreteUniform
    forall x. Rep DiscreteUniform x -> DiscreteUniform
    forall x. DiscreteUniform -> Rep DiscreteUniform x
    forall a.
    (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
    $cfrom :: forall x. DiscreteUniform -> Rep DiscreteUniform x
    from :: forall x. DiscreteUniform -> Rep DiscreteUniform x
    $cto :: forall x. Rep DiscreteUniform x -> DiscreteUniform
    to :: forall x. Rep DiscreteUniform x -> DiscreteUniform
    Generic)

    instance Show DiscreteUniform where
      showsPrec :: Int -> DiscreteUniform -> ShowS
    showsPrec Int
    i (U Int
    a Int
    b) = [Char] -> Int -> Int -> Int -> ShowS
    forall a b. (Show a, Show b) => [Char] -> a -> b -> Int -> ShowS
    defaultShow2 [Char]
    "discreteUniformAB" Int
    a Int
    b Int
    i
    instance Read DiscreteUniform where
      readPrec :: ReadPrec DiscreteUniform
    readPrec = [Char]
    -> (Int -> Int -> Maybe DiscreteUniform)
    -> ReadPrec DiscreteUniform
    forall a b r.
    (Read a, Read b) =>
    [Char] -> (a -> b -> Maybe r) -> ReadPrec r
    defaultReadPrecM2 [Char]
    "discreteUniformAB" (\Int
    a Int
    b -> DiscreteUniform -> Maybe DiscreteUniform
    forall a. a -> Maybe a
    Just (Int -> Int -> DiscreteUniform
    discreteUniformAB Int
    a Int
    b))

    instance ToJSON   DiscreteUniform
    instance FromJSON DiscreteUniform where
      parseJSON :: Value -> Parser DiscreteUniform
    parseJSON (Object Object
    v) = do
        Int
    a <- Object
    v Object -> Key -> Parser Int
    forall a. FromJSON a => Object -> Key -> Parser a
    .: Key
    "uniformA"
        Int
    b <- Object
    v Object -> Key -> Parser Int
    forall a. FromJSON a => Object -> Key -> Parser a
    .: Key
    "uniformB"
        DiscreteUniform -> Parser DiscreteUniform
    forall a. a -> Parser a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (DiscreteUniform -> Parser DiscreteUniform)
    -> DiscreteUniform -> Parser DiscreteUniform
    forall a b. (a -> b) -> a -> b
    $ Int -> Int -> DiscreteUniform
    discreteUniformAB Int
    a Int
    b
      parseJSON Value
    _ = Parser DiscreteUniform
    forall a. Parser a
    forall (f :: * -> *) a. Alternative f => f a
    empty

    instance Binary DiscreteUniform where
      put :: DiscreteUniform -> Put
    put (U Int
    a Int
    b) = Int -> Put
    forall t. Binary t => t -> Put
    put Int
    a Put -> Put -> Put
    forall a b. PutM a -> PutM b -> PutM b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> Int -> Put
    forall t. Binary t => t -> Put
    put Int
    b
      get :: Get DiscreteUniform
    get         = Int -> Int -> DiscreteUniform
    discreteUniformAB (Int -> Int -> DiscreteUniform)
    -> Get Int -> Get (Int -> DiscreteUniform)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Get Int
    forall t. Binary t => Get t
    get Get (Int -> DiscreteUniform) -> Get Int -> Get DiscreteUniform
    forall a b. Get (a -> b) -> Get a -> Get b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> Get Int
    forall t. Binary t => Get t
    get

    instance D.Distribution DiscreteUniform where
      cumulative :: DiscreteUniform -> Double -> Double
    cumulative (U Int
    a Int
    b) Double
    x
        | Double
    x Double -> Double -> Bool
    forall a. Ord a => a -> a -> Bool
    < Int -> Double
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    a = Double
    0
        | Double
    x Double -> Double -> Bool
    forall a. Ord a => a -> a -> Bool
    > Int -> Double
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    b = Double
    1
        | Bool
    otherwise = Int -> Double
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (Double -> Int
    forall b. Integral b => Double -> b
    forall a b. (RealFrac a, Integral b) => a -> b
    floor Double
    x Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Int
    a Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    1) Double -> Double -> Double
    forall a. Fractional a => a -> a -> a
    / Int -> Double
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (Int
    b Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Int
    a Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    1)

    instance D.DiscreteDistr DiscreteUniform where
      probability :: DiscreteUniform -> Int -> Double
    probability (U Int
    a Int
    b) Int
    k
        | Int
    k Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    >= Int
    a Bool -> Bool -> Bool
    && Int
    k Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Int
    b = Double
    1 Double -> Double -> Double
    forall a. Fractional a => a -> a -> a
    / Int -> Double
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (Int
    b Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Int
    a Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    1)
        | Bool
    otherwise        = Double
    0

    instance D.Mean DiscreteUniform where
      mean :: DiscreteUniform -> Double
    mean (U Int
    a Int
    b) = Int -> Double
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (Int
    aInt -> Int -> Int
    forall a. Num a => a -> a -> a
    +Int
    b)Double -> Double -> Double
    forall a. Fractional a => a -> a -> a
    /Double
    2

    instance D.Variance DiscreteUniform where
      variance :: DiscreteUniform -> Double
    variance (U Int
    a Int
    b) = (Int -> Double
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (Int
    b Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Int
    a Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    1)Double -> Int -> Double
    forall a b. (Num a, Integral b) => a -> b -> a
    ^(Int
    2::Int) Double -> Double -> Double
    forall a. Num a => a -> a -> a
    - Double
    1) Double -> Double -> Double
    forall a. Fractional a => a -> a -> a
    / Double
    12

    instance D.MaybeMean DiscreteUniform where
      maybeMean :: DiscreteUniform -> Maybe Double
    maybeMean = Double -> Maybe Double
    forall a. a -> Maybe a
    Just (Double -> Maybe Double)
    -> (DiscreteUniform -> Double) -> DiscreteUniform -> Maybe Double
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . DiscreteUniform -> Double
    forall d. Mean d => d -> Double
    D.mean

    instance D.MaybeVariance DiscreteUniform where
      maybeStdDev :: DiscreteUniform -> Maybe Double
    maybeStdDev   = Double -> Maybe Double
    forall a. a -> Maybe a
    Just (Double -> Maybe Double)
    -> (DiscreteUniform -> Double) -> DiscreteUniform -> Maybe Double
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . DiscreteUniform -> Double
    forall d. Variance d => d -> Double
    D.stdDev
      maybeVariance :: DiscreteUniform -> Maybe Double
    maybeVariance = Double -> Maybe Double
    forall a. a -> Maybe a
    Just (Double -> Maybe Double)
    -> (DiscreteUniform -> Double) -> DiscreteUniform -> Maybe Double
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . DiscreteUniform -> Double
    forall d. Variance d => d -> Double
    D.variance

    instance D.Entropy DiscreteUniform where
      entropy :: DiscreteUniform -> Double
    entropy (U Int
    a Int
    b) = Double -> Double
    forall a. Floating a => a -> a
    log (Double -> Double) -> Double -> Double
    forall a b. (a -> b) -> a -> b
    $ Int -> Double
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (Int -> Double) -> Int -> Double
    forall a b. (a -> b) -> a -> b
    $ Int
    b Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Int
    a Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    1

    instance D.MaybeEntropy DiscreteUniform where
      maybeEntropy :: DiscreteUniform -> Maybe Double
    maybeEntropy = Double -> Maybe Double
    forall a. a -> Maybe a
    Just (Double -> Maybe Double)
    -> (DiscreteUniform -> Double) -> DiscreteUniform -> Maybe Double
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . DiscreteUniform -> Double
    forall d. Entropy d => d -> Double
    D.entropy

    instance D.ContGen DiscreteUniform where
      genContVar :: forall g (m :: * -> *).
    StatefulGen g m =>
    DiscreteUniform -> g -> m Double
    genContVar DiscreteUniform
    d = (Int -> Double) -> m Int -> m Double
    forall a b. (a -> b) -> m a -> m b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap Int -> Double
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (m Int -> m Double) -> (g -> m Int) -> g -> m Double
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . DiscreteUniform -> g -> m Int
    forall d g (m :: * -> *).
    (DiscreteGen d, StatefulGen g m) =>
    d -> g -> m Int
    forall g (m :: * -> *).
    StatefulGen g m =>
    DiscreteUniform -> g -> m Int
    D.genDiscreteVar DiscreteUniform
    d

    instance D.DiscreteGen DiscreteUniform where
      genDiscreteVar :: forall g (m :: * -> *).
    StatefulGen g m =>
    DiscreteUniform -> g -> m Int
    genDiscreteVar (U Int
    a Int
    b) = (Int, Int) -> g -> m Int
    forall a g (m :: * -> *).
    (UniformRange a, StatefulGen g m) =>
    (a, a) -> g -> m a
    forall g (m :: * -> *). StatefulGen g m => (Int, Int) -> g -> m Int
    uniformRM (Int
    a,Int
    b)

    -- | Construct discrete uniform distribution on support {1, ..., n}.
    --   Range /n/ must be >0.
    discreteUniform :: Int             -- ^ Range
                    -> DiscreteUniform
    discreteUniform :: Int -> DiscreteUniform
    discreteUniform Int
    n
      | Int
    n Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    < Int
    1     = [Char] -> DiscreteUniform
    forall a. HasCallStack => [Char] -> a
    error ([Char] -> DiscreteUniform) -> [Char] -> DiscreteUniform
    forall a b. (a -> b) -> a -> b
    $ [Char]
    msg [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "range must be > 0. Got " [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ Int -> [Char]
    forall a. Show a => a -> [Char]
    show Int
    n
      | Bool
    otherwise = Int -> Int -> DiscreteUniform
    U Int
    1 Int
    n
      where msg :: [Char]
    msg = [Char]
    "Statistics.Distribution.DiscreteUniform.discreteUniform: "

    -- | Construct discrete uniform distribution on support {a, ..., b}.
    discreteUniformAB :: Int             -- ^ Lower boundary (inclusive)
                      -> Int             -- ^ Upper boundary (inclusive)
                      -> DiscreteUniform
    discreteUniformAB :: Int -> Int -> DiscreteUniform
    discreteUniformAB Int
    a Int
    b
      | Int
    b Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    < Int
    a     = Int -> Int -> DiscreteUniform
    U Int
    b Int
    a
      | Bool
    otherwise = Int -> Int -> DiscreteUniform
    U Int
    a Int
    b