1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
|
{-# LANGUAGE FlexibleContexts #-}
-- | Pearson's chi squared test.
module Statistics.Test.ChiSquared (
chi2test
, chi2testCont
, module Statistics.Test.Types
) where
import Prelude hiding (sum)
import Statistics.Distribution
import Statistics.Distribution.ChiSquared
import Statistics.Function (square)
import Statistics.Sample.Internal (sum)
import Statistics.Test.Types
import Statistics.Types
import qualified Data.Vector as V
import qualified Data.Vector.Generic as G
import qualified Data.Vector.Unboxed as U
-- | Generic form of Pearson chi squared tests for binned data. Data
-- sample is supplied in form of tuples (observed quantity,
-- expected number of events). Both must be positive.
--
-- This test should be used only if all bins have expected values of
-- at least 5.
chi2test :: (G.Vector v (Int,Double), G.Vector v Double)
=> Int -- ^ Number of additional degrees of
-- freedom. One degree of freedom
-- is due to the fact that the are
-- N observation in total and
-- accounted for automatically.
-> v (Int,Double) -- ^ Observation and expectation.
-> Maybe (Test ChiSquared)
chi2test ndf vec
| ndf < 0 = error $ "Statistics.Test.ChiSquare.chi2test: negative NDF " ++ show ndf
| n > 0 = Just Test
{ testSignificance = mkPValue $ complCumulative d chi2
, testStatistics = chi2
, testDistribution = chiSquared n
}
| otherwise = Nothing
where
n = G.length vec - ndf - 1
chi2 = sum $ G.map (\(o,e) -> square (fromIntegral o - e) / e) vec
d = chiSquared n
{-# INLINABLE chi2test #-}
{-# SPECIALIZE
chi2test :: Int -> U.Vector (Int,Double) -> Maybe (Test ChiSquared) #-}
{-# SPECIALIZE
chi2test :: Int -> V.Vector (Int,Double) -> Maybe (Test ChiSquared) #-}
-- | Chi squared test for data with normal errors. Data is supplied in
-- form of pair (observation with error, and expectation).
chi2testCont
:: (G.Vector v (Estimate NormalErr Double, Double), G.Vector v Double)
=> Int -- ^ Number of additional
-- degrees of freedom.
-> v (Estimate NormalErr Double, Double) -- ^ Observation and expectation.
-> Maybe (Test ChiSquared)
chi2testCont ndf vec
| ndf < 0 = error $ "Statistics.Test.ChiSquare.chi2testCont: negative NDF " ++ show ndf
| n > 0 = Just Test
{ testSignificance = mkPValue $ complCumulative d chi2
, testStatistics = chi2
, testDistribution = chiSquared n
}
| otherwise = Nothing
where
n = G.length vec - ndf - 1
chi2 = sum $ G.map (\(Estimate o (NormalErr s),e) -> square (o - e) / s) vec
d = chiSquared n
|