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

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

    module Data.Random.Distribution.Binomial where

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

    import Data.Int
    import Data.Word

    import Numeric.SpecFunctions ( stirlingError )
    import Numeric.SpecFunctions.Extra ( bd0 )
    import Numeric ( log1p )

        -- algorithm from Knuth's TAOCP, 3rd ed., p 136
        -- specific choice of cutoff size taken from gsl source
        -- note that although it's fast enough for large (eg, 2^10000)
        -- @Integer@s, it's not accurate enough when using @Double@ as
        -- the @b@ parameter.
    integralBinomial :: (Integral a, Floating b, Ord b, Distribution Beta b, Distribution StdUniform b) => a -> b -> RVarT m a
    integralBinomial :: forall a b (m :: * -> *).
    (Integral a, Floating b, Ord b, Distribution Beta b,
     Distribution StdUniform b) =>
    a -> b -> RVarT m a
    integralBinomial = a -> a -> b -> RVarT m a
    forall a b (m :: * -> *).
    (Integral a, Floating b, Ord b, Distribution Beta b,
     Distribution StdUniform b) =>
    a -> a -> b -> RVarT m a
    bin a
    0
        where
            bin :: (Integral a, Floating b, Ord b, Distribution Beta b, Distribution StdUniform b) => a -> a -> b -> RVarT m a
            bin :: forall a b (m :: * -> *).
    (Integral a, Floating b, Ord b, Distribution Beta b,
     Distribution StdUniform b) =>
    a -> a -> b -> RVarT m a
    bin !a
    k !a
    t !b
    p
                | a
    t a -> a -> Bool
    forall a. Ord a => a -> a -> Bool
    > a
    10    = do
                    let a :: a
    a = a
    1 a -> a -> a
    forall a. Num a => a -> a -> a
    + a
    t a -> a -> a
    forall a. Integral a => a -> a -> a
    `div` a
    2
                        b :: a
    b = a
    1 a -> a -> a
    forall a. Num a => a -> a -> a
    + a
    t a -> a -> a
    forall a. Num a => a -> a -> a
    - a
    a

                    x <- b -> b -> RVarT m b
    forall a (m :: * -> *). Distribution Beta a => a -> a -> RVarT m a
    betaT (a -> b
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral a
    a) (a -> b
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral a
    b)
                    if x >= p
                        then bin  k      (a - 1) (p / x)
                        else bin (k + a) (b - 1) ((p - x) / (1 - x))

                | Bool
    otherwise = a -> a -> RVarT m a
    forall {t} {t} {m :: * -> *}.
    (Ord t, Num t, Num t) =>
    t -> t -> RVarT m t
    count a
    k a
    t
                    where
                        count :: t -> t -> RVarT m t
    count !t
    k' t
    0         = t -> RVarT m t
    forall a. a -> RVarT m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return t
    k'
                        count !t
    k' t
    n | t
    n t -> t -> Bool
    forall a. Ord a => a -> a -> Bool
    > t
    0 = do
                            x <- RVarT m b
    forall a (m :: * -> *). Distribution StdUniform a => RVarT m a
    stdUniformT
                            count (if x < p then k' + 1 else k') (n-1)
                        count t
    _ t
    _ = [Char] -> RVarT m t
    forall a. HasCallStack => [Char] -> a
    error [Char]
    "integralBinomial: negative number of trials specified"

    integralBinomialCDF :: (Integral a, Real b) => a -> b -> a -> Double
    integralBinomialCDF :: forall a b. (Integral a, Real b) => a -> b -> a -> Double
    integralBinomialCDF a
    t b
    p a
    x = [Double] -> Double
    forall a. Num a => [a] -> a
    forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
    sum ([Double] -> Double) -> [Double] -> Double
    forall a b. (a -> b) -> a -> b
    $ (a -> Double) -> [a] -> [Double]
    forall a b. (a -> b) -> [a] -> [b]
    map (a -> b -> a -> Double
    forall a b. (Integral a, Real b) => a -> b -> a -> Double
    integralBinomialPDF a
    t b
    p) ([a] -> [Double]) -> [a] -> [Double]
    forall a b. (a -> b) -> a -> b
    $ [a
    0 .. a
    x]

    -- | The probability of getting exactly k successes in n trials is
    -- given by the probability mass function:
    --
    -- \[
    -- f(k;n,p) = \Pr(X = k) = \binom n k  p^k(1-p)^{n-k}
    -- \]
    --
    -- Note that in `integralBinomialPDF` the parameters of the mass
    -- function are given first and the range of the random variable
    -- distributed according to the binomial distribution is given
    -- last. That is, \(f(2;4,0.5)\) is calculated by @integralBinomialPDF 4 0.5 2@.

    integralBinomialPDF :: (Integral a, Real b) => a -> b -> a -> Double
    integralBinomialPDF :: forall a b. (Integral a, Real b) => a -> b -> a -> Double
    integralBinomialPDF a
    t b
    p a
    x =
      Double -> Double
    forall a. Floating a => a -> a
    exp (Double -> Double) -> Double -> Double
    forall a b. (a -> b) -> a -> b
    $ a -> b -> a -> Double
    forall a b. (Integral a, Real b) => a -> b -> a -> Double
    integralBinomialLogPdf a
    t b
    p a
    x

    -- | We use the method given in \"Fast and accurate computation of
    -- binomial probabilities, Loader, C\",
    -- <http://octave.1599824.n4.nabble.com/attachment/3829107/0/loader2000Fast.pdf>
    integralBinomialLogPdf :: (Integral a, Real b) => a -> b -> a -> Double
    integralBinomialLogPdf :: forall a b. (Integral a, Real b) => a -> b -> a -> Double
    integralBinomialLogPdf a
    nI b
    pR a
    xI
      | Double
    p Double -> Double -> Bool
    forall a. Eq a => a -> a -> Bool
    == Double
    0.0 Bool -> Bool -> Bool
    && a
    xI a -> a -> Bool
    forall a. Eq a => a -> a -> Bool
    == a
    0   = Double
    1.0
      | Double
    p Double -> Double -> Bool
    forall a. Eq a => a -> a -> Bool
    == Double
    0.0              = Double
    0.0
      | Double
    p Double -> Double -> Bool
    forall a. Eq a => a -> a -> Bool
    == Double
    1.0 Bool -> Bool -> Bool
    && a
    xI a -> a -> Bool
    forall a. Eq a => a -> a -> Bool
    == a
    nI  = Double
    1.0
      | Double
    p Double -> Double -> Bool
    forall a. Eq a => a -> a -> Bool
    == Double
    1.0              = Double
    0.0
      |             a
    xI a -> a -> Bool
    forall a. Eq a => a -> a -> Bool
    == a
    0   = Double
    n Double -> Double -> Double
    forall a. Num a => a -> a -> a
    * Double -> Double
    forall a. Floating a => a -> a
    log (Double
    1Double -> Double -> Double
    forall a. Num a => a -> a -> a
    -Double
    p)
      |             a
    xI a -> a -> Bool
    forall a. Eq a => a -> a -> Bool
    == a
    nI  = Double
    n Double -> Double -> Double
    forall a. Num a => a -> a -> a
    * Double -> Double
    forall a. Floating a => a -> a
    log Double
    p
      | Bool
    otherwise = Double
    lc Double -> Double -> Double
    forall a. Num a => a -> a -> a
    - Double
    0.5 Double -> Double -> Double
    forall a. Num a => a -> a -> a
    * Double
    lf
      where
        n :: Double
    n = a -> Double
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral a
    nI
        x :: Double
    x = a -> Double
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral a
    xI
        p :: Double
    p = b -> Double
    forall a b. (Real a, Fractional b) => a -> b
    realToFrac b
    pR
        lc :: Double
    lc = Double -> Double
    stirlingError Double
    n Double -> Double -> Double
    forall a. Num a => a -> a -> a
    -
             Double -> Double
    stirlingError Double
    x Double -> Double -> Double
    forall a. Num a => a -> a -> a
    -
             Double -> Double
    stirlingError (Double
    n Double -> Double -> Double
    forall a. Num a => a -> a -> a
    - Double
    x) Double -> Double -> Double
    forall a. Num a => a -> a -> a
    -
             Double -> Double -> Double
    bd0 Double
    x (Double
    n Double -> Double -> Double
    forall a. Num a => a -> a -> a
    * Double
    p) Double -> Double -> Double
    forall a. Num a => a -> a -> a
    -
             Double -> Double -> Double
    bd0 (Double
    n Double -> Double -> Double
    forall a. Num a => a -> a -> a
    - Double
    x) (Double
    n Double -> Double -> Double
    forall a. Num a => a -> a -> a
    * (Double
    1 Double -> Double -> Double
    forall a. Num a => a -> a -> a
    - Double
    p))
        lf :: Double
    lf = Double -> Double
    forall a. Floating a => a -> a
    log (Double
    2 Double -> Double -> Double
    forall a. Num a => a -> a -> a
    * Double
    forall a. Floating a => a
    pi) Double -> Double -> Double
    forall a. Num a => a -> a -> a
    + Double -> Double
    forall a. Floating a => a -> a
    log Double
    x Double -> Double -> Double
    forall a. Num a => a -> a -> a
    + Double -> Double
    forall a. Floating a => a -> a
    log1p (- Double
    x Double -> Double -> Double
    forall a. Fractional a => a -> a -> a
    / Double
    n)

    -- would it be valid to repeat the above computation using fractional @t@?
    -- obviously something different would have to be done with @count@ as well...
    {-# SPECIALIZE floatingBinomial :: Float  -> Float  -> RVar Float  #-}
    {-# SPECIALIZE floatingBinomial :: Float  -> Double -> RVar Float  #-}
    {-# SPECIALIZE floatingBinomial :: Double -> Float  -> RVar Double #-}
    {-# SPECIALIZE floatingBinomial :: Double -> Double -> RVar Double #-}
    floatingBinomial :: (RealFrac a, Distribution (Binomial b) Integer) => a -> b -> RVar a
    floatingBinomial :: forall a b.
    (RealFrac a, Distribution (Binomial b) Integer) =>
    a -> b -> RVar a
    floatingBinomial a
    t b
    p = (Integer -> a) -> RVarT Identity Integer -> RVarT Identity a
    forall a b. (a -> b) -> RVarT Identity a -> RVarT Identity b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap Integer -> a
    forall a. Num a => Integer -> a
    fromInteger (Binomial b Integer -> RVarT Identity Integer
    forall (d :: * -> *) t. Distribution d t => d t -> RVar t
    rvar (Integer -> b -> Binomial b Integer
    forall b a. a -> b -> Binomial b a
    Binomial (a -> Integer
    forall b. Integral b => a -> b
    forall a b. (RealFrac a, Integral b) => a -> b
    truncate a
    t) b
    p))

    floatingBinomialCDF :: (CDF (Binomial b) Integer, RealFrac a) => a -> b -> a -> Double
    floatingBinomialCDF :: forall b a.
    (CDF (Binomial b) Integer, RealFrac a) =>
    a -> b -> a -> Double
    floatingBinomialCDF a
    t b
    p a
    x = Binomial b Integer -> Integer -> Double
    forall (d :: * -> *) t. CDF d t => d t -> t -> Double
    cdf (Integer -> b -> Binomial b Integer
    forall b a. a -> b -> Binomial b a
    Binomial (a -> Integer
    forall b. Integral b => a -> b
    forall a b. (RealFrac a, Integral b) => a -> b
    truncate a
    t :: Integer) b
    p) (a -> Integer
    forall b. Integral b => a -> b
    forall a b. (RealFrac a, Integral b) => a -> b
    floor a
    x)

    floatingBinomialPDF :: (PDF (Binomial b) Integer, RealFrac a) => a -> b -> a -> Double
    floatingBinomialPDF :: forall b a.
    (PDF (Binomial b) Integer, RealFrac a) =>
    a -> b -> a -> Double
    floatingBinomialPDF a
    t b
    p a
    x = Binomial b Integer -> Integer -> Double
    forall (d :: * -> *) t. PDF d t => d t -> t -> Double
    pdf (Integer -> b -> Binomial b Integer
    forall b a. a -> b -> Binomial b a
    Binomial (a -> Integer
    forall b. Integral b => a -> b
    forall a b. (RealFrac a, Integral b) => a -> b
    truncate a
    t :: Integer) b
    p) (a -> Integer
    forall b. Integral b => a -> b
    forall a b. (RealFrac a, Integral b) => a -> b
    floor a
    x)

    floatingBinomialLogPDF :: (PDF (Binomial b) Integer, RealFrac a) => a -> b -> a -> Double
    floatingBinomialLogPDF :: forall b a.
    (PDF (Binomial b) Integer, RealFrac a) =>
    a -> b -> a -> Double
    floatingBinomialLogPDF a
    t b
    p a
    x = Binomial b Integer -> Integer -> Double
    forall (d :: * -> *) t. PDF d t => d t -> t -> Double
    logPdf (Integer -> b -> Binomial b Integer
    forall b a. a -> b -> Binomial b a
    Binomial (a -> Integer
    forall b. Integral b => a -> b
    forall a b. (RealFrac a, Integral b) => a -> b
    truncate a
    t :: Integer) b
    p) (a -> Integer
    forall b. Integral b => a -> b
    forall a b. (RealFrac a, Integral b) => a -> b
    floor a
    x)

    {-# SPECIALIZE binomial :: Int     -> Float  -> RVar Int #-}
    {-# SPECIALIZE binomial :: Int     -> Double -> RVar Int #-}
    {-# SPECIALIZE binomial :: Integer -> Float  -> RVar Integer #-}
    {-# SPECIALIZE binomial :: Integer -> Double -> RVar Integer #-}
    {-# SPECIALIZE binomial :: Float   -> Float  -> RVar Float  #-}
    {-# SPECIALIZE binomial :: Float   -> Double -> RVar Float  #-}
    {-# SPECIALIZE binomial :: Double  -> Float  -> RVar Double #-}
    {-# SPECIALIZE binomial :: Double  -> Double -> RVar Double #-}
    binomial :: Distribution (Binomial b) a => a -> b -> RVar a
    binomial :: forall b a. Distribution (Binomial b) a => a -> b -> RVar a
    binomial a
    t b
    p = Binomial b a -> RVar a
    forall (d :: * -> *) t. Distribution d t => d t -> RVar t
    rvar (a -> b -> Binomial b a
    forall b a. a -> b -> Binomial b a
    Binomial a
    t b
    p)

    {-# SPECIALIZE binomialT :: Int     -> Float  -> RVarT m Int #-}
    {-# SPECIALIZE binomialT :: Int     -> Double -> RVarT m Int #-}
    {-# SPECIALIZE binomialT :: Integer -> Float  -> RVarT m Integer #-}
    {-# SPECIALIZE binomialT :: Integer -> Double -> RVarT m Integer #-}
    {-# SPECIALIZE binomialT :: Float   -> Float  -> RVarT m Float  #-}
    {-# SPECIALIZE binomialT :: Float   -> Double -> RVarT m Float  #-}
    {-# SPECIALIZE binomialT :: Double  -> Float  -> RVarT m Double #-}
    {-# SPECIALIZE binomialT :: Double  -> Double -> RVarT m Double #-}
    binomialT :: Distribution (Binomial b) a => a -> b -> RVarT m a
    binomialT :: forall b a (m :: * -> *).
    Distribution (Binomial b) a =>
    a -> b -> RVarT m a
    binomialT a
    t b
    p = Binomial b a -> RVarT m a
    forall (n :: * -> *). Binomial b a -> RVarT n a
    forall (d :: * -> *) t (n :: * -> *).
    Distribution d t =>
    d t -> RVarT n t
    rvarT (a -> b -> Binomial b a
    forall b a. a -> b -> Binomial b a
    Binomial a
    t b
    p)

    data Binomial b a = Binomial a b

    instance (Floating b, Ord b, Distribution Beta b, Distribution StdUniform b) => Distribution (Binomial b) Integer where
        rvarT :: forall (n :: * -> *). Binomial b Integer -> RVarT n Integer
    rvarT  (Binomial Integer
    t b
    p) = Integer -> b -> RVarT n Integer
    forall a b (m :: * -> *).
    (Integral a, Floating b, Ord b, Distribution Beta b,
     Distribution StdUniform b) =>
    a -> b -> RVarT m a
    integralBinomial Integer
    t b
    p
    instance (Real b, Distribution (Binomial b) Integer)                         => CDF (Binomial b) Integer where
        cdf :: Binomial b Integer -> Integer -> Double
    cdf    (Binomial Integer
    t b
    p) = Integer -> b -> Integer -> Double
    forall a b. (Integral a, Real b) => a -> b -> a -> Double
    integralBinomialCDF Integer
    t b
    p
    instance (Real b, Distribution (Binomial b) Integer)                         => PDF (Binomial b) Integer where
        pdf :: Binomial b Integer -> Integer -> Double
    pdf    (Binomial Integer
    t b
    p) = Integer -> b -> Integer -> Double
    forall a b. (Integral a, Real b) => a -> b -> a -> Double
    integralBinomialPDF Integer
    t b
    p
        logPdf :: Binomial b Integer -> Integer -> Double
    logPdf (Binomial Integer
    t b
    p) = Integer -> b -> Integer -> Double
    forall a b. (Integral a, Real b) => a -> b -> a -> Double
    integralBinomialLogPdf Integer
    t b
    p
    instance (Floating b, Ord b, Distribution Beta b, Distribution StdUniform b) => Distribution (Binomial b) Int where
        rvarT :: forall (n :: * -> *). Binomial b Int -> RVarT n Int
    rvarT  (Binomial Int
    t b
    p) = Int -> b -> RVarT n Int
    forall a b (m :: * -> *).
    (Integral a, Floating b, Ord b, Distribution Beta b,
     Distribution StdUniform b) =>
    a -> b -> RVarT m a
    integralBinomial Int
    t b
    p
    instance (Real b, Distribution (Binomial b) Int)                             => CDF (Binomial b) Int where
        cdf :: Binomial b Int -> Int -> Double
    cdf    (Binomial Int
    t b
    p) = Int -> b -> Int -> Double
    forall a b. (Integral a, Real b) => a -> b -> a -> Double
    integralBinomialCDF Int
    t b
    p
    instance (Real b, Distribution (Binomial b) Int)                             => PDF (Binomial b) Int where
        pdf :: Binomial b Int -> Int -> Double
    pdf    (Binomial Int
    t b
    p) = Int -> b -> Int -> Double
    forall a b. (Integral a, Real b) => a -> b -> a -> Double
    integralBinomialPDF Int
    t b
    p
        logPdf :: Binomial b Int -> Int -> Double
    logPdf (Binomial Int
    t b
    p) = Int -> b -> Int -> Double
    forall a b. (Integral a, Real b) => a -> b -> a -> Double
    integralBinomialLogPdf Int
    t b
    p
    instance (Floating b, Ord b, Distribution Beta b, Distribution StdUniform b) => Distribution (Binomial b) Int8 where
        rvarT :: forall (n :: * -> *). Binomial b Int8 -> RVarT n Int8
    rvarT  (Binomial Int8
    t b
    p) = Int8 -> b -> RVarT n Int8
    forall a b (m :: * -> *).
    (Integral a, Floating b, Ord b, Distribution Beta b,
     Distribution StdUniform b) =>
    a -> b -> RVarT m a
    integralBinomial Int8
    t b
    p
    instance (Real b, Distribution (Binomial b) Int8)                            => CDF (Binomial b) Int8 where
        cdf :: Binomial b Int8 -> Int8 -> Double
    cdf    (Binomial Int8
    t b
    p) = Int8 -> b -> Int8 -> Double
    forall a b. (Integral a, Real b) => a -> b -> a -> Double
    integralBinomialCDF Int8
    t b
    p
    instance (Real b, Distribution (Binomial b) Int8)                            => PDF (Binomial b) Int8 where
        pdf :: Binomial b Int8 -> Int8 -> Double
    pdf    (Binomial Int8
    t b
    p) = Int8 -> b -> Int8 -> Double
    forall a b. (Integral a, Real b) => a -> b -> a -> Double
    integralBinomialPDF Int8
    t b
    p
        logPdf :: Binomial b Int8 -> Int8 -> Double
    logPdf (Binomial Int8
    t b
    p) = Int8 -> b -> Int8 -> Double
    forall a b. (Integral a, Real b) => a -> b -> a -> Double
    integralBinomialLogPdf Int8
    t b
    p
    instance (Floating b, Ord b, Distribution Beta b, Distribution StdUniform b) => Distribution (Binomial b) Int16 where
        rvarT :: forall (n :: * -> *). Binomial b Int16 -> RVarT n Int16
    rvarT  (Binomial Int16
    t b
    p) = Int16 -> b -> RVarT n Int16
    forall a b (m :: * -> *).
    (Integral a, Floating b, Ord b, Distribution Beta b,
     Distribution StdUniform b) =>
    a -> b -> RVarT m a
    integralBinomial Int16
    t b
    p
    instance (Real b, Distribution (Binomial b) Int16)                           => CDF (Binomial b) Int16 where
        cdf :: Binomial b Int16 -> Int16 -> Double
    cdf    (Binomial Int16
    t b
    p) = Int16 -> b -> Int16 -> Double
    forall a b. (Integral a, Real b) => a -> b -> a -> Double
    integralBinomialCDF Int16
    t b
    p
    instance (Real b, Distribution (Binomial b) Int16)                           => PDF (Binomial b) Int16 where
        pdf :: Binomial b Int16 -> Int16 -> Double
    pdf    (Binomial Int16
    t b
    p) = Int16 -> b -> Int16 -> Double
    forall a b. (Integral a, Real b) => a -> b -> a -> Double
    integralBinomialPDF Int16
    t b
    p
        logPdf :: Binomial b Int16 -> Int16 -> Double
    logPdf (Binomial Int16
    t b
    p) = Int16 -> b -> Int16 -> Double
    forall a b. (Integral a, Real b) => a -> b -> a -> Double
    integralBinomialLogPdf Int16
    t b
    p
    instance (Floating b, Ord b, Distribution Beta b, Distribution StdUniform b) => Distribution (Binomial b) Int32 where
        rvarT :: forall (n :: * -> *). Binomial b Int32 -> RVarT n Int32
    rvarT  (Binomial Int32
    t b
    p) = Int32 -> b -> RVarT n Int32
    forall a b (m :: * -> *).
    (Integral a, Floating b, Ord b, Distribution Beta b,
     Distribution StdUniform b) =>
    a -> b -> RVarT m a
    integralBinomial Int32
    t b
    p
    instance (Real b, Distribution (Binomial b) Int32)                           => CDF (Binomial b) Int32 where
        cdf :: Binomial b Int32 -> Int32 -> Double
    cdf    (Binomial Int32
    t b
    p) = Int32 -> b -> Int32 -> Double
    forall a b. (Integral a, Real b) => a -> b -> a -> Double
    integralBinomialCDF Int32
    t b
    p
    instance (Real b, Distribution (Binomial b) Int32)                           => PDF (Binomial b) Int32 where
        pdf :: Binomial b Int32 -> Int32 -> Double
    pdf    (Binomial Int32
    t b
    p) = Int32 -> b -> Int32 -> Double
    forall a b. (Integral a, Real b) => a -> b -> a -> Double
    integralBinomialPDF Int32
    t b
    p
        logPdf :: Binomial b Int32 -> Int32 -> Double
    logPdf (Binomial Int32
    t b
    p) = Int32 -> b -> Int32 -> Double
    forall a b. (Integral a, Real b) => a -> b -> a -> Double
    integralBinomialLogPdf Int32
    t b
    p
    instance (Floating b, Ord b, Distribution Beta b, Distribution StdUniform b) => Distribution (Binomial b) Int64 where
        rvarT :: forall (n :: * -> *). Binomial b Int64 -> RVarT n Int64
    rvarT  (Binomial Int64
    t b
    p) = Int64 -> b -> RVarT n Int64
    forall a b (m :: * -> *).
    (Integral a, Floating b, Ord b, Distribution Beta b,
     Distribution StdUniform b) =>
    a -> b -> RVarT m a
    integralBinomial Int64
    t b
    p
    instance (Real b, Distribution (Binomial b) Int64)                           => CDF (Binomial b) Int64 where
        cdf :: Binomial b Int64 -> Int64 -> Double
    cdf    (Binomial Int64
    t b
    p) = Int64 -> b -> Int64 -> Double
    forall a b. (Integral a, Real b) => a -> b -> a -> Double
    integralBinomialCDF Int64
    t b
    p
    instance (Real b, Distribution (Binomial b) Int64)                           => PDF (Binomial b) Int64 where
        pdf :: Binomial b Int64 -> Int64 -> Double
    pdf    (Binomial Int64
    t b
    p) = Int64 -> b -> Int64 -> Double
    forall a b. (Integral a, Real b) => a -> b -> a -> Double
    integralBinomialPDF Int64
    t b
    p
        logPdf :: Binomial b Int64 -> Int64 -> Double
    logPdf (Binomial Int64
    t b
    p) = Int64 -> b -> Int64 -> Double
    forall a b. (Integral a, Real b) => a -> b -> a -> Double
    integralBinomialLogPdf Int64
    t b
    p
    instance (Floating b, Ord b, Distribution Beta b, Distribution StdUniform b) => Distribution (Binomial b) Word where
        rvarT :: forall (n :: * -> *). Binomial b Word -> RVarT n Word
    rvarT  (Binomial Word
    t b
    p) = Word -> b -> RVarT n Word
    forall a b (m :: * -> *).
    (Integral a, Floating b, Ord b, Distribution Beta b,
     Distribution StdUniform b) =>
    a -> b -> RVarT m a
    integralBinomial Word
    t b
    p
    instance (Real b, Distribution (Binomial b) Word)                            => CDF (Binomial b) Word where
        cdf :: Binomial b Word -> Word -> Double
    cdf    (Binomial Word
    t b
    p) = Word -> b -> Word -> Double
    forall a b. (Integral a, Real b) => a -> b -> a -> Double
    integralBinomialCDF Word
    t b
    p
    instance (Real b, Distribution (Binomial b) Word)                            => PDF (Binomial b) Word where
        pdf :: Binomial b Word -> Word -> Double
    pdf    (Binomial Word
    t b
    p) = Word -> b -> Word -> Double
    forall a b. (Integral a, Real b) => a -> b -> a -> Double
    integralBinomialPDF Word
    t b
    p
        logPdf :: Binomial b Word -> Word -> Double
    logPdf (Binomial Word
    t b
    p) = Word -> b -> Word -> Double
    forall a b. (Integral a, Real b) => a -> b -> a -> Double
    integralBinomialLogPdf Word
    t b
    p
    instance (Floating b, Ord b, Distribution Beta b, Distribution StdUniform b) => Distribution (Binomial b) Word8 where
        rvarT :: forall (n :: * -> *). Binomial b Word8 -> RVarT n Word8
    rvarT  (Binomial Word8
    t b
    p) = Word8 -> b -> RVarT n Word8
    forall a b (m :: * -> *).
    (Integral a, Floating b, Ord b, Distribution Beta b,
     Distribution StdUniform b) =>
    a -> b -> RVarT m a
    integralBinomial Word8
    t b
    p
    instance (Real b, Distribution (Binomial b) Word8)                           => CDF (Binomial b) Word8 where
        cdf :: Binomial b Word8 -> Word8 -> Double
    cdf    (Binomial Word8
    t b
    p) = Word8 -> b -> Word8 -> Double
    forall a b. (Integral a, Real b) => a -> b -> a -> Double
    integralBinomialCDF Word8
    t b
    p
    instance (Real b, Distribution (Binomial b) Word8)                           => PDF (Binomial b) Word8 where
        pdf :: Binomial b Word8 -> Word8 -> Double
    pdf    (Binomial Word8
    t b
    p) = Word8 -> b -> Word8 -> Double
    forall a b. (Integral a, Real b) => a -> b -> a -> Double
    integralBinomialPDF Word8
    t b
    p
        logPdf :: Binomial b Word8 -> Word8 -> Double
    logPdf (Binomial Word8
    t b
    p) = Word8 -> b -> Word8 -> Double
    forall a b. (Integral a, Real b) => a -> b -> a -> Double
    integralBinomialLogPdf Word8
    t b
    p
    instance (Floating b, Ord b, Distribution Beta b, Distribution StdUniform b) => Distribution (Binomial b) Word16 where
        rvarT :: forall (n :: * -> *). Binomial b Word16 -> RVarT n Word16
    rvarT  (Binomial Word16
    t b
    p) = Word16 -> b -> RVarT n Word16
    forall a b (m :: * -> *).
    (Integral a, Floating b, Ord b, Distribution Beta b,
     Distribution StdUniform b) =>
    a -> b -> RVarT m a
    integralBinomial Word16
    t b
    p
    instance (Real b, Distribution (Binomial b) Word16)                          => CDF (Binomial b) Word16 where
        cdf :: Binomial b Word16 -> Word16 -> Double
    cdf    (Binomial Word16
    t b
    p) = Word16 -> b -> Word16 -> Double
    forall a b. (Integral a, Real b) => a -> b -> a -> Double
    integralBinomialCDF Word16
    t b
    p
    instance (Real b, Distribution (Binomial b) Word16)                          => PDF (Binomial b) Word16 where
        pdf :: Binomial b Word16 -> Word16 -> Double
    pdf    (Binomial Word16
    t b
    p) = Word16 -> b -> Word16 -> Double
    forall a b. (Integral a, Real b) => a -> b -> a -> Double
    integralBinomialPDF Word16
    t b
    p
        logPdf :: Binomial b Word16 -> Word16 -> Double
    logPdf (Binomial Word16
    t b
    p) = Word16 -> b -> Word16 -> Double
    forall a b. (Integral a, Real b) => a -> b -> a -> Double
    integralBinomialLogPdf Word16
    t b
    p
    instance (Floating b, Ord b, Distribution Beta b, Distribution StdUniform b) => Distribution (Binomial b) Word32 where
        rvarT :: forall (n :: * -> *). Binomial b Word32 -> RVarT n Word32
    rvarT  (Binomial Word32
    t b
    p) = Word32 -> b -> RVarT n Word32
    forall a b (m :: * -> *).
    (Integral a, Floating b, Ord b, Distribution Beta b,
     Distribution StdUniform b) =>
    a -> b -> RVarT m a
    integralBinomial Word32
    t b
    p
    instance (Real b, Distribution (Binomial b) Word32)                          => CDF (Binomial b) Word32 where
        cdf :: Binomial b Word32 -> Word32 -> Double
    cdf    (Binomial Word32
    t b
    p) = Word32 -> b -> Word32 -> Double
    forall a b. (Integral a, Real b) => a -> b -> a -> Double
    integralBinomialCDF Word32
    t b
    p
    instance (Real b, Distribution (Binomial b) Word32)                          => PDF (Binomial b) Word32 where
        pdf :: Binomial b Word32 -> Word32 -> Double
    pdf    (Binomial Word32
    t b
    p) = Word32 -> b -> Word32 -> Double
    forall a b. (Integral a, Real b) => a -> b -> a -> Double
    integralBinomialPDF Word32
    t b
    p
        logPdf :: Binomial b Word32 -> Word32 -> Double
    logPdf (Binomial Word32
    t b
    p) = Word32 -> b -> Word32 -> Double
    forall a b. (Integral a, Real b) => a -> b -> a -> Double
    integralBinomialLogPdf Word32
    t b
    p
    instance (Floating b, Ord b, Distribution Beta b, Distribution StdUniform b) => Distribution (Binomial b) Word64 where
        rvarT :: forall (n :: * -> *). Binomial b Word64 -> RVarT n Word64
    rvarT  (Binomial Word64
    t b
    p) = Word64 -> b -> RVarT n Word64
    forall a b (m :: * -> *).
    (Integral a, Floating b, Ord b, Distribution Beta b,
     Distribution StdUniform b) =>
    a -> b -> RVarT m a
    integralBinomial Word64
    t b
    p
    instance (Real b, Distribution (Binomial b) Word64)                          => CDF (Binomial b) Word64 where
        cdf :: Binomial b Word64 -> Word64 -> Double
    cdf    (Binomial Word64
    t b
    p) = Word64 -> b -> Word64 -> Double
    forall a b. (Integral a, Real b) => a -> b -> a -> Double
    integralBinomialCDF Word64
    t b
    p
    instance (Real b, Distribution (Binomial b) Word64)                          => PDF (Binomial b) Word64 where
        pdf :: Binomial b Word64 -> Word64 -> Double
    pdf    (Binomial Word64
    t b
    p) = Word64 -> b -> Word64 -> Double
    forall a b. (Integral a, Real b) => a -> b -> a -> Double
    integralBinomialPDF Word64
    t b
    p
        logPdf :: Binomial b Word64 -> Word64 -> Double
    logPdf (Binomial Word64
    t b
    p) = Word64 -> b -> Word64 -> Double
    forall a b. (Integral a, Real b) => a -> b -> a -> Double
    integralBinomialLogPdf Word64
    t b
    p

    instance Distribution (Binomial b) Integer => Distribution (Binomial b) Float where
        rvar :: Binomial b Float -> RVar Float
    rvar   (Binomial Float
    t b
    p) = Float -> b -> RVar Float
    forall a b.
    (RealFrac a, Distribution (Binomial b) Integer) =>
    a -> b -> RVar a
    floatingBinomial Float
    t b
    p
    instance CDF (Binomial b) Integer          => CDF (Binomial b) Float where
        cdf :: Binomial b Float -> Float -> Double
    cdf    (Binomial Float
    t b
    p) = Float -> b -> Float -> Double
    forall b a.
    (CDF (Binomial b) Integer, RealFrac a) =>
    a -> b -> a -> Double
    floatingBinomialCDF Float
    t b
    p
    instance PDF (Binomial b) Integer          => PDF (Binomial b) Float where
        pdf :: Binomial b Float -> Float -> Double
    pdf    (Binomial Float
    t b
    p) = Float -> b -> Float -> Double
    forall b a.
    (PDF (Binomial b) Integer, RealFrac a) =>
    a -> b -> a -> Double
    floatingBinomialPDF Float
    t b
    p
        logPdf :: Binomial b Float -> Float -> Double
    logPdf (Binomial Float
    t b
    p) = Float -> b -> Float -> Double
    forall b a.
    (PDF (Binomial b) Integer, RealFrac a) =>
    a -> b -> a -> Double
    floatingBinomialLogPDF Float
    t b
    p
    instance Distribution (Binomial b) Integer => Distribution (Binomial b) Double where
        rvar :: Binomial b Double -> RVar Double
    rvar   (Binomial Double
    t b
    p) = Double -> b -> RVar Double
    forall a b.
    (RealFrac a, Distribution (Binomial b) Integer) =>
    a -> b -> RVar a
    floatingBinomial Double
    t b
    p
    instance CDF (Binomial b) Integer          => CDF (Binomial b) Double where
        cdf :: Binomial b Double -> Double -> Double
    cdf    (Binomial Double
    t b
    p) = Double -> b -> Double -> Double
    forall b a.
    (CDF (Binomial b) Integer, RealFrac a) =>
    a -> b -> a -> Double
    floatingBinomialCDF Double
    t b
    p
    instance PDF (Binomial b) Integer          => PDF (Binomial b) Double where
        pdf :: Binomial b Double -> Double -> Double
    pdf    (Binomial Double
    t b
    p) = Double -> b -> Double -> Double
    forall b a.
    (PDF (Binomial b) Integer, RealFrac a) =>
    a -> b -> a -> Double
    floatingBinomialPDF Double
    t b
    p
        logPdf :: Binomial b Double -> Double -> Double
    logPdf (Binomial Double
    t b
    p) = Double -> b -> Double -> Double
    forall b a.
    (PDF (Binomial b) Integer, RealFrac a) =>
    a -> b -> a -> Double
    floatingBinomialLogPDF Double
    t b
    p