module Stats where

import Data.List

type Series = [Double]
type Statistic = Double

mean :: Series -> Statistic
mean xs = sum xs / genericLength xs

median :: Series -> Statistic
median xs
  | odd (length xs) = sorted !! middle_i
  | otherwise = (sorted !! middle_i + sorted !! (middle_i + 1) ) / 2
  where
    middle_i = ceiling (genericLength xs / 2) - 1
    sorted = sort xs

cov :: Series -> Series -> Statistic
cov xs ys  
  = (sum $ mult term_1 term_2) / (genericLength xs - 1)
    where
      term_1 = diffScalar xs (mean ys)
      term_2 = diffScalar ys (mean xs)

cor :: Series -> Series -> Statistic
cor xs ys = cov xs ys / (std xs * std ys)

var :: Series -> Statistic
var xs = cov xs xs

std :: Series -> Statistic
std xs = sqrt $ var xs

square :: Series -> Series
square xs = map (**2) xs

diff :: Series -> Series -> Series
diff xs ys = zipWith (-) xs ys

mult :: Series -> Series -> Series
mult xs ys = zipWith (*) xs ys

diffScalar :: Series -> Double -> Series
diffScalar xs v = [x - v | x <- xs]
