module Simulation.Aivika.Trans.Stream.Random
(
randomStream,
randomUniformStream,
randomUniformIntStream,
randomNormalStream,
randomExponentialStream,
randomErlangStream,
randomPoissonStream,
randomBinomialStream) where
import System.Random
import Control.Monad
import Control.Monad.Trans
import Simulation.Aivika.Trans.Comp
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 :: MonadComp m
=> Parameter m (Double, a)
-> Stream m (Arrival a)
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
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 :: MonadComp m
=> Double
-> Double
-> Stream m (Arrival Double)
randomUniformStream min max =
randomStream $
randomUniform min max >>= \x ->
return (x, x)
randomUniformIntStream :: MonadComp m
=> Int
-> Int
-> Stream m (Arrival Int)
randomUniformIntStream min max =
randomStream $
randomUniformInt min max >>= \x ->
return (fromIntegral x, x)
randomNormalStream :: MonadComp m
=> Double
-> Double
-> Stream m (Arrival Double)
randomNormalStream mu nu =
randomStream $
randomNormal mu nu >>= \x ->
return (x, x)
randomExponentialStream :: MonadComp m
=> Double
-> Stream m (Arrival Double)
randomExponentialStream mu =
randomStream $
randomExponential mu >>= \x ->
return (x, x)
randomErlangStream :: MonadComp m
=> Double
-> Int
-> Stream m (Arrival Double)
randomErlangStream beta m =
randomStream $
randomErlang beta m >>= \x ->
return (x, x)
randomPoissonStream :: MonadComp m
=> Double
-> Stream m (Arrival Int)
randomPoissonStream mu =
randomStream $
randomPoisson mu >>= \x ->
return (fromIntegral x, x)
randomBinomialStream :: MonadComp m
=> Double
-> Int
-> Stream m (Arrival Int)
randomBinomialStream prob trials =
randomStream $
randomBinomial prob trials >>= \x ->
return (fromIntegral x, x)