-- 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.3 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 a -> m a -- | 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 a -> m a 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 a -> m a -- | 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 a -> m a 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[a1d6d]) Integer) => CDF (Binomial b[a1d6d]) Double instance (Distribution (Binomial b[a1d6a]) Integer) => Distribution (Binomial b[a1d6a]) Double instance (CDF (Binomial b[a1d67]) Integer) => CDF (Binomial b[a1d67]) Float instance (Distribution (Binomial b[a1d64]) Integer) => Distribution (Binomial b[a1d64]) Float instance (Real b[a1cLt], Distribution (Binomial b[a1cLt]) Word64) => CDF (Binomial b[a1cLt]) Word64 instance (Floating b[a1cLq], Ord b[a1cLq], Distribution Beta b[a1cLq], Distribution StdUniform b[a1cLq]) => Distribution (Binomial b[a1cLq]) Word64 instance (Real b[a1cLn], Distribution (Binomial b[a1cLn]) Word32) => CDF (Binomial b[a1cLn]) Word32 instance (Floating b[a1cLk], Ord b[a1cLk], Distribution Beta b[a1cLk], Distribution StdUniform b[a1cLk]) => Distribution (Binomial b[a1cLk]) Word32 instance (Real b[a1cLh], Distribution (Binomial b[a1cLh]) Word16) => CDF (Binomial b[a1cLh]) Word16 instance (Floating b[a1cLe], Ord b[a1cLe], Distribution Beta b[a1cLe], Distribution StdUniform b[a1cLe]) => Distribution (Binomial b[a1cLe]) Word16 instance (Real b[a1cLb], Distribution (Binomial b[a1cLb]) Word8) => CDF (Binomial b[a1cLb]) Word8 instance (Floating b[a1cL8], Ord b[a1cL8], Distribution Beta b[a1cL8], Distribution StdUniform b[a1cL8]) => Distribution (Binomial b[a1cL8]) Word8 instance (Real b[a1cL5], Distribution (Binomial b[a1cL5]) Word) => CDF (Binomial b[a1cL5]) Word instance (Floating b[a1cL2], Ord b[a1cL2], Distribution Beta b[a1cL2], Distribution StdUniform b[a1cL2]) => Distribution (Binomial b[a1cL2]) Word instance (Real b[a1cKZ], Distribution (Binomial b[a1cKZ]) Int64) => CDF (Binomial b[a1cKZ]) Int64 instance (Floating b[a1cKW], Ord b[a1cKW], Distribution Beta b[a1cKW], Distribution StdUniform b[a1cKW]) => Distribution (Binomial b[a1cKW]) Int64 instance (Real b[a1cKT], Distribution (Binomial b[a1cKT]) Int32) => CDF (Binomial b[a1cKT]) Int32 instance (Floating b[a1cKQ], Ord b[a1cKQ], Distribution Beta b[a1cKQ], Distribution StdUniform b[a1cKQ]) => Distribution (Binomial b[a1cKQ]) Int32 instance (Real b[a1cKN], Distribution (Binomial b[a1cKN]) Int16) => CDF (Binomial b[a1cKN]) Int16 instance (Floating b[a1cKK], Ord b[a1cKK], Distribution Beta b[a1cKK], Distribution StdUniform b[a1cKK]) => Distribution (Binomial b[a1cKK]) Int16 instance (Real b[a1cKH], Distribution (Binomial b[a1cKH]) Int8) => CDF (Binomial b[a1cKH]) Int8 instance (Floating b[a1cKE], Ord b[a1cKE], Distribution Beta b[a1cKE], Distribution StdUniform b[a1cKE]) => Distribution (Binomial b[a1cKE]) Int8 instance (Real b[a1cKB], Distribution (Binomial b[a1cKB]) Int) => CDF (Binomial b[a1cKB]) Int instance (Floating b[a1cKy], Ord b[a1cKy], Distribution Beta b[a1cKy], Distribution StdUniform b[a1cKy]) => Distribution (Binomial b[a1cKy]) Int instance (Real b[a1cKv], Distribution (Binomial b[a1cKv]) Integer) => CDF (Binomial b[a1cKv]) Integer instance (Floating b[a1cKs], Ord b[a1cKs], Distribution Beta b[a1cKs], Distribution StdUniform b[a1cKs]) => Distribution (Binomial b[a1cKs]) 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[a1j5N]) Integer) => CDF (Poisson b[a1j5N]) Double instance (Distribution (Poisson b[a1j5L]) Integer) => Distribution (Poisson b[a1j5L]) Double instance (CDF (Poisson b[a1j5J]) Integer) => CDF (Poisson b[a1j5J]) Float instance (Distribution (Poisson b[a1j5H]) Integer) => Distribution (Poisson b[a1j5H]) Float instance (Real b[a1iFa], Distribution (Poisson b[a1iFa]) Word64) => CDF (Poisson b[a1iFa]) Word64 instance (RealFloat b[a1iF8], Distribution StdUniform b[a1iF8], Distribution (Erlang Word64) b[a1iF8], Distribution (Binomial b[a1iF8]) Word64) => Distribution (Poisson b[a1iF8]) Word64 instance (Real b[a1iF6], Distribution (Poisson b[a1iF6]) Word32) => CDF (Poisson b[a1iF6]) Word32 instance (RealFloat b[a1iF4], Distribution StdUniform b[a1iF4], Distribution (Erlang Word32) b[a1iF4], Distribution (Binomial b[a1iF4]) Word32) => Distribution (Poisson b[a1iF4]) Word32 instance (Real b[a1iF2], Distribution (Poisson b[a1iF2]) Word16) => CDF (Poisson b[a1iF2]) Word16 instance (RealFloat b[a1iF0], Distribution StdUniform b[a1iF0], Distribution (Erlang Word16) b[a1iF0], Distribution (Binomial b[a1iF0]) Word16) => Distribution (Poisson b[a1iF0]) Word16 instance (Real b[a1iEY], Distribution (Poisson b[a1iEY]) Word8) => CDF (Poisson b[a1iEY]) Word8 instance (RealFloat b[a1iEW], Distribution StdUniform b[a1iEW], Distribution (Erlang Word8) b[a1iEW], Distribution (Binomial b[a1iEW]) Word8) => Distribution (Poisson b[a1iEW]) Word8 instance (Real b[a1iEU], Distribution (Poisson b[a1iEU]) Word) => CDF (Poisson b[a1iEU]) Word instance (RealFloat b[a1iES], Distribution StdUniform b[a1iES], Distribution (Erlang Word) b[a1iES], Distribution (Binomial b[a1iES]) Word) => Distribution (Poisson b[a1iES]) Word instance (Real b[a1iEQ], Distribution (Poisson b[a1iEQ]) Int64) => CDF (Poisson b[a1iEQ]) Int64 instance (RealFloat b[a1iEO], Distribution StdUniform b[a1iEO], Distribution (Erlang Int64) b[a1iEO], Distribution (Binomial b[a1iEO]) Int64) => Distribution (Poisson b[a1iEO]) Int64 instance (Real b[a1iEM], Distribution (Poisson b[a1iEM]) Int32) => CDF (Poisson b[a1iEM]) Int32 instance (RealFloat b[a1iEK], Distribution StdUniform b[a1iEK], Distribution (Erlang Int32) b[a1iEK], Distribution (Binomial b[a1iEK]) Int32) => Distribution (Poisson b[a1iEK]) Int32 instance (Real b[a1iEI], Distribution (Poisson b[a1iEI]) Int16) => CDF (Poisson b[a1iEI]) Int16 instance (RealFloat b[a1iEG], Distribution StdUniform b[a1iEG], Distribution (Erlang Int16) b[a1iEG], Distribution (Binomial b[a1iEG]) Int16) => Distribution (Poisson b[a1iEG]) Int16 instance (Real b[a1iEE], Distribution (Poisson b[a1iEE]) Int8) => CDF (Poisson b[a1iEE]) Int8 instance (RealFloat b[a1iEC], Distribution StdUniform b[a1iEC], Distribution (Erlang Int8) b[a1iEC], Distribution (Binomial b[a1iEC]) Int8) => Distribution (Poisson b[a1iEC]) Int8 instance (Real b[a1iEA], Distribution (Poisson b[a1iEA]) Int) => CDF (Poisson b[a1iEA]) Int instance (RealFloat b[a1iEy], Distribution StdUniform b[a1iEy], Distribution (Erlang Int) b[a1iEy], Distribution (Binomial b[a1iEy]) Int) => Distribution (Poisson b[a1iEy]) Int instance (Real b[a1iEw], Distribution (Poisson b[a1iEw]) Integer) => CDF (Poisson b[a1iEw]) Integer instance (RealFloat b[a1iEu], Distribution StdUniform b[a1iEu], Distribution (Erlang Integer) b[a1iEu], Distribution (Binomial b[a1iEu]) Integer) => Distribution (Poisson b[a1iEu]) 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