{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE DeriveDataTypeable, DeriveGeneric #-}
-- |
-- Module    : Statistics.Distribution.Lognormal
-- Copyright : (c) 2020 Ximin Luo
-- License   : BSD3
--
-- Maintainer  : infinity0@pwned.gg
-- Stability   : experimental
-- Portability : portable
--
-- The Weibull distribution.  This is a continuous probability
-- distribution that describes the occurrence of a single event whose
-- probability changes over time, controlled by the shape parameter.

module Statistics.Distribution.Weibull
    (
      WeibullDistribution
      -- * Constructors
    , 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


-- | The Weibull distribution.
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

-- | Standard Weibull distribution with scale factor (lambda) 1.
weibullStandard :: Double -> WeibullDistribution
weibullStandard :: Double -> WeibullDistribution
weibullStandard Double
k = Double -> Double -> WeibullDistribution
weibullDistr Double
k Double
1.0

-- | Create Weibull distribution from parameters.
--
-- If the shape (first) parameter is @1.0@, the distribution is equivalent to a
-- 'Statistics.Distribution.Exponential.ExponentialDistribution' with parameter
-- @1 / lambda@ the scale (second) parameter.
weibullDistr
  :: Double            -- ^ Shape
  -> Double            -- ^ Lambda (scale)
  -> 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

-- | Create Weibull distribution from parameters.
--
-- If the shape (first) parameter is @1.0@, the distribution is equivalent to a
-- 'Statistics.Distribution.Exponential.ExponentialDistribution' with parameter
-- @1 / lambda@ the scale (second) parameter.
weibullDistrErr
  :: Double            -- ^ Shape
  -> Double            -- ^ Lambda (scale)
  -> 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

-- | Create Weibull distribution from mean and standard deviation.
--
-- The algorithm is from "Methods for Estimating Wind Speed Frequency
-- Distributions", C. G. Justus, W. R. Hargreaves, A. Mikhail, D. Graber, 1977.
-- Given the identity:
--
-- \[
-- (\frac{\sigma}{\mu})^2 = \frac{\Gamma(1+2/k)}{\Gamma(1+1/k)^2} - 1
-- \]
--
-- \(k\) can be approximated by
--
-- \[
-- k \approx (\frac{\sigma}{\mu})^{-1.086}
-- \]
--
-- \(\lambda\) is then calculated straightforwardly via the identity
--
-- \[
-- \lambda = \frac{\mu}{\Gamma(1+1/k)}
-- \]
--
-- Numerically speaking, the approximation for \(k\) is accurate only within a
-- certain range. We arbitrarily pick the range \(0.033 \le \frac{\sigma}{\mu} \le 1.45\)
-- where it is good to ~6%, and will refuse to create a distribution outside of
-- this range. The paper does not cover these details but it is straightforward
-- to check them numerically.
weibullDistrApproxMeanStddevErr
  :: Double            -- ^ Mean
  -> Double            -- ^ Stddev
  -> 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

-- | Uses an approximation based on the mean and standard deviation in
--   'weibullDistrEstMeanStddevErr', with standard deviation estimated
--   using maximum likelihood method (unbiased estimation).
--
--   Returns @Nothing@ if sample contains less than one element or
--   variance is zero (all elements are equal), or if the estimated mean
--   and standard-deviation lies outside the range for which the
--   approximation is accurate.
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