module Math.Statistics
( mean
, median
, stddev
, variance
) where
import Data.List (sort)
mean :: Floating a => [a] -> a
mean = go 0 0
where
go :: Floating a => a -> Int -> [a] -> a
go m _ [] = m
go m n (x:xs) = go (m + (x - m) / fromIntegral (n + 1)) (n + 1) xs
median :: (Floating a, Ord a) => [a] -> a
median xs
| odd n = head $ drop (n `div` 2) xs'
| otherwise = mean $ take 2 $ drop i xs'
where
i = (length xs' `div` 2) - 1
xs' = sort xs
n = length xs
stddev :: Floating a => [a] -> a
stddev xs = sqrt $ variance xs
variance :: Floating a => [a] -> a
variance xs = go 0 0 0 xs / fromIntegral (length xs - 1)
where
go :: Floating a => a -> Int -> a -> [a] -> a
go _ _ s [] = s
go m n s (x:xs') = go nm (n + 1) (s + delta * (x - nm)) xs'
where
delta = x - m
nm = m + delta / fromIntegral (n + 1)