module Statistics.Center where
import qualified Data.Sort as S
import qualified Data.Vector.Generic as VG
import qualified Data.Vector.Algorithms.Intro as VGAI
arithmeticMean :: (Foldable t, Fractional a) => t a -> a
arithmeticMean vals = (sum vals) / (fromIntegral $ length vals)
geometricMean :: (Foldable t, Floating a) => t a -> a
geometricMean vals = (product vals) ** (1/(fromIntegral $ length vals))
harmonicMean :: (Foldable t, Functor t, Fractional a) => t a -> a
harmonicMean vals = (sum $ fmap (1/) vals) / (fromIntegral $ length vals)
medianList :: (Fractional a, Ord a) => [a] -> a
medianList = medianListSorted . S.sort
medianVector
:: (VG.Vector vector a, Foldable vector, Fractional a, Ord a)
=> vector a -> a
medianVector = medianVectorSorted . VG.modify VGAI.sort
medianListSorted :: Fractional a => [a] -> a
medianListSorted vals
| odd n = vals !! mid
| otherwise = arithmeticMean $ take 2 $ drop (mid - 1) vals
where
n = length vals
mid = n `div` 2
medianVectorSorted
:: (VG.Vector vector a, Foldable vector, Fractional a)
=> vector a -> a
medianVectorSorted vals
| odd n = vals VG.! mid
| otherwise = arithmeticMean $ VG.take 2 $ VG.drop (mid - 1) vals
where
n = length vals
mid = n `div` 2