{-# 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 :: 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 :: 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

                b
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 b
x b -> b -> Bool
forall a. Ord a => a -> a -> Bool
>= b
p
                    then 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
k      (a
a a -> a -> a
forall a. Num a => a -> a -> a
- a
1) (b
p b -> b -> b
forall a. Fractional a => a -> a -> a
/ b
x)
                    else 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
k a -> a -> a
forall a. Num a => a -> a -> a
+ a
a) (a
b a -> a -> a
forall a. Num a => a -> a -> a
- a
1) ((b
p b -> b -> b
forall a. Num a => a -> a -> a
- b
x) b -> b -> b
forall a. Fractional a => a -> a -> a
/ (b
1 b -> b -> b
forall a. Num a => a -> a -> a
- b
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 (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
                        b
x <- RVarT m b
forall a (m :: * -> *). Distribution StdUniform a => RVarT m a
stdUniformT
                        t -> t -> RVarT m t
count (if b
x b -> b -> Bool
forall a. Ord a => a -> a -> Bool
< b
p then t
k' t -> t -> t
forall a. Num a => a -> a -> a
+ t
1 else t
k') (t
nt -> t -> t
forall a. Num a => a -> a -> a
-t
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 :: a -> b -> a -> Double
integralBinomialCDF a
t b
p a
x = [Double] -> Double
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 :: 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 :: 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 :: a -> b -> RVar a
floatingBinomial a
t b
p = (Integer -> a) -> RVarT Identity Integer -> RVar a
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 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 :: 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 a b. (RealFrac a, Integral b) => a -> b
truncate a
t :: Integer) b
p) (a -> Integer
forall a b. (RealFrac a, Integral b) => a -> b
floor a
x)

floatingBinomialPDF :: (PDF (Binomial b) Integer, RealFrac a) => a -> b -> a -> Double
floatingBinomialPDF :: 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 a b. (RealFrac a, Integral b) => a -> b
truncate a
t :: Integer) b
p) (a -> Integer
forall a b. (RealFrac a, Integral b) => a -> b
floor a
x)

floatingBinomialLogPDF :: (PDF (Binomial b) Integer, RealFrac a) => a -> b -> a -> Double
floatingBinomialLogPDF :: 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 a b. (RealFrac a, Integral b) => a -> b
truncate a
t :: Integer) b
p) (a -> Integer
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 :: 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 :: a -> b -> RVarT m a
binomialT a
t b
p = Binomial b a -> RVarT m 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 :: 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 :: 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 :: 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 :: 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 :: 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 :: 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 :: 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 :: 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 :: 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 :: 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 :: 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