criterion-0.5.1.0: Criterion/Analysis/Types.hs
{-# LANGUAGE DeriveDataTypeable, OverloadedStrings, RecordWildCards #-}
-- |
-- Module : Criterion.Analysis.Types
-- Copyright : (c) 2011 Bryan O'Sullivan
--
-- License : BSD-style
-- Maintainer : bos@serpentine.com
-- Stability : experimental
-- Portability : GHC
--
-- Analysis types.
module Criterion.Analysis.Types
(
Outliers (..)
, OutlierEffect(..)
, OutlierVariance(..)
, SampleAnalysis(..)
) where
import Control.Applicative ((<$>), (<*>), empty, pure)
import Control.DeepSeq (NFData(rnf))
import Data.Aeson.Types
import Data.Data (Data)
import Data.Int (Int64)
import Data.Monoid (Monoid(..))
import Data.Typeable (Typeable)
import qualified Statistics.Resampling.Bootstrap as B
-- | Outliers from sample data, calculated using the boxplot
-- technique.
data Outliers = Outliers {
samplesSeen :: {-# UNPACK #-} !Int64
, lowSevere :: {-# UNPACK #-} !Int64
-- ^ More than 3 times the interquartile range (IQR) below the
-- first quartile.
, lowMild :: {-# UNPACK #-} !Int64
-- ^ Between 1.5 and 3 times the IQR below the first quartile.
, highMild :: {-# UNPACK #-} !Int64
-- ^ Between 1.5 and 3 times the IQR above the third quartile.
, highSevere :: {-# UNPACK #-} !Int64
-- ^ More than 3 times the IQR above the third quartile.
} deriving (Eq, Read, Show, Typeable, Data)
instance NFData Outliers
instance ToJSON Outliers where
toJSON Outliers{..} = object [
"samplesSeen" .= samplesSeen
, "lowSevere" .= lowSevere
, "lowMild" .= lowMild
, "highMild" .= highMild
, "highSevere" .= highSevere
]
instance FromJSON Outliers where
parseJSON (Object v) = Outliers <$>
v .: "samplesSeen" <*>
v .: "lowSevere" <*>
v .: "lowMild" <*>
v .: "highMild" <*>
v .: "highSevere"
parseJSON _ = empty
-- | A description of the extent to which outliers in the sample data
-- affect the sample mean and standard deviation.
data OutlierEffect = Unaffected -- ^ Less than 1% effect.
| Slight -- ^ Between 1% and 10%.
| Moderate -- ^ Between 10% and 50%.
| Severe -- ^ Above 50% (i.e. measurements
-- are useless).
deriving (Eq, Ord, Read, Show, Typeable, Data)
instance NFData OutlierEffect
instance ToJSON OutlierEffect where
toJSON Unaffected = "unaffected"
toJSON Slight = "slight"
toJSON Moderate = "moderate"
toJSON Severe = "severe"
instance FromJSON OutlierEffect where
parseJSON (String t) = case t of
_| t== "unaffected" -> pure Unaffected
_| t== "slight" -> pure Slight
_| t== "moderate" -> pure Moderate
_| t== "severe" -> pure Severe
| otherwise -> empty
parseJSON _ = empty
instance Monoid Outliers where
mempty = Outliers 0 0 0 0 0
mappend = addOutliers
addOutliers :: Outliers -> Outliers -> Outliers
addOutliers (Outliers s a b c d) (Outliers t w x y z) =
Outliers (s+t) (a+w) (b+x) (c+y) (d+z)
{-# INLINE addOutliers #-}
-- | Analysis of the extent to which outliers in a sample affect its
-- mean and standard deviation.
data OutlierVariance = OutlierVariance {
ovEffect :: OutlierEffect
-- ^ Qualitative description of effect.
, ovFraction :: Double
-- ^ Quantitative description of effect (a fraction between 0 and 1).
} deriving (Eq, Read, Show, Typeable, Data)
instance NFData OutlierVariance where
rnf OutlierVariance{..} = rnf ovEffect `seq` rnf ovFraction `seq` ()
instance ToJSON OutlierVariance where
toJSON OutlierVariance{..} = object [
"effect" .= ovEffect
, "fraction" .= ovFraction
]
instance FromJSON OutlierVariance where
parseJSON (Object v) = OutlierVariance <$>
v .: "effect" <*>
v .: "fraction"
parseJSON _ = empty
-- | Result of a bootstrap analysis of a non-parametric sample.
data SampleAnalysis = SampleAnalysis {
anMean :: B.Estimate
, anStdDev :: B.Estimate
, anOutliers :: OutlierVariance
} deriving (Eq, Show, Typeable, Data)
instance NFData SampleAnalysis where
rnf SampleAnalysis{..} =
rnf anMean `seq` rnf anStdDev `seq` rnf anOutliers `seq` ()
instance ToJSON SampleAnalysis where
toJSON SampleAnalysis{..} = object [
"mean" .= anMean
, "stdDev" .= anStdDev
, "outliers" .= anOutliers
]
instance FromJSON SampleAnalysis where
parseJSON (Object v) = SampleAnalysis <$>
v .: "mean" <*>
v .: "stdDev" <*>
v .: "outliers"
parseJSON _ = empty