{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE DeriveDataTypeable, DeriveGeneric #-}
module Statistics.Distribution.Weibull
(
WeibullDistribution
, weibullDistr
, weibullDistrErr
, weibullStandard
, weibullDistrApproxMeanStddevErr
) where
import Control.Applicative
import Data.Aeson (FromJSON(..), ToJSON, Value(..), (.:))
import Data.Binary (Binary(..))
import Data.Data (Data, Typeable)
import GHC.Generics (Generic)
import Numeric.MathFunctions.Constants (m_eulerMascheroni)
import Numeric.SpecFunctions (expm1, log1p, logGamma)
import qualified Data.Vector.Generic as G
import qualified Statistics.Distribution as D
import qualified Statistics.Sample as S
import Statistics.Internal
data WeibullDistribution = WD {
WeibullDistribution -> Double
wdShape :: {-# UNPACK #-} !Double
, WeibullDistribution -> Double
wdLambda :: {-# UNPACK #-} !Double
} deriving (WeibullDistribution -> WeibullDistribution -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: WeibullDistribution -> WeibullDistribution -> Bool
$c/= :: WeibullDistribution -> WeibullDistribution -> Bool
== :: WeibullDistribution -> WeibullDistribution -> Bool
$c== :: WeibullDistribution -> WeibullDistribution -> Bool
Eq, Typeable, Typeable WeibullDistribution
WeibullDistribution -> DataType
WeibullDistribution -> Constr
(forall b. Data b => b -> b)
-> WeibullDistribution -> WeibullDistribution
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) -> WeibullDistribution -> u
forall u.
(forall d. Data d => d -> u) -> WeibullDistribution -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> WeibullDistribution -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> WeibullDistribution -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d)
-> WeibullDistribution -> m WeibullDistribution
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> WeibullDistribution -> m WeibullDistribution
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c WeibullDistribution
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g)
-> WeibullDistribution
-> c WeibullDistribution
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c WeibullDistribution)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c WeibullDistribution)
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> WeibullDistribution -> m WeibullDistribution
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> WeibullDistribution -> m WeibullDistribution
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> WeibullDistribution -> m WeibullDistribution
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> WeibullDistribution -> m WeibullDistribution
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d)
-> WeibullDistribution -> m WeibullDistribution
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d)
-> WeibullDistribution -> m WeibullDistribution
gmapQi :: forall u.
Int -> (forall d. Data d => d -> u) -> WeibullDistribution -> u
$cgmapQi :: forall u.
Int -> (forall d. Data d => d -> u) -> WeibullDistribution -> u
gmapQ :: forall u.
(forall d. Data d => d -> u) -> WeibullDistribution -> [u]
$cgmapQ :: forall u.
(forall d. Data d => d -> u) -> WeibullDistribution -> [u]
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> WeibullDistribution -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> WeibullDistribution -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> WeibullDistribution -> r
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> WeibullDistribution -> r
gmapT :: (forall b. Data b => b -> b)
-> WeibullDistribution -> WeibullDistribution
$cgmapT :: (forall b. Data b => b -> b)
-> WeibullDistribution -> WeibullDistribution
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c WeibullDistribution)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c WeibullDistribution)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c WeibullDistribution)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c WeibullDistribution)
dataTypeOf :: WeibullDistribution -> DataType
$cdataTypeOf :: WeibullDistribution -> DataType
toConstr :: WeibullDistribution -> Constr
$ctoConstr :: WeibullDistribution -> Constr
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c WeibullDistribution
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c WeibullDistribution
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g)
-> WeibullDistribution
-> c WeibullDistribution
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g)
-> WeibullDistribution
-> c WeibullDistribution
Data, forall x. Rep WeibullDistribution x -> WeibullDistribution
forall x. WeibullDistribution -> Rep WeibullDistribution x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep WeibullDistribution x -> WeibullDistribution
$cfrom :: forall x. WeibullDistribution -> Rep WeibullDistribution x
Generic)
instance Show WeibullDistribution where
showsPrec :: Int -> WeibullDistribution -> ShowS
showsPrec Int
i (WD Double
k Double
l) = forall a b. (Show a, Show b) => [Char] -> a -> b -> Int -> ShowS
defaultShow2 [Char]
"weibullDistr" Double
k Double
l Int
i
instance Read WeibullDistribution where
readPrec :: ReadPrec WeibullDistribution
readPrec = forall a b r.
(Read a, Read b) =>
[Char] -> (a -> b -> Maybe r) -> ReadPrec r
defaultReadPrecM2 [Char]
"weibullDistr" forall a b. (a -> b) -> a -> b
$
(forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (forall a b. a -> b -> a
const forall a. Maybe a
Nothing) forall a. a -> Maybe a
Just forall b c a. (b -> c) -> (a -> b) -> a -> c
.) forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> Double -> Either [Char] WeibullDistribution
weibullDistrErr
instance ToJSON WeibullDistribution
instance FromJSON WeibullDistribution where
parseJSON :: Value -> Parser WeibullDistribution
parseJSON (Object Object
v) = do
Double
k <- Object
v forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"wdShape"
Double
l <- Object
v forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"wdLambda"
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either forall (m :: * -> *) a. MonadFail m => [Char] -> m a
fail forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Double -> Double -> Either [Char] WeibullDistribution
weibullDistrErr Double
k Double
l
parseJSON Value
_ = forall (f :: * -> *) a. Alternative f => f a
empty
instance Binary WeibullDistribution where
put :: WeibullDistribution -> Put
put (WD Double
k Double
l) = forall t. Binary t => t -> Put
put Double
k forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall t. Binary t => t -> Put
put Double
l
get :: Get WeibullDistribution
get = do
Double
k <- forall t. Binary t => Get t
get
Double
l <- forall t. Binary t => Get t
get
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either forall (m :: * -> *) a. MonadFail m => [Char] -> m a
fail forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Double -> Double -> Either [Char] WeibullDistribution
weibullDistrErr Double
k Double
l
instance D.Distribution WeibullDistribution where
cumulative :: WeibullDistribution -> Double -> Double
cumulative = WeibullDistribution -> Double -> Double
cumulative
complCumulative :: WeibullDistribution -> Double -> Double
complCumulative = WeibullDistribution -> Double -> Double
complCumulative
instance D.ContDistr WeibullDistribution where
logDensity :: WeibullDistribution -> Double -> Double
logDensity = WeibullDistribution -> Double -> Double
logDensity
quantile :: WeibullDistribution -> Double -> Double
quantile = WeibullDistribution -> Double -> Double
quantile
complQuantile :: WeibullDistribution -> Double -> Double
complQuantile = WeibullDistribution -> Double -> Double
complQuantile
instance D.MaybeMean WeibullDistribution where
maybeMean :: WeibullDistribution -> Maybe Double
maybeMean = forall a. a -> Maybe a
Just forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall d. Mean d => d -> Double
D.mean
instance D.Mean WeibullDistribution where
mean :: WeibullDistribution -> Double
mean (WD Double
k Double
l) = Double
l forall a. Num a => a -> a -> a
* forall a. Floating a => a -> a
exp (Double -> Double
logGamma (Double
1 forall a. Num a => a -> a -> a
+ Double
1 forall a. Fractional a => a -> a -> a
/ Double
k))
instance D.MaybeVariance WeibullDistribution where
maybeStdDev :: WeibullDistribution -> Maybe Double
maybeStdDev = forall a. a -> Maybe a
Just forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall d. Variance d => d -> Double
D.stdDev
maybeVariance :: WeibullDistribution -> Maybe Double
maybeVariance = forall a. a -> Maybe a
Just forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall d. Variance d => d -> Double
D.variance
instance D.Variance WeibullDistribution where
variance :: WeibullDistribution -> Double
variance (WD Double
k Double
l) = Double
l forall a. Num a => a -> a -> a
* Double
l forall a. Num a => a -> a -> a
* (forall a. Floating a => a -> a
exp (Double -> Double
logGamma (Double
1 forall a. Num a => a -> a -> a
+ Double
2 forall a. Num a => a -> a -> a
* Double
invk)) forall a. Num a => a -> a -> a
- Double
q forall a. Num a => a -> a -> a
* Double
q)
where
invk :: Double
invk = Double
1 forall a. Fractional a => a -> a -> a
/ Double
k
q :: Double
q = forall a. Floating a => a -> a
exp (Double -> Double
logGamma (Double
1 forall a. Num a => a -> a -> a
+ Double
invk))
instance D.Entropy WeibullDistribution where
entropy :: WeibullDistribution -> Double
entropy (WD Double
k Double
l) = Double
m_eulerMascheroni forall a. Num a => a -> a -> a
* (Double
1 forall a. Num a => a -> a -> a
- Double
1 forall a. Fractional a => a -> a -> a
/ Double
k) forall a. Num a => a -> a -> a
+ forall a. Floating a => a -> a
log (Double
l forall a. Fractional a => a -> a -> a
/ Double
k) forall a. Num a => a -> a -> a
+ Double
1
instance D.MaybeEntropy WeibullDistribution where
maybeEntropy :: WeibullDistribution -> Maybe Double
maybeEntropy = forall a. a -> Maybe a
Just forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall d. Entropy d => d -> Double
D.entropy
instance D.ContGen WeibullDistribution where
genContVar :: forall g (m :: * -> *).
StatefulGen g m =>
WeibullDistribution -> g -> m Double
genContVar WeibullDistribution
d = forall d g (m :: * -> *).
(ContDistr d, StatefulGen g m) =>
d -> g -> m Double
D.genContinuous WeibullDistribution
d
weibullStandard :: Double -> WeibullDistribution
weibullStandard :: Double -> WeibullDistribution
weibullStandard Double
k = Double -> Double -> WeibullDistribution
weibullDistr Double
k Double
1.0
weibullDistr
:: Double
-> Double
-> WeibullDistribution
weibullDistr :: Double -> Double -> WeibullDistribution
weibullDistr Double
k Double
l = forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either forall a. HasCallStack => [Char] -> a
error forall a. a -> a
id forall a b. (a -> b) -> a -> b
$ Double -> Double -> Either [Char] WeibullDistribution
weibullDistrErr Double
k Double
l
weibullDistrErr
:: Double
-> Double
-> Either String WeibullDistribution
weibullDistrErr :: Double -> Double -> Either [Char] WeibullDistribution
weibullDistrErr Double
k Double
l | Double
k forall a. Ord a => a -> a -> Bool
<= Double
0 = forall a b. a -> Either a b
Left forall a b. (a -> b) -> a -> b
$ Double -> Double -> [Char]
errMsg Double
k Double
l
| Double
l forall a. Ord a => a -> a -> Bool
<= Double
0 = forall a b. a -> Either a b
Left forall a b. (a -> b) -> a -> b
$ Double -> Double -> [Char]
errMsg Double
k Double
l
| Bool
otherwise = forall a b. b -> Either a b
Right forall a b. (a -> b) -> a -> b
$ Double -> Double -> WeibullDistribution
WD Double
k Double
l
errMsg :: Double -> Double -> String
errMsg :: Double -> Double -> [Char]
errMsg Double
k Double
l =
[Char]
"Statistics.Distribution.Weibull.weibullDistr: both shape and lambda must be positive. Got shape "
forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Double
k
forall a. [a] -> [a] -> [a]
++ [Char]
" and lambda "
forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Double
l
weibullDistrApproxMeanStddevErr
:: Double
-> Double
-> Either String WeibullDistribution
weibullDistrApproxMeanStddevErr :: Double -> Double -> Either [Char] WeibullDistribution
weibullDistrApproxMeanStddevErr Double
m Double
s = if Double
r forall a. Ord a => a -> a -> Bool
> Double
1.45 Bool -> Bool -> Bool
|| Double
r forall a. Ord a => a -> a -> Bool
< Double
0.033
then forall a b. a -> Either a b
Left [Char]
msg
else Double -> Double -> Either [Char] WeibullDistribution
weibullDistrErr Double
k Double
l
where r :: Double
r = Double
s forall a. Fractional a => a -> a -> a
/ Double
m
k :: Double
k = (Double
s forall a. Fractional a => a -> a -> a
/ Double
m) forall a. Floating a => a -> a -> a
** (-Double
1.086)
l :: Double
l = Double
m forall a. Fractional a => a -> a -> a
/ forall a. Floating a => a -> a
exp (Double -> Double
logGamma (Double
1 forall a. Num a => a -> a -> a
+ Double
1forall a. Fractional a => a -> a -> a
/Double
k))
msg :: [Char]
msg = [Char]
"Statistics.Distribution.Weibull.weibullDistr: stddev-mean ratio "
forall a. [a] -> [a] -> [a]
++ [Char]
"outside approximation accuracy range [0.033, 1.45]. Got "
forall a. [a] -> [a] -> [a]
++ [Char]
"stddev " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Double
s forall a. [a] -> [a] -> [a]
++ [Char]
" and mean " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Double
m
instance D.FromSample WeibullDistribution Double where
fromSample :: forall (v :: * -> *).
Vector v Double =>
v Double -> Maybe WeibullDistribution
fromSample v Double
xs
| forall (v :: * -> *) a. Vector v a => v a -> Int
G.length v Double
xs forall a. Ord a => a -> a -> Bool
<= Int
1 = forall a. Maybe a
Nothing
| Double
v forall a. Eq a => a -> a -> Bool
== Double
0 = forall a. Maybe a
Nothing
| Bool
otherwise = forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (forall a b. a -> b -> a
const forall a. Maybe a
Nothing) forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$
Double -> Double -> Either [Char] WeibullDistribution
weibullDistrApproxMeanStddevErr Double
m (forall a. Floating a => a -> a
sqrt Double
v)
where
(Double
m,Double
v) = forall (v :: * -> *).
Vector v Double =>
v Double -> (Double, Double)
S.meanVarianceUnb v Double
xs
logDensity :: WeibullDistribution -> Double -> Double
logDensity :: WeibullDistribution -> Double -> Double
logDensity (WD Double
k Double
l) Double
x
| Double
x forall a. Ord a => a -> a -> Bool
< Double
0 = Double
0
| Bool
otherwise = forall a. Floating a => a -> a
log Double
k forall a. Num a => a -> a -> a
+ (Double
k forall a. Num a => a -> a -> a
- Double
1) forall a. Num a => a -> a -> a
* forall a. Floating a => a -> a
log Double
x forall a. Num a => a -> a -> a
- Double
k forall a. Num a => a -> a -> a
* forall a. Floating a => a -> a
log Double
l forall a. Num a => a -> a -> a
- (Double
x forall a. Fractional a => a -> a -> a
/ Double
l) forall a. Floating a => a -> a -> a
** Double
k
cumulative :: WeibullDistribution -> Double -> Double
cumulative :: WeibullDistribution -> Double -> Double
cumulative (WD Double
k Double
l) Double
x | Double
x forall a. Ord a => a -> a -> Bool
< Double
0 = Double
0
| Bool
otherwise = -forall a. Floating a => a -> a
expm1 (-(Double
x forall a. Fractional a => a -> a -> a
/ Double
l) forall a. Floating a => a -> a -> a
** Double
k)
complCumulative :: WeibullDistribution -> Double -> Double
complCumulative :: WeibullDistribution -> Double -> Double
complCumulative (WD Double
k Double
l) Double
x | Double
x forall a. Ord a => a -> a -> Bool
< Double
0 = Double
1
| Bool
otherwise = forall a. Floating a => a -> a
exp (-(Double
x forall a. Fractional a => a -> a -> a
/ Double
l) forall a. Floating a => a -> a -> a
** Double
k)
quantile :: WeibullDistribution -> Double -> Double
quantile :: WeibullDistribution -> Double -> Double
quantile (WD Double
k Double
l) Double
p
| Double
p forall a. Eq a => a -> a -> Bool
== Double
0 = Double
0
| Double
p forall a. Eq a => a -> a -> Bool
== Double
1 = Double
inf
| Double
p forall a. Ord a => a -> a -> Bool
> Double
0 Bool -> Bool -> Bool
&& Double
p forall a. Ord a => a -> a -> Bool
< Double
1 = Double
l forall a. Num a => a -> a -> a
* (-forall a. Floating a => a -> a
log1p (-Double
p)) forall a. Floating a => a -> a -> a
** (Double
1 forall a. Fractional a => a -> a -> a
/ Double
k)
| Bool
otherwise =
forall a. HasCallStack => [Char] -> a
error forall a b. (a -> b) -> a -> b
$ [Char]
"Statistics.Distribution.Weibull.quantile: p must be in [0,1] range. Got: " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Double
p
where inf :: Double
inf = Double
1 forall a. Fractional a => a -> a -> a
/ Double
0
complQuantile :: WeibullDistribution -> Double -> Double
complQuantile :: WeibullDistribution -> Double -> Double
complQuantile (WD Double
k Double
l) Double
q
| Double
q forall a. Eq a => a -> a -> Bool
== Double
0 = Double
inf
| Double
q forall a. Eq a => a -> a -> Bool
== Double
1 = Double
0
| Double
q forall a. Ord a => a -> a -> Bool
> Double
0 Bool -> Bool -> Bool
&& Double
q forall a. Ord a => a -> a -> Bool
< Double
1 = Double
l forall a. Num a => a -> a -> a
* (-forall a. Floating a => a -> a
log Double
q) forall a. Floating a => a -> a -> a
** (Double
1 forall a. Fractional a => a -> a -> a
/ Double
k)
| Bool
otherwise =
forall a. HasCallStack => [Char] -> a
error forall a b. (a -> b) -> a -> b
$ [Char]
"Statistics.Distribution.Weibull.complQuantile: q must be in [0,1] range. Got: " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Double
q
where inf :: Double
inf = Double
1 forall a. Fractional a => a -> a -> a
/ Double
0