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 :: Parameter m (Double, a) -> Stream m (Arrival a)
randomStream Parameter m (Double, a)
delay = Process m (Arrival a, Stream m (Arrival a)) -> Stream m (Arrival a)
forall (m :: * -> *) a. Process m (a, Stream m a) -> Stream m a
Cons (Process m (Arrival a, Stream m (Arrival a))
-> Stream m (Arrival a))
-> Process m (Arrival a, Stream m (Arrival a))
-> Stream m (Arrival a)
forall a b. (a -> b) -> a -> b
$ Maybe Double -> Process m (Arrival a, Stream m (Arrival a))
loop Maybe Double
forall a. Maybe a
Nothing where
loop :: Maybe Double -> Process m (Arrival a, Stream m (Arrival a))
loop Maybe Double
t0 =
do Double
t1 <- Dynamics m Double -> Process m Double
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
DynamicsLift t m =>
Dynamics m a -> t m a
liftDynamics Dynamics m Double
forall (m :: * -> *). Monad m => Dynamics m Double
time
case Maybe Double
t0 of
Maybe Double
Nothing -> () -> Process m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
Just Double
t0 ->
Bool -> Process m () -> Process m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Double
t1 Double -> Double -> Bool
forall a. Eq a => a -> a -> Bool
/= Double
t0) (Process m () -> Process m ()) -> Process m () -> Process m ()
forall a b. (a -> b) -> a -> b
$
[Char] -> Process m ()
forall a. HasCallStack => [Char] -> a
error ([Char] -> Process m ()) -> [Char] -> Process m ()
forall a b. (a -> b) -> a -> b
$
[Char]
"The time of requesting for a new random event is different from " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++
[Char]
"the time when the previous event has arrived. Probably, your model " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++
[Char]
"contains a logical error. The random events should be requested permanently. " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++
[Char]
"At least, they can be lost, for example, when trying to enqueue them, but " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++
[Char]
"the random stream itself must always execute: randomStream."
(Double
delay, a
a) <- Parameter m (Double, a) -> Process m (Double, a)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
ParameterLift t m =>
Parameter m a -> t m a
liftParameter Parameter m (Double, a)
delay
Bool -> Process m () -> Process m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Double
delay Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
> Double
0) (Process m () -> Process m ()) -> Process m () -> Process m ()
forall a b. (a -> b) -> a -> b
$
Double -> Process m ()
forall (m :: * -> *). MonadDES m => Double -> Process m ()
holdProcess Double
delay
Double
t2 <- Dynamics m Double -> Process m Double
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
DynamicsLift t m =>
Dynamics m a -> t m a
liftDynamics Dynamics m Double
forall (m :: * -> *). Monad m => Dynamics m Double
time
let arrival :: Arrival a
arrival = Arrival :: forall a. a -> Double -> Maybe Double -> Arrival a
Arrival { arrivalValue :: a
arrivalValue = a
a,
arrivalTime :: Double
arrivalTime = Double
t2,
arrivalDelay :: Maybe Double
arrivalDelay =
case Maybe Double
t0 of
Maybe Double
Nothing -> Maybe Double
forall a. Maybe a
Nothing
Just Double
t0 -> Double -> Maybe Double
forall a. a -> Maybe a
Just Double
delay }
(Arrival a, Stream m (Arrival a))
-> Process m (Arrival a, Stream m (Arrival a))
forall (m :: * -> *) a. Monad m => a -> m a
return (Arrival a
arrival, Process m (Arrival a, Stream m (Arrival a)) -> Stream m (Arrival a)
forall (m :: * -> *) a. Process m (a, Stream m a) -> Stream m a
Cons (Process m (Arrival a, Stream m (Arrival a))
-> Stream m (Arrival a))
-> Process m (Arrival a, Stream m (Arrival a))
-> Stream m (Arrival a)
forall a b. (a -> b) -> a -> b
$ Maybe Double -> Process m (Arrival a, Stream m (Arrival a))
loop (Double -> Maybe Double
forall a. a -> Maybe a
Just Double
t2))
randomUniformStream :: MonadDES m
=> Double
-> Double
-> Stream m (Arrival Double)
{-# INLINABLE randomUniformStream #-}
randomUniformStream :: Double -> Double -> Stream m (Arrival Double)
randomUniformStream Double
min Double
max =
Parameter m (Double, Double) -> Stream m (Arrival Double)
forall (m :: * -> *) a.
MonadDES m =>
Parameter m (Double, a) -> Stream m (Arrival a)
randomStream (Parameter m (Double, Double) -> Stream m (Arrival Double))
-> Parameter m (Double, Double) -> Stream m (Arrival Double)
forall a b. (a -> b) -> a -> b
$
Double -> Double -> Parameter m Double
forall (m :: * -> *).
MonadComp m =>
Double -> Double -> Parameter m Double
randomUniform Double
min Double
max Parameter m Double
-> (Double -> Parameter m (Double, Double))
-> Parameter m (Double, Double)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Double
x ->
(Double, Double) -> Parameter m (Double, Double)
forall (m :: * -> *) a. Monad m => a -> m a
return (Double
x, Double
x)
randomUniformIntStream :: MonadDES m
=> Int
-> Int
-> Stream m (Arrival Int)
{-# INLINABLE randomUniformIntStream #-}
randomUniformIntStream :: Int -> Int -> Stream m (Arrival Int)
randomUniformIntStream Int
min Int
max =
Parameter m (Double, Int) -> Stream m (Arrival Int)
forall (m :: * -> *) a.
MonadDES m =>
Parameter m (Double, a) -> Stream m (Arrival a)
randomStream (Parameter m (Double, Int) -> Stream m (Arrival Int))
-> Parameter m (Double, Int) -> Stream m (Arrival Int)
forall a b. (a -> b) -> a -> b
$
Int -> Int -> Parameter m Int
forall (m :: * -> *). MonadComp m => Int -> Int -> Parameter m Int
randomUniformInt Int
min Int
max Parameter m Int
-> (Int -> Parameter m (Double, Int)) -> Parameter m (Double, Int)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Int
x ->
(Double, Int) -> Parameter m (Double, Int)
forall (m :: * -> *) a. Monad m => a -> m a
return (Int -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
x, Int
x)
randomTriangularStream :: MonadDES m
=> Double
-> Double
-> Double
-> Stream m (Arrival Double)
{-# INLINABLE randomTriangularStream #-}
randomTriangularStream :: Double -> Double -> Double -> Stream m (Arrival Double)
randomTriangularStream Double
min Double
median Double
max =
Parameter m (Double, Double) -> Stream m (Arrival Double)
forall (m :: * -> *) a.
MonadDES m =>
Parameter m (Double, a) -> Stream m (Arrival a)
randomStream (Parameter m (Double, Double) -> Stream m (Arrival Double))
-> Parameter m (Double, Double) -> Stream m (Arrival Double)
forall a b. (a -> b) -> a -> b
$
Double -> Double -> Double -> Parameter m Double
forall (m :: * -> *).
MonadComp m =>
Double -> Double -> Double -> Parameter m Double
randomTriangular Double
min Double
median Double
max Parameter m Double
-> (Double -> Parameter m (Double, Double))
-> Parameter m (Double, Double)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Double
x ->
(Double, Double) -> Parameter m (Double, Double)
forall (m :: * -> *) a. Monad m => a -> m a
return (Double
x, Double
x)
randomNormalStream :: MonadDES m
=> Double
-> Double
-> Stream m (Arrival Double)
{-# INLINABLE randomNormalStream #-}
randomNormalStream :: Double -> Double -> Stream m (Arrival Double)
randomNormalStream Double
mu Double
nu =
Parameter m (Double, Double) -> Stream m (Arrival Double)
forall (m :: * -> *) a.
MonadDES m =>
Parameter m (Double, a) -> Stream m (Arrival a)
randomStream (Parameter m (Double, Double) -> Stream m (Arrival Double))
-> Parameter m (Double, Double) -> Stream m (Arrival Double)
forall a b. (a -> b) -> a -> b
$
Double -> Double -> Parameter m Double
forall (m :: * -> *).
MonadComp m =>
Double -> Double -> Parameter m Double
randomNormal Double
mu Double
nu Parameter m Double
-> (Double -> Parameter m (Double, Double))
-> Parameter m (Double, Double)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Double
x ->
(Double, Double) -> Parameter m (Double, Double)
forall (m :: * -> *) a. Monad m => a -> m a
return (Double
x, Double
x)
randomLogNormalStream :: MonadDES m
=> Double
-> Double
-> Stream m (Arrival Double)
{-# INLINABLE randomLogNormalStream #-}
randomLogNormalStream :: Double -> Double -> Stream m (Arrival Double)
randomLogNormalStream Double
mu Double
nu =
Parameter m (Double, Double) -> Stream m (Arrival Double)
forall (m :: * -> *) a.
MonadDES m =>
Parameter m (Double, a) -> Stream m (Arrival a)
randomStream (Parameter m (Double, Double) -> Stream m (Arrival Double))
-> Parameter m (Double, Double) -> Stream m (Arrival Double)
forall a b. (a -> b) -> a -> b
$
Double -> Double -> Parameter m Double
forall (m :: * -> *).
MonadComp m =>
Double -> Double -> Parameter m Double
randomLogNormal Double
mu Double
nu Parameter m Double
-> (Double -> Parameter m (Double, Double))
-> Parameter m (Double, Double)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Double
x ->
(Double, Double) -> Parameter m (Double, Double)
forall (m :: * -> *) a. Monad m => a -> m a
return (Double
x, Double
x)
randomExponentialStream :: MonadDES m
=> Double
-> Stream m (Arrival Double)
{-# INLINABLE randomExponentialStream #-}
randomExponentialStream :: Double -> Stream m (Arrival Double)
randomExponentialStream Double
mu =
Parameter m (Double, Double) -> Stream m (Arrival Double)
forall (m :: * -> *) a.
MonadDES m =>
Parameter m (Double, a) -> Stream m (Arrival a)
randomStream (Parameter m (Double, Double) -> Stream m (Arrival Double))
-> Parameter m (Double, Double) -> Stream m (Arrival Double)
forall a b. (a -> b) -> a -> b
$
Double -> Parameter m Double
forall (m :: * -> *). MonadComp m => Double -> Parameter m Double
randomExponential Double
mu Parameter m Double
-> (Double -> Parameter m (Double, Double))
-> Parameter m (Double, Double)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Double
x ->
(Double, Double) -> Parameter m (Double, Double)
forall (m :: * -> *) a. Monad m => a -> m a
return (Double
x, Double
x)
randomErlangStream :: MonadDES m
=> Double
-> Int
-> Stream m (Arrival Double)
{-# INLINABLE randomErlangStream #-}
randomErlangStream :: Double -> Int -> Stream m (Arrival Double)
randomErlangStream Double
beta Int
m =
Parameter m (Double, Double) -> Stream m (Arrival Double)
forall (m :: * -> *) a.
MonadDES m =>
Parameter m (Double, a) -> Stream m (Arrival a)
randomStream (Parameter m (Double, Double) -> Stream m (Arrival Double))
-> Parameter m (Double, Double) -> Stream m (Arrival Double)
forall a b. (a -> b) -> a -> b
$
Double -> Int -> Parameter m Double
forall (m :: * -> *).
MonadComp m =>
Double -> Int -> Parameter m Double
randomErlang Double
beta Int
m Parameter m Double
-> (Double -> Parameter m (Double, Double))
-> Parameter m (Double, Double)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Double
x ->
(Double, Double) -> Parameter m (Double, Double)
forall (m :: * -> *) a. Monad m => a -> m a
return (Double
x, Double
x)
randomPoissonStream :: MonadDES m
=> Double
-> Stream m (Arrival Int)
{-# INLINABLE randomPoissonStream #-}
randomPoissonStream :: Double -> Stream m (Arrival Int)
randomPoissonStream Double
mu =
Parameter m (Double, Int) -> Stream m (Arrival Int)
forall (m :: * -> *) a.
MonadDES m =>
Parameter m (Double, a) -> Stream m (Arrival a)
randomStream (Parameter m (Double, Int) -> Stream m (Arrival Int))
-> Parameter m (Double, Int) -> Stream m (Arrival Int)
forall a b. (a -> b) -> a -> b
$
Double -> Parameter m Int
forall (m :: * -> *). MonadComp m => Double -> Parameter m Int
randomPoisson Double
mu Parameter m Int
-> (Int -> Parameter m (Double, Int)) -> Parameter m (Double, Int)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Int
x ->
(Double, Int) -> Parameter m (Double, Int)
forall (m :: * -> *) a. Monad m => a -> m a
return (Int -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
x, Int
x)
randomBinomialStream :: MonadDES m
=> Double
-> Int
-> Stream m (Arrival Int)
{-# INLINABLE randomBinomialStream #-}
randomBinomialStream :: Double -> Int -> Stream m (Arrival Int)
randomBinomialStream Double
prob Int
trials =
Parameter m (Double, Int) -> Stream m (Arrival Int)
forall (m :: * -> *) a.
MonadDES m =>
Parameter m (Double, a) -> Stream m (Arrival a)
randomStream (Parameter m (Double, Int) -> Stream m (Arrival Int))
-> Parameter m (Double, Int) -> Stream m (Arrival Int)
forall a b. (a -> b) -> a -> b
$
Double -> Int -> Parameter m Int
forall (m :: * -> *).
MonadComp m =>
Double -> Int -> Parameter m Int
randomBinomial Double
prob Int
trials Parameter m Int
-> (Int -> Parameter m (Double, Int)) -> Parameter m (Double, Int)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Int
x ->
(Double, Int) -> Parameter m (Double, Int)
forall (m :: * -> *) a. Monad m => a -> m a
return (Int -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
x, Int
x)
randomGammaStream :: MonadDES m
=> Double
-> Double
-> Stream m (Arrival Double)
{-# INLINABLE randomGammaStream #-}
randomGammaStream :: Double -> Double -> Stream m (Arrival Double)
randomGammaStream Double
kappa Double
theta =
Parameter m (Double, Double) -> Stream m (Arrival Double)
forall (m :: * -> *) a.
MonadDES m =>
Parameter m (Double, a) -> Stream m (Arrival a)
randomStream (Parameter m (Double, Double) -> Stream m (Arrival Double))
-> Parameter m (Double, Double) -> Stream m (Arrival Double)
forall a b. (a -> b) -> a -> b
$
Double -> Double -> Parameter m Double
forall (m :: * -> *).
MonadComp m =>
Double -> Double -> Parameter m Double
randomGamma Double
kappa Double
theta Parameter m Double
-> (Double -> Parameter m (Double, Double))
-> Parameter m (Double, Double)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Double
x ->
(Double, Double) -> Parameter m (Double, Double)
forall (m :: * -> *) a. Monad m => a -> m a
return (Double
x, Double
x)
randomBetaStream :: MonadDES m
=> Double
-> Double
-> Stream m (Arrival Double)
{-# INLINABLE randomBetaStream #-}
randomBetaStream :: Double -> Double -> Stream m (Arrival Double)
randomBetaStream Double
alpha Double
beta =
Parameter m (Double, Double) -> Stream m (Arrival Double)
forall (m :: * -> *) a.
MonadDES m =>
Parameter m (Double, a) -> Stream m (Arrival a)
randomStream (Parameter m (Double, Double) -> Stream m (Arrival Double))
-> Parameter m (Double, Double) -> Stream m (Arrival Double)
forall a b. (a -> b) -> a -> b
$
Double -> Double -> Parameter m Double
forall (m :: * -> *).
MonadComp m =>
Double -> Double -> Parameter m Double
randomBeta Double
alpha Double
beta Parameter m Double
-> (Double -> Parameter m (Double, Double))
-> Parameter m (Double, Double)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Double
x ->
(Double, Double) -> Parameter m (Double, Double)
forall (m :: * -> *) a. Monad m => a -> m a
return (Double
x, Double
x)
randomWeibullStream :: MonadDES m
=> Double
-> Double
-> Stream m (Arrival Double)
{-# INLINABLE randomWeibullStream #-}
randomWeibullStream :: Double -> Double -> Stream m (Arrival Double)
randomWeibullStream Double
alpha Double
beta =
Parameter m (Double, Double) -> Stream m (Arrival Double)
forall (m :: * -> *) a.
MonadDES m =>
Parameter m (Double, a) -> Stream m (Arrival a)
randomStream (Parameter m (Double, Double) -> Stream m (Arrival Double))
-> Parameter m (Double, Double) -> Stream m (Arrival Double)
forall a b. (a -> b) -> a -> b
$
Double -> Double -> Parameter m Double
forall (m :: * -> *).
MonadComp m =>
Double -> Double -> Parameter m Double
randomWeibull Double
alpha Double
beta Parameter m Double
-> (Double -> Parameter m (Double, Double))
-> Parameter m (Double, Double)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Double
x ->
(Double, Double) -> Parameter m (Double, Double)
forall (m :: * -> *) a. Monad m => a -> m a
return (Double
x, Double
x)
randomDiscreteStream :: MonadDES m
=> DiscretePDF Double
-> Stream m (Arrival Double)
{-# INLINABLE randomDiscreteStream #-}
randomDiscreteStream :: DiscretePDF Double -> Stream m (Arrival Double)
randomDiscreteStream DiscretePDF Double
dpdf =
Parameter m (Double, Double) -> Stream m (Arrival Double)
forall (m :: * -> *) a.
MonadDES m =>
Parameter m (Double, a) -> Stream m (Arrival a)
randomStream (Parameter m (Double, Double) -> Stream m (Arrival Double))
-> Parameter m (Double, Double) -> Stream m (Arrival Double)
forall a b. (a -> b) -> a -> b
$
DiscretePDF Double -> Parameter m Double
forall (m :: * -> *) a.
MonadComp m =>
DiscretePDF a -> Parameter m a
randomDiscrete DiscretePDF Double
dpdf Parameter m Double
-> (Double -> Parameter m (Double, Double))
-> Parameter m (Double, Double)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Double
x ->
(Double, Double) -> Parameter m (Double, Double)
forall (m :: * -> *) a. Monad m => a -> m a
return (Double
x, Double
x)