    {-# 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
    (WeibullDistribution -> WeibullDistribution -> Bool)
    -> (WeibullDistribution -> WeibullDistribution -> Bool)
    -> Eq WeibullDistribution
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: WeibullDistribution -> WeibullDistribution -> Bool
    == :: WeibullDistribution -> WeibullDistribution -> Bool
    $c/= :: WeibullDistribution -> WeibullDistribution -> Bool
    /= :: WeibullDistribution -> WeibullDistribution -> Bool
    Eq, Typeable, Typeable WeibullDistribution
    Typeable WeibullDistribution
    -> (forall (c :: * -> *).
        (forall d b. Data d => c (d -> b) -> d -> c b)
        -> (forall g. g -> c g)
        -> WeibullDistribution
        -> c WeibullDistribution)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c WeibullDistribution)
    -> (WeibullDistribution -> Constr)
    -> (WeibullDistribution -> DataType)
    -> (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))
    -> ((forall b. Data b => b -> b)
        -> WeibullDistribution -> WeibullDistribution)
    -> (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 u.
        (forall d. Data d => d -> u) -> WeibullDistribution -> [u])
    -> (forall u.
        Int -> (forall d. Data d => d -> u) -> WeibullDistribution -> u)
    -> (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 (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d)
        -> WeibullDistribution -> m WeibullDistribution)
    -> Data WeibullDistribution
    WeibullDistribution -> Constr
    WeibullDistribution -> DataType
    (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)
    $cgfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g)
    -> WeibullDistribution
    -> c WeibullDistribution
    gfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g)
    -> WeibullDistribution
    -> c WeibullDistribution
    $cgunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c WeibullDistribution
    gunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c WeibullDistribution
    $ctoConstr :: WeibullDistribution -> Constr
    toConstr :: WeibullDistribution -> Constr
    $cdataTypeOf :: WeibullDistribution -> DataType
    dataTypeOf :: WeibullDistribution -> DataType
    $cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c WeibullDistribution)
    dataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c WeibullDistribution)
    $cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c WeibullDistribution)
    dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c WeibullDistribution)
    $cgmapT :: (forall b. Data b => b -> b)
    -> WeibullDistribution -> WeibullDistribution
    gmapT :: (forall b. Data b => b -> b)
    -> WeibullDistribution -> WeibullDistribution
    $cgmapQl :: 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
    $cgmapQr :: forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> WeibullDistribution -> r
    gmapQr :: forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> WeibullDistribution -> r
    $cgmapQ :: forall u.
    (forall d. Data d => d -> u) -> WeibullDistribution -> [u]
    gmapQ :: forall u.
    (forall d. Data d => d -> u) -> WeibullDistribution -> [u]
    $cgmapQi :: forall u.
    Int -> (forall d. Data d => d -> u) -> WeibullDistribution -> u
    gmapQi :: forall u.
    Int -> (forall d. Data d => d -> u) -> WeibullDistribution -> u
    $cgmapM :: forall (m :: * -> *).
    Monad 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
    $cgmapMp :: 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
    $cgmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> WeibullDistribution -> m WeibullDistribution
    gmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> WeibullDistribution -> m WeibullDistribution
    Data, (forall x. WeibullDistribution -> Rep WeibullDistribution x)
    -> (forall x. Rep WeibullDistribution x -> WeibullDistribution)
    -> Generic WeibullDistribution
    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
    $cfrom :: forall x. WeibullDistribution -> Rep WeibullDistribution x
    from :: forall x. WeibullDistribution -> Rep WeibullDistribution x
    $cto :: forall x. Rep WeibullDistribution x -> WeibullDistribution
    to :: forall x. Rep WeibullDistribution x -> WeibullDistribution
    Generic)

    instance Show WeibullDistribution where
      showsPrec :: Int -> WeibullDistribution -> ShowS
    showsPrec Int
    i (WD Double
    k Double
    l) = [Char] -> Double -> Double -> Int -> ShowS
    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 = [Char]
    -> (Double -> Double -> Maybe WeibullDistribution)
    -> ReadPrec WeibullDistribution
    forall a b r.
    (Read a, Read b) =>
    [Char] -> (a -> b -> Maybe r) -> ReadPrec r
    defaultReadPrecM2 [Char]
    "weibullDistr" ((Double -> Double -> Maybe WeibullDistribution)
     -> ReadPrec WeibullDistribution)
    -> (Double -> Double -> Maybe WeibullDistribution)
    -> ReadPrec WeibullDistribution
    forall a b. (a -> b) -> a -> b
    $
        (([Char] -> Maybe WeibullDistribution)
    -> (WeibullDistribution -> Maybe WeibullDistribution)
    -> Either [Char] WeibullDistribution
    -> Maybe WeibullDistribution
    forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
    either (Maybe WeibullDistribution -> [Char] -> Maybe WeibullDistribution
    forall a b. a -> b -> a
    const Maybe WeibullDistribution
    forall a. Maybe a
    Nothing) WeibullDistribution -> Maybe WeibullDistribution
    forall a. a -> Maybe a
    Just (Either [Char] WeibullDistribution -> Maybe WeibullDistribution)
    -> (Double -> Either [Char] WeibullDistribution)
    -> Double
    -> Maybe WeibullDistribution
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    .) ((Double -> Either [Char] WeibullDistribution)
     -> Double -> Maybe WeibullDistribution)
    -> (Double -> Double -> Either [Char] WeibullDistribution)
    -> Double
    -> Double
    -> Maybe WeibullDistribution
    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 Object -> Key -> Parser Double
    forall a. FromJSON a => Object -> Key -> Parser a
    .: Key
    "wdShape"
        Double
    l <- Object
    v Object -> Key -> Parser Double
    forall a. FromJSON a => Object -> Key -> Parser a
    .: Key
    "wdLambda"
        ([Char] -> Parser WeibullDistribution)
    -> (WeibullDistribution -> Parser WeibullDistribution)
    -> Either [Char] WeibullDistribution
    -> Parser WeibullDistribution
    forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
    either [Char] -> Parser WeibullDistribution
    forall a. [Char] -> Parser a
    forall (m :: * -> *) a. MonadFail m => [Char] -> m a
    fail WeibullDistribution -> Parser WeibullDistribution
    forall a. a -> Parser a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Either [Char] WeibullDistribution -> Parser WeibullDistribution)
    -> Either [Char] WeibullDistribution -> Parser WeibullDistribution
    forall a b. (a -> b) -> a -> b
    $ Double -> Double -> Either [Char] WeibullDistribution
    weibullDistrErr Double
    k Double
    l
      parseJSON Value
    _ = Parser WeibullDistribution
    forall a. Parser a
    forall (f :: * -> *) a. Alternative f => f a
    empty

    instance Binary WeibullDistribution where
      put :: WeibullDistribution -> Put
    put (WD Double
    k Double
    l) = Double -> Put
    forall t. Binary t => t -> Put
    put Double
    k Put -> Put -> Put
    forall a b. PutM a -> PutM b -> PutM b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> Double -> Put
    forall t. Binary t => t -> Put
    put Double
    l
      get :: Get WeibullDistribution
    get = do
        Double
    k <- Get Double
    forall t. Binary t => Get t
    get
        Double
    l <- Get Double
    forall t. Binary t => Get t
    get
        ([Char] -> Get WeibullDistribution)
    -> (WeibullDistribution -> Get WeibullDistribution)
    -> Either [Char] WeibullDistribution
    -> Get WeibullDistribution
    forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
    either [Char] -> Get WeibullDistribution
    forall a. [Char] -> Get a
    forall (m :: * -> *) a. MonadFail m => [Char] -> m a
    fail WeibullDistribution -> Get WeibullDistribution
    forall a. a -> Get a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Either [Char] WeibullDistribution -> Get WeibullDistribution)
    -> Either [Char] WeibullDistribution -> Get WeibullDistribution
    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 = Double -> Maybe Double
    forall a. a -> Maybe a
    Just (Double -> Maybe Double)
    -> (WeibullDistribution -> Double)
    -> WeibullDistribution
    -> Maybe Double
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . WeibullDistribution -> Double
    forall d. Mean d => d -> Double
    D.mean

    instance D.Mean WeibullDistribution where
      mean :: WeibullDistribution -> Double
    mean (WD Double
    k Double
    l) = Double
    l Double -> Double -> Double
    forall a. Num a => a -> a -> a
    * Double -> Double
    forall a. Floating a => a -> a
    exp (Double -> Double
    logGamma (Double
    1 Double -> Double -> Double
    forall a. Num a => a -> a -> a
    + Double
    1 Double -> Double -> Double
    forall a. Fractional a => a -> a -> a
    / Double
    k))

    instance D.MaybeVariance WeibullDistribution where
      maybeStdDev :: WeibullDistribution -> Maybe Double
    maybeStdDev   = Double -> Maybe Double
    forall a. a -> Maybe a
    Just (Double -> Maybe Double)
    -> (WeibullDistribution -> Double)
    -> WeibullDistribution
    -> Maybe Double
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . WeibullDistribution -> Double
    forall d. Variance d => d -> Double
    D.stdDev
      maybeVariance :: WeibullDistribution -> Maybe Double
    maybeVariance = Double -> Maybe Double
    forall a. a -> Maybe a
    Just (Double -> Maybe Double)
    -> (WeibullDistribution -> Double)
    -> WeibullDistribution
    -> Maybe Double
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . WeibullDistribution -> Double
    forall d. Variance d => d -> Double
    D.variance

    instance D.Variance WeibullDistribution where
      variance :: WeibullDistribution -> Double
    variance (WD Double
    k Double
    l) = Double
    l Double -> Double -> Double
    forall a. Num a => a -> a -> a
    * Double
    l Double -> Double -> Double
    forall a. Num a => a -> a -> a
    * (Double -> Double
    forall a. Floating a => a -> a
    exp (Double -> Double
    logGamma (Double
    1 Double -> Double -> Double
    forall a. Num a => a -> a -> a
    + Double
    2 Double -> Double -> Double
    forall a. Num a => a -> a -> a
    * Double
    invk)) Double -> Double -> Double
    forall a. Num a => a -> a -> a
    - Double
    q Double -> Double -> Double
    forall a. Num a => a -> a -> a
    * Double
    q)
       where
        invk :: Double
    invk = Double
    1 Double -> Double -> Double
    forall a. Fractional a => a -> a -> a
    / Double
    k
        q :: Double
    q    = Double -> Double
    forall a. Floating a => a -> a
    exp (Double -> Double
    logGamma (Double
    1 Double -> Double -> Double
    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 Double -> Double -> Double
    forall a. Num a => a -> a -> a
    * (Double
    1 Double -> Double -> Double
    forall a. Num a => a -> a -> a
    - Double
    1 Double -> Double -> Double
    forall a. Fractional a => a -> a -> a
    / Double
    k) Double -> Double -> Double
    forall a. Num a => a -> a -> a
    + Double -> Double
    forall a. Floating a => a -> a
    log (Double
    l Double -> Double -> Double
    forall a. Fractional a => a -> a -> a
    / Double
    k) Double -> Double -> Double
    forall a. Num a => a -> a -> a
    + Double
    1

    instance D.MaybeEntropy WeibullDistribution where
      maybeEntropy :: WeibullDistribution -> Maybe Double
    maybeEntropy = Double -> Maybe Double
    forall a. a -> Maybe a
    Just (Double -> Maybe Double)
    -> (WeibullDistribution -> Double)
    -> WeibullDistribution
    -> Maybe Double
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . WeibullDistribution -> Double
    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 = WeibullDistribution -> g -> m Double
    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 = ([Char] -> WeibullDistribution)
    -> (WeibullDistribution -> WeibullDistribution)
    -> Either [Char] WeibullDistribution
    -> WeibullDistribution
    forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
    either [Char] -> WeibullDistribution
    forall a. HasCallStack => [Char] -> a
    error WeibullDistribution -> WeibullDistribution
    forall a. a -> a
    id (Either [Char] WeibullDistribution -> WeibullDistribution)
    -> Either [Char] WeibullDistribution -> WeibullDistribution
    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 Double -> Double -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Double
    0     = [Char] -> Either [Char] WeibullDistribution
    forall a b. a -> Either a b
    Left ([Char] -> Either [Char] WeibullDistribution)
    -> [Char] -> Either [Char] WeibullDistribution
    forall a b. (a -> b) -> a -> b
    $ Double -> Double -> [Char]
    errMsg Double
    k Double
    l
                        | Double
    l Double -> Double -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Double
    0     = [Char] -> Either [Char] WeibullDistribution
    forall a b. a -> Either a b
    Left ([Char] -> Either [Char] WeibullDistribution)
    -> [Char] -> Either [Char] WeibullDistribution
    forall a b. (a -> b) -> a -> b
    $ Double -> Double -> [Char]
    errMsg Double
    k Double
    l
                        | Bool
    otherwise = WeibullDistribution -> Either [Char] WeibullDistribution
    forall a b. b -> Either a b
    Right (WeibullDistribution -> Either [Char] WeibullDistribution)
    -> WeibullDistribution -> Either [Char] WeibullDistribution
    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 "
        [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ Double -> [Char]
    forall a. Show a => a -> [Char]
    show Double
    k
        [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    " and lambda "
        [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ Double -> [Char]
    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 Double -> Double -> Bool
    forall a. Ord a => a -> a -> Bool
    > Double
    1.45 Bool -> Bool -> Bool
    || Double
    r Double -> Double -> Bool
    forall a. Ord a => a -> a -> Bool
    < Double
    0.033
        then [Char] -> Either [Char] WeibullDistribution
    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 Double -> Double -> Double
    forall a. Fractional a => a -> a -> a
    / Double
    m
            k :: Double
    k = (Double
    s Double -> Double -> Double
    forall a. Fractional a => a -> a -> a
    / Double
    m) Double -> Double -> Double
    forall a. Floating a => a -> a -> a
    ** (-Double
    1.086)
            l :: Double
    l = Double
    m Double -> Double -> Double
    forall a. Fractional a => a -> a -> a
    / Double -> Double
    forall a. Floating a => a -> a
    exp (Double -> Double
    logGamma (Double
    1 Double -> Double -> Double
    forall a. Num a => a -> a -> a
    + Double
    1Double -> Double -> Double
    forall a. Fractional a => a -> a -> a
    /Double
    k))
            msg :: [Char]
    msg = [Char]
    "Statistics.Distribution.Weibull.weibullDistr: stddev-mean ratio "
              [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "outside approximation accuracy range [0.033, 1.45]. Got "
              [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "stddev " [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ Double -> [Char]
    forall a. Show a => a -> [Char]
    show Double
    s [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    " and mean " [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ Double -> [Char]
    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
        | v Double -> Int
    forall (v :: * -> *) a. Vector v a => v a -> Int
    G.length v Double
    xs Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Int
    1 = Maybe WeibullDistribution
    forall a. Maybe a
    Nothing
        | Double
    v Double -> Double -> Bool
    forall a. Eq a => a -> a -> Bool
    == Double
    0           = Maybe WeibullDistribution
    forall a. Maybe a
    Nothing
        | Bool
    otherwise        = ([Char] -> Maybe WeibullDistribution)
    -> (WeibullDistribution -> Maybe WeibullDistribution)
    -> Either [Char] WeibullDistribution
    -> Maybe WeibullDistribution
    forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
    either (Maybe WeibullDistribution -> [Char] -> Maybe WeibullDistribution
    forall a b. a -> b -> a
    const Maybe WeibullDistribution
    forall a. Maybe a
    Nothing) WeibullDistribution -> Maybe WeibullDistribution
    forall a. a -> Maybe a
    Just (Either [Char] WeibullDistribution -> Maybe WeibullDistribution)
    -> Either [Char] WeibullDistribution -> Maybe WeibullDistribution
    forall a b. (a -> b) -> a -> b
    $
          Double -> Double -> Either [Char] WeibullDistribution
    weibullDistrApproxMeanStddevErr Double
    m (Double -> Double
    forall a. Floating a => a -> a
    sqrt Double
    v)
        where
          (Double
    m,Double
    v) = v Double -> (Double, Double)
    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 Double -> Double -> Bool
    forall a. Ord a => a -> a -> Bool
    < Double
    0     = Double
    0
      | Bool
    otherwise = Double -> Double
    forall a. Floating a => a -> a
    log Double
    k Double -> Double -> Double
    forall a. Num a => a -> a -> a
    + (Double
    k Double -> Double -> Double
    forall a. Num a => a -> a -> a
    - Double
    1) Double -> Double -> Double
    forall a. Num a => a -> a -> a
    * Double -> Double
    forall a. Floating a => a -> a
    log Double
    x Double -> Double -> Double
    forall a. Num a => a -> a -> a
    - Double
    k Double -> Double -> Double
    forall a. Num a => a -> a -> a
    * Double -> Double
    forall a. Floating a => a -> a
    log Double
    l Double -> Double -> Double
    forall a. Num a => a -> a -> a
    - (Double
    x Double -> Double -> Double
    forall a. Fractional a => a -> a -> a
    / Double
    l) Double -> Double -> Double
    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 Double -> Double -> Bool
    forall a. Ord a => a -> a -> Bool
    < Double
    0     = Double
    0
                          | Bool
    otherwise = -Double -> Double
    forall a. Floating a => a -> a
    expm1 (-(Double
    x Double -> Double -> Double
    forall a. Fractional a => a -> a -> a
    / Double
    l) Double -> Double -> Double
    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 Double -> Double -> Bool
    forall a. Ord a => a -> a -> Bool
    < Double
    0     = Double
    1
                               | Bool
    otherwise = Double -> Double
    forall a. Floating a => a -> a
    exp (-(Double
    x Double -> Double -> Double
    forall a. Fractional a => a -> a -> a
    / Double
    l) Double -> Double -> Double
    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 Double -> Double -> Bool
    forall a. Eq a => a -> a -> Bool
    == Double
    0         = Double
    0
      | Double
    p Double -> Double -> Bool
    forall a. Eq a => a -> a -> Bool
    == Double
    1         = Double
    inf
      | Double
    p Double -> Double -> Bool
    forall a. Ord a => a -> a -> Bool
    > Double
    0 Bool -> Bool -> Bool
    && Double
    p Double -> Double -> Bool
    forall a. Ord a => a -> a -> Bool
    < Double
    1 = Double
    l Double -> Double -> Double
    forall a. Num a => a -> a -> a
    * (-Double -> Double
    forall a. Floating a => a -> a
    log1p (-Double
    p)) Double -> Double -> Double
    forall a. Floating a => a -> a -> a
    ** (Double
    1 Double -> Double -> Double
    forall a. Fractional a => a -> a -> a
    / Double
    k)
      | Bool
    otherwise      =
        [Char] -> Double
    forall a. HasCallStack => [Char] -> a
    error ([Char] -> Double) -> [Char] -> Double
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "Statistics.Distribution.Weibull.quantile: p must be in [0,1] range. Got: " [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ Double -> [Char]
    forall a. Show a => a -> [Char]
    show Double
    p
      where inf :: Double
    inf = Double
    1 Double -> Double -> Double
    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 Double -> Double -> Bool
    forall a. Eq a => a -> a -> Bool
    == Double
    0         = Double
    inf
      | Double
    q Double -> Double -> Bool
    forall a. Eq a => a -> a -> Bool
    == Double
    1         = Double
    0
      | Double
    q Double -> Double -> Bool
    forall a. Ord a => a -> a -> Bool
    > Double
    0 Bool -> Bool -> Bool
    && Double
    q Double -> Double -> Bool
    forall a. Ord a => a -> a -> Bool
    < Double
    1 = Double
    l Double -> Double -> Double
    forall a. Num a => a -> a -> a
    * (-Double -> Double
    forall a. Floating a => a -> a
    log Double
    q) Double -> Double -> Double
    forall a. Floating a => a -> a -> a
    ** (Double
    1 Double -> Double -> Double
    forall a. Fractional a => a -> a -> a
    / Double
    k)
      | Bool
    otherwise      =
        [Char] -> Double
    forall a. HasCallStack => [Char] -> a
    error ([Char] -> Double) -> [Char] -> Double
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "Statistics.Distribution.Weibull.complQuantile: q must be in [0,1] range. Got: " [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ Double -> [Char]
    forall a. Show a => a -> [Char]
    show Double
    q
      where inf :: Double
    inf = Double
    1 Double -> Double -> Double
    forall a. Fractional a => a -> a -> a
    / Double
    0