{-# LANGUAGE BangPatterns          #-}
{-# LANGUAGE DeriveDataTypeable    #-}
{-# LANGUAGE DeriveGeneric         #-}
{-# LANGUAGE FlexibleContexts      #-}
{-# LANGUAGE FlexibleInstances     #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TemplateHaskell       #-}
{-# LANGUAGE TypeFamilies          #-}
-- |
-- Monoids for calculating various statistics in constant space. This
-- module contains algorithms that should be generally avoided unless
-- there's specific reason to use them.
module Data.Monoid.Statistics.Extra (
    -- * Mean
    WelfordMean(..)
  , asWelfordMean
  , MeanKahan(..)
  , asMeanKahan
  , MeanKB2(..)
  , asMeanKB2
    -- $references
  ) where

import Control.Monad.Catch          (MonadThrow(..))
import Data.Data                    (Typeable,Data)
import Data.Vector.Unboxed.Deriving (derivingUnbox)
import Numeric.Sum
import GHC.Generics                 (Generic)

import Data.Monoid.Statistics.Class



----------------------------------------------------------------
-- Mean
----------------------------------------------------------------


-- | Incremental calculation of mean which uses second-order
--   compensated Kahan-Babuška summation. In most cases
--   'Data.Monoid.Statistics.Numeric.KBNSum' should provide enough
--   precision.
data MeanKB2 = MeanKB2 !Int {-# UNPACK #-} !KB2Sum
             deriving (Int -> MeanKB2 -> ShowS
[MeanKB2] -> ShowS
MeanKB2 -> String
(Int -> MeanKB2 -> ShowS)
-> (MeanKB2 -> String) -> ([MeanKB2] -> ShowS) -> Show MeanKB2
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [MeanKB2] -> ShowS
$cshowList :: [MeanKB2] -> ShowS
show :: MeanKB2 -> String
$cshow :: MeanKB2 -> String
showsPrec :: Int -> MeanKB2 -> ShowS
$cshowsPrec :: Int -> MeanKB2 -> ShowS
Show,MeanKB2 -> MeanKB2 -> Bool
(MeanKB2 -> MeanKB2 -> Bool)
-> (MeanKB2 -> MeanKB2 -> Bool) -> Eq MeanKB2
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: MeanKB2 -> MeanKB2 -> Bool
$c/= :: MeanKB2 -> MeanKB2 -> Bool
== :: MeanKB2 -> MeanKB2 -> Bool
$c== :: MeanKB2 -> MeanKB2 -> Bool
Eq)

asMeanKB2 :: MeanKB2 -> MeanKB2
asMeanKB2 :: MeanKB2 -> MeanKB2
asMeanKB2 = MeanKB2 -> MeanKB2
forall a. a -> a
id

instance Semigroup MeanKB2 where
  MeanKB2 Int
0  KB2Sum
_  <> :: MeanKB2 -> MeanKB2 -> MeanKB2
<> MeanKB2
m             = MeanKB2
m
  MeanKB2
m             <> MeanKB2 Int
0  KB2Sum
_  = MeanKB2
m
  MeanKB2 Int
n1 KB2Sum
s1 <> MeanKB2 Int
n2 KB2Sum
s2 = Int -> KB2Sum -> MeanKB2
MeanKB2 (Int
n1Int -> Int -> Int
forall a. Num a => a -> a -> a
+Int
n2) (KB2Sum
s1 KB2Sum -> KB2Sum -> KB2Sum
forall a. Semigroup a => a -> a -> a
<> KB2Sum
s2)

instance Monoid MeanKB2 where
  mempty :: MeanKB2
mempty  = Int -> KB2Sum -> MeanKB2
MeanKB2 Int
0 KB2Sum
forall a. Monoid a => a
mempty
  mappend :: MeanKB2 -> MeanKB2 -> MeanKB2
mappend = MeanKB2 -> MeanKB2 -> MeanKB2
forall a. Semigroup a => a -> a -> a
(<>)

instance Real a => StatMonoid MeanKB2 a where
  addValue :: MeanKB2 -> a -> MeanKB2
addValue (MeanKB2 Int
n KB2Sum
m) a
x = Int -> KB2Sum -> MeanKB2
MeanKB2 (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1) (KB2Sum -> a -> KB2Sum
forall m a. StatMonoid m a => m -> a -> m
addValue KB2Sum
m a
x)

instance CalcMean MeanKB2 where
  calcMean :: MeanKB2 -> m Double
calcMean (MeanKB2 Int
0 KB2Sum
_) = SampleError -> m Double
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM (SampleError -> m Double) -> SampleError -> m Double
forall a b. (a -> b) -> a -> b
$ String -> SampleError
EmptySample String
"Data.Monoid.Statistics.Extra.MeanKB2"
  calcMean (MeanKB2 Int
n KB2Sum
s) = Double -> m Double
forall (m :: * -> *) a. Monad m => a -> m a
return (Double -> m Double) -> Double -> m Double
forall a b. (a -> b) -> a -> b
$! KB2Sum -> Double
kb2 KB2Sum
s Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Int -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
n



-- | Incremental calculation of mean. Sum of elements is calculated
--   using compensated Kahan summation. It's provided only for sake of
--   completeness. 'Data.Monoid.Statistics.Numeric.KBNSum' should be used
--   instead.
data MeanKahan = MeanKahan !Int !KahanSum
             deriving (Int -> MeanKahan -> ShowS
[MeanKahan] -> ShowS
MeanKahan -> String
(Int -> MeanKahan -> ShowS)
-> (MeanKahan -> String)
-> ([MeanKahan] -> ShowS)
-> Show MeanKahan
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [MeanKahan] -> ShowS
$cshowList :: [MeanKahan] -> ShowS
show :: MeanKahan -> String
$cshow :: MeanKahan -> String
showsPrec :: Int -> MeanKahan -> ShowS
$cshowsPrec :: Int -> MeanKahan -> ShowS
Show,MeanKahan -> MeanKahan -> Bool
(MeanKahan -> MeanKahan -> Bool)
-> (MeanKahan -> MeanKahan -> Bool) -> Eq MeanKahan
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: MeanKahan -> MeanKahan -> Bool
$c/= :: MeanKahan -> MeanKahan -> Bool
== :: MeanKahan -> MeanKahan -> Bool
$c== :: MeanKahan -> MeanKahan -> Bool
Eq,Typeable,Typeable MeanKahan
DataType
Constr
Typeable MeanKahan
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> MeanKahan -> c MeanKahan)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c MeanKahan)
-> (MeanKahan -> Constr)
-> (MeanKahan -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c MeanKahan))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c MeanKahan))
-> ((forall b. Data b => b -> b) -> MeanKahan -> MeanKahan)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> MeanKahan -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> MeanKahan -> r)
-> (forall u. (forall d. Data d => d -> u) -> MeanKahan -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> MeanKahan -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> MeanKahan -> m MeanKahan)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> MeanKahan -> m MeanKahan)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> MeanKahan -> m MeanKahan)
-> Data MeanKahan
MeanKahan -> DataType
MeanKahan -> Constr
(forall b. Data b => b -> b) -> MeanKahan -> MeanKahan
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> MeanKahan -> c MeanKahan
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c MeanKahan
forall a.
Typeable a
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> MeanKahan -> u
forall u. (forall d. Data d => d -> u) -> MeanKahan -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> MeanKahan -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> MeanKahan -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> MeanKahan -> m MeanKahan
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> MeanKahan -> m MeanKahan
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c MeanKahan
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> MeanKahan -> c MeanKahan
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c MeanKahan)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c MeanKahan)
$cMeanKahan :: Constr
$tMeanKahan :: DataType
gmapMo :: (forall d. Data d => d -> m d) -> MeanKahan -> m MeanKahan
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> MeanKahan -> m MeanKahan
gmapMp :: (forall d. Data d => d -> m d) -> MeanKahan -> m MeanKahan
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> MeanKahan -> m MeanKahan
gmapM :: (forall d. Data d => d -> m d) -> MeanKahan -> m MeanKahan
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> MeanKahan -> m MeanKahan
gmapQi :: Int -> (forall d. Data d => d -> u) -> MeanKahan -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> MeanKahan -> u
gmapQ :: (forall d. Data d => d -> u) -> MeanKahan -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> MeanKahan -> [u]
gmapQr :: (r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> MeanKahan -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> MeanKahan -> r
gmapQl :: (r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> MeanKahan -> r
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> MeanKahan -> r
gmapT :: (forall b. Data b => b -> b) -> MeanKahan -> MeanKahan
$cgmapT :: (forall b. Data b => b -> b) -> MeanKahan -> MeanKahan
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c MeanKahan)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c MeanKahan)
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c MeanKahan)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c MeanKahan)
dataTypeOf :: MeanKahan -> DataType
$cdataTypeOf :: MeanKahan -> DataType
toConstr :: MeanKahan -> Constr
$ctoConstr :: MeanKahan -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c MeanKahan
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c MeanKahan
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> MeanKahan -> c MeanKahan
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> MeanKahan -> c MeanKahan
$cp1Data :: Typeable MeanKahan
Data,(forall x. MeanKahan -> Rep MeanKahan x)
-> (forall x. Rep MeanKahan x -> MeanKahan) -> Generic MeanKahan
forall x. Rep MeanKahan x -> MeanKahan
forall x. MeanKahan -> Rep MeanKahan x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep MeanKahan x -> MeanKahan
$cfrom :: forall x. MeanKahan -> Rep MeanKahan x
Generic)

asMeanKahan :: MeanKahan -> MeanKahan
asMeanKahan :: MeanKahan -> MeanKahan
asMeanKahan = MeanKahan -> MeanKahan
forall a. a -> a
id


instance Semigroup MeanKahan where
  MeanKahan Int
0  KahanSum
_  <> :: MeanKahan -> MeanKahan -> MeanKahan
<> MeanKahan
m               = MeanKahan
m
  MeanKahan
m               <> MeanKahan Int
0  KahanSum
_  = MeanKahan
m
  MeanKahan Int
n1 KahanSum
s1 <> MeanKahan Int
n2 KahanSum
s2 = Int -> KahanSum -> MeanKahan
MeanKahan (Int
n1Int -> Int -> Int
forall a. Num a => a -> a -> a
+Int
n2) (KahanSum
s1 KahanSum -> KahanSum -> KahanSum
forall a. Semigroup a => a -> a -> a
<> KahanSum
s2)
  {-# INLINE (<>) #-}

instance Monoid MeanKahan where
  mempty :: MeanKahan
mempty  = Int -> KahanSum -> MeanKahan
MeanKahan Int
0 KahanSum
forall a. Monoid a => a
mempty
  mappend :: MeanKahan -> MeanKahan -> MeanKahan
mappend = MeanKahan -> MeanKahan -> MeanKahan
forall a. Semigroup a => a -> a -> a
(<>)

instance Real a => StatMonoid MeanKahan a where
  addValue :: MeanKahan -> a -> MeanKahan
addValue (MeanKahan Int
n KahanSum
m) a
x = Int -> KahanSum -> MeanKahan
MeanKahan (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1) (KahanSum -> a -> KahanSum
forall m a. StatMonoid m a => m -> a -> m
addValue KahanSum
m a
x)

instance CalcCount MeanKahan where
  calcCount :: MeanKahan -> Int
calcCount (MeanKahan Int
n KahanSum
_) = Int
n
instance CalcMean MeanKahan where
  calcMean :: MeanKahan -> m Double
calcMean (MeanKahan Int
0 KahanSum
_) = SampleError -> m Double
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM (SampleError -> m Double) -> SampleError -> m Double
forall a b. (a -> b) -> a -> b
$ String -> SampleError
EmptySample String
"Data.Monoid.Statistics.Extra.WelfordMean"
  calcMean (MeanKahan Int
n KahanSum
s) = Double -> m Double
forall (m :: * -> *) a. Monad m => a -> m a
return (KahanSum -> Double
kahan KahanSum
s Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Int -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
n)


-- | Incremental calculation of mean. Note that this algorithm doesn't
--   offer better numeric precision than plain summation. Its only
--   advantage is protection against double overflow:
--
-- >>> calcMean $ reduceSample @MeanKBN (replicate 100 1e308) :: Maybe Double
-- Just NaN
-- >>> calcMean $ reduceSample @WelfordMean (replicate 100 1e308) :: Maybe Double
-- Just 1.0e308
--
--   Unless this feature is needed 'Data.Monoid.Statistics.Numeric.KBNSum'
--   should be used. Algorithm is due to Welford [Welford1962]
--
-- \[ s_n = s_{n-1} + \frac{x_n - s_{n-1}}{n} \]
data WelfordMean = WelfordMean !Int    -- Number of entries
                               !Double -- Current mean
  deriving (Int -> WelfordMean -> ShowS
[WelfordMean] -> ShowS
WelfordMean -> String
(Int -> WelfordMean -> ShowS)
-> (WelfordMean -> String)
-> ([WelfordMean] -> ShowS)
-> Show WelfordMean
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [WelfordMean] -> ShowS
$cshowList :: [WelfordMean] -> ShowS
show :: WelfordMean -> String
$cshow :: WelfordMean -> String
showsPrec :: Int -> WelfordMean -> ShowS
$cshowsPrec :: Int -> WelfordMean -> ShowS
Show,WelfordMean -> WelfordMean -> Bool
(WelfordMean -> WelfordMean -> Bool)
-> (WelfordMean -> WelfordMean -> Bool) -> Eq WelfordMean
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: WelfordMean -> WelfordMean -> Bool
$c/= :: WelfordMean -> WelfordMean -> Bool
== :: WelfordMean -> WelfordMean -> Bool
$c== :: WelfordMean -> WelfordMean -> Bool
Eq,Typeable,Typeable WelfordMean
DataType
Constr
Typeable WelfordMean
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> WelfordMean -> c WelfordMean)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c WelfordMean)
-> (WelfordMean -> Constr)
-> (WelfordMean -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c WelfordMean))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c WelfordMean))
-> ((forall b. Data b => b -> b) -> WelfordMean -> WelfordMean)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> WelfordMean -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> WelfordMean -> r)
-> (forall u. (forall d. Data d => d -> u) -> WelfordMean -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> WelfordMean -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> WelfordMean -> m WelfordMean)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> WelfordMean -> m WelfordMean)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> WelfordMean -> m WelfordMean)
-> Data WelfordMean
WelfordMean -> DataType
WelfordMean -> Constr
(forall b. Data b => b -> b) -> WelfordMean -> WelfordMean
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> WelfordMean -> c WelfordMean
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c WelfordMean
forall a.
Typeable a
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> WelfordMean -> u
forall u. (forall d. Data d => d -> u) -> WelfordMean -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> WelfordMean -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> WelfordMean -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> WelfordMean -> m WelfordMean
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> WelfordMean -> m WelfordMean
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c WelfordMean
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> WelfordMean -> c WelfordMean
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c WelfordMean)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c WelfordMean)
$cWelfordMean :: Constr
$tWelfordMean :: DataType
gmapMo :: (forall d. Data d => d -> m d) -> WelfordMean -> m WelfordMean
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> WelfordMean -> m WelfordMean
gmapMp :: (forall d. Data d => d -> m d) -> WelfordMean -> m WelfordMean
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> WelfordMean -> m WelfordMean
gmapM :: (forall d. Data d => d -> m d) -> WelfordMean -> m WelfordMean
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> WelfordMean -> m WelfordMean
gmapQi :: Int -> (forall d. Data d => d -> u) -> WelfordMean -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> WelfordMean -> u
gmapQ :: (forall d. Data d => d -> u) -> WelfordMean -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> WelfordMean -> [u]
gmapQr :: (r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> WelfordMean -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> WelfordMean -> r
gmapQl :: (r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> WelfordMean -> r
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> WelfordMean -> r
gmapT :: (forall b. Data b => b -> b) -> WelfordMean -> WelfordMean
$cgmapT :: (forall b. Data b => b -> b) -> WelfordMean -> WelfordMean
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c WelfordMean)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c WelfordMean)
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c WelfordMean)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c WelfordMean)
dataTypeOf :: WelfordMean -> DataType
$cdataTypeOf :: WelfordMean -> DataType
toConstr :: WelfordMean -> Constr
$ctoConstr :: WelfordMean -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c WelfordMean
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c WelfordMean
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> WelfordMean -> c WelfordMean
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> WelfordMean -> c WelfordMean
$cp1Data :: Typeable WelfordMean
Data,(forall x. WelfordMean -> Rep WelfordMean x)
-> (forall x. Rep WelfordMean x -> WelfordMean)
-> Generic WelfordMean
forall x. Rep WelfordMean x -> WelfordMean
forall x. WelfordMean -> Rep WelfordMean x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep WelfordMean x -> WelfordMean
$cfrom :: forall x. WelfordMean -> Rep WelfordMean x
Generic)

-- | Type restricted 'id'
asWelfordMean :: WelfordMean -> WelfordMean
asWelfordMean :: WelfordMean -> WelfordMean
asWelfordMean = WelfordMean -> WelfordMean
forall a. a -> a
id

instance Semigroup WelfordMean where
  WelfordMean Int
0 Double
_ <> :: WelfordMean -> WelfordMean -> WelfordMean
<> WelfordMean
m = WelfordMean
m
  WelfordMean
m <> WelfordMean Int
0 Double
_ = WelfordMean
m
  WelfordMean Int
n Double
x <> WelfordMean Int
k Double
y
    = Int -> Double -> WelfordMean
WelfordMean (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
k) ((Double
xDouble -> Double -> Double
forall a. Num a => a -> a -> a
*Double
n' Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double
yDouble -> Double -> Double
forall a. Num a => a -> a -> a
*Double
k') Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ (Double
n' Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double
k'))
    where
      n' :: Double
n' = Int -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
n
      k' :: Double
k' = Int -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k
  {-# INLINE (<>) #-}

instance Monoid WelfordMean where
  mempty :: WelfordMean
mempty  = Int -> Double -> WelfordMean
WelfordMean Int
0 Double
0
  mappend :: WelfordMean -> WelfordMean -> WelfordMean
mappend = WelfordMean -> WelfordMean -> WelfordMean
forall a. Semigroup a => a -> a -> a
(<>)
  {-# INLINE mempty  #-}
  {-# INLINE mappend #-}

instance Real a => StatMonoid WelfordMean a where
  addValue :: WelfordMean -> a -> WelfordMean
addValue (WelfordMean Int
n Double
m) !a
x
    = Int -> Double -> WelfordMean
WelfordMean Int
n' (Double
m Double -> Double -> Double
forall a. Num a => a -> a -> a
+ (a -> Double
forall a b. (Real a, Fractional b) => a -> b
realToFrac a
x Double -> Double -> Double
forall a. Num a => a -> a -> a
- Double
m) Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Int -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
n')
    where
      n' :: Int
n' = Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1
  {-# INLINE addValue #-}

instance CalcCount WelfordMean where
  calcCount :: WelfordMean -> Int
calcCount (WelfordMean Int
n Double
_) = Int
n
instance CalcMean WelfordMean where
  calcMean :: WelfordMean -> m Double
calcMean (WelfordMean Int
0 Double
_) = SampleError -> m Double
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM (SampleError -> m Double) -> SampleError -> m Double
forall a b. (a -> b) -> a -> b
$ String -> SampleError
EmptySample String
"Data.Monoid.Statistics.Extra.WelfordMean"
  calcMean (WelfordMean Int
_ Double
m) = Double -> m Double
forall (m :: * -> *) a. Monad m => a -> m a
return Double
m



----------------------------------------------------------------
-- Unboxed instances
----------------------------------------------------------------

derivingUnbox "MeanKahan"
  [t| MeanKahan -> (Int,Double,Double) |]
  [| \(MeanKahan a (KahanSum b c)) -> (a,b,c)   |]
  [| \(a,b,c) -> MeanKahan a (KahanSum b c) |]

derivingUnbox "WelfordMean"
  [t| WelfordMean -> (Int,Double) |]
  [| \(WelfordMean a b) -> (a,b)  |]
  [| \(a,b) -> WelfordMean a b    |]


-- $references
--
-- * [Welford1962] Welford, B.P. (1962) Note on a method for
--   calculating corrected sums of squares and
--   products. /Technometrics/
--   4(3):419-420. <http://www.jstor.org/stable/1266577>

-- $setup
--
-- >>> :set -XTypeApplications
-- >>> import Data.Monoid.Statistics.Numeric