{-# LANGUAGE CPP #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE DeriveDataTypeable, DeriveGeneric #-}
module Statistics.Types
(
CL
, confidenceLevel
, significanceLevel
, mkCL
, mkCLE
, mkCLFromSignificance
, mkCLFromSignificanceE
, cl90
, cl95
, cl99
, nSigma
, nSigma1
, getNSigma
, getNSigma1
, PValue
, pValue
, mkPValue
, mkPValueE
, Estimate(..)
, NormalErr(..)
, ConfInt(..)
, UpperLimit(..)
, LowerLimit(..)
, estimateNormErr
, (±)
, estimateFromInterval
, estimateFromErr
, confidenceInterval
, asymErrors
, Scale(..)
, Sample
, WeightedSample
, Weights
) where
import Control.Monad ((<=<), liftM2, liftM3)
import Control.DeepSeq (NFData(..))
import Data.Aeson (FromJSON(..), ToJSON)
import Data.Binary (Binary(..))
import Data.Data (Data,Typeable)
import Data.Maybe (fromMaybe)
import Data.Vector.Unboxed (Unbox)
import Data.Vector.Unboxed.Deriving (derivingUnbox)
import GHC.Generics (Generic)
#if __GLASGOW_HASKELL__ == 704
import qualified Data.Vector.Generic
import qualified Data.Vector.Generic.Mutable
#endif
import Statistics.Internal
import Statistics.Types.Internal
import Statistics.Distribution
import Statistics.Distribution.Normal
newtype CL a = CL a
deriving (Eq, Typeable, Data, Generic)
instance Show a => Show (CL a) where
showsPrec n (CL p) = defaultShow1 "mkCLFromSignificance" p n
instance (Num a, Ord a, Read a) => Read (CL a) where
readPrec = defaultReadPrecM1 "mkCLFromSignificance" mkCLFromSignificanceE
instance (Binary a, Num a, Ord a) => Binary (CL a) where
put (CL p) = put p
get = maybe (fail errMkCL) return . mkCLFromSignificanceE =<< get
instance (ToJSON a) => ToJSON (CL a)
instance (FromJSON a, Num a, Ord a) => FromJSON (CL a) where
parseJSON = maybe (fail errMkCL) return . mkCLFromSignificanceE <=< parseJSON
instance NFData a => NFData (CL a) where
rnf (CL a) = rnf a
instance Ord a => Ord (CL a) where
CL a < CL b = a > b
CL a <= CL b = a >= b
CL a > CL b = a < b
CL a >= CL b = a <= b
max (CL a) (CL b) = CL (min a b)
min (CL a) (CL b) = CL (max a b)
mkCL :: (Ord a, Num a) => a -> CL a
mkCL
= fromMaybe (error "Statistics.Types.mkCL: probability is out if [0,1] range")
. mkCLE
mkCLE :: (Ord a, Num a) => a -> Maybe (CL a)
mkCLE p
| p >= 0 && p <= 1 = Just $ CL (1 - p)
| otherwise = Nothing
mkCLFromSignificance :: (Ord a, Num a) => a -> CL a
mkCLFromSignificance = fromMaybe (error errMkCL) . mkCLFromSignificanceE
mkCLFromSignificanceE :: (Ord a, Num a) => a -> Maybe (CL a)
mkCLFromSignificanceE p
| p >= 0 && p <= 1 = Just $ CL p
| otherwise = Nothing
errMkCL :: String
errMkCL = "Statistics.Types.mkPValCL: probability is out if [0,1] range"
confidenceLevel :: (Num a) => CL a -> a
confidenceLevel (CL p) = 1 - p
significanceLevel :: CL a -> a
significanceLevel (CL p) = p
cl90 :: Fractional a => CL a
cl90 = CL 0.10
cl95 :: Fractional a => CL a
cl95 = CL 0.05
cl99 :: Fractional a => CL a
cl99 = CL 0.01
newtype PValue a = PValue a
deriving (Eq,Ord, Typeable, Data, Generic)
instance Show a => Show (PValue a) where
showsPrec n (PValue p) = defaultShow1 "mkPValue" p n
instance (Num a, Ord a, Read a) => Read (PValue a) where
readPrec = defaultReadPrecM1 "mkPValue" mkPValueE
instance (Binary a, Num a, Ord a) => Binary (PValue a) where
put (PValue p) = put p
get = maybe (fail errMkPValue) return . mkPValueE =<< get
instance (ToJSON a) => ToJSON (PValue a)
instance (FromJSON a, Num a, Ord a) => FromJSON (PValue a) where
parseJSON = maybe (fail errMkPValue) return . mkPValueE <=< parseJSON
instance NFData a => NFData (PValue a) where
rnf (PValue a) = rnf a
mkPValue :: (Ord a, Num a) => a -> PValue a
mkPValue = fromMaybe (error errMkPValue) . mkPValueE
mkPValueE :: (Ord a, Num a) => a -> Maybe (PValue a)
mkPValueE p
| p >= 0 && p <= 1 = Just $ PValue p
| otherwise = Nothing
pValue :: PValue a -> a
pValue (PValue p) = p
nSigma :: Double -> PValue Double
nSigma n
| n > 0 = PValue $ 2 * cumulative standard (-n)
| otherwise = error "Statistics.Extra.Error.nSigma: non-positive number of sigma"
nSigma1 :: Double -> PValue Double
nSigma1 n
| n > 0 = PValue $ cumulative standard (-n)
| otherwise = error "Statistics.Extra.Error.nSigma1: non-positive number of sigma"
getNSigma :: PValue Double -> Double
getNSigma (PValue p) = negate $ quantile standard (p / 2)
getNSigma1 :: PValue Double -> Double
getNSigma1 (PValue p) = negate $ quantile standard p
errMkPValue :: String
errMkPValue = "Statistics.Types.mkPValue: probability is out if [0,1] range"
data Estimate e a = Estimate
{ estPoint :: !a
, estError :: !(e a)
} deriving (Eq, Read, Show, Generic
#if __GLASGOW_HASKELL__ >= 708
, Typeable, Data
#endif
)
instance (Binary (e a), Binary a) => Binary (Estimate e a) where
get = liftM2 Estimate get get
put (Estimate ep ee) = put ep >> put ee
instance (FromJSON (e a), FromJSON a) => FromJSON (Estimate e a)
instance (ToJSON (e a), ToJSON a) => ToJSON (Estimate e a)
instance (NFData (e a), NFData a) => NFData (Estimate e a) where
rnf (Estimate x dx) = rnf x `seq` rnf dx
newtype NormalErr a = NormalErr
{ normalError :: a
}
deriving (Eq, Read, Show, Typeable, Data, Generic)
instance Binary a => Binary (NormalErr a) where
get = fmap NormalErr get
put = put . normalError
instance FromJSON a => FromJSON (NormalErr a)
instance ToJSON a => ToJSON (NormalErr a)
instance NFData a => NFData (NormalErr a) where
rnf (NormalErr x) = rnf x
data ConfInt a = ConfInt
{ confIntLDX :: !a
, confIntUDX :: !a
, confIntCL :: !(CL Double)
}
deriving (Read,Show,Eq,Typeable,Data,Generic)
instance Binary a => Binary (ConfInt a) where
get = liftM3 ConfInt get get get
put (ConfInt l u cl) = put l >> put u >> put cl
instance FromJSON a => FromJSON (ConfInt a)
instance ToJSON a => ToJSON (ConfInt a)
instance NFData a => NFData (ConfInt a) where
rnf (ConfInt x y _) = rnf x `seq` rnf y
estimateNormErr :: a
-> a
-> Estimate NormalErr a
estimateNormErr x dx = Estimate x (NormalErr dx)
(±) :: a
-> a
-> Estimate NormalErr a
(±) = estimateNormErr
estimateFromErr
:: a
-> (a,a)
-> CL Double
-> Estimate ConfInt a
estimateFromErr x (ldx,udx) cl = Estimate x (ConfInt ldx udx cl)
estimateFromInterval
:: Num a
=> a
-> (a,a)
-> CL Double
-> Estimate ConfInt a
estimateFromInterval x (lx,ux) cl
= Estimate x (ConfInt (x-lx) (ux-x) cl)
confidenceInterval :: Num a => Estimate ConfInt a -> (a,a)
confidenceInterval (Estimate x (ConfInt ldx udx _))
= (x - ldx, x + udx)
asymErrors :: Estimate ConfInt a -> (a,a)
asymErrors (Estimate _ (ConfInt ldx udx _)) = (ldx,udx)
class Scale e where
scale :: (Ord a, Num a) => a -> e a -> e a
instance Scale NormalErr where
scale a (NormalErr e) = NormalErr (abs a * e)
instance Scale ConfInt where
scale a (ConfInt l u cl) | a >= 0 = ConfInt (a*l) (a*u) cl
| otherwise = ConfInt (-a*u) (-a*l) cl
instance Scale e => Scale (Estimate e) where
scale a (Estimate x dx) = Estimate (a*x) (scale a dx)
data UpperLimit a = UpperLimit
{ upperLimit :: !a
, ulConfidenceLevel :: !(CL Double)
} deriving (Eq, Read, Show, Typeable, Data, Generic)
instance Binary a => Binary (UpperLimit a) where
get = liftM2 UpperLimit get get
put (UpperLimit l cl) = put l >> put cl
instance FromJSON a => FromJSON (UpperLimit a)
instance ToJSON a => ToJSON (UpperLimit a)
instance NFData a => NFData (UpperLimit a) where
rnf (UpperLimit x cl) = rnf x `seq` rnf cl
data LowerLimit a = LowerLimit {
lowerLimit :: !a
, llConfidenceLevel :: !(CL Double)
} deriving (Eq, Read, Show, Typeable, Data, Generic)
instance Binary a => Binary (LowerLimit a) where
get = liftM2 LowerLimit get get
put (LowerLimit l cl) = put l >> put cl
instance FromJSON a => FromJSON (LowerLimit a)
instance ToJSON a => ToJSON (LowerLimit a)
instance NFData a => NFData (LowerLimit a) where
rnf (LowerLimit x cl) = rnf x `seq` rnf cl
derivingUnbox "CL"
[t| forall a. Unbox a => CL a -> a |]
[| \(CL a) -> a |]
[| CL |]
derivingUnbox "PValue"
[t| forall a. Unbox a => PValue a -> a |]
[| \(PValue a) -> a |]
[| PValue |]
derivingUnbox "Estimate"
[t| forall a e. (Unbox a, Unbox (e a)) => Estimate e a -> (a, e a) |]
[| \(Estimate x dx) -> (x,dx) |]
[| \(x,dx) -> (Estimate x dx) |]
derivingUnbox "NormalErr"
[t| forall a. Unbox a => NormalErr a -> a |]
[| \(NormalErr a) -> a |]
[| NormalErr |]
derivingUnbox "ConfInt"
[t| forall a. Unbox a => ConfInt a -> (a, a, CL Double) |]
[| \(ConfInt a b c) -> (a,b,c) |]
[| \(a,b,c) -> ConfInt a b c |]
derivingUnbox "UpperLimit"
[t| forall a. Unbox a => UpperLimit a -> (a, CL Double) |]
[| \(UpperLimit a b) -> (a,b) |]
[| \(a,b) -> UpperLimit a b |]
derivingUnbox "LowerLimit"
[t| forall a. Unbox a => LowerLimit a -> (a, CL Double) |]
[| \(LowerLimit a b) -> (a,b) |]
[| \(a,b) -> LowerLimit a b |]