module Data.Summary.Double (
Summary,
size,
sum,
sumSquaredErrors,
mean,
meanSE,
meanCI,
stddev,
variance,
maximum,
minimum,
empty,
singleton,
insert,
insertWith,
union,
unions,
fromList,
fromListWith,
toStats,
fromStats,
) where
import Prelude hiding (maximum, minimum, sum)
import qualified Prelude as P
import Data.Data( Data, Typeable )
import Data.List( foldl' )
import Data.Monoid
import Text.Printf
import Data.Summary.Utils( interval )
data Summary = S !Int
!Double
!Double
!Double
!Double
deriving(Eq, Data, Typeable)
instance Show Summary where
show s@(S n mu _ l h) =
printf " sample size: %d" n
++ printf "\n minimum: %g" l
++ printf "\n maximum: %g" h
++ printf "\n mean: %g" mu
++ printf "\n SE: %g" (meanSE s)
++ printf "\n 99%% CI: (%g, %g)" c1 c2
where (c1,c2) = meanCI 0.99 s
instance Monoid Summary where
mempty = empty
mappend = union
size :: Summary -> Int
size (S n _ _ _ _) = n
sum :: Summary -> Double
sum s = (fromIntegral $ size s) * (mean s)
mean :: Summary -> Double
mean (S _ m _ _ _) = m
meanSE :: Summary -> Double
meanSE s = sqrt (variance s / fromIntegral (size s))
meanCI :: Double -> Summary -> (Double,Double)
meanCI level s = interval level (mean s) (meanSE s)
stddev :: Summary -> Double
stddev s = sqrt (variance s)
variance :: Summary -> Double
variance s = (sumSquaredErrors s) / fromIntegral (size s 1)
sumSquaredErrors :: Summary -> Double
sumSquaredErrors (S _ _ s _ _) = s
maximum :: Summary -> Double
maximum (S _ _ _ _ h) = h
minimum :: Summary -> Double
minimum (S _ _ _ l _) = l
empty :: Summary
empty = S 0 0 0 (1/0) (1/0)
singleton :: Double -> Summary
singleton x = S 1 x 0 x x
insert :: Double -> Summary -> Summary
insert x (S n m s l h) =
let n' = n+1
delta = x m
m' = m + delta / fromIntegral n'
s' = s + delta*(x m')
l' = if x < l then x else l
h' = if x > h then x else h
in S n' m' s' l' h'
insertWith :: (a -> Double) -> a -> Summary -> Summary
insertWith f a = insert (f a)
union :: Summary -> Summary -> Summary
union (S na ma sa la ha) (S nb mb sb lb hb) =
let delta = mb ma
(na', nb') = (fromIntegral na, fromIntegral nb)
n = na + nb
n' = fromIntegral n
weightedDelta = delta*nb'/n'
m | n == 0 = 0
| otherwise = ma + weightedDelta
s | n == 0 = 0
| otherwise = sa + sb + delta*na'*weightedDelta
l = P.min la lb
h = P.max ha hb
in S n m s l h
unions :: [Summary] -> Summary
unions = foldl' union empty
fromList :: [Double] -> Summary
fromList = foldl' (flip insert) empty
fromListWith :: (a -> Double) -> [a] -> Summary
fromListWith f = fromList . map f
toStats :: Summary -> (Int,Double,Double,Double,Double)
toStats (S n m s l u) = (n,m,s,l,u)
fromStats :: Int -> Double -> Double -> Double -> Double -> Summary
fromStats = S