{-# LANGUAGE DeriveDataTypeable, DeriveGeneric #-}

-- |
-- Module     : Simulation.Aivika.Statistics
-- Copyright  : Copyright (c) 2009-2017, David Sorokin <david.sorokin@gmail.com>
-- License    : BSD3
-- Maintainer : David Sorokin <david.sorokin@gmail.com>
-- Stability  : experimental
-- Tested with: GHC 8.0.1
--
-- Represents statistics.
--

module Simulation.Aivika.Statistics
       (-- * Simple Statistics
        SamplingStats(..),
        SamplingData(..),
        combineSamplingStatsEither,
        samplingStatsVariance,
        samplingStatsDeviation,
        samplingStatsSummary,
        returnSamplingStats,
        listSamplingStats,
        fromIntSamplingStats,
        -- * Timing Statistics
        TimingStats(..),
        TimingData(..),
        timingStatsDeviation,
        timingStatsSummary,
        returnTimingStats,
        fromIntTimingStats,
        normTimingStats,
        -- * Simple Counter
        SamplingCounter(..),
        emptySamplingCounter,
        incSamplingCounter,
        decSamplingCounter,
        setSamplingCounter,
        returnSamplingCounter,
        -- * Timing Counter
        TimingCounter(..),
        emptyTimingCounter,
        incTimingCounter,
        decTimingCounter,
        setTimingCounter,
        returnTimingCounter) where

import GHC.Generics (Generic)

import Control.DeepSeq

import Data.Monoid hiding ((<>))
import Data.Semigroup (Semigroup(..))
import Data.Typeable
import Data.Binary

-- | Defines data types that can be converted to 'Double'.
class Ord a => ConvertableToDouble a where
  
  -- | Convert the value to 'Double'.
  convertToDouble :: a -> Double
  
instance ConvertableToDouble Double where
  convertToDouble :: Double -> Double
convertToDouble = forall a. a -> a
id
  
instance ConvertableToDouble Int where
  convertToDouble :: Int -> Double
convertToDouble = forall a b. (Integral a, Num b) => a -> b
fromIntegral

-- | Describes when the statistics consists of only samples 
-- not bound to the simulation time.
data SamplingStats a =       
  SamplingStats { forall a. SamplingStats a -> Int
samplingStatsCount :: !Int,
                  -- ^ The total number of samples.
                  forall a. SamplingStats a -> a
samplingStatsMin   :: !a,
                  -- ^ The minimum value among the samples.
                  forall a. SamplingStats a -> a
samplingStatsMax   :: !a,
                  -- ^ The maximum value among the samples.
                  forall a. SamplingStats a -> Double
samplingStatsMean  :: !Double,
                  -- ^ The average value.
                  forall a. SamplingStats a -> Double
samplingStatsMean2 :: !Double 
                  -- ^ The average square value.
                }
  deriving (SamplingStats a -> SamplingStats a -> Bool
forall a. Eq a => SamplingStats a -> SamplingStats a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: SamplingStats a -> SamplingStats a -> Bool
$c/= :: forall a. Eq a => SamplingStats a -> SamplingStats a -> Bool
== :: SamplingStats a -> SamplingStats a -> Bool
$c== :: forall a. Eq a => SamplingStats a -> SamplingStats a -> Bool
Eq, SamplingStats a -> SamplingStats a -> Bool
SamplingStats a -> SamplingStats a -> Ordering
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall {a}. Ord a => Eq (SamplingStats a)
forall a. Ord a => SamplingStats a -> SamplingStats a -> Bool
forall a. Ord a => SamplingStats a -> SamplingStats a -> Ordering
forall a.
Ord a =>
SamplingStats a -> SamplingStats a -> SamplingStats a
min :: SamplingStats a -> SamplingStats a -> SamplingStats a
$cmin :: forall a.
Ord a =>
SamplingStats a -> SamplingStats a -> SamplingStats a
max :: SamplingStats a -> SamplingStats a -> SamplingStats a
$cmax :: forall a.
Ord a =>
SamplingStats a -> SamplingStats a -> SamplingStats a
>= :: SamplingStats a -> SamplingStats a -> Bool
$c>= :: forall a. Ord a => SamplingStats a -> SamplingStats a -> Bool
> :: SamplingStats a -> SamplingStats a -> Bool
$c> :: forall a. Ord a => SamplingStats a -> SamplingStats a -> Bool
<= :: SamplingStats a -> SamplingStats a -> Bool
$c<= :: forall a. Ord a => SamplingStats a -> SamplingStats a -> Bool
< :: SamplingStats a -> SamplingStats a -> Bool
$c< :: forall a. Ord a => SamplingStats a -> SamplingStats a -> Bool
compare :: SamplingStats a -> SamplingStats a -> Ordering
$ccompare :: forall a. Ord a => SamplingStats a -> SamplingStats a -> Ordering
Ord, Typeable, forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall a x. Rep (SamplingStats a) x -> SamplingStats a
forall a x. SamplingStats a -> Rep (SamplingStats a) x
$cto :: forall a x. Rep (SamplingStats a) x -> SamplingStats a
$cfrom :: forall a x. SamplingStats a -> Rep (SamplingStats a) x
Generic)

instance NFData a => NFData (SamplingStats a)
instance Binary a => Binary (SamplingStats a)

-- | Specifies data type from which values we can gather the statistics.           
class Num a => SamplingData a where           
  
  -- | An empty statistics that has no samples.           
  emptySamplingStats :: SamplingStats a
           
  -- | Add a new sample to the statistics.
  addSamplingStats :: a -> SamplingStats a -> SamplingStats a

  -- | Combine two statistics.
  combineSamplingStats :: SamplingStats a -> SamplingStats a -> SamplingStats a

instance SamplingData a => Semigroup (SamplingStats a) where
  <> :: SamplingStats a -> SamplingStats a -> SamplingStats a
(<>) = forall a.
SamplingData a =>
SamplingStats a -> SamplingStats a -> SamplingStats a
combineSamplingStats

instance SamplingData a => Monoid (SamplingStats a) where 
  
  mempty :: SamplingStats a
mempty = forall a. SamplingData a => SamplingStats a
emptySamplingStats
  
  mappend :: SamplingStats a -> SamplingStats a -> SamplingStats a
mappend = forall a. Semigroup a => a -> a -> a
(<>)

instance SamplingData Double where

  emptySamplingStats :: SamplingStats Double
emptySamplingStats =
    SamplingStats { samplingStatsCount :: Int
samplingStatsCount = Int
0,
                    samplingStatsMin :: Double
samplingStatsMin   = Double
1 forall a. Fractional a => a -> a -> a
/ Double
0,
                    samplingStatsMax :: Double
samplingStatsMax   = (-Double
1) forall a. Fractional a => a -> a -> a
/ Double
0,
                    samplingStatsMean :: Double
samplingStatsMean  = Double
0 forall a. Fractional a => a -> a -> a
/ Double
0,
                    samplingStatsMean2 :: Double
samplingStatsMean2 = Double
0 forall a. Fractional a => a -> a -> a
/ Double
0 }
    
  addSamplingStats :: Double -> SamplingStats Double -> SamplingStats Double
addSamplingStats = forall a.
ConvertableToDouble a =>
a -> SamplingStats a -> SamplingStats a
addSamplingStatsGeneric
  
  combineSamplingStats :: SamplingStats Double
-> SamplingStats Double -> SamplingStats Double
combineSamplingStats = forall a.
ConvertableToDouble a =>
SamplingStats a -> SamplingStats a -> SamplingStats a
combineSamplingStatsGeneric
  
instance SamplingData Int where

  emptySamplingStats :: SamplingStats Int
emptySamplingStats =
    SamplingStats { samplingStatsCount :: Int
samplingStatsCount = Int
0,
                    samplingStatsMin :: Int
samplingStatsMin   = forall a. Bounded a => a
maxBound,
                    samplingStatsMax :: Int
samplingStatsMax   = forall a. Bounded a => a
minBound,
                    samplingStatsMean :: Double
samplingStatsMean  = Double
0 forall a. Fractional a => a -> a -> a
/ Double
0,
                    samplingStatsMean2 :: Double
samplingStatsMean2 = Double
0 forall a. Fractional a => a -> a -> a
/ Double
0 }
    
  addSamplingStats :: Int -> SamplingStats Int -> SamplingStats Int
addSamplingStats = forall a.
ConvertableToDouble a =>
a -> SamplingStats a -> SamplingStats a
addSamplingStatsGeneric

  combineSamplingStats :: SamplingStats Int -> SamplingStats Int -> SamplingStats Int
combineSamplingStats = forall a.
ConvertableToDouble a =>
SamplingStats a -> SamplingStats a -> SamplingStats a
combineSamplingStatsGeneric
  
addSamplingStatsGeneric :: ConvertableToDouble a => a -> SamplingStats a -> SamplingStats a
addSamplingStatsGeneric :: forall a.
ConvertableToDouble a =>
a -> SamplingStats a -> SamplingStats a
addSamplingStatsGeneric a
a SamplingStats a
stats 
  | forall a. RealFloat a => a -> Bool
isNaN Double
x    = SamplingStats a
stats
  | Int
count forall a. Eq a => a -> a -> Bool
== Int
1 = SamplingStats { samplingStatsCount :: Int
samplingStatsCount = Int
1,
                                 samplingStatsMin :: a
samplingStatsMin   = a
a,
                                 samplingStatsMax :: a
samplingStatsMax   = a
a,
                                 samplingStatsMean :: Double
samplingStatsMean  = Double
x,
                                 samplingStatsMean2 :: Double
samplingStatsMean2 = Double
x forall a. Num a => a -> a -> a
* Double
x }
  | Bool
otherwise  = SamplingStats { samplingStatsCount :: Int
samplingStatsCount = Int
count,
                                 samplingStatsMin :: a
samplingStatsMin   = a
minX,
                                 samplingStatsMax :: a
samplingStatsMax   = a
maxX,
                                 samplingStatsMean :: Double
samplingStatsMean  = Double
meanX,
                                 samplingStatsMean2 :: Double
samplingStatsMean2 = Double
meanX2 }
    where count :: Int
count  = Int
1 forall a. Num a => a -> a -> a
+ forall a. SamplingStats a -> Int
samplingStatsCount SamplingStats a
stats
          minX :: a
minX   = a
a seq :: forall a b. a -> b -> b
`seq` forall a. Ord a => a -> a -> a
min a
a (forall a. SamplingStats a -> a
samplingStatsMin SamplingStats a
stats)
          maxX :: a
maxX   = a
a seq :: forall a b. a -> b -> b
`seq` forall a. Ord a => a -> a -> a
max a
a (forall a. SamplingStats a -> a
samplingStatsMax SamplingStats a
stats)
          meanX :: Double
meanX  = Double
k1 forall a. Num a => a -> a -> a
* Double
x forall a. Num a => a -> a -> a
+ Double
k2 forall a. Num a => a -> a -> a
* forall a. SamplingStats a -> Double
samplingStatsMean SamplingStats a
stats
          meanX2 :: Double
meanX2 = Double
k1 forall a. Num a => a -> a -> a
* Double
x forall a. Num a => a -> a -> a
* Double
x forall a. Num a => a -> a -> a
+ Double
k2 forall a. Num a => a -> a -> a
* forall a. SamplingStats a -> Double
samplingStatsMean2 SamplingStats a
stats
          n :: Double
n      = forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
count
          x :: Double
x      = forall a. ConvertableToDouble a => a -> Double
convertToDouble a
a
          k1 :: Double
k1     = Double
1.0 forall a. Fractional a => a -> a -> a
/ Double
n
          k2 :: Double
k2     = (Double
n forall a. Num a => a -> a -> a
- Double
1.0) forall a. Fractional a => a -> a -> a
/ Double
n

combineSamplingStatsGeneric :: ConvertableToDouble a =>
                               SamplingStats a -> SamplingStats a -> SamplingStats a
combineSamplingStatsGeneric :: forall a.
ConvertableToDouble a =>
SamplingStats a -> SamplingStats a -> SamplingStats a
combineSamplingStatsGeneric SamplingStats a
stats1 SamplingStats a
stats2
  | Int
c1 forall a. Eq a => a -> a -> Bool
== Int
0   = SamplingStats a
stats2
  | Int
c2 forall a. Eq a => a -> a -> Bool
== Int
0   = SamplingStats a
stats1
  | Bool
otherwise = SamplingStats { samplingStatsCount :: Int
samplingStatsCount = Int
c,
                                samplingStatsMin :: a
samplingStatsMin   = a
minZ,
                                samplingStatsMax :: a
samplingStatsMax   = a
maxZ,
                                samplingStatsMean :: Double
samplingStatsMean  = Double
meanZ,
                                samplingStatsMean2 :: Double
samplingStatsMean2 = Double
meanZ2 }
  where c1 :: Int
c1     = forall a. SamplingStats a -> Int
samplingStatsCount SamplingStats a
stats1
        c2 :: Int
c2     = forall a. SamplingStats a -> Int
samplingStatsCount SamplingStats a
stats2
        c :: Int
c      = Int
c1 forall a. Num a => a -> a -> a
+ Int
c2
        n1 :: Double
n1     = forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
c1
        n2 :: Double
n2     = forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
c2
        n :: Double
n      = Double
n1 forall a. Num a => a -> a -> a
+ Double
n2
        minX :: a
minX   = forall a. SamplingStats a -> a
samplingStatsMin SamplingStats a
stats1
        minY :: a
minY   = forall a. SamplingStats a -> a
samplingStatsMin SamplingStats a
stats2
        minZ :: a
minZ   = forall a. Ord a => a -> a -> a
min a
minX a
minY
        maxX :: a
maxX   = forall a. SamplingStats a -> a
samplingStatsMax SamplingStats a
stats1
        maxY :: a
maxY   = forall a. SamplingStats a -> a
samplingStatsMax SamplingStats a
stats2
        maxZ :: a
maxZ   = forall a. Ord a => a -> a -> a
max a
maxX a
maxY
        meanX :: Double
meanX  = forall a. SamplingStats a -> Double
samplingStatsMean SamplingStats a
stats1
        meanY :: Double
meanY  = forall a. SamplingStats a -> Double
samplingStatsMean SamplingStats a
stats2
        meanZ :: Double
meanZ  = Double
k1 forall a. Num a => a -> a -> a
* Double
meanX forall a. Num a => a -> a -> a
+ Double
k2 forall a. Num a => a -> a -> a
* Double
meanY
        meanX2 :: Double
meanX2 = forall a. SamplingStats a -> Double
samplingStatsMean2 SamplingStats a
stats1
        meanY2 :: Double
meanY2 = forall a. SamplingStats a -> Double
samplingStatsMean2 SamplingStats a
stats2
        meanZ2 :: Double
meanZ2 = Double
k1 forall a. Num a => a -> a -> a
* Double
meanX2 forall a. Num a => a -> a -> a
+ Double
k2 forall a. Num a => a -> a -> a
* Double
meanY2
        k1 :: Double
k1     = Double
n1 forall a. Fractional a => a -> a -> a
/ Double
n
        k2 :: Double
k2     = Double
n2 forall a. Fractional a => a -> a -> a
/ Double
n

-- | If allows combining statistics more efficiently if we know that the first argument can be a scalar.
combineSamplingStatsEither :: SamplingData a => Either a (SamplingStats a) -> SamplingStats a -> SamplingStats a
combineSamplingStatsEither :: forall a.
SamplingData a =>
Either a (SamplingStats a) -> SamplingStats a -> SamplingStats a
combineSamplingStatsEither (Left a
a) SamplingStats a
stats2 = forall a. SamplingData a => a -> SamplingStats a -> SamplingStats a
addSamplingStats a
a SamplingStats a
stats2
combineSamplingStatsEither (Right SamplingStats a
stats1) SamplingStats a
stats2 = forall a.
SamplingData a =>
SamplingStats a -> SamplingStats a -> SamplingStats a
combineSamplingStats SamplingStats a
stats1 SamplingStats a
stats2

-- | Return the variance.
samplingStatsVariance :: SamplingStats a -> Double
samplingStatsVariance :: forall a. SamplingStats a -> Double
samplingStatsVariance SamplingStats a
stats
  | Int
count forall a. Eq a => a -> a -> Bool
== Int
1 = Double
0
  | Bool
otherwise  = (Double
meanX2 forall a. Num a => a -> a -> a
- Double
meanX forall a. Num a => a -> a -> a
* Double
meanX) forall a. Num a => a -> a -> a
* (Double
n forall a. Fractional a => a -> a -> a
/ (Double
n forall a. Num a => a -> a -> a
- Double
1))
    where count :: Int
count  = forall a. SamplingStats a -> Int
samplingStatsCount SamplingStats a
stats
          meanX :: Double
meanX  = forall a. SamplingStats a -> Double
samplingStatsMean SamplingStats a
stats
          meanX2 :: Double
meanX2 = forall a. SamplingStats a -> Double
samplingStatsMean2 SamplingStats a
stats
          n :: Double
n      = forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
count
          
-- | Return the deviation.          
samplingStatsDeviation :: SamplingStats a -> Double
samplingStatsDeviation :: forall a. SamplingStats a -> Double
samplingStatsDeviation = forall a. Floating a => a -> a
sqrt forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. SamplingStats a -> Double
samplingStatsVariance

-- | Return the statistics by a single sample.
returnSamplingStats :: SamplingData a => a -> SamplingStats a
returnSamplingStats :: forall a. SamplingData a => a -> SamplingStats a
returnSamplingStats a
x = forall a. SamplingData a => a -> SamplingStats a -> SamplingStats a
addSamplingStats a
x forall a. SamplingData a => SamplingStats a
emptySamplingStats

-- | Create the statistics by the specified list of data.
listSamplingStats :: SamplingData a => [a] -> SamplingStats a
listSamplingStats :: forall a. SamplingData a => [a] -> SamplingStats a
listSamplingStats = forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr forall a. SamplingData a => a -> SamplingStats a -> SamplingStats a
addSamplingStats forall a. SamplingData a => SamplingStats a
emptySamplingStats

-- | Convert the statistics from integer to double values.
fromIntSamplingStats :: SamplingStats Int -> SamplingStats Double
fromIntSamplingStats :: SamplingStats Int -> SamplingStats Double
fromIntSamplingStats SamplingStats Int
stats =
  SamplingStats Int
stats { samplingStatsMin :: Double
samplingStatsMin = forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ forall a. SamplingStats a -> a
samplingStatsMin SamplingStats Int
stats,
          samplingStatsMax :: Double
samplingStatsMax = forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ forall a. SamplingStats a -> a
samplingStatsMax SamplingStats Int
stats }

-- | Show the summary of the statistics.       
showSamplingStats :: (Show a) => SamplingStats a -> ShowS
showSamplingStats :: forall a. Show a => SamplingStats a -> ShowS
showSamplingStats SamplingStats a
stats =
  String -> ShowS
showString String
"{ count = " forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> ShowS
shows (forall a. SamplingStats a -> Int
samplingStatsCount SamplingStats a
stats) forall b c a. (b -> c) -> (a -> b) -> a -> c
. 
  String -> ShowS
showString String
", mean = " forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> ShowS
shows (forall a. SamplingStats a -> Double
samplingStatsMean SamplingStats a
stats) forall b c a. (b -> c) -> (a -> b) -> a -> c
. 
  String -> ShowS
showString String
", std = " forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> ShowS
shows (forall a. SamplingStats a -> Double
samplingStatsDeviation SamplingStats a
stats) forall b c a. (b -> c) -> (a -> b) -> a -> c
. 
  String -> ShowS
showString String
", min = " forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> ShowS
shows (forall a. SamplingStats a -> a
samplingStatsMin SamplingStats a
stats) forall b c a. (b -> c) -> (a -> b) -> a -> c
. 
  String -> ShowS
showString String
", max = " forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> ShowS
shows (forall a. SamplingStats a -> a
samplingStatsMax SamplingStats a
stats) forall b c a. (b -> c) -> (a -> b) -> a -> c
.
  String -> ShowS
showString String
" }"

instance Show a => Show (SamplingStats a) where
  showsPrec :: Int -> SamplingStats a -> ShowS
showsPrec Int
prec = forall a. Show a => SamplingStats a -> ShowS
showSamplingStats

-- | Show the summary of the statistics using the specified indent.       
samplingStatsSummary :: (Show a) => SamplingStats a -> Int -> ShowS
samplingStatsSummary :: forall a. Show a => SamplingStats a -> Int -> ShowS
samplingStatsSummary SamplingStats a
stats Int
indent =
  let tab :: String
tab = forall a. Int -> a -> [a]
replicate Int
indent Char
' '
  in String -> ShowS
showString String
tab forall b c a. (b -> c) -> (a -> b) -> a -> c
.
     String -> ShowS
showString String
"count = " forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> ShowS
shows (forall a. SamplingStats a -> Int
samplingStatsCount SamplingStats a
stats) forall b c a. (b -> c) -> (a -> b) -> a -> c
.
     String -> ShowS
showString String
"\n" forall b c a. (b -> c) -> (a -> b) -> a -> c
.
     String -> ShowS
showString String
tab forall b c a. (b -> c) -> (a -> b) -> a -> c
.
     String -> ShowS
showString String
"mean = " forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> ShowS
shows (forall a. SamplingStats a -> Double
samplingStatsMean SamplingStats a
stats) forall b c a. (b -> c) -> (a -> b) -> a -> c
. 
     String -> ShowS
showString String
"\n" forall b c a. (b -> c) -> (a -> b) -> a -> c
.
     String -> ShowS
showString String
tab forall b c a. (b -> c) -> (a -> b) -> a -> c
.
     String -> ShowS
showString String
"std = " forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> ShowS
shows (forall a. SamplingStats a -> Double
samplingStatsDeviation SamplingStats a
stats) forall b c a. (b -> c) -> (a -> b) -> a -> c
. 
     String -> ShowS
showString String
"\n" forall b c a. (b -> c) -> (a -> b) -> a -> c
.
     String -> ShowS
showString String
tab forall b c a. (b -> c) -> (a -> b) -> a -> c
.
     String -> ShowS
showString String
"min = " forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> ShowS
shows (forall a. SamplingStats a -> a
samplingStatsMin SamplingStats a
stats) forall b c a. (b -> c) -> (a -> b) -> a -> c
. 
     String -> ShowS
showString String
"\n" forall b c a. (b -> c) -> (a -> b) -> a -> c
.
     String -> ShowS
showString String
tab forall b c a. (b -> c) -> (a -> b) -> a -> c
.
     String -> ShowS
showString String
"max = " forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> ShowS
shows (forall a. SamplingStats a -> a
samplingStatsMax SamplingStats a
stats)
     
-- | This is the timing statistics where data are bound to the time.
data TimingStats a =
  TimingStats { forall a. TimingStats a -> Int
timingStatsCount     :: !Int,
                -- ^ Return the number of samples.
                forall a. TimingStats a -> a
timingStatsMin       :: !a,
                -- ^ Return the minimum value.
                forall a. TimingStats a -> a
timingStatsMax       :: !a,
                -- ^ Return the maximum value.
                forall a. TimingStats a -> a
timingStatsLast      :: !a,
                -- ^ Return the last value.
                forall a. TimingStats a -> Double
timingStatsMinTime   :: !Double,
                -- ^ Return the time at which the minimum is attained.
                forall a. TimingStats a -> Double
timingStatsMaxTime   :: !Double,
                -- ^ Return the time at which the maximum is attained.
                forall a. TimingStats a -> Double
timingStatsStartTime :: !Double,
                -- ^ Return the start time of sampling.
                forall a. TimingStats a -> Double
timingStatsLastTime  :: !Double,
                -- ^ Return the last time of sampling.
                forall a. TimingStats a -> Double
timingStatsSum       :: !Double,
                -- ^ Return the sum of values.
                forall a. TimingStats a -> Double
timingStatsSum2      :: !Double 
                -- ^ Return the sum of square values.
                } deriving (TimingStats a -> TimingStats a -> Bool
forall a. Eq a => TimingStats a -> TimingStats a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: TimingStats a -> TimingStats a -> Bool
$c/= :: forall a. Eq a => TimingStats a -> TimingStats a -> Bool
== :: TimingStats a -> TimingStats a -> Bool
$c== :: forall a. Eq a => TimingStats a -> TimingStats a -> Bool
Eq, TimingStats a -> TimingStats a -> Bool
TimingStats a -> TimingStats a -> Ordering
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall {a}. Ord a => Eq (TimingStats a)
forall a. Ord a => TimingStats a -> TimingStats a -> Bool
forall a. Ord a => TimingStats a -> TimingStats a -> Ordering
forall a. Ord a => TimingStats a -> TimingStats a -> TimingStats a
min :: TimingStats a -> TimingStats a -> TimingStats a
$cmin :: forall a. Ord a => TimingStats a -> TimingStats a -> TimingStats a
max :: TimingStats a -> TimingStats a -> TimingStats a
$cmax :: forall a. Ord a => TimingStats a -> TimingStats a -> TimingStats a
>= :: TimingStats a -> TimingStats a -> Bool
$c>= :: forall a. Ord a => TimingStats a -> TimingStats a -> Bool
> :: TimingStats a -> TimingStats a -> Bool
$c> :: forall a. Ord a => TimingStats a -> TimingStats a -> Bool
<= :: TimingStats a -> TimingStats a -> Bool
$c<= :: forall a. Ord a => TimingStats a -> TimingStats a -> Bool
< :: TimingStats a -> TimingStats a -> Bool
$c< :: forall a. Ord a => TimingStats a -> TimingStats a -> Bool
compare :: TimingStats a -> TimingStats a -> Ordering
$ccompare :: forall a. Ord a => TimingStats a -> TimingStats a -> Ordering
Ord, Typeable, forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall a x. Rep (TimingStats a) x -> TimingStats a
forall a x. TimingStats a -> Rep (TimingStats a) x
$cto :: forall a x. Rep (TimingStats a) x -> TimingStats a
$cfrom :: forall a x. TimingStats a -> Rep (TimingStats a) x
Generic)

instance NFData a => NFData (TimingStats a)
instance Binary a => Binary (TimingStats a)
                           
-- | Defines the data type from which values we can gather the timing statistics.
class Num a => TimingData a where                           
  
  -- | An empty statistics that has no samples.
  emptyTimingStats :: TimingStats a
  
  -- | Add a sample with the specified time to the statistics.
  addTimingStats :: Double -> a -> TimingStats a -> TimingStats a
  
  -- | Return the average value.
  timingStatsMean :: TimingStats a -> Double
  
  -- | Return the average square value.
  timingStatsMean2 :: TimingStats a -> Double
  
  -- | Return the variance.
  timingStatsVariance :: TimingStats a -> Double
  
instance TimingData Double where
  
  emptyTimingStats :: TimingStats Double
emptyTimingStats = 
    TimingStats { timingStatsCount :: Int
timingStatsCount     = Int
0,
                  timingStatsMin :: Double
timingStatsMin       = Double
1 forall a. Fractional a => a -> a -> a
/ Double
0,
                  timingStatsMax :: Double
timingStatsMax       = (-Double
1) forall a. Fractional a => a -> a -> a
/ Double
0,
                  timingStatsLast :: Double
timingStatsLast      = Double
0 forall a. Fractional a => a -> a -> a
/ Double
0,
                  timingStatsMinTime :: Double
timingStatsMinTime   = Double
1 forall a. Fractional a => a -> a -> a
/ Double
0,
                  timingStatsMaxTime :: Double
timingStatsMaxTime   = (-Double
1) forall a. Fractional a => a -> a -> a
/ Double
0,
                  timingStatsStartTime :: Double
timingStatsStartTime = Double
1 forall a. Fractional a => a -> a -> a
/ Double
0,
                  timingStatsLastTime :: Double
timingStatsLastTime  = (-Double
1) forall a. Fractional a => a -> a -> a
/ Double
0,
                  timingStatsSum :: Double
timingStatsSum       = Double
0 forall a. Fractional a => a -> a -> a
/ Double
0,
                  timingStatsSum2 :: Double
timingStatsSum2      = Double
0 forall a. Fractional a => a -> a -> a
/ Double
0 }
    
  addTimingStats :: Double -> Double -> TimingStats Double -> TimingStats Double
addTimingStats      = forall a.
ConvertableToDouble a =>
Double -> a -> TimingStats a -> TimingStats a
addTimingStatsGeneric
  timingStatsMean :: TimingStats Double -> Double
timingStatsMean     = forall a. ConvertableToDouble a => TimingStats a -> Double
timingStatsMeanGeneric
  timingStatsMean2 :: TimingStats Double -> Double
timingStatsMean2    = forall a. ConvertableToDouble a => TimingStats a -> Double
timingStatsMean2Generic
  timingStatsVariance :: TimingStats Double -> Double
timingStatsVariance = forall a. ConvertableToDouble a => TimingStats a -> Double
timingStatsVarianceGeneric

instance TimingData Int where
  
  emptyTimingStats :: TimingStats Int
emptyTimingStats = 
    TimingStats { timingStatsCount :: Int
timingStatsCount     = Int
0,
                  timingStatsMin :: Int
timingStatsMin       = forall a. Bounded a => a
maxBound,
                  timingStatsMax :: Int
timingStatsMax       = forall a. Bounded a => a
minBound,
                  timingStatsLast :: Int
timingStatsLast      = Int
0,
                  timingStatsMinTime :: Double
timingStatsMinTime   = Double
1 forall a. Fractional a => a -> a -> a
/ Double
0,
                  timingStatsMaxTime :: Double
timingStatsMaxTime   = (-Double
1) forall a. Fractional a => a -> a -> a
/ Double
0,
                  timingStatsStartTime :: Double
timingStatsStartTime = Double
1 forall a. Fractional a => a -> a -> a
/ Double
0,
                  timingStatsLastTime :: Double
timingStatsLastTime  = (-Double
1) forall a. Fractional a => a -> a -> a
/ Double
0,
                  timingStatsSum :: Double
timingStatsSum       = Double
0 forall a. Fractional a => a -> a -> a
/ Double
0,
                  timingStatsSum2 :: Double
timingStatsSum2      = Double
0 forall a. Fractional a => a -> a -> a
/ Double
0 }
    
  addTimingStats :: Double -> Int -> TimingStats Int -> TimingStats Int
addTimingStats      = forall a.
ConvertableToDouble a =>
Double -> a -> TimingStats a -> TimingStats a
addTimingStatsGeneric
  timingStatsMean :: TimingStats Int -> Double
timingStatsMean     = forall a. ConvertableToDouble a => TimingStats a -> Double
timingStatsMeanGeneric
  timingStatsMean2 :: TimingStats Int -> Double
timingStatsMean2    = forall a. ConvertableToDouble a => TimingStats a -> Double
timingStatsMean2Generic
  timingStatsVariance :: TimingStats Int -> Double
timingStatsVariance = forall a. ConvertableToDouble a => TimingStats a -> Double
timingStatsVarianceGeneric

addTimingStatsGeneric :: ConvertableToDouble a => Double -> a -> TimingStats a -> TimingStats a
addTimingStatsGeneric :: forall a.
ConvertableToDouble a =>
Double -> a -> TimingStats a -> TimingStats a
addTimingStatsGeneric Double
t a
a TimingStats a
stats
  | Double
t forall a. Ord a => a -> a -> Bool
< Double
t'     = forall a. HasCallStack => String -> a
error String
"The current time cannot be less than the previous one: addTimingStats"
  | forall a. RealFloat a => a -> Bool
isNaN Double
x    = TimingStats a
stats
  | Int
count forall a. Eq a => a -> a -> Bool
== Int
1 = TimingStats { timingStatsCount :: Int
timingStatsCount     = Int
1,
                               timingStatsMin :: a
timingStatsMin       = a
a,
                               timingStatsMax :: a
timingStatsMax       = a
a,
                               timingStatsLast :: a
timingStatsLast      = a
a,
                               timingStatsMinTime :: Double
timingStatsMinTime   = Double
t,
                               timingStatsMaxTime :: Double
timingStatsMaxTime   = Double
t,
                               timingStatsStartTime :: Double
timingStatsStartTime = Double
t,
                               timingStatsLastTime :: Double
timingStatsLastTime  = Double
t,
                               timingStatsSum :: Double
timingStatsSum       = Double
0,
                               timingStatsSum2 :: Double
timingStatsSum2      = Double
0 }
  | Bool
otherwise  = TimingStats { timingStatsCount :: Int
timingStatsCount     = Int
count,
                               timingStatsMin :: a
timingStatsMin       = a
minX,
                               timingStatsMax :: a
timingStatsMax       = a
maxX,
                               timingStatsLast :: a
timingStatsLast      = a
a,
                               timingStatsMinTime :: Double
timingStatsMinTime   = Double
minT,
                               timingStatsMaxTime :: Double
timingStatsMaxTime   = Double
maxT,
                               timingStatsStartTime :: Double
timingStatsStartTime = Double
t0,
                               timingStatsLastTime :: Double
timingStatsLastTime  = Double
t,
                               timingStatsSum :: Double
timingStatsSum       = Double
sumX,
                               timingStatsSum2 :: Double
timingStatsSum2      = Double
sumX2 }
    where count :: Int
count = Int
1 forall a. Num a => a -> a -> a
+ forall a. TimingStats a -> Int
timingStatsCount TimingStats a
stats
          minX' :: a
minX' = forall a. TimingStats a -> a
timingStatsMin TimingStats a
stats
          maxX' :: a
maxX' = forall a. TimingStats a -> a
timingStatsMax TimingStats a
stats
          minX :: a
minX  = a
a seq :: forall a b. a -> b -> b
`seq` forall a. Ord a => a -> a -> a
min a
a a
minX'
          maxX :: a
maxX  = a
a seq :: forall a b. a -> b -> b
`seq` forall a. Ord a => a -> a -> a
max a
a a
maxX'
          minT :: Double
minT | a
a forall a. Ord a => a -> a -> Bool
< a
minX' = Double
t
               | Bool
otherwise = forall a. TimingStats a -> Double
timingStatsMinTime TimingStats a
stats
          maxT :: Double
maxT | a
a forall a. Ord a => a -> a -> Bool
> a
maxX' = Double
t
               | Bool
otherwise = forall a. TimingStats a -> Double
timingStatsMaxTime TimingStats a
stats
          t0 :: Double
t0 = forall a. TimingStats a -> Double
timingStatsStartTime TimingStats a
stats
          t' :: Double
t' = forall a. TimingStats a -> Double
timingStatsLastTime TimingStats a
stats
          a' :: a
a' = forall a. TimingStats a -> a
timingStatsLast TimingStats a
stats
          x :: Double
x  = forall a. ConvertableToDouble a => a -> Double
convertToDouble a
a
          x' :: Double
x' = forall a. ConvertableToDouble a => a -> Double
convertToDouble a
a'
          sumX' :: Double
sumX'  = forall a. TimingStats a -> Double
timingStatsSum TimingStats a
stats
          sumX :: Double
sumX   = Double
sumX' forall a. Num a => a -> a -> a
+ (Double
t forall a. Num a => a -> a -> a
- Double
t') forall a. Num a => a -> a -> a
* Double
x'
          sumX2' :: Double
sumX2' = forall a. TimingStats a -> Double
timingStatsSum2 TimingStats a
stats
          sumX2 :: Double
sumX2  = Double
sumX2' forall a. Num a => a -> a -> a
+ (Double
t forall a. Num a => a -> a -> a
- Double
t') forall a. Num a => a -> a -> a
* Double
x' forall a. Num a => a -> a -> a
* Double
x'
      
timingStatsMeanGeneric :: ConvertableToDouble a => TimingStats a -> Double
timingStatsMeanGeneric :: forall a. ConvertableToDouble a => TimingStats a -> Double
timingStatsMeanGeneric TimingStats a
stats
  | Int
count forall a. Eq a => a -> a -> Bool
== Int
0 = Double
0 forall a. Fractional a => a -> a -> a
/ Double
0
  | Double
t1 forall a. Ord a => a -> a -> Bool
> Double
t0    = Double
sumX forall a. Fractional a => a -> a -> a
/ (Double
t1 forall a. Num a => a -> a -> a
- Double
t0)
  | Bool
otherwise  = Double
minX
    where t0 :: Double
t0    = forall a. TimingStats a -> Double
timingStatsStartTime TimingStats a
stats
          t1 :: Double
t1    = forall a. TimingStats a -> Double
timingStatsLastTime TimingStats a
stats
          sumX :: Double
sumX  = forall a. TimingStats a -> Double
timingStatsSum TimingStats a
stats
          minX :: Double
minX  = forall a. ConvertableToDouble a => a -> Double
convertToDouble forall a b. (a -> b) -> a -> b
$ forall a. TimingStats a -> a
timingStatsMin TimingStats a
stats
          count :: Int
count = forall a. TimingStats a -> Int
timingStatsCount TimingStats a
stats
  
timingStatsMean2Generic :: ConvertableToDouble a => TimingStats a -> Double
timingStatsMean2Generic :: forall a. ConvertableToDouble a => TimingStats a -> Double
timingStatsMean2Generic TimingStats a
stats
  | Int
count forall a. Eq a => a -> a -> Bool
== Int
0 = Double
0 forall a. Fractional a => a -> a -> a
/ Double
0
  | Double
t1 forall a. Ord a => a -> a -> Bool
> Double
t0    = Double
sumX2 forall a. Fractional a => a -> a -> a
/ (Double
t1 forall a. Num a => a -> a -> a
- Double
t0)
  | Bool
otherwise  = Double
minX forall a. Num a => a -> a -> a
* Double
minX
    where t0 :: Double
t0    = forall a. TimingStats a -> Double
timingStatsStartTime TimingStats a
stats
          t1 :: Double
t1    = forall a. TimingStats a -> Double
timingStatsLastTime TimingStats a
stats
          sumX2 :: Double
sumX2 = forall a. TimingStats a -> Double
timingStatsSum2 TimingStats a
stats
          minX :: Double
minX  = forall a. ConvertableToDouble a => a -> Double
convertToDouble forall a b. (a -> b) -> a -> b
$ forall a. TimingStats a -> a
timingStatsMin TimingStats a
stats
          count :: Int
count = forall a. TimingStats a -> Int
timingStatsCount TimingStats a
stats

timingStatsVarianceGeneric :: ConvertableToDouble a => TimingStats a -> Double
timingStatsVarianceGeneric :: forall a. ConvertableToDouble a => TimingStats a -> Double
timingStatsVarianceGeneric TimingStats a
stats = Double
ex2 forall a. Num a => a -> a -> a
- Double
ex forall a. Num a => a -> a -> a
* Double
ex
  where ex :: Double
ex  = forall a. ConvertableToDouble a => TimingStats a -> Double
timingStatsMeanGeneric TimingStats a
stats
        ex2 :: Double
ex2 = forall a. ConvertableToDouble a => TimingStats a -> Double
timingStatsMean2Generic TimingStats a
stats
                
-- | Return the deviation.              
timingStatsDeviation :: TimingData a => TimingStats a -> Double
timingStatsDeviation :: forall a. TimingData a => TimingStats a -> Double
timingStatsDeviation = forall a. Floating a => a -> a
sqrt forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. TimingData a => TimingStats a -> Double
timingStatsVariance

-- | Return the statistics by single timing data.
returnTimingStats :: TimingData a => Double -> a -> TimingStats a
returnTimingStats :: forall a. TimingData a => Double -> a -> TimingStats a
returnTimingStats Double
t a
a = forall a.
TimingData a =>
Double -> a -> TimingStats a -> TimingStats a
addTimingStats Double
t a
a forall a. TimingData a => TimingStats a
emptyTimingStats

-- | Convert the statistics from integer to double values.
fromIntTimingStats :: TimingStats Int -> TimingStats Double
fromIntTimingStats :: TimingStats Int -> TimingStats Double
fromIntTimingStats TimingStats Int
stats =
  TimingStats Int
stats { timingStatsMin :: Double
timingStatsMin  = forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ forall a. TimingStats a -> a
timingStatsMin TimingStats Int
stats,
          timingStatsMax :: Double
timingStatsMax  = forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ forall a. TimingStats a -> a
timingStatsMax TimingStats Int
stats,
          timingStatsLast :: Double
timingStatsLast = forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ forall a. TimingStats a -> a
timingStatsLast TimingStats Int
stats }

-- | Convert the statistics to its normalised sampling-based representation,
-- where the first argument specifies the number of pseudo-samples.
normTimingStats :: TimingData a => Int -> TimingStats a -> SamplingStats a
normTimingStats :: forall a. TimingData a => Int -> TimingStats a -> SamplingStats a
normTimingStats Int
n TimingStats a
stats =
  SamplingStats { samplingStatsCount :: Int
samplingStatsCount = Int
n,
                  samplingStatsMin :: a
samplingStatsMin   = forall a. TimingStats a -> a
timingStatsMin TimingStats a
stats,
                  samplingStatsMax :: a
samplingStatsMax   = forall a. TimingStats a -> a
timingStatsMax TimingStats a
stats,
                  samplingStatsMean :: Double
samplingStatsMean  = forall a. TimingData a => TimingStats a -> Double
timingStatsMean TimingStats a
stats,
                  samplingStatsMean2 :: Double
samplingStatsMean2 = forall a. TimingData a => TimingStats a -> Double
timingStatsMean2 TimingStats a
stats }

-- | Show the summary of the statistics.       
showTimingStats :: (Show a, TimingData a) => TimingStats a -> ShowS
showTimingStats :: forall a. (Show a, TimingData a) => TimingStats a -> ShowS
showTimingStats TimingStats a
stats =
  String -> ShowS
showString String
"{ count = " forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> ShowS
shows (forall a. TimingStats a -> Int
timingStatsCount TimingStats a
stats) forall b c a. (b -> c) -> (a -> b) -> a -> c
. 
  String -> ShowS
showString String
", mean = " forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> ShowS
shows (forall a. TimingData a => TimingStats a -> Double
timingStatsMean TimingStats a
stats) forall b c a. (b -> c) -> (a -> b) -> a -> c
. 
  String -> ShowS
showString String
", std = " forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> ShowS
shows (forall a. TimingData a => TimingStats a -> Double
timingStatsDeviation TimingStats a
stats) forall b c a. (b -> c) -> (a -> b) -> a -> c
. 
  String -> ShowS
showString String
", min = " forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> ShowS
shows (forall a. TimingStats a -> a
timingStatsMin TimingStats a
stats) forall b c a. (b -> c) -> (a -> b) -> a -> c
. 
  String -> ShowS
showString String
" (t = " forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> ShowS
shows (forall a. TimingStats a -> Double
timingStatsMinTime TimingStats a
stats) forall b c a. (b -> c) -> (a -> b) -> a -> c
.
  String -> ShowS
showString String
"), max = " forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> ShowS
shows (forall a. TimingStats a -> a
timingStatsMax TimingStats a
stats) forall b c a. (b -> c) -> (a -> b) -> a -> c
.
  String -> ShowS
showString String
" (t = " forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> ShowS
shows (forall a. TimingStats a -> Double
timingStatsMaxTime TimingStats a
stats) forall b c a. (b -> c) -> (a -> b) -> a -> c
.
  String -> ShowS
showString String
"), t in [" forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> ShowS
shows (forall a. TimingStats a -> Double
timingStatsStartTime TimingStats a
stats) forall b c a. (b -> c) -> (a -> b) -> a -> c
.
  String -> ShowS
showString String
", " forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> ShowS
shows (forall a. TimingStats a -> Double
timingStatsLastTime TimingStats a
stats) forall b c a. (b -> c) -> (a -> b) -> a -> c
.
  String -> ShowS
showString String
"] }"

instance (Show a, TimingData a) => Show (TimingStats a) where
  showsPrec :: Int -> TimingStats a -> ShowS
showsPrec Int
prec = forall a. (Show a, TimingData a) => TimingStats a -> ShowS
showTimingStats

-- | Show the summary of the statistics using the specified indent.       
timingStatsSummary :: (Show a, TimingData a) => TimingStats a -> Int -> ShowS
timingStatsSummary :: forall a. (Show a, TimingData a) => TimingStats a -> Int -> ShowS
timingStatsSummary TimingStats a
stats Int
indent =
  let tab :: String
tab = forall a. Int -> a -> [a]
replicate Int
indent Char
' '
  in String -> ShowS
showString String
tab forall b c a. (b -> c) -> (a -> b) -> a -> c
.
     String -> ShowS
showString String
"count = " forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> ShowS
shows (forall a. TimingStats a -> Int
timingStatsCount TimingStats a
stats) forall b c a. (b -> c) -> (a -> b) -> a -> c
. 
     String -> ShowS
showString String
"\n" forall b c a. (b -> c) -> (a -> b) -> a -> c
.
     String -> ShowS
showString String
tab forall b c a. (b -> c) -> (a -> b) -> a -> c
.
     String -> ShowS
showString String
"mean = " forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> ShowS
shows (forall a. TimingData a => TimingStats a -> Double
timingStatsMean TimingStats a
stats) forall b c a. (b -> c) -> (a -> b) -> a -> c
. 
     String -> ShowS
showString String
"\n" forall b c a. (b -> c) -> (a -> b) -> a -> c
.
     String -> ShowS
showString String
tab forall b c a. (b -> c) -> (a -> b) -> a -> c
.
     String -> ShowS
showString String
"std = " forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> ShowS
shows (forall a. TimingData a => TimingStats a -> Double
timingStatsDeviation TimingStats a
stats) forall b c a. (b -> c) -> (a -> b) -> a -> c
. 
     String -> ShowS
showString String
"\n" forall b c a. (b -> c) -> (a -> b) -> a -> c
.
     String -> ShowS
showString String
tab forall b c a. (b -> c) -> (a -> b) -> a -> c
.
     String -> ShowS
showString String
"min = " forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> ShowS
shows (forall a. TimingStats a -> a
timingStatsMin TimingStats a
stats) forall b c a. (b -> c) -> (a -> b) -> a -> c
. 
     String -> ShowS
showString String
" (t = " forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> ShowS
shows (forall a. TimingStats a -> Double
timingStatsMinTime TimingStats a
stats) forall b c a. (b -> c) -> (a -> b) -> a -> c
.
     String -> ShowS
showString String
")\n" forall b c a. (b -> c) -> (a -> b) -> a -> c
.
     String -> ShowS
showString String
tab forall b c a. (b -> c) -> (a -> b) -> a -> c
.
     String -> ShowS
showString String
"max = " forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> ShowS
shows (forall a. TimingStats a -> a
timingStatsMax TimingStats a
stats) forall b c a. (b -> c) -> (a -> b) -> a -> c
.
     String -> ShowS
showString String
" (t = " forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> ShowS
shows (forall a. TimingStats a -> Double
timingStatsMaxTime TimingStats a
stats) forall b c a. (b -> c) -> (a -> b) -> a -> c
.
     String -> ShowS
showString String
")\n" forall b c a. (b -> c) -> (a -> b) -> a -> c
.
     String -> ShowS
showString String
tab forall b c a. (b -> c) -> (a -> b) -> a -> c
.
     String -> ShowS
showString String
"t in [" forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> ShowS
shows (forall a. TimingStats a -> Double
timingStatsStartTime TimingStats a
stats) forall b c a. (b -> c) -> (a -> b) -> a -> c
.
     String -> ShowS
showString String
", " forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> ShowS
shows (forall a. TimingStats a -> Double
timingStatsLastTime TimingStats a
stats) forall b c a. (b -> c) -> (a -> b) -> a -> c
.
     String -> ShowS
showString String
"]"

-- | A counter for which the statistics is collected too.
data SamplingCounter a =
  SamplingCounter { forall a. SamplingCounter a -> a
samplingCounterValue :: a,
                    -- ^ The counter value.
                    forall a. SamplingCounter a -> SamplingStats a
samplingCounterStats :: SamplingStats a
                    -- ^ The counter statistics.
                  } deriving (SamplingCounter a -> SamplingCounter a -> Bool
forall a. Eq a => SamplingCounter a -> SamplingCounter a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: SamplingCounter a -> SamplingCounter a -> Bool
$c/= :: forall a. Eq a => SamplingCounter a -> SamplingCounter a -> Bool
== :: SamplingCounter a -> SamplingCounter a -> Bool
$c== :: forall a. Eq a => SamplingCounter a -> SamplingCounter a -> Bool
Eq, SamplingCounter a -> SamplingCounter a -> Bool
SamplingCounter a -> SamplingCounter a -> Ordering
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall {a}. Ord a => Eq (SamplingCounter a)
forall a. Ord a => SamplingCounter a -> SamplingCounter a -> Bool
forall a.
Ord a =>
SamplingCounter a -> SamplingCounter a -> Ordering
forall a.
Ord a =>
SamplingCounter a -> SamplingCounter a -> SamplingCounter a
min :: SamplingCounter a -> SamplingCounter a -> SamplingCounter a
$cmin :: forall a.
Ord a =>
SamplingCounter a -> SamplingCounter a -> SamplingCounter a
max :: SamplingCounter a -> SamplingCounter a -> SamplingCounter a
$cmax :: forall a.
Ord a =>
SamplingCounter a -> SamplingCounter a -> SamplingCounter a
>= :: SamplingCounter a -> SamplingCounter a -> Bool
$c>= :: forall a. Ord a => SamplingCounter a -> SamplingCounter a -> Bool
> :: SamplingCounter a -> SamplingCounter a -> Bool
$c> :: forall a. Ord a => SamplingCounter a -> SamplingCounter a -> Bool
<= :: SamplingCounter a -> SamplingCounter a -> Bool
$c<= :: forall a. Ord a => SamplingCounter a -> SamplingCounter a -> Bool
< :: SamplingCounter a -> SamplingCounter a -> Bool
$c< :: forall a. Ord a => SamplingCounter a -> SamplingCounter a -> Bool
compare :: SamplingCounter a -> SamplingCounter a -> Ordering
$ccompare :: forall a.
Ord a =>
SamplingCounter a -> SamplingCounter a -> Ordering
Ord, Int -> SamplingCounter a -> ShowS
forall a. Show a => Int -> SamplingCounter a -> ShowS
forall a. Show a => [SamplingCounter a] -> ShowS
forall a. Show a => SamplingCounter a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [SamplingCounter a] -> ShowS
$cshowList :: forall a. Show a => [SamplingCounter a] -> ShowS
show :: SamplingCounter a -> String
$cshow :: forall a. Show a => SamplingCounter a -> String
showsPrec :: Int -> SamplingCounter a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> SamplingCounter a -> ShowS
Show, Typeable, forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall a x. Rep (SamplingCounter a) x -> SamplingCounter a
forall a x. SamplingCounter a -> Rep (SamplingCounter a) x
$cto :: forall a x. Rep (SamplingCounter a) x -> SamplingCounter a
$cfrom :: forall a x. SamplingCounter a -> Rep (SamplingCounter a) x
Generic)

instance NFData a => NFData (SamplingCounter a)
instance Binary a => Binary (SamplingCounter a)

-- | An empty counter.
emptySamplingCounter :: SamplingData a => SamplingCounter a
emptySamplingCounter :: forall a. SamplingData a => SamplingCounter a
emptySamplingCounter =
  SamplingCounter { samplingCounterValue :: a
samplingCounterValue = a
0,
                    samplingCounterStats :: SamplingStats a
samplingCounterStats = forall a. SamplingData a => SamplingStats a
emptySamplingStats }

-- | Increase the counter.
incSamplingCounter :: SamplingData a => a -> SamplingCounter a -> SamplingCounter a
incSamplingCounter :: forall a.
SamplingData a =>
a -> SamplingCounter a -> SamplingCounter a
incSamplingCounter a
a SamplingCounter a
counter =
  SamplingCounter { samplingCounterValue :: a
samplingCounterValue = a
a',
                    samplingCounterStats :: SamplingStats a
samplingCounterStats = forall a. SamplingData a => a -> SamplingStats a -> SamplingStats a
addSamplingStats a
a' (forall a. SamplingCounter a -> SamplingStats a
samplingCounterStats SamplingCounter a
counter) }
  where a' :: a
a' = forall a. SamplingCounter a -> a
samplingCounterValue SamplingCounter a
counter forall a. Num a => a -> a -> a
+ a
a

-- | Decrease the counter.
decSamplingCounter :: SamplingData a => a -> SamplingCounter a -> SamplingCounter a
decSamplingCounter :: forall a.
SamplingData a =>
a -> SamplingCounter a -> SamplingCounter a
decSamplingCounter a
a SamplingCounter a
counter =
  SamplingCounter { samplingCounterValue :: a
samplingCounterValue = a
a',
                    samplingCounterStats :: SamplingStats a
samplingCounterStats = forall a. SamplingData a => a -> SamplingStats a -> SamplingStats a
addSamplingStats a
a' (forall a. SamplingCounter a -> SamplingStats a
samplingCounterStats SamplingCounter a
counter) }
  where a' :: a
a' = forall a. SamplingCounter a -> a
samplingCounterValue SamplingCounter a
counter forall a. Num a => a -> a -> a
- a
a

-- | Set a new value for the counter.
setSamplingCounter :: SamplingData a => a -> SamplingCounter a -> SamplingCounter a
setSamplingCounter :: forall a.
SamplingData a =>
a -> SamplingCounter a -> SamplingCounter a
setSamplingCounter a
a SamplingCounter a
counter =
  SamplingCounter { samplingCounterValue :: a
samplingCounterValue = a
a,
                    samplingCounterStats :: SamplingStats a
samplingCounterStats = forall a. SamplingData a => a -> SamplingStats a -> SamplingStats a
addSamplingStats a
a (forall a. SamplingCounter a -> SamplingStats a
samplingCounterStats SamplingCounter a
counter) }

-- | Create a counter with the specified initial value.
returnSamplingCounter :: SamplingData  a => a -> SamplingCounter a
returnSamplingCounter :: forall a. SamplingData a => a -> SamplingCounter a
returnSamplingCounter a
a =
  SamplingCounter { samplingCounterValue :: a
samplingCounterValue = a
a,
                    samplingCounterStats :: SamplingStats a
samplingCounterStats = forall a. SamplingData a => a -> SamplingStats a
returnSamplingStats a
a }

-- | A counter for which the timing statistics is collected too.
data TimingCounter a =
  TimingCounter { forall a. TimingCounter a -> a
timingCounterValue :: a,
                  -- ^ The counter value.
                  forall a. TimingCounter a -> TimingStats a
timingCounterStats :: TimingStats a
                  -- ^ The counter statistics.
                } deriving (TimingCounter a -> TimingCounter a -> Bool
forall a. Eq a => TimingCounter a -> TimingCounter a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: TimingCounter a -> TimingCounter a -> Bool
$c/= :: forall a. Eq a => TimingCounter a -> TimingCounter a -> Bool
== :: TimingCounter a -> TimingCounter a -> Bool
$c== :: forall a. Eq a => TimingCounter a -> TimingCounter a -> Bool
Eq, TimingCounter a -> TimingCounter a -> Bool
TimingCounter a -> TimingCounter a -> Ordering
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall {a}. Ord a => Eq (TimingCounter a)
forall a. Ord a => TimingCounter a -> TimingCounter a -> Bool
forall a. Ord a => TimingCounter a -> TimingCounter a -> Ordering
forall a.
Ord a =>
TimingCounter a -> TimingCounter a -> TimingCounter a
min :: TimingCounter a -> TimingCounter a -> TimingCounter a
$cmin :: forall a.
Ord a =>
TimingCounter a -> TimingCounter a -> TimingCounter a
max :: TimingCounter a -> TimingCounter a -> TimingCounter a
$cmax :: forall a.
Ord a =>
TimingCounter a -> TimingCounter a -> TimingCounter a
>= :: TimingCounter a -> TimingCounter a -> Bool
$c>= :: forall a. Ord a => TimingCounter a -> TimingCounter a -> Bool
> :: TimingCounter a -> TimingCounter a -> Bool
$c> :: forall a. Ord a => TimingCounter a -> TimingCounter a -> Bool
<= :: TimingCounter a -> TimingCounter a -> Bool
$c<= :: forall a. Ord a => TimingCounter a -> TimingCounter a -> Bool
< :: TimingCounter a -> TimingCounter a -> Bool
$c< :: forall a. Ord a => TimingCounter a -> TimingCounter a -> Bool
compare :: TimingCounter a -> TimingCounter a -> Ordering
$ccompare :: forall a. Ord a => TimingCounter a -> TimingCounter a -> Ordering
Ord, Int -> TimingCounter a -> ShowS
forall a. (Show a, TimingData a) => Int -> TimingCounter a -> ShowS
forall a. (Show a, TimingData a) => [TimingCounter a] -> ShowS
forall a. (Show a, TimingData a) => TimingCounter a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [TimingCounter a] -> ShowS
$cshowList :: forall a. (Show a, TimingData a) => [TimingCounter a] -> ShowS
show :: TimingCounter a -> String
$cshow :: forall a. (Show a, TimingData a) => TimingCounter a -> String
showsPrec :: Int -> TimingCounter a -> ShowS
$cshowsPrec :: forall a. (Show a, TimingData a) => Int -> TimingCounter a -> ShowS
Show, Typeable, forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall a x. Rep (TimingCounter a) x -> TimingCounter a
forall a x. TimingCounter a -> Rep (TimingCounter a) x
$cto :: forall a x. Rep (TimingCounter a) x -> TimingCounter a
$cfrom :: forall a x. TimingCounter a -> Rep (TimingCounter a) x
Generic)

instance NFData a => NFData (TimingCounter a)
instance Binary a => Binary (TimingCounter a)

-- | An empty counter.
emptyTimingCounter :: TimingData a => TimingCounter a
emptyTimingCounter :: forall a. TimingData a => TimingCounter a
emptyTimingCounter =
  TimingCounter { timingCounterValue :: a
timingCounterValue = a
0,
                  timingCounterStats :: TimingStats a
timingCounterStats = forall a. TimingData a => TimingStats a
emptyTimingStats }

-- | Increase the counter at the specified time.
incTimingCounter :: TimingData a => Double -> a -> TimingCounter a -> TimingCounter a
incTimingCounter :: forall a.
TimingData a =>
Double -> a -> TimingCounter a -> TimingCounter a
incTimingCounter Double
t a
a TimingCounter a
counter =
  TimingCounter { timingCounterValue :: a
timingCounterValue = a
a',
                  timingCounterStats :: TimingStats a
timingCounterStats = forall a.
TimingData a =>
Double -> a -> TimingStats a -> TimingStats a
addTimingStats Double
t a
a' (forall a. TimingCounter a -> TimingStats a
timingCounterStats TimingCounter a
counter) }
  where a' :: a
a' = forall a. TimingCounter a -> a
timingCounterValue TimingCounter a
counter forall a. Num a => a -> a -> a
+ a
a

-- | Decrease the counter at the specified time.
decTimingCounter :: TimingData a => Double -> a -> TimingCounter a -> TimingCounter a
decTimingCounter :: forall a.
TimingData a =>
Double -> a -> TimingCounter a -> TimingCounter a
decTimingCounter Double
t a
a TimingCounter a
counter =
  TimingCounter { timingCounterValue :: a
timingCounterValue = a
a',
                  timingCounterStats :: TimingStats a
timingCounterStats = forall a.
TimingData a =>
Double -> a -> TimingStats a -> TimingStats a
addTimingStats Double
t a
a' (forall a. TimingCounter a -> TimingStats a
timingCounterStats TimingCounter a
counter) }
  where a' :: a
a' = forall a. TimingCounter a -> a
timingCounterValue TimingCounter a
counter forall a. Num a => a -> a -> a
- a
a

-- | Set a new value for the counter at the specified time.
setTimingCounter :: TimingData a => Double -> a -> TimingCounter a -> TimingCounter a
setTimingCounter :: forall a.
TimingData a =>
Double -> a -> TimingCounter a -> TimingCounter a
setTimingCounter Double
t a
a TimingCounter a
counter =
  TimingCounter { timingCounterValue :: a
timingCounterValue = a
a,
                  timingCounterStats :: TimingStats a
timingCounterStats = forall a.
TimingData a =>
Double -> a -> TimingStats a -> TimingStats a
addTimingStats Double
t a
a (forall a. TimingCounter a -> TimingStats a
timingCounterStats TimingCounter a
counter) }

-- | Create a timing counter with the specified initial value at the given time.
returnTimingCounter :: TimingData a => Double -> a -> TimingCounter a
returnTimingCounter :: forall a. TimingData a => Double -> a -> TimingCounter a
returnTimingCounter Double
t a
a =
  TimingCounter { timingCounterValue :: a
timingCounterValue = a
a,
                  timingCounterStats :: TimingStats a
timingCounterStats = forall a. TimingData a => Double -> a -> TimingStats a
returnTimingStats Double
t a
a }