Copyright | (c) 2015-2018 Jared Tobin Marco Zocca |
---|---|
License | MIT |
Maintainer | Jared Tobin <jared@jtobin.ca>, Marco Zocca <zocca.marco gmail> |
Stability | unstable |
Portability | ghc |
Safe Haskell | None |
Language | Haskell2010 |
A probability monad based on sampling functions, implemented as a thin wrapper over the mwc-random library.
Probability distributions are abstract constructs that can be represented in a variety of ways. The sampling function representation is particularly useful -- it's computationally efficient, and collections of samples are amenable to much practical work.
Probability monads propagate uncertainty under the hood. An expression like
corresponds to a
beta-binomial
distribution in which the uncertainty captured by beta
1 8 >>= binomial
10
has been
marginalized out.beta
1 8
The distribution resulting from a series of effects is called the predictive distribution of the model described by the corresponding expression. The monadic structure lets one piece together a hierarchical structure from simpler, local conditionals:
hierarchicalModel = do [c, d, e, f] <- replicateM 4 $ uniformR (1, 10) a <- gamma c d b <- gamma e f p <- beta a b n <- uniformR (5, 10) binomial n p
The functor instance allows one to transforms the support of a distribution
while leaving its density structure invariant. For example,
is
a distribution over the 0-1 interval, but uniform
fmap (+ 1) uniform
is the
translated distribution over the 1-2 interval:
>>>
create >>= sample (fmap (+ 1) uniform)
1.5480073474340754
The applicative instance guarantees that the generated samples are generated independently:
>>>
create >>= sample ((,) <$> uniform <*> uniform)
Synopsis
- uniformVector :: (PrimMonad m, StatefulGen g m, Uniform a, Vector v a) => g -> Int -> m (v a)
- withSystemRandom :: PrimBase m => (Gen (PrimState m) -> m a) -> IO a
- withSystemRandomST :: (forall s. Gen s -> ST s a) -> IO a
- createSystemRandom :: IO GenIO
- createSystemSeed :: IO Seed
- restore :: PrimMonad m => Seed -> m (Gen (PrimState m))
- save :: PrimMonad m => Gen (PrimState m) -> m Seed
- toSeed :: Vector v Word32 => v Word32 -> Seed
- fromSeed :: Seed -> Vector Word32
- initialize :: (PrimMonad m, Vector v Word32) => v Word32 -> m (Gen (PrimState m))
- create :: PrimMonad m => m (Gen (PrimState m))
- asGenST :: (GenST s -> ST s a) -> GenST s -> ST s a
- asGenIO :: (GenIO -> IO a) -> GenIO -> IO a
- class Variate a
- data Gen s
- type GenIO = Gen (PrimState IO)
- type GenST s = Gen (PrimState (ST s))
- data Seed
- class UniformRange a where
- uniformRM :: StatefulGen g m => (a, a) -> g -> m a
- class Uniform a where
- uniformM :: StatefulGen g m => g -> m a
- newtype Prob m a = Prob {}
- samples :: PrimMonad m => Int -> Prob m a -> Gen (PrimState m) -> m [a]
- uniform :: (PrimMonad m, Variate a) => Prob m a
- uniformR :: (PrimMonad m, Variate a) => (a, a) -> Prob m a
- normal :: PrimMonad m => Double -> Double -> Prob m Double
- standardNormal :: PrimMonad m => Prob m Double
- isoNormal :: (Traversable f, PrimMonad m) => f Double -> Double -> Prob m (f Double)
- logNormal :: PrimMonad m => Double -> Double -> Prob m Double
- exponential :: PrimMonad m => Double -> Prob m Double
- inverseGaussian :: PrimMonad m => Double -> Double -> Prob m Double
- laplace :: (Floating a, Variate a, PrimMonad m) => a -> a -> Prob m a
- gamma :: PrimMonad m => Double -> Double -> Prob m Double
- inverseGamma :: PrimMonad m => Double -> Double -> Prob m Double
- normalGamma :: PrimMonad m => Double -> Double -> Double -> Double -> Prob m Double
- weibull :: (Floating a, Variate a, PrimMonad m) => a -> a -> Prob m a
- chiSquare :: PrimMonad m => Int -> Prob m Double
- beta :: PrimMonad m => Double -> Double -> Prob m Double
- gstudent :: PrimMonad m => Double -> Double -> Double -> Prob m Double
- student :: PrimMonad m => Double -> Prob m Double
- pareto :: PrimMonad m => Double -> Double -> Prob m Double
- dirichlet :: (Traversable f, PrimMonad m) => f Double -> Prob m (f Double)
- symmetricDirichlet :: PrimMonad m => Int -> Double -> Prob m [Double]
- discreteUniform :: (PrimMonad m, Foldable f) => f a -> Prob m a
- zipf :: (PrimMonad m, Integral b) => Double -> Prob m b
- categorical :: (Foldable f, PrimMonad m) => f Double -> Prob m Int
- discrete :: (Foldable f, PrimMonad m) => f (Double, a) -> Prob m a
- bernoulli :: PrimMonad m => Double -> Prob m Bool
- binomial :: PrimMonad m => Int -> Double -> Prob m Int
- negativeBinomial :: (PrimMonad m, Integral a) => a -> Double -> Prob m Int
- multinomial :: (Foldable f, PrimMonad m) => Int -> f Double -> Prob m [Int]
- poisson :: PrimMonad m => Double -> Prob m Int
- crp :: PrimMonad m => Double -> Int -> Prob m [Integer]
Documentation
uniformVector :: (PrimMonad m, StatefulGen g m, Uniform a, Vector v a) => g -> Int -> m (v a) #
Generate a vector of pseudo-random variates. This is not
necessarily faster than invoking uniform
repeatedly in a loop,
but it may be more convenient to use in some situations.
withSystemRandom :: PrimBase m => (Gen (PrimState m) -> m a) -> IO a #
Seed a PRNG with data from the system's fast source of pseudo-random numbers, then run the given action.
This function is unsafe and for example allows STRefs or any other mutable data structure to escape scope:
>>>
ref <- withSystemRandom $ \_ -> newSTRef 1
>>>
withSystemRandom $ \_ -> modifySTRef ref succ >> readSTRef ref
2>>>
withSystemRandom $ \_ -> modifySTRef ref succ >> readSTRef ref
3
withSystemRandomST :: (forall s. Gen s -> ST s a) -> IO a #
Seed PRNG with data from the system's fast source of pseudo-random numbers and execute computation in ST monad.
Since: mwc-random-0.15.0.0
createSystemRandom :: IO GenIO #
Seed a PRNG with data from the system's fast source of pseudo-random numbers.
createSystemSeed :: IO Seed #
Generate random seed for generator using system's fast source of pseudo-random numbers.
Since: mwc-random-0.15.0.0
toSeed :: Vector v Word32 => v Word32 -> Seed #
Convert vector to Seed
. It acts similarily to initialize
and
will accept any vector. If you want to pass seed immediately to
restore you better call initialize directly since following law holds:
restore (toSeed v) = initialize v
initialize :: (PrimMonad m, Vector v Word32) => v Word32 -> m (Gen (PrimState m)) #
Create a generator for variates using the given seed, of which up to 256 elements will be used. For arrays of less than 256 elements, part of the default seed will be used to finish initializing the generator's state.
Examples:
initialize (singleton 42)
initialize (fromList [4, 8, 15, 16, 23, 42])
If a seed contains fewer than 256 elements, it is first used
verbatim, then its elements are xor
ed against elements of the
default seed until 256 elements are reached.
If a seed contains exactly 258 elements, then the last two elements
are used to set the generator's initial state. This allows for
complete generator reproducibility, so that e.g. gen' == gen
in
the following example:
gen' <-initialize
.fromSeed
=<<save
In the MWC algorithm, the carry value must be strictly smaller than the multiplicator (see https://en.wikipedia.org/wiki/Multiply-with-carry). Hence, if a seed contains exactly 258 elements, the carry value, which is the last of the 258 values, is moduloed by the multiplicator.
Note that if the first carry value is strictly smaller than the multiplicator,
all subsequent carry values are also strictly smaller than the multiplicator
(a proof of this is in the comments of the code of uniformWord32
), hence
when restoring a saved state, we have the guarantee that moduloing the saved
carry won't modify its value.
asGenST :: (GenST s -> ST s a) -> GenST s -> ST s a #
Constrain the type of an action to run in the ST
monad.
asGenIO :: (GenIO -> IO a) -> GenIO -> IO a #
Constrain the type of an action to run in the IO
monad.
NOTE: Consider use of more principled type classes
Uniform
and UniformRange
instead.
The class of types for which we can generate uniformly distributed random variates.
The uniform PRNG uses Marsaglia's MWC256 (also known as MWC8222) multiply-with-carry generator, which has a period of 2^8222 and fares well in tests of randomness. It is also extremely fast, between 2 and 3 times faster than the Mersenne Twister.
Note: Marsaglia's PRNG is not known to be cryptographically secure, so you should not use it for cryptographic operations.
Instances
Variate Bool | |
Variate Double | |
Variate Float | |
Variate Int | |
Variate Int8 | |
Variate Int16 | |
Variate Int32 | |
Variate Int64 | |
Variate Word | |
Variate Word8 | |
Variate Word16 | |
Variate Word32 | |
Variate Word64 | |
(Variate a, Variate b) => Variate (a, b) | |
(Variate a, Variate b, Variate c) => Variate (a, b, c) | |
(Variate a, Variate b, Variate c, Variate d) => Variate (a, b, c, d) | |
State of the pseudo-random number generator. It uses mutable state so same generator shouldn't be used from the different threads simultaneously.
Instances
(s ~ PrimState m, PrimMonad m) => StatefulGen (Gen s) m | Since: mwc-random-0.15.0.0 |
Defined in System.Random.MWC uniformWord32R :: Word32 -> Gen s -> m Word32 # uniformWord64R :: Word64 -> Gen s -> m Word64 # uniformWord8 :: Gen s -> m Word8 # uniformWord16 :: Gen s -> m Word16 # uniformWord32 :: Gen s -> m Word32 # uniformWord64 :: Gen s -> m Word64 # uniformShortByteString :: Int -> Gen s -> m ShortByteString # |
An immutable snapshot of the state of a Gen
.
Instances
Eq Seed | |
Show Seed | |
PrimMonad m => FrozenGen Seed m | Since: mwc-random-0.15.0.0 |
Defined in System.Random.MWC type MutableGen Seed m = (g :: Type) # freezeGen :: MutableGen Seed m -> m Seed # thawGen :: Seed -> m (MutableGen Seed m) # | |
type MutableGen Seed m | |
Defined in System.Random.MWC |
class UniformRange a where #
The class of types for which a uniformly distributed value can be drawn from a range.
Since: random-1.2.0
uniformRM :: StatefulGen g m => (a, a) -> g -> m a #
Generates a value uniformly distributed over the provided range, which is interpreted as inclusive in the lower and upper bound.
uniformRM (1 :: Int, 4 :: Int)
generates values uniformly from the set \(\{1,2,3,4\}\)uniformRM (1 :: Float, 4 :: Float)
generates values uniformly from the set \(\{x\;|\;1 \le x \le 4\}\)
The following law should hold to make the function always defined:
uniformRM (a, b) = uniformRM (b, a)
Since: random-1.2.0
Instances
The class of types for which a uniformly distributed value can be drawn from all possible values of the type.
Since: random-1.2.0
uniformM :: StatefulGen g m => g -> m a #
Generates a value uniformly distributed over all possible values of that type.
Since: random-1.2.0
Instances
A probability distribution characterized by a sampling function.
>>>
gen <- createSystemRandom
>>>
sample uniform gen
0.4208881170464097
Instances
MonadTrans Prob Source # | |
Defined in System.Random.MWC.Probability | |
Monad m => Monad (Prob m) Source # | |
Functor m => Functor (Prob m) Source # | |
Monad m => Applicative (Prob m) Source # | |
MonadIO m => MonadIO (Prob m) Source # | |
Defined in System.Random.MWC.Probability | |
PrimMonad m => PrimMonad (Prob m) Source # | |
(Monad m, Num a) => Num (Prob m a) Source # | |
type PrimState (Prob m) Source # | |
Defined in System.Random.MWC.Probability |
samples :: PrimMonad m => Int -> Prob m a -> Gen (PrimState m) -> m [a] Source #
Sample from a model n
times.
>>>
samples 2 uniform gen
[0.6738707766845254,0.9730405951541817]
uniformR :: (PrimMonad m, Variate a) => (a, a) -> Prob m a Source #
The uniform distribution over the provided interval.
>>>
sample (uniformR (0, 1)) gen
0.44984153252922365
normal :: PrimMonad m => Double -> Double -> Prob m Double Source #
The normal or Gaussian distribution with specified mean and standard deviation.
Note that sd
should be positive.
standardNormal :: PrimMonad m => Prob m Double Source #
The standard normal or Gaussian distribution with mean 0 and standard deviation 1.
isoNormal :: (Traversable f, PrimMonad m) => f Double -> Double -> Prob m (f Double) Source #
An isotropic or spherical Gaussian distribution with specified mean vector and scalar standard deviation parameter.
Note that sd
should be positive.
logNormal :: PrimMonad m => Double -> Double -> Prob m Double Source #
The log-normal distribution with specified mean and standard deviation.
Note that sd
should be positive.
exponential :: PrimMonad m => Double -> Prob m Double Source #
The exponential distribution with provided rate parameter.
Note that r
should be positive.
inverseGaussian :: PrimMonad m => Double -> Double -> Prob m Double Source #
The inverse Gaussian (also known as Wald) distribution with mean parameter
mu
and shape parameter lambda
.
Note that both mu
and lambda
should be positive.
laplace :: (Floating a, Variate a, PrimMonad m) => a -> a -> Prob m a Source #
The Laplace or double-exponential distribution with provided location and scale parameters.
Note that sigma
should be positive.
gamma :: PrimMonad m => Double -> Double -> Prob m Double Source #
The gamma distribution with shape parameter a
and scale parameter b
.
This is the parameterization used more traditionally in frequentist statistics. It has the following corresponding probability density function:
f(x; a, b) = 1 / (Gamma(a) * b ^ a) x ^ (a - 1) e ^ (- x / b)
Note that both parameters should be positive.
inverseGamma :: PrimMonad m => Double -> Double -> Prob m Double Source #
The inverse-gamma distribution with shape parameter a
and scale
parameter b
.
Note that both parameters should be positive.
normalGamma :: PrimMonad m => Double -> Double -> Double -> Double -> Prob m Double Source #
The Normal-Gamma distribution.
Note that the lambda
, a
, and b
parameters should be positive.
weibull :: (Floating a, Variate a, PrimMonad m) => a -> a -> Prob m a Source #
The Weibull distribution with provided shape and scale parameters.
Note that both parameters should be positive.
chiSquare :: PrimMonad m => Int -> Prob m Double Source #
The chi-square distribution with the specified degrees of freedom.
Note that k
should be positive.
beta :: PrimMonad m => Double -> Double -> Prob m Double Source #
The beta distribution with the specified shape parameters.
Note that both parameters should be positive.
gstudent :: PrimMonad m => Double -> Double -> Double -> Prob m Double Source #
Generalized Student's t distribution with location parameter m
, scale
parameter s
, and degrees of freedom k
.
Note that the s
and k
parameters should be positive.
student :: PrimMonad m => Double -> Prob m Double Source #
Student's t distribution with k
degrees of freedom.
Note that k
should be positive.
pareto :: PrimMonad m => Double -> Double -> Prob m Double Source #
The Pareto distribution with specified index a
and minimum xmin
parameters.
Note that both parameters should be positive.
dirichlet :: (Traversable f, PrimMonad m) => f Double -> Prob m (f Double) Source #
The Dirichlet distribution with the provided concentration parameters. The dimension of the distribution is determined by the number of concentration parameters supplied.
>>>
sample (dirichlet [0.1, 1, 10]) gen
[1.2375387187120799e-5,3.4952460651813816e-3,0.9964923785476316]
Note that all concentration parameters should be positive.
symmetricDirichlet :: PrimMonad m => Int -> Double -> Prob m [Double] Source #
The symmetric Dirichlet distribution with dimension n
. The provided
concentration parameter is simply replicated n
times.
Note that a
should be positive.
discreteUniform :: (PrimMonad m, Foldable f) => f a -> Prob m a Source #
The discrete uniform distribution.
>>>
sample (discreteUniform [0..10]) gen
6>>>
sample (discreteUniform "abcdefghijklmnopqrstuvwxyz") gen
'a'
zipf :: (PrimMonad m, Integral b) => Double -> Prob m b Source #
The Zipf-Mandelbrot distribution.
Note that a
should be positive, and that values close to 1 should be
avoided as they are very computationally intensive.
>>>
samples 10 (zipf 1.1) gen
[11315371987423520,2746946,653,609,2,13,85,4,256184577853,50]
>>>
samples 10 (zipf 1.5) gen
[19,3,3,1,1,2,1,191,2,1]
categorical :: (Foldable f, PrimMonad m) => f Double -> Prob m Int Source #
A categorical distribution defined by the supplied probabilities.
Note that the supplied probability container should consist of non-negative values but is not required to sum to one.
discrete :: (Foldable f, PrimMonad m) => f (Double, a) -> Prob m a Source #
A categorical distribution defined by the supplied support.
Note that the supplied probabilities should be non-negative, but are not required to sum to one.
>>>
samples 10 (discrete [(0.1, "yeah"), (0.9, "nah")]) gen
["yeah","nah","nah","nah","nah","yeah","nah","nah","nah","nah"]
bernoulli :: PrimMonad m => Double -> Prob m Bool Source #
The Bernoulli distribution with success probability p
.
binomial :: PrimMonad m => Int -> Double -> Prob m Int Source #
The binomial distribution with number of trials n
and success
probability p
.
>>>
sample (binomial 10 0.3) gen
4
negativeBinomial :: (PrimMonad m, Integral a) => a -> Double -> Prob m Int Source #
The negative binomial distribution with number of trials n
and success
probability p
.
>>>
sample (negativeBinomial 10 0.3) gen
21
multinomial :: (Foldable f, PrimMonad m) => Int -> f Double -> Prob m [Int] Source #
The multinomial distribution of n
trials and category probabilities
ps
.
Note that the supplied probability container should consist of non-negative values but is not required to sum to one.