-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Random number generation -- -- Random number generation based on modeling random variables in two -- complementary ways: first, by the parameters of standard mathematical -- distributions and, second, by an abstract type (RVar) which can -- be composed and manipulated monadically and sampled in either monadic -- or "pure" styles. The primary purpose of this library is to support -- defining and sampling a wide variety of high quality random variables. -- Quality is prioritized over speed, but performance is an important -- goal too. In my testing, I have found it capable of speed comparable -- to other Haskell libraries, but still a fair bit slower than straight -- C implementations of the same algorithms. Warning to anyone upgrading -- from "< 0.1": Discrete has been renamed Categorical, -- the entropy source classes have been redesigned, and many things are -- no longer exported from the root module Data.Random (In -- particular, DevRandom - this is not available on windows, so it will -- likely move to its own package eventually so that client code -- dependencies on it will be made explicit). Support for base -- packages earlier than version 4 (and thus GHC releases earlier than -- 6.10) has been dropped, as too many of this package's dependencies do -- not support older versions. The Data.Random module itself -- should now have a relatively stable interface, but the other modules -- are still subject to change. Specifically, I am considering hiding -- data constructors for most or all of the distributions. @package random-fu @version 0.1.4 module Data.Random.Internal.Find findMax :: (Fractional a, Ord a) => (a -> Bool) -> a -- | Given an upward-closed predicate on an ordered Fractional type, find -- the smallest value satisfying the predicate. findMin :: (Fractional a, Ord a) => (a -> Bool) -> a -- | Given an upward-closed predicate on an ordered Fractional type, find -- the smallest value satisfying the predicate. Starts at the specified -- point with the specified stepsize, performs an exponential search out -- from there until it finds an interval bracketing the change-point of -- the predicate, and then performs a bisection search to isolate the -- change point. Note that infinitely-divisible domains such as -- Rational cannot be searched by this function because it does -- not terminate until it reaches a point where further subdivision of -- the interval has no effect. findMinFrom :: (Fractional a, Ord a) => a -> a -> (a -> Bool) -> a module Data.Random.Internal.Fixed resolutionOf :: HasResolution r => f r -> Integer resolutionOf2 :: HasResolution r => f (g r) -> Integer -- | The Fixed type doesn't expose its constructors, but I need a -- way to convert them to and from their raw representation in order to -- sample them. As long as Fixed is a newtype wrapping -- Integer, mkFixed and unMkFixed as defined here -- will work. Both are implemented using unsafeCoerce. mkFixed :: Integer -> Fixed r unMkFixed :: Fixed r -> Integer -- | A few little functions I found myself writing inline over and over -- again. module Data.Random.Internal.Words -- | Build a word out of 2 bytes. No promises are made regarding the order -- in which the bytes are stuffed. Note that this means that a -- RandomSource or MonadRandom making use of the -- default definition of getRandomWord, etc., may return -- different random values on different platforms when started with the -- same seed, depending on the platform's endianness. buildWord16 :: Word8 -> Word8 -> Word16 -- | Build a word out of 4 bytes. No promises are made regarding the order -- in which the bytes are stuffed. Note that this means that a -- RandomSource or MonadRandom making use of the -- default definition of getRandomWord, etc., may return -- different random values on different platforms when started with the -- same seed, depending on the platform's endianness. buildWord32 :: Word8 -> Word8 -> Word8 -> Word8 -> Word32 buildWord32' :: Word16 -> Word16 -> Word32 -- | Build a word out of 8 bytes. No promises are made regarding the order -- in which the bytes are stuffed. Note that this means that a -- RandomSource or MonadRandom making use of the -- default definition of getRandomWord, etc., may return -- different random values on different platforms when started with the -- same seed, depending on the platform's endianness. buildWord64 :: Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Word64 buildWord64' :: Word16 -> Word16 -> Word16 -> Word16 -> Word64 buildWord64'' :: Word32 -> Word32 -> Word64 -- | Pack the low 23 bits from a Word32 into a Float in the -- range [0,1). Used to convert a stdUniform Word32 to a -- stdUniform Double. word32ToFloat :: Word32 -> Float -- | Same as word32ToFloat, but also return the unused bits (as the 9 least -- significant bits of a Word32) word32ToFloatWithExcess :: Word32 -> (Float, Word32) -- | Pack the low 23 bits from a Word64 into a Float in the -- range [0,1). Used to convert a stdUniform Word64 to a -- stdUniform Double. wordToFloat :: Word64 -> Float -- | Same as wordToFloat, but also return the unused bits (as the 41 least -- significant bits of a Word64) wordToFloatWithExcess :: Word64 -> (Float, Word64) -- | Pack the low 52 bits from a Word64 into a Double in the -- range [0,1). Used to convert a stdUniform Word64 to a -- stdUniform Double. wordToDouble :: Word64 -> Double -- | Pack a Word32 into a Double in the range [0,1). Note -- that a Double's mantissa is 52 bits, so this does not fill all of -- them. word32ToDouble :: Word32 -> Double -- | Same as wordToDouble, but also return the unused bits (as the 12 least -- significant bits of a Word64) wordToDoubleWithExcess :: Word64 -> (Double, Word64) -- | Template Haskell utility code to replicate instance declarations to -- cover large numbers of types. I'm doing that rather than using class -- contexts because most Distribution instances need to cover multiple -- classes (such as Enum, Integral and Fractional) and that can't be done -- easily because of overlap. -- -- I experimented a bit with a convoluted type-level classification -- scheme, but I think this is simpler and easier to understand. It makes -- the haddock docs more cluttered because of the combinatorial explosion -- of instances, but overall I think it's just more sane than anything -- else I've come up with yet. module Data.Random.Internal.TH -- | replicateInstances standin types decls will take the -- template-haskell Decs in decls and substitute every -- instance of the Name standin with each Name in -- types, producing one copy of the Decs in -- decls for every Name in types. -- -- For example, Data.Random.Distribution.Uniform has the -- following bit of TH code: -- --
-- $( replicateInstances ''Int integralTypes [d| ---- --
-- instance Distribution Uniform Int where rvar (Uniform a b) = integralUniform a b ---- --
-- instance CDF Uniform Int where cdf (Uniform a b) = integralUniformCDF a b ---- --
-- |]) ---- -- This code takes those 2 instance declarations and creates identical -- ones for every type named in integralTypes. replicateInstances :: (Monad m, Data t) => Name -> [Name] -> m [t] -> m [t] -- | Names of standard Integral types integralTypes :: [Name] -- | Names of standard RealFloat types realFloatTypes :: [Name] module Data.Random.Lift -- | A class for "liftable" data structures. Conceptually an extension of -- MonadTrans to allow deep lifting, but lifting need not be done -- between monads only. Eg lifting between Applicatives is -- allowed. -- -- For instances where m and n have 'return'/'pure' -- defined, these instances must satisfy lift (return x) == return -- x. -- -- This form of lift has an extremely general type and is used -- primarily to support sample. Its excessive generality is the -- main reason it's not exported from Data.Random. RVarT -- is, however, an instance of MonadTrans, which in most cases is -- the preferred way to do the lifting. class Lift m n lift :: Lift m n => m a -> n a instance [incoherent] Monad m => Lift Identity m instance [incoherent] Lift m m instance [incoherent] (Monad m, MonadTrans t) => Lift m (t m) -- | This is an experimental interface to support an extensible set of -- primitives, where a RandomSource will be able to support whatever -- subset of them they want and have well-founded defaults generated -- automatically for any unsupported primitives. -- -- The purpose, in case it's not clear, is to decouple the -- implementations of entropy sources from any particular set of -- primitives, so that implementors of random variates can make use of a -- large number of primitives, supported on all entropy sources, while -- the burden on entropy-source implementors is only to provide one or -- two basic primitives of their choice. -- -- One challenge I foresee with this interface is optimization - -- different compilers or even different versions of GHC may treat this -- interface radically differently, making it very hard to achieve -- reliable performance on all platforms. It may even be that no compiler -- optimizes sufficiently to make the flexibility this system provides -- worth the overhead. I hope this is not the case, but if it turns out -- to be a major problem, this system may disappear or be modified in -- significant ways. module Data.Random.Internal.Primitives -- | A Prompt GADT describing a request for a primitive random -- variate. Random variable definitions will request their entropy via -- these prompts, and entropy sources will satisfy some or all of them. -- The decomposePrimWhere function extends an entropy source's -- incomplete definition to a complete definition, essentially defining a -- very flexible implementation-defaulting system. -- -- Some possible future additions: PrimFloat :: Prim Float PrimInt :: -- Prim Int PrimPair :: Prim a -> Prim b -> Prim (a :*: b) -- PrimNormal :: Prim Double PrimChoice :: [(Double :*: a)] -> Prim a -- -- Unfortunately, I cannot get Haddock to accept my comments about the -- data constructors, but hopefully they should be reasonably -- self-explanatory. data Prim a PrimWord8 :: Prim Word8 PrimWord16 :: Prim Word16 PrimWord32 :: Prim Word32 PrimWord64 :: Prim Word64 PrimDouble :: Prim Double PrimNByteInteger :: !Int -> Prim Integer -- | This function wraps up the most common calling convention for -- decomposePrimWhere. Given a predicate identifying "supported" -- Prims, and a (possibly partial) function that maps those -- Prims to implementations, derives a total function mapping all -- Prims to implementations. getPrimWhere :: Monad m => (forall t. Prim t -> Bool) -> (forall t. Prim t -> m t) -> Prim a -> m a -- | This is essentially a suite of interrelated default implementations, -- each definition making use of only "supported" primitives. It _really_ -- ought to be inlined to the point where the supported -- predicate is able to be inlined into it and eliminated. -- -- When inlined sufficiently, it should in theory be optimized down to -- the static set of best definitions for each required primitive -- in terms of only supported primitives. -- -- Hopefully it does not impose too much overhead when not inlined. decomposePrimWhere :: (forall t. Prim t -> Bool) -> Prim a -> Prompt Prim a instance Typeable1 Prim instance Show (Prim a) module Data.Random.Source -- | A typeclass for monads with a chosen source of entropy. For example, -- RVar is such a monad - the source from which it is -- (eventually) sampled is the only source from which a random variable -- is permitted to draw, so when directly requesting entropy for a random -- variable these functions are used. -- -- Occasionally one might want a RandomSource specifying the -- MonadRandom instance (for example, when using -- runRVar). For those cases, -- Data.Random.Source.Std.StdRandom provides a -- RandomSource that maps to the MonadRandom instance. -- -- For example, State StdGen has a MonadRandom instance, -- so to run an RVar (called x in this example) in this -- monad one could write runRVar x StdRandom (or more concisely -- with the sample function: sample x). class Monad m => MonadRandom m getRandomPrim :: MonadRandom m => Prim t -> m t -- | A source of entropy which can be used in the given monad. -- -- See also MonadRandom. class Monad m => RandomSource m s getRandomPrimFrom :: RandomSource m s => s -> Prim t -> m t -- | A Prompt GADT describing a request for a primitive random -- variate. Random variable definitions will request their entropy via -- these prompts, and entropy sources will satisfy some or all of them. -- The decomposePrimWhere function extends an entropy source's -- incomplete definition to a complete definition, essentially defining a -- very flexible implementation-defaulting system. -- -- Some possible future additions: PrimFloat :: Prim Float PrimInt :: -- Prim Int PrimPair :: Prim a -> Prim b -> Prim (a :*: b) -- PrimNormal :: Prim Double PrimChoice :: [(Double :*: a)] -> Prim a -- -- Unfortunately, I cannot get Haddock to accept my comments about the -- data constructors, but hopefully they should be reasonably -- self-explanatory. data Prim a PrimWord8 :: Prim Word8 PrimWord16 :: Prim Word16 PrimWord32 :: Prim Word32 PrimWord64 :: Prim Word64 PrimDouble :: Prim Double PrimNByteInteger :: !Int -> Prim Integer instance Monad m => RandomSource m (m Double) instance Monad m => RandomSource m (m Word64) instance Monad m => RandomSource m (m Word32) instance Monad m => RandomSource m (m Word16) instance Monad m => RandomSource m (m Word8) module Data.Random.Source.DevRandom -- | On systems that have it, /dev/random is a handy-dandy ready-to-use -- source of nonsense. Keep in mind that on some systems, Linux included, -- /dev/random collects "real" entropy, and if you don't have a good -- source of it, such as special hardware for the purpose or a *lot* of -- network traffic, it's pretty easy to suck the entropy pool dry with -- entropy-intensive applications. For many purposes other than -- cryptography, /dev/urandom is preferable because when it runs out of -- real entropy it'll still churn out pseudorandom data. data DevRandom DevRandom :: DevRandom DevURandom :: DevRandom instance Eq DevRandom instance Show DevRandom instance RandomSource IO DevRandom -- | This module defines the following instances: -- --
-- instance RandomSource (ST s) (Gen s) -- instance RandomSource IO (Gen RealWorld) --module Data.Random.Source.MWC instance RandomSource IO (Gen RealWorld) instance RandomSource (ST s) (Gen s) -- | This module provides functions useful for implementing new -- MonadRandom and RandomSource instances for -- state-abstractions containing StdGen values (the pure -- pseudorandom generator provided by the System.Random module in the -- "random" package), as well as instances for some common cases. module Data.Random.Source.StdGen getRandomPrimFromStdGenIO :: Prim a -> IO a -- | Given a mutable reference to a RandomGen generator, we can make -- a RandomSource usable in any monad in which the reference can -- be modified. -- -- See Data.Random.Source.PureMT.getRandomPrimFromMTRef -- for more detailed usage hints - this function serves exactly the same -- purpose except for a StdGen generator instead of a -- PureMT generator. getRandomPrimFromRandomGenRef :: (Monad m, ModifyRef sr m g, RandomGen g) => sr -> Prim t -> m t -- | Similarly, getRandomWordFromRandomGenState x can be used in -- any "state" monad in the mtl sense whose state is a RandomGen -- generator. Additionally, the standard mtl state monads have -- MonadRandom instances which do precisely that, allowing an easy -- conversion of RVars and other Distribution instances -- to "pure" random variables. -- -- Again, see -- Data.Random.Source.PureMT.getRandomPrimFromMTState for -- more detailed usage hints - this function serves exactly the same -- purpose except for a StdGen generator instead of a -- PureMT generator. getRandomPrimFromRandomGenState :: (RandomGen g, MonadState g m) => Prim t -> m t instance Monad m => MonadRandom (StateT StdGen m) instance Monad m => MonadRandom (StateT StdGen m) instance (Monad m, ModifyRef (STRef s StdGen) m StdGen) => RandomSource m (STRef s StdGen) instance (Monad m, ModifyRef (IORef StdGen) m StdGen) => RandomSource m (IORef StdGen) instance (Monad m1, ModifyRef (Ref m2 StdGen) m1 StdGen) => RandomSource m1 (Ref m2 StdGen) -- | This module provides functions useful for implementing new -- MonadRandom and RandomSource instances for -- state-abstractions containing PureMT values (the pure -- pseudorandom generator provided by the mersenne-random-pure64 -- package), as well as instances for some common cases. -- -- A PureMT generator is immutable, so PureMT by itself -- cannot be a RandomSource (if it were, it would always give the -- same "random" values). Some form of mutable state must be used, such -- as an IORef, State monad, etc.. A few default instances -- are provided by this module along with more-general functions -- (getRandomPrimFromMTRef and getRandomPrimFromMTState) -- usable as implementations for new cases users might need. module Data.Random.Source.PureMT -- | PureMT, a pure mersenne twister pseudo-random number generator data PureMT :: * -- | Create a new PureMT generator, using the clocktime as the base for the -- seed. newPureMT :: IO PureMT -- | Create a PureMT generator from a Word64 seed. pureMT :: Word64 -> PureMT -- | Given a function for applying a PureMT transformation to some -- hidden state, this function derives a function able to generate all -- Prims in the given monad. This is then suitable for either a -- MonadRandom or RandomSource instance, where the -- supportedPrims or supportedPrimsFrom function -- (respectively) is const True. getRandomPrimBy :: Monad m => (forall t. (PureMT -> (t, PureMT)) -> m t) -> Prim a -> m a -- | Given a mutable reference to a PureMT generator, we can -- implement RandomSource for in any monad in which the reference -- can be modified. -- -- Typically this would be used to define a new RandomSource -- instance for some new reference type or new monad in which an existing -- reference type can be modified atomically. As an example, the -- following instance could be used to describe how IORef -- PureMT can be a RandomSource in the IO monad: -- --
-- instance RandomSource IO (IORef PureMT) where -- supportedPrimsFrom _ _ = True -- getSupportedRandomPrimFrom = getRandomPrimFromMTRef ---- -- (note that there is actually a more general instance declared already -- covering this as a a special case, so there's no need to repeat this -- declaration anywhere) -- -- Example usage: -- --
-- main = do -- src <- newIORef (pureMT 1234) -- OR: newPureMT >>= newIORef -- x <- sampleFrom src (uniform 0 100) -- OR: runRVar (uniform 0 100) src -- print x --getRandomPrimFromMTRef :: (Monad m, ModifyRef sr m PureMT) => sr -> Prim t -> m t -- | Similarly, getRandomPrimFromMTState x can be used in any -- "state" monad in the mtl sense whose state is a PureMT -- generator. Additionally, the standard mtl state monads have -- MonadRandom instances which do precisely that, allowing an easy -- conversion of RVars and other Distribution instances -- to "pure" random variables (e.g., by runState . sample :: -- Distribution d t => d t -> PureMT -> (t, PureMT). -- PureMT in the type there can be replaced by StdGen or -- anything else satisfying MonadRandom (State s) => s). -- -- For example, this module includes the following declaration: -- --
-- instance MonadRandom (State PureMT) where -- supportedPrims _ _ = True -- getSupportedRandomPrim = getRandomPrimFromMTState ---- -- This describes a "standard" way of getting random values in -- State PureMT, which can then be used in various ways, -- for example (assuming some RVar foo and some -- Word64 seed): -- --
-- runState (runRVar foo StdRandom) (pureMT seed) -- runState (sampleFrom StdRandom foo) (pureMT seed) -- runState (sample foo) (pureMT seed) ---- -- Of course, the initial PureMT state could also be obtained by -- any other convenient means, such as newPureMT if you don't care -- what seed is used. getRandomPrimFromMTState :: MonadState PureMT m => Prim t -> m t instance (Monad m, ModifyRef (STRef s PureMT) m PureMT) => RandomSource m (STRef s PureMT) instance (Monad m, ModifyRef (IORef PureMT) m PureMT) => RandomSource m (IORef PureMT) instance Monad m => MonadRandom (StateT PureMT m) instance Monad m => MonadRandom (StateT PureMT m) instance (Monad m1, ModifyRef (Ref m2 PureMT) m1 PureMT) => RandomSource m1 (Ref m2 PureMT) module Data.Random.Source.Std -- | A token representing the "standard" entropy source in a -- MonadRandom monad. Its sole purpose is to make the following -- true (when the types check): -- --
-- sampleFrom StdRandom === sample --data StdRandom StdRandom :: StdRandom instance MonadRandom m => RandomSource m StdRandom -- | Random variables. An RVar is a sampleable random variable. -- Because probability distributions form a monad, they are quite easy to -- work with in the standard Haskell monadic styles. For examples, see -- the source for any of the Distribution instances - they all -- are defined in terms of RVars. module Data.Random.RVar -- | An opaque type modeling a "random variable" - a value which depends on -- the outcome of some random event. RVars can be conveniently -- defined by an imperative-looking style: -- --
-- normalPair = do -- u <- stdUniform -- t <- stdUniform -- let r = sqrt (-2 * log u) -- theta = (2 * pi) * t -- -- x = r * cos theta -- y = r * sin theta -- return (x,y) ---- -- OR by a more applicative style: -- --
-- logNormal = exp <$> stdNormal ---- -- Once defined (in any style), there are several ways to sample -- RVars: -- --
-- sampleFrom DevRandom (uniform 1 100) :: IO Int ---- --
-- sample (uniform 1 100) :: State PureMT Int ---- --
-- sampleState (uniform 1 100) :: StdGen -> (Int, StdGen) --type RVar = RVarT Identity -- | "Run" an RVar - samples the random variable from the provided -- source of entropy. Typically sample, sampleFrom or -- sampleState will be more convenient to use. runRVar :: RandomSource m s => RVar a -> s -> m a -- | A random variable with access to operations in an underlying monad. -- Useful examples include any form of state for implementing random -- processes with hysteresis, or writer monads for implementing tracing -- of complicated algorithms. -- -- For example, a simple random walk can be implemented as an -- RVarT IO value: -- --
-- rwalkIO :: IO (RVarT IO Double) -- rwalkIO d = do -- lastVal <- newIORef 0 -- -- let x = do -- prev <- lift (readIORef lastVal) -- change <- rvarT StdNormal -- -- let new = prev + change -- lift (writeIORef lastVal new) -- return new -- -- return x ---- -- To run the random walk, it must first be initialized, and then it can -- be sampled as usual: -- --
-- do -- rw <- rwalkIO -- x <- sampleFrom DevURandom rw -- y <- sampleFrom DevURandom rw -- ... ---- -- The same random-walk process as above can be implemented using MTL -- types as follows (using import Control.Monad.Trans as MTL): -- --
-- rwalkState :: RVarT (State Double) Double -- rwalkState = do -- prev <- MTL.lift get -- change <- rvarT StdNormal -- -- let new = prev + change -- MTL.lift (put new) -- return new ---- -- Invocation is straightforward (although a bit noisy) if you're used to -- MTL, but there is a gotcha lurking here: sample and -- runRVarT inherit the extreme generality of lift, so -- there will almost always need to be an explicit type signature lurking -- somewhere in any client code making use of RVarT with MTL -- types. In this example, the inferred type of start would be -- too general to be practical, so the signature for rwalk -- explicitly fixes it to Double. Alternatively, in this case -- sample could be replaced with \x -> runRVarTWith -- MTL.lift x StdRandom. -- --
-- rwalk :: Int -> Double -> StdGen -> ([Double], StdGen) -- rwalk count start gen = evalState (runStateT (sample (replicateM count rwalkState)) gen) start --data RVarT m a -- | "Runs" an RVarT, sampling the random variable it defines. -- -- The Lift context allows random variables to be defined using a -- minimal underlying functor (Identity is sufficient for -- "conventional" random variables) and then sampled in any monad into -- which the underlying functor can be embedded (which, for -- Identity, is all monads). -- -- The lifting is very important - without it, every RVar would -- have to either be given access to the full capability of the monad in -- which it will eventually be sampled (which, incidentally, would also -- have to be monomorphic so you couldn't sample one RVar in more -- than one monad) or functions manipulating RVars would have to -- use higher-ranked types to enforce the same kind of isolation and -- polymorphism. -- -- For non-standard liftings or those where you would rather not -- introduce a Lift instance, see runRVarTWith. runRVarT :: (Lift n m, RandomSource m s) => RVarT n a -> s -> m a -- | Like runRVarT but allowing a user-specified lift operation. -- This operation must obey the "monad transformer" laws: -- --
-- lift . return = return -- lift (x >>= f) = (lift x) >>= (lift . f) ---- -- One example of a useful non-standard lifting would be one that takes -- State s to another monad with a different state -- representation (such as IO with the state mapped to an -- IORef): -- --
-- embedState :: (Monad m) => m s -> (s -> m ()) -> State s a -> m a -- embedState get put = \m -> do -- s <- get -- (res,s) <- return (runState m s) -- put s -- return res --runRVarTWith :: RandomSource m s => (forall t. n t -> m t) -> RVarT n a -> s -> m a instance MonadRandom (RVarT n) instance MonadIO m => MonadIO (RVarT m) instance Lift (RVarT Identity) (RVarT m) instance MonadTrans RVarT instance Applicative (RVarT n) instance Monad (RVarT n) instance Functor (RVarT n) module Data.Random.Distribution -- | A Distribution is a data representation of a random variable's -- probability structure. For example, in -- Data.Random.Distribution.Normal, the Normal -- distribution is defined as: -- --
-- data Normal a -- = StdNormal -- | Normal a a ---- -- Where the two parameters of the Normal data constructor are -- the mean and standard deviation of the random variable, respectively. -- To make use of the Normal type, one can convert it to an -- rvar and manipulate it or sample it directly: -- --
-- x <- sample (rvar (Normal 10 2)) -- x <- sample (Normal 10 2) ---- -- A Distribution is typically more transparent than an -- RVar but less composable (precisely because of that -- transparency). There are several practical uses for types implementing -- Distribution: -- --
-- normalPair = do -- u <- stdUniform -- t <- stdUniform -- let r = sqrt (-2 * log u) -- theta = (2 * pi) * t -- -- x = r * cos theta -- y = r * sin theta -- return (x,y) ---- -- OR by a more applicative style: -- --
-- logNormal = exp <$> stdNormal ---- -- Once defined (in any style), there are several ways to sample -- RVars: -- --
-- sampleFrom DevRandom (uniform 1 100) :: IO Int ---- --
-- sample (uniform 1 100) :: State PureMT Int ---- --
-- sampleState (uniform 1 100) :: StdGen -> (Int, StdGen) --type RVar = RVarT Identity -- | A random variable with access to operations in an underlying monad. -- Useful examples include any form of state for implementing random -- processes with hysteresis, or writer monads for implementing tracing -- of complicated algorithms. -- -- For example, a simple random walk can be implemented as an -- RVarT IO value: -- --
-- rwalkIO :: IO (RVarT IO Double) -- rwalkIO d = do -- lastVal <- newIORef 0 -- -- let x = do -- prev <- lift (readIORef lastVal) -- change <- rvarT StdNormal -- -- let new = prev + change -- lift (writeIORef lastVal new) -- return new -- -- return x ---- -- To run the random walk, it must first be initialized, and then it can -- be sampled as usual: -- --
-- do -- rw <- rwalkIO -- x <- sampleFrom DevURandom rw -- y <- sampleFrom DevURandom rw -- ... ---- -- The same random-walk process as above can be implemented using MTL -- types as follows (using import Control.Monad.Trans as MTL): -- --
-- rwalkState :: RVarT (State Double) Double -- rwalkState = do -- prev <- MTL.lift get -- change <- rvarT StdNormal -- -- let new = prev + change -- MTL.lift (put new) -- return new ---- -- Invocation is straightforward (although a bit noisy) if you're used to -- MTL, but there is a gotcha lurking here: sample and -- runRVarT inherit the extreme generality of lift, so -- there will almost always need to be an explicit type signature lurking -- somewhere in any client code making use of RVarT with MTL -- types. In this example, the inferred type of start would be -- too general to be practical, so the signature for rwalk -- explicitly fixes it to Double. Alternatively, in this case -- sample could be replaced with \x -> runRVarTWith -- MTL.lift x StdRandom. -- --
-- rwalk :: Int -> Double -> StdGen -> ([Double], StdGen) -- rwalk count start gen = evalState (runStateT (sample (replicateM count rwalkState)) gen) start --data RVarT m a -- | "Run" an RVar - samples the random variable from the provided -- source of entropy. Typically sample, sampleFrom or -- sampleState will be more convenient to use. runRVar :: RandomSource m s => RVar a -> s -> m a -- | "Runs" an RVarT, sampling the random variable it defines. -- -- The Lift context allows random variables to be defined using a -- minimal underlying functor (Identity is sufficient for -- "conventional" random variables) and then sampled in any monad into -- which the underlying functor can be embedded (which, for -- Identity, is all monads). -- -- The lifting is very important - without it, every RVar would -- have to either be given access to the full capability of the monad in -- which it will eventually be sampled (which, incidentally, would also -- have to be monomorphic so you couldn't sample one RVar in more -- than one monad) or functions manipulating RVars would have to -- use higher-ranked types to enforce the same kind of isolation and -- polymorphism. -- -- For non-standard liftings or those where you would rather not -- introduce a Lift instance, see runRVarTWith. runRVarT :: (Lift n m, RandomSource m s) => RVarT n a -> s -> m a -- | Like runRVarT but allowing a user-specified lift operation. -- This operation must obey the "monad transformer" laws: -- --
-- lift . return = return -- lift (x >>= f) = (lift x) >>= (lift . f) ---- -- One example of a useful non-standard lifting would be one that takes -- State s to another monad with a different state -- representation (such as IO with the state mapped to an -- IORef): -- --
-- embedState :: (Monad m) => m s -> (s -> m ()) -> State s a -> m a -- embedState get put = \m -> do -- s <- get -- (res,s) <- return (runState m s) -- put s -- return res --runRVarTWith :: RandomSource m s => (forall t. n t -> m t) -> RVarT n a -> s -> m a -- | A Distribution is a data representation of a random variable's -- probability structure. For example, in -- Data.Random.Distribution.Normal, the Normal -- distribution is defined as: -- --
-- data Normal a -- = StdNormal -- | Normal a a ---- -- Where the two parameters of the Normal data constructor are -- the mean and standard deviation of the random variable, respectively. -- To make use of the Normal type, one can convert it to an -- rvar and manipulate it or sample it directly: -- --
-- x <- sample (rvar (Normal 10 2)) -- x <- sample (Normal 10 2) ---- -- A Distribution is typically more transparent than an -- RVar but less composable (precisely because of that -- transparency). There are several practical uses for types implementing -- Distribution: -- --
-- sampleFrom StdRandom === sample --data StdRandom StdRandom :: StdRandom -- | A random variable returning an arbitrary element of the given list. -- Every element has equal probability of being chosen. Because it is a -- pure RVar it has no memory - that is, it "draws with -- replacement." randomElement :: [a] -> RVar a -- | A random variable that returns the given list in an arbitrary shuffled -- order. Every ordering of the list has equal probability. shuffle :: [a] -> RVar [a] -- | A random variable that shuffles a list of a known length (or a list -- prefix of the specified length). Useful for shuffling large lists when -- the length is known in advance. Avoids needing to traverse the list to -- discover its length. Each ordering has equal probability. shuffleN :: Int -> [a] -> RVar [a] -- | A random variable that selects N arbitrary elements of a list of known -- length M. shuffleNofM :: Int -> Int -> [a] -> RVar [a] module Data.Random.Distribution.Beta fractionalBeta :: (Fractional a, Distribution Gamma a, Distribution StdUniform a) => a -> a -> RVarT m a beta :: Distribution Beta a => a -> a -> RVar a betaT :: Distribution Beta a => a -> a -> RVarT m a data Beta a Beta :: a -> a -> Beta a instance Distribution Beta Double instance Distribution Beta Float module Data.Random.Distribution.Binomial integralBinomial :: (Integral a, Floating b, Ord b, Distribution Beta b, Distribution StdUniform b) => a -> b -> RVarT m a integralBinomialCDF :: (Integral a, Real b) => a -> b -> a -> Double floatingBinomial :: (RealFrac a, Distribution (Binomial b) Integer) => a -> b -> RVar a floatingBinomialCDF :: (CDF (Binomial b) Integer, RealFrac a) => a -> b -> a -> Double binomial :: Distribution (Binomial b) a => a -> b -> RVar a binomialT :: Distribution (Binomial b) a => a -> b -> RVarT m a data Binomial b a Binomial :: a -> b -> Binomial b a instance CDF (Binomial b[a1ouv]) Integer => CDF (Binomial b[a1ouv]) Double instance Distribution (Binomial b[a1ous]) Integer => Distribution (Binomial b[a1ous]) Double instance CDF (Binomial b[a1oup]) Integer => CDF (Binomial b[a1oup]) Float instance Distribution (Binomial b[a1oum]) Integer => Distribution (Binomial b[a1oum]) Float instance (Real b[a1ogR], Distribution (Binomial b[a1ogR]) Word64) => CDF (Binomial b[a1ogR]) Word64 instance (Floating b[a1ogO], Ord b[a1ogO], Distribution Beta b[a1ogO], Distribution StdUniform b[a1ogO]) => Distribution (Binomial b[a1ogO]) Word64 instance (Real b[a1ogL], Distribution (Binomial b[a1ogL]) Word32) => CDF (Binomial b[a1ogL]) Word32 instance (Floating b[a1ogI], Ord b[a1ogI], Distribution Beta b[a1ogI], Distribution StdUniform b[a1ogI]) => Distribution (Binomial b[a1ogI]) Word32 instance (Real b[a1ogF], Distribution (Binomial b[a1ogF]) Word16) => CDF (Binomial b[a1ogF]) Word16 instance (Floating b[a1ogC], Ord b[a1ogC], Distribution Beta b[a1ogC], Distribution StdUniform b[a1ogC]) => Distribution (Binomial b[a1ogC]) Word16 instance (Real b[a1ogz], Distribution (Binomial b[a1ogz]) Word8) => CDF (Binomial b[a1ogz]) Word8 instance (Floating b[a1ogw], Ord b[a1ogw], Distribution Beta b[a1ogw], Distribution StdUniform b[a1ogw]) => Distribution (Binomial b[a1ogw]) Word8 instance (Real b[a1ogt], Distribution (Binomial b[a1ogt]) Word) => CDF (Binomial b[a1ogt]) Word instance (Floating b[a1ogq], Ord b[a1ogq], Distribution Beta b[a1ogq], Distribution StdUniform b[a1ogq]) => Distribution (Binomial b[a1ogq]) Word instance (Real b[a1ogn], Distribution (Binomial b[a1ogn]) Int64) => CDF (Binomial b[a1ogn]) Int64 instance (Floating b[a1ogk], Ord b[a1ogk], Distribution Beta b[a1ogk], Distribution StdUniform b[a1ogk]) => Distribution (Binomial b[a1ogk]) Int64 instance (Real b[a1ogh], Distribution (Binomial b[a1ogh]) Int32) => CDF (Binomial b[a1ogh]) Int32 instance (Floating b[a1oge], Ord b[a1oge], Distribution Beta b[a1oge], Distribution StdUniform b[a1oge]) => Distribution (Binomial b[a1oge]) Int32 instance (Real b[a1ogb], Distribution (Binomial b[a1ogb]) Int16) => CDF (Binomial b[a1ogb]) Int16 instance (Floating b[a1og8], Ord b[a1og8], Distribution Beta b[a1og8], Distribution StdUniform b[a1og8]) => Distribution (Binomial b[a1og8]) Int16 instance (Real b[a1og5], Distribution (Binomial b[a1og5]) Int8) => CDF (Binomial b[a1og5]) Int8 instance (Floating b[a1og2], Ord b[a1og2], Distribution Beta b[a1og2], Distribution StdUniform b[a1og2]) => Distribution (Binomial b[a1og2]) Int8 instance (Real b[a1ofZ], Distribution (Binomial b[a1ofZ]) Int) => CDF (Binomial b[a1ofZ]) Int instance (Floating b[a1ofW], Ord b[a1ofW], Distribution Beta b[a1ofW], Distribution StdUniform b[a1ofW]) => Distribution (Binomial b[a1ofW]) Int instance (Real b[a1ofT], Distribution (Binomial b[a1ofT]) Integer) => CDF (Binomial b[a1ofT]) Integer instance (Floating b[a1ofQ], Ord b[a1ofQ], Distribution Beta b[a1ofQ], Distribution StdUniform b[a1ofQ]) => Distribution (Binomial b[a1ofQ]) Integer module Data.Random.Distribution.Multinomial multinomial :: Distribution (Multinomial p) [a] => [p] -> a -> RVar [a] multinomialT :: Distribution (Multinomial p) [a] => [p] -> a -> RVarT m [a] data Multinomial p a Multinomial :: [p] -> a -> Multinomial p [a] instance (Num a, Fractional p, Distribution (Binomial p) a) => Distribution (Multinomial p) [a] module Data.Random.Distribution.Dirichlet fractionalDirichlet :: (Fractional a, Distribution Gamma a) => [a] -> RVarT m [a] dirichlet :: Distribution Dirichlet [a] => [a] -> RVar [a] dirichletT :: Distribution Dirichlet [a] => [a] -> RVarT m [a] newtype Dirichlet a Dirichlet :: a -> Dirichlet a instance Eq a => Eq (Dirichlet a) instance Show a => Show (Dirichlet a) instance (Fractional a, Distribution Gamma a) => Distribution Dirichlet [a] module Data.Random.Distribution.Poisson integralPoisson :: (Integral a, RealFloat b, Distribution StdUniform b, Distribution (Erlang a) b, Distribution (Binomial b) a) => b -> RVarT m a integralPoissonCDF :: (Integral a, Real b) => b -> a -> Double fractionalPoisson :: (Num a, Distribution (Poisson b) Integer) => b -> RVarT m a fractionalPoissonCDF :: (CDF (Poisson b) Integer, RealFrac a) => b -> a -> Double poisson :: Distribution (Poisson b) a => b -> RVar a poissonT :: Distribution (Poisson b) a => b -> RVarT m a data Poisson b a Poisson :: b -> Poisson b a instance CDF (Poisson b[a1ume]) Integer => CDF (Poisson b[a1ume]) Double instance Distribution (Poisson b[a1umc]) Integer => Distribution (Poisson b[a1umc]) Double instance CDF (Poisson b[a1uma]) Integer => CDF (Poisson b[a1uma]) Float instance Distribution (Poisson b[a1um8]) Integer => Distribution (Poisson b[a1um8]) Float instance (Real b[a1u9D], Distribution (Poisson b[a1u9D]) Word64) => CDF (Poisson b[a1u9D]) Word64 instance (RealFloat b[a1u9B], Distribution StdUniform b[a1u9B], Distribution (Erlang Word64) b[a1u9B], Distribution (Binomial b[a1u9B]) Word64) => Distribution (Poisson b[a1u9B]) Word64 instance (Real b[a1u9z], Distribution (Poisson b[a1u9z]) Word32) => CDF (Poisson b[a1u9z]) Word32 instance (RealFloat b[a1u9x], Distribution StdUniform b[a1u9x], Distribution (Erlang Word32) b[a1u9x], Distribution (Binomial b[a1u9x]) Word32) => Distribution (Poisson b[a1u9x]) Word32 instance (Real b[a1u9v], Distribution (Poisson b[a1u9v]) Word16) => CDF (Poisson b[a1u9v]) Word16 instance (RealFloat b[a1u9t], Distribution StdUniform b[a1u9t], Distribution (Erlang Word16) b[a1u9t], Distribution (Binomial b[a1u9t]) Word16) => Distribution (Poisson b[a1u9t]) Word16 instance (Real b[a1u9r], Distribution (Poisson b[a1u9r]) Word8) => CDF (Poisson b[a1u9r]) Word8 instance (RealFloat b[a1u9p], Distribution StdUniform b[a1u9p], Distribution (Erlang Word8) b[a1u9p], Distribution (Binomial b[a1u9p]) Word8) => Distribution (Poisson b[a1u9p]) Word8 instance (Real b[a1u9n], Distribution (Poisson b[a1u9n]) Word) => CDF (Poisson b[a1u9n]) Word instance (RealFloat b[a1u9l], Distribution StdUniform b[a1u9l], Distribution (Erlang Word) b[a1u9l], Distribution (Binomial b[a1u9l]) Word) => Distribution (Poisson b[a1u9l]) Word instance (Real b[a1u9j], Distribution (Poisson b[a1u9j]) Int64) => CDF (Poisson b[a1u9j]) Int64 instance (RealFloat b[a1u9h], Distribution StdUniform b[a1u9h], Distribution (Erlang Int64) b[a1u9h], Distribution (Binomial b[a1u9h]) Int64) => Distribution (Poisson b[a1u9h]) Int64 instance (Real b[a1u9f], Distribution (Poisson b[a1u9f]) Int32) => CDF (Poisson b[a1u9f]) Int32 instance (RealFloat b[a1u9d], Distribution StdUniform b[a1u9d], Distribution (Erlang Int32) b[a1u9d], Distribution (Binomial b[a1u9d]) Int32) => Distribution (Poisson b[a1u9d]) Int32 instance (Real b[a1u9b], Distribution (Poisson b[a1u9b]) Int16) => CDF (Poisson b[a1u9b]) Int16 instance (RealFloat b[a1u99], Distribution StdUniform b[a1u99], Distribution (Erlang Int16) b[a1u99], Distribution (Binomial b[a1u99]) Int16) => Distribution (Poisson b[a1u99]) Int16 instance (Real b[a1u97], Distribution (Poisson b[a1u97]) Int8) => CDF (Poisson b[a1u97]) Int8 instance (RealFloat b[a1u95], Distribution StdUniform b[a1u95], Distribution (Erlang Int8) b[a1u95], Distribution (Binomial b[a1u95]) Int8) => Distribution (Poisson b[a1u95]) Int8 instance (Real b[a1u93], Distribution (Poisson b[a1u93]) Int) => CDF (Poisson b[a1u93]) Int instance (RealFloat b[a1u91], Distribution StdUniform b[a1u91], Distribution (Erlang Int) b[a1u91], Distribution (Binomial b[a1u91]) Int) => Distribution (Poisson b[a1u91]) Int instance (Real b[a1u8Z], Distribution (Poisson b[a1u8Z]) Integer) => CDF (Poisson b[a1u8Z]) Integer instance (RealFloat b[a1u8X], Distribution StdUniform b[a1u8X], Distribution (Erlang Integer) b[a1u8X], Distribution (Binomial b[a1u8X]) Integer) => Distribution (Poisson b[a1u8X]) Integer module Data.Random.Distribution.Rayleigh floatingRayleigh :: (Floating a, Distribution StdUniform a) => a -> RVarT m a -- | The rayleigh distribution with a specified mode ("sigma") parameter. -- Its mean will be sigma*sqrt(pi2)@ and its variance will be -- @sigma^2*(4-pi)2 -- -- (therefore if you want one with a particular mean m, -- sigma should be m*sqrt(2/pi)) newtype Rayleigh a Rayleigh :: a -> Rayleigh a rayleigh :: Distribution Rayleigh a => a -> RVar a rayleighT :: Distribution Rayleigh a => a -> RVarT m a rayleighCDF :: Real a => a -> a -> Double instance (Real a, Distribution Rayleigh a) => CDF Rayleigh a instance (RealFloat a, Distribution StdUniform a) => Distribution Rayleigh a module Data.Random.Distribution.Triangular -- | A description of a triangular distribution - a distribution whose PDF -- is a triangle ramping up from a lower bound to a specified midpoint -- and back down to the upper bound. This is a very simple distribution -- that does not generally occur naturally but is used sometimes as an -- estimate of a true distribution when only the range of the values and -- an approximate mode of the true distribution are known. data Triangular a Triangular :: a -> a -> a -> Triangular a -- | The lower bound of the triangle in the PDF (the smallest number the -- distribution can generate) triLower :: Triangular a -> a -- | The midpoint of the triangle (also the mode of the distribution) triMid :: Triangular a -> a -- | The upper bound of the triangle (and the largest number the -- distribution can generate) triUpper :: Triangular a -> a -- | Compute a triangular distribution for a Floating type. floatingTriangular :: (Floating a, Ord a, Distribution StdUniform a) => a -> a -> a -> RVarT m a -- | triangularCDF a b c is the CDF of realFloatTriangular a b -- c. triangularCDF :: RealFrac a => a -> a -> a -> a -> Double instance Eq a => Eq (Triangular a) instance Show a => Show (Triangular a) instance (RealFrac a, Distribution Triangular a) => CDF Triangular a instance (RealFloat a, Ord a, Distribution StdUniform a) => Distribution Triangular a