module Statistics.Test.MannWhitneyU (
mannWhitneyUtest
, mannWhitneyU
, mannWhitneyUCriticalValue
, mannWhitneyUSignificant
, wilcoxonRankSums
, module Statistics.Test.Types
) where
import Data.List (findIndex)
import Data.Ord (comparing)
import Numeric.SpecFunctions (choose)
import Prelude hiding (sum)
import Statistics.Distribution (quantile)
import Statistics.Distribution.Normal (standard)
import Statistics.Function (sortBy)
import Statistics.Sample.Internal (sum)
import Statistics.Test.Internal (rank, splitByTags)
import Statistics.Test.Types (TestResult(..), PositionTest(..), significant)
import Statistics.Types (PValue,pValue)
import qualified Data.Vector.Unboxed as U
wilcoxonRankSums :: (Ord a, U.Unbox a) => U.Vector a -> U.Vector a -> (Double, Double)
wilcoxonRankSums :: forall a.
(Ord a, Unbox a) =>
Vector a -> Vector a -> (Double, Double)
wilcoxonRankSums Vector a
xs1 Vector a
xs2 = (forall (v :: * -> *). Vector v Double => v Double -> Double
sum Vector Double
ranks1, forall (v :: * -> *). Vector v Double => v Double -> Double
sum Vector Double
ranks2)
where
(Vector Double
ranks1,Vector Double
ranks2) = forall (v :: * -> *) a.
(Vector v a, Vector v (Bool, a)) =>
v (Bool, a) -> (v a, v a)
splitByTags forall a b. (a -> b) -> a -> b
$ forall a b.
(Unbox a, Unbox b) =>
Vector a -> Vector b -> Vector (a, b)
U.zip Vector Bool
tags (forall (v :: * -> *) a.
(Vector v a, Vector v Double) =>
(a -> a -> Bool) -> v a -> v Double
rank forall a. Eq a => a -> a -> Bool
(==) Vector a
joinSample)
(Vector Bool
tags,Vector a
joinSample) = forall a b.
(Unbox a, Unbox b) =>
Vector (a, b) -> (Vector a, Vector b)
U.unzip
forall a b. (a -> b) -> a -> b
$ forall (v :: * -> *) e. Vector v e => Comparison e -> v e -> v e
sortBy (forall a b. Ord a => (b -> a) -> b -> b -> Ordering
comparing forall a b. (a, b) -> b
snd)
forall a b. (a -> b) -> a -> b
$ forall {b} {a}.
(Unbox b, Unbox a) =>
a -> Vector b -> Vector (a, b)
tagSample Bool
True Vector a
xs1 forall a. Unbox a => Vector a -> Vector a -> Vector a
U.++ forall {b} {a}.
(Unbox b, Unbox a) =>
a -> Vector b -> Vector (a, b)
tagSample Bool
False Vector a
xs2
tagSample :: a -> Vector b -> Vector (a, b)
tagSample a
t = forall a b. (Unbox a, Unbox b) => (a -> b) -> Vector a -> Vector b
U.map (\b
x -> (a
t,b
x))
mannWhitneyU :: (Ord a, U.Unbox a) => U.Vector a -> U.Vector a -> (Double, Double)
mannWhitneyU :: forall a.
(Ord a, Unbox a) =>
Vector a -> Vector a -> (Double, Double)
mannWhitneyU Vector a
xs1 Vector a
xs2
= (forall a b. (a, b) -> a
fst (Double, Double)
summedRanks forall a. Num a => a -> a -> a
- (Double
n1forall a. Num a => a -> a -> a
*(Double
n1 forall a. Num a => a -> a -> a
+ Double
1))forall a. Fractional a => a -> a -> a
/Double
2
,forall a b. (a, b) -> b
snd (Double, Double)
summedRanks forall a. Num a => a -> a -> a
- (Double
n2forall a. Num a => a -> a -> a
*(Double
n2 forall a. Num a => a -> a -> a
+ Double
1))forall a. Fractional a => a -> a -> a
/Double
2)
where
n1 :: Double
n1 = forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ forall a. Unbox a => Vector a -> Int
U.length Vector a
xs1
n2 :: Double
n2 = forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ forall a. Unbox a => Vector a -> Int
U.length Vector a
xs2
summedRanks :: (Double, Double)
summedRanks = forall a.
(Ord a, Unbox a) =>
Vector a -> Vector a -> (Double, Double)
wilcoxonRankSums Vector a
xs1 Vector a
xs2
mannWhitneyUCriticalValue
:: (Int, Int)
-> PValue Double
-> Maybe Int
mannWhitneyUCriticalValue :: (Int, Int) -> PValue Double -> Maybe Int
mannWhitneyUCriticalValue (Int
m, Int
n) PValue Double
p
| Int
m forall a. Ord a => a -> a -> Bool
< Int
1 Bool -> Bool -> Bool
|| Int
n forall a. Ord a => a -> a -> Bool
< Int
1 = forall a. Maybe a
Nothing
| Double
p' forall a. Ord a => a -> a -> Bool
<= Double
1 = forall a. Maybe a
Nothing
| Bool
otherwise = forall a. (a -> Bool) -> [a] -> Maybe Int
findIndex (forall a. Ord a => a -> a -> Bool
>= Double
p')
forall a b. (a -> b) -> a -> b
$ forall a. Int -> [a] -> [a]
take (Int
mforall a. Num a => a -> a -> a
*Int
n)
forall a b. (a -> b) -> a -> b
$ forall a. [a] -> [a]
tail
forall a b. (a -> b) -> a -> b
$ [[[Double]]]
alookup forall a. [a] -> Int -> a
!! (Int
mforall a. Num a => a -> a -> a
+Int
nforall a. Num a => a -> a -> a
-Int
2) forall a. [a] -> Int -> a
!! (forall a. Ord a => a -> a -> a
min Int
m Int
n forall a. Num a => a -> a -> a
- Int
1)
where
mnCn :: Double
mnCn = (Int
mforall a. Num a => a -> a -> a
+Int
n) Int -> Int -> Double
`choose` Int
n
p' :: Double
p' = Double
mnCn forall a. Num a => a -> a -> a
* forall a. PValue a -> a
pValue PValue Double
p
alookup :: [[[Double]]]
alookup :: [[[Double]]]
alookup = Int -> [[Double]] -> [[[Double]]]
gen Int
2 [Double
1 forall a. a -> [a] -> [a]
: forall a. a -> [a]
repeat Double
2]
where
gen :: Int -> [[Double]] -> [[[Double]]]
gen Int
bigN [[Double]]
predBigNList
= let bigNlist :: [[Double]]
bigNlist = [ [ Int -> Int -> Double
amemoed Int
u Int
m
| Int
u <- [Int
0 .. Int
mforall a. Num a => a -> a -> a
*(Int
bigNforall a. Num a => a -> a -> a
-Int
m)]
] forall a. [a] -> [a] -> [a]
++ forall a. a -> [a]
repeat (Int
bigN Int -> Int -> Double
`choose` Int
m)
| Int
m <- [Int
1 .. (Int
bigNforall a. Num a => a -> a -> a
-Int
1)]]
in [[Double]]
bigNlist forall a. a -> [a] -> [a]
: Int -> [[Double]] -> [[[Double]]]
gen (Int
bigNforall a. Num a => a -> a -> a
+Int
1) [[Double]]
bigNlist
where
amemoed :: Int -> Int -> Double
amemoed :: Int -> Int -> Double
amemoed Int
u Int
m
| Int
m forall a. Eq a => a -> a -> Bool
== Int
1 Bool -> Bool -> Bool
|| Int
n forall a. Eq a => a -> a -> Bool
== Int
1 = forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int
u forall a. Num a => a -> a -> a
+ Int
1)
| Bool
otherwise = [Double]
mList forall a. [a] -> Int -> a
!! Int
u
forall a. Num a => a -> a -> a
+ if Int
u forall a. Ord a => a -> a -> Bool
< Int
n then Double
0 else [Double]
predmList forall a. [a] -> Int -> a
!! (Int
uforall a. Num a => a -> a -> a
-Int
n)
where
n :: Int
n = Int
bigN forall a. Num a => a -> a -> a
- Int
m
([Double]
predmList : [Double]
mList : [[Double]]
_) = forall a. Int -> [a] -> [a]
drop (Int
mforall a. Num a => a -> a -> a
-Int
2) [[Double]]
predBigNList
mannWhitneyUSignificant
:: PositionTest
-> (Int, Int)
-> PValue Double
-> (Double, Double)
-> Maybe TestResult
mannWhitneyUSignificant :: PositionTest
-> (Int, Int)
-> PValue Double
-> (Double, Double)
-> Maybe TestResult
mannWhitneyUSignificant PositionTest
test (Int
in1, Int
in2) PValue Double
pVal (Double
u1, Double
u2)
| Int
in1 forall a. Ord a => a -> a -> Bool
> Int
20 Bool -> Bool -> Bool
|| Int
in2 forall a. Ord a => a -> a -> Bool
> Int
20 =
let mean :: Double
mean = Double
n1 forall a. Num a => a -> a -> a
* Double
n2 forall a. Fractional a => a -> a -> a
/ Double
2
sigma :: Double
sigma = forall a. Floating a => a -> a
sqrt forall a b. (a -> b) -> a -> b
$ Double
n1forall a. Num a => a -> a -> a
*Double
n2forall a. Num a => a -> a -> a
*(Double
n1 forall a. Num a => a -> a -> a
+ Double
n2 forall a. Num a => a -> a -> a
+ Double
1) forall a. Fractional a => a -> a -> a
/ Double
12
z :: Double
z = (Double
mean forall a. Num a => a -> a -> a
- Double
u1) forall a. Fractional a => a -> a -> a
/ Double
sigma
in forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ case PositionTest
test of
PositionTest
AGreater -> Bool -> TestResult
significant forall a b. (a -> b) -> a -> b
$ Double
z forall a. Ord a => a -> a -> Bool
< forall d. ContDistr d => d -> Double -> Double
quantile NormalDistribution
standard Double
p
PositionTest
BGreater -> Bool -> TestResult
significant forall a b. (a -> b) -> a -> b
$ (-Double
z) forall a. Ord a => a -> a -> Bool
< forall d. ContDistr d => d -> Double -> Double
quantile NormalDistribution
standard Double
p
PositionTest
SamplesDiffer -> Bool -> TestResult
significant forall a b. (a -> b) -> a -> b
$ forall a. Num a => a -> a
abs Double
z forall a. Ord a => a -> a -> Bool
> forall a. Num a => a -> a
abs (forall d. ContDistr d => d -> Double -> Double
quantile NormalDistribution
standard (Double
pforall a. Fractional a => a -> a -> a
/Double
2))
| Bool
otherwise = do Double
crit <- forall a b. (Integral a, Num b) => a -> b
fromIntegral forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Int, Int) -> PValue Double -> Maybe Int
mannWhitneyUCriticalValue (Int
in1, Int
in2) PValue Double
pVal
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ case PositionTest
test of
PositionTest
AGreater -> Bool -> TestResult
significant forall a b. (a -> b) -> a -> b
$ Double
u2 forall a. Ord a => a -> a -> Bool
<= Double
crit
PositionTest
BGreater -> Bool -> TestResult
significant forall a b. (a -> b) -> a -> b
$ Double
u1 forall a. Ord a => a -> a -> Bool
<= Double
crit
PositionTest
SamplesDiffer -> Bool -> TestResult
significant forall a b. (a -> b) -> a -> b
$ forall a. Ord a => a -> a -> a
min Double
u1 Double
u2 forall a. Ord a => a -> a -> Bool
<= Double
crit
where
n1 :: Double
n1 = forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
in1
n2 :: Double
n2 = forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
in2
p :: Double
p = forall a. PValue a -> a
pValue PValue Double
pVal
mannWhitneyUtest
:: (Ord a, U.Unbox a)
=> PositionTest
-> PValue Double
-> U.Vector a
-> U.Vector a
-> Maybe TestResult
mannWhitneyUtest :: forall a.
(Ord a, Unbox a) =>
PositionTest
-> PValue Double -> Vector a -> Vector a -> Maybe TestResult
mannWhitneyUtest PositionTest
ontTail PValue Double
p Vector a
smp1 Vector a
smp2 =
PositionTest
-> (Int, Int)
-> PValue Double
-> (Double, Double)
-> Maybe TestResult
mannWhitneyUSignificant PositionTest
ontTail (Int
n1,Int
n2) PValue Double
p forall a b. (a -> b) -> a -> b
$ forall a.
(Ord a, Unbox a) =>
Vector a -> Vector a -> (Double, Double)
mannWhitneyU Vector a
smp1 Vector a
smp2
where
n1 :: Int
n1 = forall a. Unbox a => Vector a -> Int
U.length Vector a
smp1
n2 :: Int
n2 = forall a. Unbox a => Vector a -> Int
U.length Vector a
smp2