# bos/statistics

Rewrote generalized t in terms of linear transformer over distributions.

`Made @Shimuuar's suggested changes.`
1 parent aee10c9 commit 90185e2afc0f2f900040233589af6bda0fba6b8b johnmcdonnell committed with Shimuuar Mar 14, 2013
Showing with 88 additions and 3 deletions.
1. +10 −3 Statistics/Distribution/StudentT.hs
2. +52 −0 Statistics/Distribution/Transform.hs
3. +1 −0 statistics.cabal
4. +25 −0 tests/Tests/Distribution.hs
13 Statistics/Distribution/StudentT.hs
 @@ -13,19 +13,19 @@ module Statistics.Distribution.StudentT ( StudentT , studentT , studentTndf + , studentTUnstandardized ) where + import qualified Statistics.Distribution as D +import Statistics.Distribution.Transform (LinearTransform (..)) import Data.Typeable (Typeable) import Numeric.SpecFunctions (logBeta, incompleteBeta, invIncompleteBeta) - - -- | Student-T distribution newtype StudentT = StudentT { studentTndf :: Double } deriving (Eq,Show,Read,Typeable) - -- | Create Student-T distribution. Number of parameters must be positive. studentT :: Double -> StudentT studentT ndf @@ -72,3 +72,10 @@ instance D.MaybeVariance StudentT where instance D.ContGen StudentT where genContVar = D.genContinous + +-- | Create an unstandardized Student-t distribution +studentTUnstandardized :: Double -> Double -> Double -> LinearTransform StudentT +studentTUnstandardized ndf mu sigma + | sigma <= 0 = error \$ "Statistics.Distribution.StudentT.studentTGeneral: sigma must be > 0. Got: " ++ (show sigma) + | otherwise = LinearTransform mu sigma (StudentT ndf) +
52 Statistics/Distribution/Transform.hs
 @@ -0,0 +1,52 @@ +{-# LANGUAGE FlexibleInstances, UndecidableInstances, FlexibleContexts, DeriveDataTypeable #-} +-- | +-- Module : Statistics.Distribution.Transform +-- Copyright : (c) 2013 John McDonnell; +-- License : BSD3 +-- +-- Maintainer : bos@serpentine.com +-- Stability : experimental +-- Portability : portable +-- +-- Transformations over distributions + +module Statistics.Distribution.Transform ( + LinearTransform (..) + ) where + +import qualified Statistics.Distribution as D +import Data.Typeable (Typeable) + +data LinearTransform d = LinearTransform + { location :: {-# UNPACK #-} !Double + , scale :: {-# UNPACK #-} !Double + , distr :: d + } deriving (Eq,Show,Read,Typeable) + +instance Functor LinearTransform where + fmap f (LinearTransform loc sc dist) = LinearTransform loc sc (f dist) + +instance D.Distribution d => D.Distribution (LinearTransform d) where + cumulative (LinearTransform loc sc dist) x = D.cumulative dist ((x-loc)/sc) + +instance D.ContDistr d => D.ContDistr (LinearTransform d) where + density (LinearTransform loc sc dist) x = (/sc) \$ D.density dist ((x-loc)/sc) + quantile (LinearTransform loc sc dist) p = loc + sc * D.quantile dist p + +instance D.MaybeMean d => D.MaybeMean (LinearTransform d) where + maybeMean (LinearTransform loc _ dist) = fmap (+loc) (D.maybeMean dist) + +instance (D.Mean d) => D.Mean (LinearTransform d) where + mean (LinearTransform loc _ dist) = loc + (D.mean dist) + +instance D.MaybeVariance d => D.MaybeVariance (LinearTransform d) where + maybeVariance (LinearTransform _ sc dist) = fmap ((*sc).(*sc)) (D.maybeVariance dist) + maybeStdDev (LinearTransform _ sc dist) = fmap (*sc) (D.maybeStdDev dist) + +instance (D.Variance d) => D.Variance (LinearTransform d) where + variance (LinearTransform _ sc dist) = sc * sc * (D.variance dist) + stdDev (LinearTransform _ sc dist) = sc * (D.stdDev dist) + +instance D.ContDistr d => D.ContGen (LinearTransform d) where + genContVar = D.genContinous +
1 statistics.cabal
 @@ -171,6 +171,7 @@ library Statistics.Distribution.Normal Statistics.Distribution.Poisson Statistics.Distribution.StudentT + Statistics.Distribution.Transform Statistics.Distribution.Uniform Statistics.Function Statistics.Math
25 tests/Tests/Distribution.hs
 @@ -35,6 +35,7 @@ import Statistics.Distribution.Hypergeometric import Statistics.Distribution.Normal import Statistics.Distribution.Poisson import Statistics.Distribution.StudentT +import Statistics.Distribution.Transform import Statistics.Distribution.Uniform import Prelude hiding (catch) @@ -53,6 +54,7 @@ distributionTests = testGroup "Tests for all distributions" , contDistrTests (T :: T NormalDistribution ) , contDistrTests (T :: T UniformDistribution ) , contDistrTests (T :: T StudentT ) + , contDistrTests (T :: T (LinearTransform StudentT) ) , contDistrTests (T :: T FDistribution ) , discreteDistrTests (T :: T BinomialDistribution ) @@ -249,6 +251,11 @@ instance QC.Arbitrary CauchyDistribution where <*> ((abs <\$> arbitrary) `suchThat` (> 0)) instance QC.Arbitrary StudentT where arbitrary = studentT <\$> ((abs <\$> arbitrary) `suchThat` (>0)) +instance QC.Arbitrary (LinearTransform StudentT) where + arbitrary = studentTUnstandardized + <\$> ((abs <\$> arbitrary) `suchThat` (>0)) + <*> ((abs <\$> arbitrary)) + <*> ((abs <\$> arbitrary) `suchThat` (>0)) instance QC.Arbitrary FDistribution where arbitrary = fDistribution <\$> ((abs <\$> arbitrary) `suchThat` (>0)) @@ -273,6 +280,10 @@ instance Param StudentT where invQuantilePrec _ = 1e-13 okForInfLimit d = studentTndf d > 0.75 +instance Param (LinearTransform StudentT) where + invQuantilePrec _ = 1e-13 + okForInfLimit d = (studentTndf . distr) d > 0.75 + instance Param FDistribution where invQuantilePrec _ = 1e-12 @@ -293,6 +304,13 @@ unitTests = testGroup "Unit tests" , testStudentCDF 0.3 3.34 0.757146 -- CDF , testStudentCDF 1 0.42 0.626569 , testStudentCDF 4.4 0.33 0.621739 + -- Student-T General + , testStudentUnstandardizedPDF 0.3 1.2 4 0.45 0.0533456 -- PDF + , testStudentUnstandardizedPDF 4.3 (-2.4) 3.22 (-0.6) 0.0971141 + , testStudentUnstandardizedPDF 3.8 0.22 7.62 0.14 0.0490523 + , testStudentUnstandardizedCDF 0.3 1.2 4 0.45 0.458035 -- CDF + , testStudentUnstandardizedCDF 4.3 (-2.4) 3.22 (-0.6) 0.698001 + , testStudentUnstandardizedCDF 3.8 0.22 7.62 0.14 0.496076 -- F-distribution , testFdistrPDF 1 3 3 (1/(6 * pi)) -- PDF , testFdistrPDF 2 2 1.2 0.206612 @@ -309,6 +327,13 @@ unitTests = testGroup "Unit tests" testStudentCDF ndf x exact = testAssertion (printf "cumulative (studentT %f) %f ~ %f" ndf x exact) \$ eq 1e-5 exact (cumulative (studentT ndf) x) + -- Student-T General + testStudentUnstandardizedPDF ndf mu sigma x exact + = testAssertion (printf "density (studentTUnstandardized %f %f %f) %f ~ %f" ndf mu sigma x exact) + \$ eq 1e-5 exact (density (studentTUnstandardized ndf mu sigma) x) + testStudentUnstandardizedCDF ndf mu sigma x exact + = testAssertion (printf "cumulative (studentTUnstandardized %f %f %f) %f ~ %f" ndf mu sigma x exact) + \$ eq 1e-5 exact (cumulative (studentTUnstandardized ndf mu sigma) x) -- F-distribution testFdistrPDF n m x exact = testAssertion (printf "density (fDistribution %i %i) %f ~ %f [got %f]" n m x exact d)