module Statistics.RankProduct
( rankList
, rankProduct
, prerankProduct
, rankProductPermutation
) where
import Data.Function (on)
import Data.List
import Data.Random
import Statistics.Types
rankList :: (Ord a) => [a] -> [Int]
rankList = fmap fst
. sortBy (compare `on` (fst . snd))
. zip [1..]
. sortBy (compare `on` snd)
. zip [1..]
rankProduct :: [Entity] -> [RankProductEntity]
rankProduct xs =
fmap (RankProductEntity . (** (1 / genericLength xs)) . fromIntegral . product)
. transpose
. fmap rankList
. transpose
. fmap unEntity
$ xs
prerankProduct :: [RankEntity] -> [RankProductEntity]
prerankProduct xs =
fmap
( RankProductEntity
. (** (1 / genericLength xs))
. fromIntegral
. product
. unRankEntity
)
xs
permuteEntities :: [RankEntity] -> IO [RankEntity]
permuteEntities = fmap (fmap RankEntity . transpose)
. mapM (sample . shuffle)
. transpose
. fmap unRankEntity
boolToNum :: (Num a) => Bool -> a
boolToNum False = 0
boolToNum True = 1
rankProductPermutation :: Permutations
-> [Entity]
-> IO [(RankProductEntity, PValue)]
rankProductPermutation (Permutations permutations) entities = do
let ranked = fmap RankEntity
. transpose
. fmap rankList
. transpose
. fmap unEntity
$ entities
obs = prerankProduct ranked
expTest (RankProductEntity o) = (<= o) . unRankProductEntity
let successes :: [Int] -> Int -> IO [Int]
successes !acc 0 = return acc
successes !acc !n = do
shuffledEntities <- permuteEntities ranked
let res = prerankProduct shuffledEntities
success = zipWith (\o -> boolToNum . expTest o) obs res
successes (zipWith (+) acc success) (n 1)
exp <- successes (take (genericLength entities) [0,0..]) permutations
let pVals =
fmap (\e -> PValue $ (fromIntegral e) / (fromIntegral permutations)) exp
return . zip obs $ pVals