{-# LANGUAGE BangPatterns #-}
module Moo.GeneticAlgorithm.Statistics
( average
, variance
, quantiles
, median
, iqr
) where
import Data.List (sort, foldl')
average :: (Num a, Fractional a) => [a] -> a
average :: [a] -> a
average = (a -> a -> a) -> (a, a) -> a
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry a -> a -> a
forall a. Fractional a => a -> a -> a
(/) ((a, a) -> a) -> ([a] -> (a, a)) -> [a] -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((a, a) -> a -> (a, a)) -> (a, a) -> [a] -> (a, a)
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (\(!a
s, !a
c) a
x -> (a
sa -> a -> a
forall a. Num a => a -> a -> a
+a
x, a
ca -> a -> a
forall a. Num a => a -> a -> a
+a
1)) (a
0, a
0)
variance :: (Floating a) => [a] -> a
variance :: [a] -> a
variance [a]
xs = let (Int
n, a
_, a
q) = (a -> (Int, a, a) -> (Int, a, a))
-> (Int, a, a) -> [a] -> (Int, a, a)
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr a -> (Int, a, a) -> (Int, a, a)
forall a. Floating a => a -> (Int, a, a) -> (Int, a, a)
go (Int
0, a
0, a
0) [a]
xs
in a
q a -> a -> a
forall a. Fractional a => a -> a -> a
/ Int -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
n
where
go :: Floating a => a -> (Int, a, a) -> (Int, a, a)
go :: a -> (Int, a, a) -> (Int, a, a)
go a
x (Int
n, a
sa, a
qa)
| Int
n Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 = (Int
1, a
x, a
0)
| Bool
otherwise =
let na :: a
na = Int -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
n
delta :: a
delta = a
x a -> a -> a
forall a. Num a => a -> a -> a
- a
saa -> a -> a
forall a. Fractional a => a -> a -> a
/a
na
sa' :: a
sa' = a
sa a -> a -> a
forall a. Num a => a -> a -> a
+ a
x
qa' :: a
qa' = a
qa a -> a -> a
forall a. Num a => a -> a -> a
+ a
deltaa -> a -> a
forall a. Num a => a -> a -> a
*a
deltaa -> a -> a
forall a. Num a => a -> a -> a
*a
naa -> a -> a
forall a. Fractional a => a -> a -> a
/(a
naa -> a -> a
forall a. Num a => a -> a -> a
+a
1)
in (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1, a
sa', a
qa')
quantiles :: (Real a, RealFrac a)
=> [a]
-> [a]
-> [a]
quantiles :: [a] -> [a] -> [a]
quantiles [a]
xs [a]
probs =
let xs' :: [a]
xs' = [a] -> [a]
forall a. Ord a => [a] -> [a]
sort [a]
xs
n :: Int
n = [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
xs'
in (a -> a) -> [a] -> [a]
forall a b. (a -> b) -> [a] -> [b]
map (Int -> [a] -> a -> a
forall a. (Real a, RealFrac a) => Int -> [a] -> a -> a
quantile7 Int
n [a]
xs') [a]
probs
quantile7 :: (Real a, RealFrac a)
=> Int
-> [a]
-> a
-> a
quantile7 :: Int -> [a] -> a -> a
quantile7 Int
n [a]
xs a
prob =
let h :: a
h = Int -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) a -> a -> a
forall a. Num a => a -> a -> a
* a
prob a -> a -> a
forall a. Num a => a -> a -> a
+ a
1
i :: Int
i = a -> Int
forall a b. (RealFrac a, Integral b) => a -> b
floor a
h
x1 :: a
x1 = [a]
xs [a] -> Int -> a
forall a. [a] -> Int -> a
!! (Int
iInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1)
x2 :: a
x2 = [a]
xs [a] -> Int -> a
forall a. [a] -> Int -> a
!! (Int
i)
in case (Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
n, Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
1) of
(Bool
True, Bool
_) -> [a]
xs [a] -> Int -> a
forall a. [a] -> Int -> a
!! (Int
iInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1)
(Bool
_, Bool
True) -> [a]
xs [a] -> Int -> a
forall a. [a] -> Int -> a
!! Int
0
(Bool, Bool)
_ -> a
x1 a -> a -> a
forall a. Num a => a -> a -> a
+ (a
h a -> a -> a
forall a. Num a => a -> a -> a
- Int -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
i)a -> a -> a
forall a. Num a => a -> a -> a
*(a
x2 a -> a -> a
forall a. Num a => a -> a -> a
-a
x1)
median :: (Real a, RealFrac a) => [a] -> a
median :: [a] -> a
median [a]
xs = [a] -> a
forall a. [a] -> a
head ([a] -> a) -> [a] -> a
forall a b. (a -> b) -> a -> b
$ [a] -> [a] -> [a]
forall a. (Real a, RealFrac a) => [a] -> [a] -> [a]
quantiles [a]
xs [a
0.5]
iqr :: (Real a, RealFrac a) => [a] -> a
iqr :: [a] -> a
iqr [a]
xs =
let [a
q1,a
q2] = [a] -> [a] -> [a]
forall a. (Real a, RealFrac a) => [a] -> [a] -> [a]
quantiles [a]
xs [a
0.25, a
0.75]
in a
q2 a -> a -> a
forall a. Num a => a -> a -> a
- a
q1