module Factory.Math.Probability(
Distribution(..),
ContinuousDistribution(..),
DiscreteDistribution(..),
maxPreciseInteger,
boxMullerTransform,
generateStandardizedNormalDistribution,
generateContinuousPopulation,
generateDiscretePopulation
) where
import qualified Control.Arrow
import Control.Arrow((***), (&&&))
import qualified Factory.Data.Interval as Data.Interval
import qualified Factory.Math.Power as Math.Power
import qualified System.Random
import qualified ToolShed.Data.List
import qualified ToolShed.Data.Pair
import qualified ToolShed.SelfValidate
maxPreciseInteger :: RealFloat a => a -> Integer
maxPreciseInteger :: a -> Integer
maxPreciseInteger = (Integer
2 Integer -> Int -> Integer
forall a b. (Num a, Integral b) => a -> b -> a
^) (Int -> Integer) -> (a -> Int) -> a -> Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Int
forall a. RealFloat a => a -> Int
floatDigits
minPositiveFloat :: RealFloat a => a -> a
minPositiveFloat :: a -> a
minPositiveFloat = Integer -> Int -> a
forall a. RealFloat a => Integer -> Int -> a
encodeFloat Integer
1 (Int -> a) -> (a -> Int) -> a -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int -> Int -> Int) -> (Int, Int) -> Int
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry (-) ((Int, Int) -> Int) -> (a -> (Int, Int)) -> a -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Int, Int) -> Int
forall a b. (a, b) -> a
fst ((Int, Int) -> Int) -> (a -> (Int, Int)) -> a -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> (Int, Int)
forall a. RealFloat a => a -> (Int, Int)
floatRange (a -> Int) -> (a -> Int) -> a -> (Int, Int)
forall (a :: * -> * -> *) b c c'.
Arrow a =>
a b c -> a b c' -> a b (c, c')
&&& a -> Int
forall a. RealFloat a => a -> Int
floatDigits)
data ContinuousDistribution parameter
= ExponentialDistribution parameter
| LogNormalDistribution parameter parameter
| NormalDistribution parameter parameter
| UniformDistribution (Data.Interval.Interval parameter)
deriving (ContinuousDistribution parameter
-> ContinuousDistribution parameter -> Bool
(ContinuousDistribution parameter
-> ContinuousDistribution parameter -> Bool)
-> (ContinuousDistribution parameter
-> ContinuousDistribution parameter -> Bool)
-> Eq (ContinuousDistribution parameter)
forall parameter.
Eq parameter =>
ContinuousDistribution parameter
-> ContinuousDistribution parameter -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ContinuousDistribution parameter
-> ContinuousDistribution parameter -> Bool
$c/= :: forall parameter.
Eq parameter =>
ContinuousDistribution parameter
-> ContinuousDistribution parameter -> Bool
== :: ContinuousDistribution parameter
-> ContinuousDistribution parameter -> Bool
$c== :: forall parameter.
Eq parameter =>
ContinuousDistribution parameter
-> ContinuousDistribution parameter -> Bool
Eq, ReadPrec [ContinuousDistribution parameter]
ReadPrec (ContinuousDistribution parameter)
Int -> ReadS (ContinuousDistribution parameter)
ReadS [ContinuousDistribution parameter]
(Int -> ReadS (ContinuousDistribution parameter))
-> ReadS [ContinuousDistribution parameter]
-> ReadPrec (ContinuousDistribution parameter)
-> ReadPrec [ContinuousDistribution parameter]
-> Read (ContinuousDistribution parameter)
forall parameter.
Read parameter =>
ReadPrec [ContinuousDistribution parameter]
forall parameter.
Read parameter =>
ReadPrec (ContinuousDistribution parameter)
forall parameter.
Read parameter =>
Int -> ReadS (ContinuousDistribution parameter)
forall parameter.
Read parameter =>
ReadS [ContinuousDistribution parameter]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [ContinuousDistribution parameter]
$creadListPrec :: forall parameter.
Read parameter =>
ReadPrec [ContinuousDistribution parameter]
readPrec :: ReadPrec (ContinuousDistribution parameter)
$creadPrec :: forall parameter.
Read parameter =>
ReadPrec (ContinuousDistribution parameter)
readList :: ReadS [ContinuousDistribution parameter]
$creadList :: forall parameter.
Read parameter =>
ReadS [ContinuousDistribution parameter]
readsPrec :: Int -> ReadS (ContinuousDistribution parameter)
$creadsPrec :: forall parameter.
Read parameter =>
Int -> ReadS (ContinuousDistribution parameter)
Read, Int -> ContinuousDistribution parameter -> ShowS
[ContinuousDistribution parameter] -> ShowS
ContinuousDistribution parameter -> String
(Int -> ContinuousDistribution parameter -> ShowS)
-> (ContinuousDistribution parameter -> String)
-> ([ContinuousDistribution parameter] -> ShowS)
-> Show (ContinuousDistribution parameter)
forall parameter.
Show parameter =>
Int -> ContinuousDistribution parameter -> ShowS
forall parameter.
Show parameter =>
[ContinuousDistribution parameter] -> ShowS
forall parameter.
Show parameter =>
ContinuousDistribution parameter -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ContinuousDistribution parameter] -> ShowS
$cshowList :: forall parameter.
Show parameter =>
[ContinuousDistribution parameter] -> ShowS
show :: ContinuousDistribution parameter -> String
$cshow :: forall parameter.
Show parameter =>
ContinuousDistribution parameter -> String
showsPrec :: Int -> ContinuousDistribution parameter -> ShowS
$cshowsPrec :: forall parameter.
Show parameter =>
Int -> ContinuousDistribution parameter -> ShowS
Show)
instance (Floating parameter, Ord parameter, Show parameter) => ToolShed.SelfValidate.SelfValidator (ContinuousDistribution parameter) where
getErrors :: ContinuousDistribution parameter -> [String]
getErrors ContinuousDistribution parameter
probabilityDistribution = [(Bool, String)] -> [String]
ToolShed.SelfValidate.extractErrors ([(Bool, String)] -> [String]) -> [(Bool, String)] -> [String]
forall a b. (a -> b) -> a -> b
$ case ContinuousDistribution parameter
probabilityDistribution of
ExponentialDistribution parameter
lambda -> [(parameter
lambda parameter -> parameter -> Bool
forall a. Ord a => a -> a -> Bool
<= parameter
0, String
"'lambda' must exceed zero; " String -> ShowS
forall a. [a] -> [a] -> [a]
++ ContinuousDistribution parameter -> String
forall a. Show a => a -> String
show ContinuousDistribution parameter
probabilityDistribution String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
".")]
LogNormalDistribution parameter
location parameter
scale2 -> let
maxParameter :: parameter
maxParameter = parameter -> parameter
forall a. Floating a => a -> a
log (parameter -> parameter)
-> (Integer -> parameter) -> Integer -> parameter
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> parameter
forall a. Num a => Integer -> a
fromInteger (Integer -> parameter) -> Integer -> parameter
forall a b. (a -> b) -> a -> b
$ Double -> Integer
forall a. RealFloat a => a -> Integer
maxPreciseInteger (Double
forall a. HasCallStack => a
undefined :: Double)
in [
(parameter
scale2 parameter -> parameter -> Bool
forall a. Ord a => a -> a -> Bool
<= parameter
0, String
"'scale' must exceed zero; " String -> ShowS
forall a. [a] -> [a] -> [a]
++ ContinuousDistribution parameter -> String
forall a. Show a => a -> String
show ContinuousDistribution parameter
probabilityDistribution String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"."),
(parameter
location parameter -> parameter -> Bool
forall a. Ord a => a -> a -> Bool
> parameter
maxParameter Bool -> Bool -> Bool
|| parameter
scale2 parameter -> parameter -> Bool
forall a. Ord a => a -> a -> Bool
> parameter
maxParameter, String
"loss of precision will result from either 'location' or 'scale^2' exceeding '" String -> ShowS
forall a. [a] -> [a] -> [a]
++ parameter -> String
forall a. Show a => a -> String
show parameter
maxParameter String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"'; " String -> ShowS
forall a. [a] -> [a] -> [a]
++ ContinuousDistribution parameter -> String
forall a. Show a => a -> String
show ContinuousDistribution parameter
probabilityDistribution String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
".")
]
NormalDistribution parameter
_ parameter
variance -> [(parameter
variance parameter -> parameter -> Bool
forall a. Ord a => a -> a -> Bool
<= parameter
0, String
"variance must exceed zero; " String -> ShowS
forall a. [a] -> [a] -> [a]
++ ContinuousDistribution parameter -> String
forall a. Show a => a -> String
show ContinuousDistribution parameter
probabilityDistribution String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
".")]
UniformDistribution Interval parameter
interval -> [(Interval parameter -> Bool
forall endPoint. Ord endPoint => Interval endPoint -> Bool
Data.Interval.isReversed Interval parameter
interval, String
"reversed interval='" String -> ShowS
forall a. [a] -> [a] -> [a]
++ ContinuousDistribution parameter -> String
forall a. Show a => a -> String
show ContinuousDistribution parameter
probabilityDistribution String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"'.")]
data DiscreteDistribution parameter
= PoissonDistribution parameter
| ShiftedGeometricDistribution parameter
deriving (DiscreteDistribution parameter
-> DiscreteDistribution parameter -> Bool
(DiscreteDistribution parameter
-> DiscreteDistribution parameter -> Bool)
-> (DiscreteDistribution parameter
-> DiscreteDistribution parameter -> Bool)
-> Eq (DiscreteDistribution parameter)
forall parameter.
Eq parameter =>
DiscreteDistribution parameter
-> DiscreteDistribution parameter -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: DiscreteDistribution parameter
-> DiscreteDistribution parameter -> Bool
$c/= :: forall parameter.
Eq parameter =>
DiscreteDistribution parameter
-> DiscreteDistribution parameter -> Bool
== :: DiscreteDistribution parameter
-> DiscreteDistribution parameter -> Bool
$c== :: forall parameter.
Eq parameter =>
DiscreteDistribution parameter
-> DiscreteDistribution parameter -> Bool
Eq, ReadPrec [DiscreteDistribution parameter]
ReadPrec (DiscreteDistribution parameter)
Int -> ReadS (DiscreteDistribution parameter)
ReadS [DiscreteDistribution parameter]
(Int -> ReadS (DiscreteDistribution parameter))
-> ReadS [DiscreteDistribution parameter]
-> ReadPrec (DiscreteDistribution parameter)
-> ReadPrec [DiscreteDistribution parameter]
-> Read (DiscreteDistribution parameter)
forall parameter.
Read parameter =>
ReadPrec [DiscreteDistribution parameter]
forall parameter.
Read parameter =>
ReadPrec (DiscreteDistribution parameter)
forall parameter.
Read parameter =>
Int -> ReadS (DiscreteDistribution parameter)
forall parameter.
Read parameter =>
ReadS [DiscreteDistribution parameter]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [DiscreteDistribution parameter]
$creadListPrec :: forall parameter.
Read parameter =>
ReadPrec [DiscreteDistribution parameter]
readPrec :: ReadPrec (DiscreteDistribution parameter)
$creadPrec :: forall parameter.
Read parameter =>
ReadPrec (DiscreteDistribution parameter)
readList :: ReadS [DiscreteDistribution parameter]
$creadList :: forall parameter.
Read parameter =>
ReadS [DiscreteDistribution parameter]
readsPrec :: Int -> ReadS (DiscreteDistribution parameter)
$creadsPrec :: forall parameter.
Read parameter =>
Int -> ReadS (DiscreteDistribution parameter)
Read, Int -> DiscreteDistribution parameter -> ShowS
[DiscreteDistribution parameter] -> ShowS
DiscreteDistribution parameter -> String
(Int -> DiscreteDistribution parameter -> ShowS)
-> (DiscreteDistribution parameter -> String)
-> ([DiscreteDistribution parameter] -> ShowS)
-> Show (DiscreteDistribution parameter)
forall parameter.
Show parameter =>
Int -> DiscreteDistribution parameter -> ShowS
forall parameter.
Show parameter =>
[DiscreteDistribution parameter] -> ShowS
forall parameter.
Show parameter =>
DiscreteDistribution parameter -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [DiscreteDistribution parameter] -> ShowS
$cshowList :: forall parameter.
Show parameter =>
[DiscreteDistribution parameter] -> ShowS
show :: DiscreteDistribution parameter -> String
$cshow :: forall parameter.
Show parameter =>
DiscreteDistribution parameter -> String
showsPrec :: Int -> DiscreteDistribution parameter -> ShowS
$cshowsPrec :: forall parameter.
Show parameter =>
Int -> DiscreteDistribution parameter -> ShowS
Show)
instance (Num parameter, Ord parameter, Show parameter) => ToolShed.SelfValidate.SelfValidator (DiscreteDistribution parameter) where
getErrors :: DiscreteDistribution parameter -> [String]
getErrors DiscreteDistribution parameter
probabilityDistribution = [(Bool, String)] -> [String]
ToolShed.SelfValidate.extractErrors ([(Bool, String)] -> [String]) -> [(Bool, String)] -> [String]
forall a b. (a -> b) -> a -> b
$ case DiscreteDistribution parameter
probabilityDistribution of
PoissonDistribution parameter
lambda -> [(parameter
lambda parameter -> parameter -> Bool
forall a. Ord a => a -> a -> Bool
<= parameter
0, String
"'lambda' must exceed zero; " String -> ShowS
forall a. [a] -> [a] -> [a]
++ DiscreteDistribution parameter -> String
forall a. Show a => a -> String
show DiscreteDistribution parameter
probabilityDistribution String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
".")]
ShiftedGeometricDistribution parameter
probability -> [(((parameter -> Bool) -> Bool) -> [parameter -> Bool] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any ((parameter -> Bool) -> parameter -> Bool
forall a b. (a -> b) -> a -> b
$ parameter
probability) [(parameter -> parameter -> Bool
forall a. Ord a => a -> a -> Bool
<= parameter
0), (parameter -> parameter -> Bool
forall a. Ord a => a -> a -> Bool
> parameter
1)], String
"probability must be in the semi-closed unit-interval (0, 1]; " String -> ShowS
forall a. [a] -> [a] -> [a]
++ DiscreteDistribution parameter -> String
forall a. Show a => a -> String
show DiscreteDistribution parameter
probabilityDistribution String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
".")]
class Distribution probabilityDistribution where
generatePopulation
:: (Fractional sample, System.Random.RandomGen randomGen)
=> probabilityDistribution
-> randomGen
-> [sample]
getMean :: Fractional mean => probabilityDistribution -> mean
getStandardDeviation :: Floating standardDeviation => probabilityDistribution -> standardDeviation
getStandardDeviation = standardDeviation -> standardDeviation
forall a. Floating a => a -> a
sqrt (standardDeviation -> standardDeviation)
-> (probabilityDistribution -> standardDeviation)
-> probabilityDistribution
-> standardDeviation
forall b c a. (b -> c) -> (a -> b) -> a -> c
. probabilityDistribution -> standardDeviation
forall probabilityDistribution variance.
(Distribution probabilityDistribution, Floating variance) =>
probabilityDistribution -> variance
getVariance
getVariance :: Floating variance => probabilityDistribution -> variance
getVariance = variance -> variance
forall n. Num n => n -> n
Math.Power.square (variance -> variance)
-> (probabilityDistribution -> variance)
-> probabilityDistribution
-> variance
forall b c a. (b -> c) -> (a -> b) -> a -> c
. probabilityDistribution -> variance
forall probabilityDistribution variance.
(Distribution probabilityDistribution, Floating variance) =>
probabilityDistribution -> variance
getStandardDeviation
instance (RealFloat parameter, Show parameter, System.Random.Random parameter) => Distribution (ContinuousDistribution parameter) where
generatePopulation :: ContinuousDistribution parameter -> randomGen -> [sample]
generatePopulation ContinuousDistribution parameter
probabilityDistribution = (parameter -> sample) -> [parameter] -> [sample]
forall a b. (a -> b) -> [a] -> [b]
map parameter -> sample
forall a b. (Real a, Fractional b) => a -> b
realToFrac ([parameter] -> [sample])
-> (randomGen -> [parameter]) -> randomGen -> [sample]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ContinuousDistribution parameter -> randomGen -> [parameter]
forall f randomGen.
(RealFloat f, Show f, Random f, RandomGen randomGen) =>
ContinuousDistribution f -> randomGen -> [f]
generateContinuousPopulation ContinuousDistribution parameter
probabilityDistribution
getMean :: ContinuousDistribution parameter -> mean
getMean (ExponentialDistribution parameter
lambda) = parameter -> mean
forall a b. (Real a, Fractional b) => a -> b
realToFrac (parameter -> mean) -> parameter -> mean
forall a b. (a -> b) -> a -> b
$ parameter -> parameter
forall a. Fractional a => a -> a
recip parameter
lambda
getMean (LogNormalDistribution parameter
location parameter
scale2) = parameter -> mean
forall a b. (Real a, Fractional b) => a -> b
realToFrac (parameter -> mean)
-> (parameter -> parameter) -> parameter -> mean
forall b c a. (b -> c) -> (a -> b) -> a -> c
. parameter -> parameter
forall a. Floating a => a -> a
exp (parameter -> parameter)
-> (parameter -> parameter) -> parameter -> parameter
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (parameter -> parameter -> parameter
forall a. Num a => a -> a -> a
+ parameter
location) (parameter -> mean) -> parameter -> mean
forall a b. (a -> b) -> a -> b
$ parameter
scale2 parameter -> parameter -> parameter
forall a. Fractional a => a -> a -> a
/ parameter
2
getMean (NormalDistribution parameter
mean parameter
_) = parameter -> mean
forall a b. (Real a, Fractional b) => a -> b
realToFrac parameter
mean
getMean (UniformDistribution (parameter
minParameter, parameter
maxParameter)) = parameter -> mean
forall a b. (Real a, Fractional b) => a -> b
realToFrac (parameter -> mean) -> parameter -> mean
forall a b. (a -> b) -> a -> b
$ (parameter
minParameter parameter -> parameter -> parameter
forall a. Num a => a -> a -> a
+ parameter
maxParameter) parameter -> parameter -> parameter
forall a. Fractional a => a -> a -> a
/ parameter
2
getVariance :: ContinuousDistribution parameter -> variance
getVariance (ExponentialDistribution parameter
lambda) = parameter -> variance
forall a b. (Real a, Fractional b) => a -> b
realToFrac (parameter -> variance)
-> (parameter -> parameter) -> parameter -> variance
forall b c a. (b -> c) -> (a -> b) -> a -> c
. parameter -> parameter
forall a. Fractional a => a -> a
recip (parameter -> variance) -> parameter -> variance
forall a b. (a -> b) -> a -> b
$ parameter -> parameter
forall n. Num n => n -> n
Math.Power.square parameter
lambda
getVariance (LogNormalDistribution parameter
location parameter
scale2) = parameter -> variance
forall a b. (Real a, Fractional b) => a -> b
realToFrac (parameter -> variance) -> parameter -> variance
forall a b. (a -> b) -> a -> b
$ (parameter -> parameter
forall a. Floating a => a -> a
exp parameter
scale2 parameter -> parameter -> parameter
forall a. Num a => a -> a -> a
- parameter
1) parameter -> parameter -> parameter
forall a. Num a => a -> a -> a
* parameter -> parameter
forall a. Floating a => a -> a
exp (parameter
2 parameter -> parameter -> parameter
forall a. Num a => a -> a -> a
* parameter
location parameter -> parameter -> parameter
forall a. Num a => a -> a -> a
+ parameter
scale2)
getVariance (NormalDistribution parameter
_ parameter
variance) = parameter -> variance
forall a b. (Real a, Fractional b) => a -> b
realToFrac parameter
variance
getVariance (UniformDistribution (parameter
minParameter, parameter
maxParameter)) = parameter -> variance
forall a b. (Real a, Fractional b) => a -> b
realToFrac (parameter -> variance) -> parameter -> variance
forall a b. (a -> b) -> a -> b
$ parameter -> parameter
forall n. Num n => n -> n
Math.Power.square (parameter
maxParameter parameter -> parameter -> parameter
forall a. Num a => a -> a -> a
- parameter
minParameter) parameter -> parameter -> parameter
forall a. Fractional a => a -> a -> a
/ parameter
12
instance (RealFloat parameter, Show parameter, System.Random.Random parameter) => Distribution (DiscreteDistribution parameter) where
generatePopulation :: DiscreteDistribution parameter -> randomGen -> [sample]
generatePopulation DiscreteDistribution parameter
probabilityDistribution = (Integer -> sample) -> [Integer] -> [sample]
forall a b. (a -> b) -> [a] -> [b]
map Integer -> sample
forall a. Num a => Integer -> a
fromInteger ([Integer] -> [sample])
-> (randomGen -> [Integer]) -> randomGen -> [sample]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DiscreteDistribution parameter -> randomGen -> [Integer]
forall sample parameter randomGen.
(Integral sample, Ord parameter, RealFloat parameter,
Show parameter, Random parameter, RandomGen randomGen) =>
DiscreteDistribution parameter -> randomGen -> [sample]
generateDiscretePopulation DiscreteDistribution parameter
probabilityDistribution
getMean :: DiscreteDistribution parameter -> mean
getMean (PoissonDistribution parameter
lambda) = parameter -> mean
forall a b. (Real a, Fractional b) => a -> b
realToFrac parameter
lambda
getMean (ShiftedGeometricDistribution parameter
probability) = parameter -> mean
forall a b. (Real a, Fractional b) => a -> b
realToFrac (parameter -> mean) -> parameter -> mean
forall a b. (a -> b) -> a -> b
$ parameter -> parameter
forall a. Fractional a => a -> a
recip parameter
probability
getVariance :: DiscreteDistribution parameter -> variance
getVariance (PoissonDistribution parameter
lambda) = parameter -> variance
forall a b. (Real a, Fractional b) => a -> b
realToFrac parameter
lambda
getVariance (ShiftedGeometricDistribution parameter
probability) = parameter -> variance
forall a b. (Real a, Fractional b) => a -> b
realToFrac (parameter -> variance) -> parameter -> variance
forall a b. (a -> b) -> a -> b
$ (parameter
1 parameter -> parameter -> parameter
forall a. Num a => a -> a -> a
- parameter
probability) parameter -> parameter -> parameter
forall a. Fractional a => a -> a -> a
/ parameter -> parameter
forall n. Num n => n -> n
Math.Power.square parameter
probability
boxMullerTransform :: (
Floating f,
Ord f,
Show f
)
=> (f, f)
-> (f, f)
boxMullerTransform :: (f, f) -> (f, f)
boxMullerTransform (f, f)
cartesian
| Bool -> Bool
not (Bool -> Bool) -> ((Bool, Bool) -> Bool) -> (Bool, Bool) -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Bool -> Bool -> Bool) -> (Bool, Bool) -> Bool
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Bool -> Bool -> Bool
(&&) ((Bool, Bool) -> Bool) -> (Bool, Bool) -> Bool
forall a b. (a -> b) -> a -> b
$ (f -> Bool) -> (f, f) -> (Bool, Bool)
forall a b. (a -> b) -> (a, a) -> (b, b)
ToolShed.Data.Pair.mirror f -> Bool
forall n. (Num n, Ord n) => n -> Bool
inSemiClosedUnitInterval (f, f)
cartesian = String -> (f, f)
forall a. HasCallStack => String -> a
error (String -> (f, f)) -> String -> (f, f)
forall a b. (a -> b) -> a -> b
$ String
"Factory.Math.Probability.boxMullerTransform:\tspecified Cartesian coordinates, must be within semi-closed unit-interval (0, 1]; " String -> ShowS
forall a. [a] -> [a] -> [a]
++ (f, f) -> String
forall a. Show a => a -> String
show (f, f)
cartesian
| Bool
otherwise = (f, f) -> (f, f)
forall f. Floating f => (f, f) -> (f, f)
polarToCartesianTransform ((f, f) -> (f, f)) -> (f, f) -> (f, f)
forall a b. (a -> b) -> a -> b
$ (f -> f
forall a. Floating a => a -> a
sqrt (f -> f) -> (f -> f) -> f -> f
forall b c a. (b -> c) -> (a -> b) -> a -> c
. f -> f
forall n. Num n => n -> n
negate (f -> f) -> (f -> f) -> f -> f
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (f -> f -> f
forall a. Num a => a -> a -> a
* f
2) (f -> f) -> (f -> f) -> f -> f
forall b c a. (b -> c) -> (a -> b) -> a -> c
. f -> f
forall a. Floating a => a -> a
log (f -> f) -> (f -> f) -> (f, f) -> (f, f)
forall (a :: * -> * -> *) b c b' c'.
Arrow a =>
a b c -> a b' c' -> a (b, b') (c, c')
*** (f -> f -> f
forall a. Num a => a -> a -> a
* f
2) (f -> f) -> (f -> f) -> f -> f
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (f -> f -> f
forall a. Num a => a -> a -> a
* f
forall a. Floating a => a
pi)) (f, f)
cartesian
where
inSemiClosedUnitInterval :: (Num n, Ord n) => n -> Bool
inSemiClosedUnitInterval :: n -> Bool
inSemiClosedUnitInterval = (Bool -> Bool -> Bool) -> (Bool, Bool) -> Bool
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Bool -> Bool -> Bool
(&&) ((Bool, Bool) -> Bool) -> (n -> (Bool, Bool)) -> n -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((n -> n -> Bool
forall a. Ord a => a -> a -> Bool
> n
0) (n -> Bool) -> (n -> Bool) -> n -> (Bool, Bool)
forall (a :: * -> * -> *) b c c'.
Arrow a =>
a b c -> a b c' -> a b (c, c')
&&& (n -> n -> Bool
forall a. Ord a => a -> a -> Bool
<= n
1))
polarToCartesianTransform :: Floating f => (f, f) -> (f, f)
polarToCartesianTransform :: (f, f) -> (f, f)
polarToCartesianTransform = (f -> f -> f) -> (f, f) -> f
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry f -> f -> f
forall a. Num a => a -> a -> a
(*) ((f, f) -> f) -> ((f, f) -> (f, f)) -> (f, f) -> f
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (f -> f) -> (f, f) -> (f, f)
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (d, b) (d, c)
Control.Arrow.second f -> f
forall a. Floating a => a -> a
cos ((f, f) -> f) -> ((f, f) -> f) -> (f, f) -> (f, f)
forall (a :: * -> * -> *) b c c'.
Arrow a =>
a b c -> a b c' -> a b (c, c')
&&& (f -> f -> f) -> (f, f) -> f
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry f -> f -> f
forall a. Num a => a -> a -> a
(*) ((f, f) -> f) -> ((f, f) -> (f, f)) -> (f, f) -> f
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (f -> f) -> (f, f) -> (f, f)
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (d, b) (d, c)
Control.Arrow.second f -> f
forall a. Floating a => a -> a
sin
generateStandardizedNormalDistribution :: (
RealFloat f,
Show f,
System.Random.Random f,
System.Random.RandomGen randomGen
) => randomGen -> [f]
generateStandardizedNormalDistribution :: randomGen -> [f]
generateStandardizedNormalDistribution = [(f, f)] -> [f]
forall a. [(a, a)] -> [a]
ToolShed.Data.List.linearise ([(f, f)] -> [f]) -> (randomGen -> [(f, f)]) -> randomGen -> [f]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([f] -> [f] -> [(f, f)]) -> ([f], [f]) -> [(f, f)]
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry ((f -> f -> (f, f)) -> [f] -> [f] -> [(f, f)]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith ((f -> f -> (f, f)) -> [f] -> [f] -> [(f, f)])
-> (f -> f -> (f, f)) -> [f] -> [f] -> [(f, f)]
forall a b. (a -> b) -> a -> b
$ ((f, f) -> (f, f)) -> f -> f -> (f, f)
forall a b c. ((a, b) -> c) -> a -> b -> c
curry (f, f) -> (f, f)
forall f. (Floating f, Ord f, Show f) => (f, f) -> (f, f)
boxMullerTransform) (([f], [f]) -> [(f, f)])
-> (randomGen -> ([f], [f])) -> randomGen -> [(f, f)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (randomGen -> [f]) -> (randomGen, randomGen) -> ([f], [f])
forall a b. (a -> b) -> (a, a) -> (b, b)
ToolShed.Data.Pair.mirror (
(f, f) -> randomGen -> [f]
forall a g. (Random a, RandomGen g) => (a, a) -> g -> [a]
System.Random.randomRs (f -> f
forall a. RealFloat a => a -> a
minPositiveFloat f
forall a. HasCallStack => a
undefined, f
1)
) ((randomGen, randomGen) -> ([f], [f]))
-> (randomGen -> (randomGen, randomGen)) -> randomGen -> ([f], [f])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. randomGen -> (randomGen, randomGen)
forall g. RandomGen g => g -> (g, g)
System.Random.split
reProfile :: (Distribution distribution, Floating n) => distribution -> [n] -> [n]
reProfile :: distribution -> [n] -> [n]
reProfile distribution
distribution = (n -> n) -> [n] -> [n]
forall a b. (a -> b) -> [a] -> [b]
map ((n -> n -> n
forall a. Num a => a -> a -> a
+ distribution -> n
forall probabilityDistribution mean.
(Distribution probabilityDistribution, Fractional mean) =>
probabilityDistribution -> mean
getMean distribution
distribution) (n -> n) -> (n -> n) -> n -> n
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (n -> n -> n
forall a. Num a => a -> a -> a
* distribution -> n
forall probabilityDistribution variance.
(Distribution probabilityDistribution, Floating variance) =>
probabilityDistribution -> variance
getStandardDeviation distribution
distribution))
generateContinuousPopulation :: (
RealFloat f,
Show f,
System.Random.Random f,
System.Random.RandomGen randomGen
)
=> ContinuousDistribution f
-> randomGen
-> [f]
generateContinuousPopulation :: ContinuousDistribution f -> randomGen -> [f]
generateContinuousPopulation ContinuousDistribution f
probabilityDistribution randomGen
randomGen
| Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ ContinuousDistribution f -> Bool
forall v. SelfValidator v => v -> Bool
ToolShed.SelfValidate.isValid ContinuousDistribution f
probabilityDistribution = String -> [f]
forall a. HasCallStack => String -> a
error (String -> [f]) -> String -> [f]
forall a b. (a -> b) -> a -> b
$ String
"Factory.Math.Probability.generateContinuousPopulation:\t" String -> ShowS
forall a. [a] -> [a] -> [a]
++ ContinuousDistribution f -> String
forall v. SelfValidator v => v -> String
ToolShed.SelfValidate.getFirstError ContinuousDistribution f
probabilityDistribution
| Bool
otherwise = (
case ContinuousDistribution f
probabilityDistribution of
ExponentialDistribution f
lambda -> let
quantile :: f -> f
quantile = (f -> f -> f
forall a. Fractional a => a -> a -> a
/ f
lambda) (f -> f) -> (f -> f) -> f -> f
forall b c a. (b -> c) -> (a -> b) -> a -> c
. f -> f
forall n. Num n => n -> n
negate (f -> f) -> (f -> f) -> f -> f
forall b c a. (b -> c) -> (a -> b) -> a -> c
. f -> f
forall a. Floating a => a -> a
log (f -> f) -> (f -> f) -> f -> f
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (f
1 f -> f -> f
forall a. Num a => a -> a -> a
-)
in (f -> f) -> [f] -> [f]
forall a b. (a -> b) -> [a] -> [b]
map f -> f
quantile ([f] -> [f]) -> (randomGen -> [f]) -> randomGen -> [f]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (f, f) -> randomGen -> [f]
forall a g. (Random a, RandomGen g) => (a, a) -> g -> [a]
System.Random.randomRs (f
0, f
1)
LogNormalDistribution f
location f
scale2 -> (f -> f) -> [f] -> [f]
forall a b. (a -> b) -> [a] -> [b]
map (
f -> f
forall a. Floating a => a -> a
exp (f -> f) -> (f -> f) -> f -> f
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (f -> f -> f
forall a. Num a => a -> a -> a
+ f
location) (f -> f) -> (f -> f) -> f -> f
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (f -> f -> f
forall a. Num a => a -> a -> a
* f -> f
forall a. Floating a => a -> a
sqrt f
scale2)
) ([f] -> [f]) -> (randomGen -> [f]) -> randomGen -> [f]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. randomGen -> [f]
forall f randomGen.
(RealFloat f, Show f, Random f, RandomGen randomGen) =>
randomGen -> [f]
generateStandardizedNormalDistribution
NormalDistribution f
_ f
_ -> ContinuousDistribution f -> [f] -> [f]
forall distribution n.
(Distribution distribution, Floating n) =>
distribution -> [n] -> [n]
reProfile ContinuousDistribution f
probabilityDistribution ([f] -> [f]) -> (randomGen -> [f]) -> randomGen -> [f]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. randomGen -> [f]
forall f randomGen.
(RealFloat f, Show f, Random f, RandomGen randomGen) =>
randomGen -> [f]
generateStandardizedNormalDistribution
UniformDistribution (f, f)
interval -> (f, f) -> randomGen -> [f]
forall a g. (Random a, RandomGen g) => (a, a) -> g -> [a]
System.Random.randomRs (f, f)
interval
) randomGen
randomGen
generatePoissonDistribution :: (
Integral sample,
RealFloat lambda,
Show lambda,
System.Random.Random lambda,
System.Random.RandomGen randomGen
)
=> lambda
-> randomGen
-> [sample]
generatePoissonDistribution :: lambda -> randomGen -> [sample]
generatePoissonDistribution lambda
lambda
| lambda
lambda lambda -> lambda -> Bool
forall a. Ord a => a -> a -> Bool
<= lambda
0 = String -> randomGen -> [sample]
forall a. HasCallStack => String -> a
error (String -> randomGen -> [sample])
-> String -> randomGen -> [sample]
forall a b. (a -> b) -> a -> b
$ String
"Factory.Math.Probability.generatePoissonDistribution:\tlambda must exceed zero " String -> ShowS
forall a. [a] -> [a] -> [a]
++ lambda -> String
forall a. Show a => a -> String
show lambda
lambda
| lambda
lambda lambda -> lambda -> Bool
forall a. Ord a => a -> a -> Bool
> (
lambda -> lambda
forall n. Num n => n -> n
negate (lambda -> lambda) -> (lambda -> lambda) -> lambda -> lambda
forall b c a. (b -> c) -> (a -> b) -> a -> c
. lambda -> lambda
forall a. Floating a => a -> a
log (lambda -> lambda) -> lambda -> lambda
forall a b. (a -> b) -> a -> b
$ lambda -> lambda
forall a. RealFloat a => a -> a
minPositiveFloat lambda
lambda
) = (sample -> Bool) -> [sample] -> [sample]
forall a. (a -> Bool) -> [a] -> [a]
filter (sample -> sample -> Bool
forall a. Ord a => a -> a -> Bool
>= sample
0) ([sample] -> [sample])
-> (randomGen -> [sample]) -> randomGen -> [sample]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Double -> sample) -> [Double] -> [sample]
forall a b. (a -> b) -> [a] -> [b]
map Double -> sample
forall a b. (RealFrac a, Integral b) => a -> b
round ([Double] -> [sample])
-> (randomGen -> [Double]) -> randomGen -> [sample]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (DiscreteDistribution lambda -> [Double] -> [Double]
forall distribution n.
(Distribution distribution, Floating n) =>
distribution -> [n] -> [n]
reProfile (lambda -> DiscreteDistribution lambda
forall parameter. parameter -> DiscreteDistribution parameter
PoissonDistribution lambda
lambda) :: [Double] -> [Double]) ([Double] -> [Double])
-> (randomGen -> [Double]) -> randomGen -> [Double]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. randomGen -> [Double]
forall f randomGen.
(RealFloat f, Show f, Random f, RandomGen randomGen) =>
randomGen -> [f]
generateStandardizedNormalDistribution
| Bool
otherwise = randomGen -> [sample]
generator
where
generator :: randomGen -> [sample]
generator = (sample -> [sample] -> [sample]) -> (sample, [sample]) -> [sample]
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry (:) ((sample, [sample]) -> [sample])
-> (randomGen -> (sample, [sample])) -> randomGen -> [sample]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (
(sample, lambda) -> sample
forall a b. (a, b) -> a
fst ((sample, lambda) -> sample)
-> (randomGen -> (sample, lambda)) -> randomGen -> sample
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(sample, lambda)] -> (sample, lambda)
forall a. [a] -> a
head ([(sample, lambda)] -> (sample, lambda))
-> (randomGen -> [(sample, lambda)])
-> randomGen
-> (sample, lambda)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((sample, lambda) -> Bool)
-> [(sample, lambda)] -> [(sample, lambda)]
forall a. (a -> Bool) -> [a] -> [a]
dropWhile (
(lambda -> lambda -> Bool
forall a. Ord a => a -> a -> Bool
> lambda -> lambda
forall a. Floating a => a -> a
exp (lambda -> lambda
forall n. Num n => n -> n
negate lambda
lambda)) (lambda -> Bool)
-> ((sample, lambda) -> lambda) -> (sample, lambda) -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (sample, lambda) -> lambda
forall a b. (a, b) -> b
snd
) ([(sample, lambda)] -> [(sample, lambda)])
-> (randomGen -> [(sample, lambda)])
-> randomGen
-> [(sample, lambda)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((sample, lambda) -> lambda -> (sample, lambda))
-> (sample, lambda) -> [lambda] -> [(sample, lambda)]
forall b a. (b -> a -> b) -> b -> [a] -> [b]
scanl (
\(sample, lambda)
accumulator lambda
random -> sample -> sample
forall a. Enum a => a -> a
succ (sample -> sample)
-> (lambda -> lambda) -> (sample, lambda) -> (sample, lambda)
forall (a :: * -> * -> *) b c b' c'.
Arrow a =>
a b c -> a b' c' -> a (b, b') (c, c')
*** (lambda -> lambda -> lambda
forall a. Num a => a -> a -> a
* lambda
random) ((sample, lambda) -> (sample, lambda))
-> (sample, lambda) -> (sample, lambda)
forall a b. (a -> b) -> a -> b
$ (sample, lambda)
accumulator
) (sample -> sample
forall n. Num n => n -> n
negate sample
1, lambda
1) ([lambda] -> [(sample, lambda)])
-> (randomGen -> [lambda]) -> randomGen -> [(sample, lambda)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (lambda, lambda) -> randomGen -> [lambda]
forall a g. (Random a, RandomGen g) => (a, a) -> g -> [a]
System.Random.randomRs (lambda
0, lambda
1) (randomGen -> sample)
-> (randomGen -> [sample])
-> (randomGen, randomGen)
-> (sample, [sample])
forall (a :: * -> * -> *) b c b' c'.
Arrow a =>
a b c -> a b' c' -> a (b, b') (c, c')
*** randomGen -> [sample]
generator
) ((randomGen, randomGen) -> (sample, [sample]))
-> (randomGen -> (randomGen, randomGen))
-> randomGen
-> (sample, [sample])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. randomGen -> (randomGen, randomGen)
forall g. RandomGen g => g -> (g, g)
System.Random.split
generateDiscretePopulation :: (
Integral sample,
Ord parameter,
RealFloat parameter,
Show parameter,
System.Random.Random parameter,
System.Random.RandomGen randomGen
)
=> DiscreteDistribution parameter
-> randomGen
-> [sample]
generateDiscretePopulation :: DiscreteDistribution parameter -> randomGen -> [sample]
generateDiscretePopulation DiscreteDistribution parameter
probabilityDistribution randomGen
randomGen
| Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ DiscreteDistribution parameter -> Bool
forall v. SelfValidator v => v -> Bool
ToolShed.SelfValidate.isValid DiscreteDistribution parameter
probabilityDistribution = String -> [sample]
forall a. HasCallStack => String -> a
error (String -> [sample]) -> String -> [sample]
forall a b. (a -> b) -> a -> b
$ String
"Factory.Math.Probability.generateDiscretePopulation:\t" String -> ShowS
forall a. [a] -> [a] -> [a]
++ DiscreteDistribution parameter -> String
forall v. SelfValidator v => v -> String
ToolShed.SelfValidate.getFirstError DiscreteDistribution parameter
probabilityDistribution
| Bool
otherwise = (
case DiscreteDistribution parameter
probabilityDistribution of
PoissonDistribution parameter
lambda -> parameter -> randomGen -> [sample]
forall sample lambda randomGen.
(Integral sample, RealFloat lambda, Show lambda, Random lambda,
RandomGen randomGen) =>
lambda -> randomGen -> [sample]
generatePoissonDistribution parameter
lambda
ShiftedGeometricDistribution parameter
probability
| parameter
probability parameter -> parameter -> Bool
forall a. Eq a => a -> a -> Bool
== parameter
1 -> [sample] -> randomGen -> [sample]
forall a b. a -> b -> a
const ([sample] -> randomGen -> [sample])
-> [sample] -> randomGen -> [sample]
forall a b. (a -> b) -> a -> b
$ sample -> [sample]
forall a. a -> [a]
repeat sample
1
| Bool
otherwise -> (Rational -> sample) -> [Rational] -> [sample]
forall a b. (a -> b) -> [a] -> [b]
map Rational -> sample
forall a b. (RealFrac a, Integral b) => a -> b
ceiling ([Rational] -> [sample])
-> (randomGen -> [Rational]) -> randomGen -> [sample]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (\[Rational]
x -> [Rational]
x :: [Rational]) ([Rational] -> [Rational])
-> (randomGen -> [Rational]) -> randomGen -> [Rational]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ContinuousDistribution parameter -> randomGen -> [Rational]
forall probabilityDistribution sample randomGen.
(Distribution probabilityDistribution, Fractional sample,
RandomGen randomGen) =>
probabilityDistribution -> randomGen -> [sample]
generatePopulation (parameter -> ContinuousDistribution parameter
forall parameter. parameter -> ContinuousDistribution parameter
ExponentialDistribution (parameter -> ContinuousDistribution parameter)
-> (parameter -> parameter)
-> parameter
-> ContinuousDistribution parameter
forall b c a. (b -> c) -> (a -> b) -> a -> c
. parameter -> parameter
forall n. Num n => n -> n
negate (parameter -> ContinuousDistribution parameter)
-> parameter -> ContinuousDistribution parameter
forall a b. (a -> b) -> a -> b
$ parameter -> parameter
forall a. Floating a => a -> a
log (parameter
1 parameter -> parameter -> parameter
forall a. Num a => a -> a -> a
- parameter
probability))
) randomGen
randomGen