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

    {-# OPTIONS_GHC -Wall                      #-}
    {-# OPTIONS_GHC -fno-warn-name-shadowing   #-}
    {-# OPTIONS_GHC -fno-warn-type-defaults    #-}
    {-# OPTIONS_GHC -fno-warn-unused-do-bind   #-}
    {-# OPTIONS_GHC -fno-warn-missing-methods  #-}
    {-# OPTIONS_GHC -fno-warn-orphans          #-}

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

    module Data.Random.Distribution.T where

    import Data.RVar
    import Data.Random.Distribution
    import Data.Random.Distribution.ChiSquare
    import Data.Random.Distribution.Normal

    import Numeric.SpecFunctions

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

    tT :: Distribution T a => Integer -> RVarT m a
    tT :: forall a (m :: * -> *). Distribution T a => Integer -> RVarT m a
    tT = T a -> RVarT m a
    forall (n :: * -> *). T a -> RVarT n a
    forall (d :: * -> *) t (n :: * -> *).
    Distribution d t =>
    d t -> RVarT n t
    rvarT (T a -> RVarT m a) -> (Integer -> T a) -> Integer -> RVarT m a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Integer -> T a
    forall a. Integer -> T a
    T

    newtype T a = T Integer
        deriving (T a -> T a -> Bool
    (T a -> T a -> Bool) -> (T a -> T a -> Bool) -> Eq (T a)
    forall a. T a -> T a -> Bool
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: forall a. T a -> T a -> Bool
    == :: T a -> T a -> Bool
    $c/= :: forall a. T a -> T a -> Bool
    /= :: T a -> T a -> Bool
    Eq, Eq (T a)
    Eq (T a) =>
    (T a -> T a -> Ordering)
    -> (T a -> T a -> Bool)
    -> (T a -> T a -> Bool)
    -> (T a -> T a -> Bool)
    -> (T a -> T a -> Bool)
    -> (T a -> T a -> T a)
    -> (T a -> T a -> T a)
    -> Ord (T a)
    T a -> T a -> Bool
    T a -> T a -> Ordering
    T a -> T a -> T a
    forall a. Eq (T a)
    forall a.
    Eq a =>
    (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    forall a. T a -> T a -> Bool
    forall a. T a -> T a -> Ordering
    forall a. T a -> T a -> T a
    $ccompare :: forall a. T a -> T a -> Ordering
    compare :: T a -> T a -> Ordering
    $c< :: forall a. T a -> T a -> Bool
    < :: T a -> T a -> Bool
    $c<= :: forall a. T a -> T a -> Bool
    <= :: T a -> T a -> Bool
    $c> :: forall a. T a -> T a -> Bool
    > :: T a -> T a -> Bool
    $c>= :: forall a. T a -> T a -> Bool
    >= :: T a -> T a -> Bool
    $cmax :: forall a. T a -> T a -> T a
    max :: T a -> T a -> T a
    $cmin :: forall a. T a -> T a -> T a
    min :: T a -> T a -> T a
    Ord, Int -> T a -> ShowS
    [T a] -> ShowS
    T a -> String
    (Int -> T a -> ShowS)
    -> (T a -> String) -> ([T a] -> ShowS) -> Show (T a)
    forall a. Int -> T a -> ShowS
    forall a. [T a] -> ShowS
    forall a. T a -> String
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: forall a. Int -> T a -> ShowS
    showsPrec :: Int -> T a -> ShowS
    $cshow :: forall a. T a -> String
    show :: T a -> String
    $cshowList :: forall a. [T a] -> ShowS
    showList :: [T a] -> ShowS
    Show)

    instance (Floating a, Distribution Normal a, Distribution ChiSquare a) => Distribution T a where
        rvarT :: forall (n :: * -> *). T a -> RVarT n a
    rvarT (T Integer
    n)
            | Integer
    n Integer -> Integer -> Bool
    forall a. Ord a => a -> a -> Bool
    > Integer
    0     = do
                x <- RVarT n a
    forall a (m :: * -> *). Distribution Normal a => RVarT m a
    stdNormalT
                y <- chiSquareT n
                return (x * sqrt (fromInteger n / y))
            | Bool
    otherwise = String -> RVarT n a
    forall a. HasCallStack => String -> a
    error String
    "Student's t-distribution: degrees of freedom must be positive"

    instance (Real a, Distribution T a) => CDF T a where
        cdf :: T a -> a -> Double
    cdf (T Integer
    n) a
    t = Double -> Double -> Double -> Double
    incompleteBeta Double
    v2 Double
    v2 Double
    x
            where
                v :: Double
    v = Integer -> Double
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Integer
    n
                v2 :: Double
    v2 = Double
    0.5 Double -> Double -> Double
    forall a. Num a => a -> a -> a
    * Double
    v
                tD :: Double
    tD = a -> Double
    forall a b. (Real a, Fractional b) => a -> b
    realToFrac a
    t
                u :: Double
    u = Double -> Double
    forall a. Floating a => a -> a
    sqrt (Double
    tDDouble -> Double -> Double
    forall a. Num a => a -> a -> a
    *Double
    tD Double -> Double -> Double
    forall a. Num a => a -> a -> a
    + Double
    v)
                x :: Double
    x = (Double
    tD Double -> Double -> Double
    forall a. Num a => a -> a -> a
    + Double
    u) Double -> Double -> Double
    forall a. Fractional a => a -> a -> a
    / (Double
    u Double -> Double -> Double
    forall a. Num a => a -> a -> a
    + Double
    u)