module Simulation.Aivika.Trans.Stream.Random
(
randomStream,
randomUniformStream,
randomUniformIntStream,
randomTriangularStream,
randomNormalStream,
randomLogNormalStream,
randomExponentialStream,
randomErlangStream,
randomPoissonStream,
randomBinomialStream,
randomGammaStream,
randomBetaStream,
randomWeibullStream,
randomDiscreteStream) where
import Control.Monad
import Control.Monad.Trans
import Simulation.Aivika.Trans.DES
import Simulation.Aivika.Trans.Generator
import Simulation.Aivika.Trans.Parameter
import Simulation.Aivika.Trans.Parameter.Random
import Simulation.Aivika.Trans.Simulation
import Simulation.Aivika.Trans.Dynamics
import Simulation.Aivika.Trans.Event
import Simulation.Aivika.Trans.Process
import Simulation.Aivika.Trans.Processor
import Simulation.Aivika.Trans.Stream
import Simulation.Aivika.Trans.Statistics
import Simulation.Aivika.Trans.Ref
import Simulation.Aivika.Trans.Arrival
randomStream :: MonadDES m
=> Parameter m (Double, a)
-> Stream m (Arrival a)
{-# INLINE randomStream #-}
randomStream delay = Cons $ loop Nothing where
loop t0 =
do t1 <- liftDynamics time
case t0 of
Nothing -> return ()
Just t0 ->
when (t1 /= t0) $
error $
"The time of requesting for a new random event is different from " ++
"the time when the previous event has arrived. Probably, your model " ++
"contains a logical error. The random events should be requested permanently. " ++
"At least, they can be lost, for example, when trying to enqueue them, but " ++
"the random stream itself must always execute: randomStream."
(delay, a) <- liftParameter delay
when (delay > 0) $
holdProcess delay
t2 <- liftDynamics time
let arrival = Arrival { arrivalValue = a,
arrivalTime = t2,
arrivalDelay =
case t0 of
Nothing -> Nothing
Just t0 -> Just delay }
return (arrival, Cons $ loop (Just t2))
randomUniformStream :: MonadDES m
=> Double
-> Double
-> Stream m (Arrival Double)
{-# INLINABLE randomUniformStream #-}
randomUniformStream min max =
randomStream $
randomUniform min max >>= \x ->
return (x, x)
randomUniformIntStream :: MonadDES m
=> Int
-> Int
-> Stream m (Arrival Int)
{-# INLINABLE randomUniformIntStream #-}
randomUniformIntStream min max =
randomStream $
randomUniformInt min max >>= \x ->
return (fromIntegral x, x)
randomTriangularStream :: MonadDES m
=> Double
-> Double
-> Double
-> Stream m (Arrival Double)
{-# INLINABLE randomTriangularStream #-}
randomTriangularStream min median max =
randomStream $
randomTriangular min median max >>= \x ->
return (x, x)
randomNormalStream :: MonadDES m
=> Double
-> Double
-> Stream m (Arrival Double)
{-# INLINABLE randomNormalStream #-}
randomNormalStream mu nu =
randomStream $
randomNormal mu nu >>= \x ->
return (x, x)
randomLogNormalStream :: MonadDES m
=> Double
-> Double
-> Stream m (Arrival Double)
{-# INLINABLE randomLogNormalStream #-}
randomLogNormalStream mu nu =
randomStream $
randomLogNormal mu nu >>= \x ->
return (x, x)
randomExponentialStream :: MonadDES m
=> Double
-> Stream m (Arrival Double)
{-# INLINABLE randomExponentialStream #-}
randomExponentialStream mu =
randomStream $
randomExponential mu >>= \x ->
return (x, x)
randomErlangStream :: MonadDES m
=> Double
-> Int
-> Stream m (Arrival Double)
{-# INLINABLE randomErlangStream #-}
randomErlangStream beta m =
randomStream $
randomErlang beta m >>= \x ->
return (x, x)
randomPoissonStream :: MonadDES m
=> Double
-> Stream m (Arrival Int)
{-# INLINABLE randomPoissonStream #-}
randomPoissonStream mu =
randomStream $
randomPoisson mu >>= \x ->
return (fromIntegral x, x)
randomBinomialStream :: MonadDES m
=> Double
-> Int
-> Stream m (Arrival Int)
{-# INLINABLE randomBinomialStream #-}
randomBinomialStream prob trials =
randomStream $
randomBinomial prob trials >>= \x ->
return (fromIntegral x, x)
randomGammaStream :: MonadDES m
=> Double
-> Double
-> Stream m (Arrival Double)
{-# INLINABLE randomGammaStream #-}
randomGammaStream kappa theta =
randomStream $
randomGamma kappa theta >>= \x ->
return (x, x)
randomBetaStream :: MonadDES m
=> Double
-> Double
-> Stream m (Arrival Double)
{-# INLINABLE randomBetaStream #-}
randomBetaStream alpha beta =
randomStream $
randomBeta alpha beta >>= \x ->
return (x, x)
randomWeibullStream :: MonadDES m
=> Double
-> Double
-> Stream m (Arrival Double)
{-# INLINABLE randomWeibullStream #-}
randomWeibullStream alpha beta =
randomStream $
randomWeibull alpha beta >>= \x ->
return (x, x)
randomDiscreteStream :: MonadDES m
=> DiscretePDF Double
-> Stream m (Arrival Double)
{-# INLINABLE randomDiscreteStream #-}
randomDiscreteStream dpdf =
randomStream $
randomDiscrete dpdf >>= \x ->
return (x, x)