probability-0.2.9.1: src/Numeric/Probability/Random.hs
-- | Randomized values
module Numeric.Probability.Random where
import qualified Numeric.Probability.Distribution as Dist
import qualified Numeric.Probability.Transition as Trans
import qualified System.Random as Random
import System.Random (Random, )
import Control.Applicative (Applicative(..))
import Control.Monad.Trans.State (State, state, evalState, runState, )
import qualified System.IO as IO
import Prelude hiding (print)
-- * random generator
-- | Random values
newtype T a = Cons {decons :: State Random.StdGen a}
instance Monad T where
Cons x >>= y =
Cons (decons . y =<< x)
instance Functor T where
fmap f = Cons . fmap f . decons
instance Applicative T where
pure x = Cons (pure x)
fm <*> m = Cons (decons fm <*> decons m)
randomR :: Random.Random a => (a, a) -> T a
randomR rng =
Cons (state (Random.randomR rng))
{- |
Run random action in 'IO' monad.
-}
run :: T a -> IO a
run = Random.getStdRandom . runState . decons
{- |
Run random action without 'IO' using a seed.
-}
runSeed :: Random.StdGen -> T a -> a
runSeed g r = evalState (decons r) g
print :: Show a => T a -> IO ()
print r = IO.print =<< run r
-- instance Show (IO a) where
-- show _ = ""
pick :: (Num prob, Ord prob, Random prob) =>
Dist.T prob a -> T a
pick d = return . Dist.selectP d =<< randomR (0,1)
-- * random distribution
-- | Randomized distribution
type Distribution prob a = T (Dist.T prob a)
above, below :: (Num prob, Ord prob, Ord a) =>
prob -> Distribution prob a -> Distribution prob (Dist.Select a)
above p = fmap (Dist.above p)
below p = fmap (Dist.below p)
{- |
'dist' converts a list of randomly generated values into
a distribution by taking equal weights for all values.
Thus @dist (replicate n rnd)@ simulates @rnd@ @n@ times
and returns an estimation of the distribution represented by @rnd@.
-}
dist :: (Fractional prob, Ord a) => [T a] -> Distribution prob a
dist = fmap (Dist.norm . Dist.uniform) . sequence
-- * Randomized changes
-- | random change
type Change a = a -> T a
change :: (Num prob, Ord prob, Random prob) =>
Trans.T prob a -> Change a
change t = pick . t
-- * Randomized transitions
-- | random transition
type Transition prob a = a -> Distribution prob a
type ApproxDist a = T [a]
{-
for quickCheck
LAWS
const . pick = random . const
-}