{-# 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
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
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 = 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
n1forall a. Num a => a -> a -> a
+Int
n2) (KB2Sum
s1 forall a. Semigroup a => a -> a -> a
<> KB2Sum
s2)

instance Monoid MeanKB2 where
  mempty :: MeanKB2
mempty  = Int -> KB2Sum -> MeanKB2
MeanKB2 Int
0 forall a. Monoid a => a
mempty
  mappend :: MeanKB2 -> MeanKB2 -> MeanKB2
mappend = 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
nforall a. Num a => a -> a -> a
+Int
1) (forall m a. StatMonoid m a => m -> a -> m
addValue KB2Sum
m a
x)

instance CalcMean MeanKB2 where
  calcMean :: forall (m :: * -> *). MonadThrow m => MeanKB2 -> m Double
calcMean (MeanKB2 Int
0 KB2Sum
_) = forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM forall a b. (a -> b) -> a -> b
$ String -> SampleError
EmptySample String
"Data.Monoid.Statistics.Extra.MeanKB2"
  calcMean (MeanKB2 Int
n KB2Sum
s) = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$! KB2Sum -> Double
kb2 KB2Sum
s forall a. Fractional a => a -> a -> a
/ 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
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
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
MeanKahan -> DataType
MeanKahan -> Constr
(forall b. Data b => b -> b) -> MeanKahan -> 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)
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(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 (m :: * -> *).
MonadPlus m =>
(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 (m :: * -> *).
Monad m =>
(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 :: forall u. Int -> (forall d. Data d => d -> u) -> MeanKahan -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> MeanKahan -> u
gmapQ :: forall u. (forall d. Data d => d -> u) -> MeanKahan -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> MeanKahan -> [u]
gmapQr :: forall r r'.
(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 :: forall r r'.
(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 (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(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 (t :: * -> *) (c :: * -> *).
Typeable t =>
(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 (c :: * -> *).
(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 (c :: * -> *).
(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
Data,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 = 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
n1forall a. Num a => a -> a -> a
+Int
n2) (KahanSum
s1 forall a. Semigroup a => a -> a -> a
<> KahanSum
s2)
  {-# INLINE (<>) #-}

instance Monoid MeanKahan where
  mempty :: MeanKahan
mempty  = Int -> KahanSum -> MeanKahan
MeanKahan Int
0 forall a. Monoid a => a
mempty
  mappend :: MeanKahan -> MeanKahan -> MeanKahan
mappend = 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
nforall a. Num a => a -> a -> a
+Int
1) (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 :: forall (m :: * -> *). MonadThrow m => MeanKahan -> m Double
calcMean (MeanKahan Int
0 KahanSum
_) = forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM forall a b. (a -> b) -> a -> b
$ String -> SampleError
EmptySample String
"Data.Monoid.Statistics.Extra.WelfordMean"
  calcMean (MeanKahan Int
n KahanSum
s) = forall (m :: * -> *) a. Monad m => a -> m a
return (KahanSum -> Double
kahan KahanSum
s forall a. Fractional a => a -> a -> a
/ 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
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
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
WelfordMean -> DataType
WelfordMean -> Constr
(forall b. Data b => b -> b) -> WelfordMean -> 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)
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(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 (m :: * -> *).
MonadPlus m =>
(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 (m :: * -> *).
Monad m =>
(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 :: forall u. Int -> (forall d. Data d => d -> u) -> WelfordMean -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> WelfordMean -> u
gmapQ :: forall u. (forall d. Data d => d -> u) -> WelfordMean -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> WelfordMean -> [u]
gmapQr :: forall r r'.
(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 :: forall r r'.
(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 (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(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 (t :: * -> *) (c :: * -> *).
Typeable t =>
(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 (c :: * -> *).
(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 (c :: * -> *).
(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
Data,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 = 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 forall a. Num a => a -> a -> a
+ Int
k) ((Double
xforall a. Num a => a -> a -> a
*Double
n' forall a. Num a => a -> a -> a
+ Double
yforall a. Num a => a -> a -> a
*Double
k') forall a. Fractional a => a -> a -> a
/ (Double
n' forall a. Num a => a -> a -> a
+ Double
k'))
    where
      n' :: Double
n' = forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
n
      k' :: Double
k' = 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 = 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 forall a. Num a => a -> a -> a
+ (forall a b. (Real a, Fractional b) => a -> b
realToFrac a
x forall a. Num a => a -> a -> a
- Double
m) forall a. Fractional a => a -> a -> a
/ forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
n')
    where
      n' :: Int
n' = Int
nforall 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 :: forall (m :: * -> *). MonadThrow m => WelfordMean -> m Double
calcMean (WelfordMean Int
0 Double
_) = forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM forall a b. (a -> b) -> a -> b
$ String -> SampleError
EmptySample String
"Data.Monoid.Statistics.Extra.WelfordMean"
  calcMean (WelfordMean Int
_ Double
m) = 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