-- |
-- Module     : Simulation.Aivika.Trans.Processor.Random
-- Copyright  : Copyright (c) 2009-2017, David Sorokin <david.sorokin@gmail.com>
-- License    : BSD3
-- Maintainer : David Sorokin <david.sorokin@gmail.com>
-- Stability  : experimental
-- Tested with: GHC 8.0.1
--
-- This module defines some useful random processors that
-- hold the current process for the corresponding time interval,
-- when processing every input element.
--

module Simulation.Aivika.Trans.Processor.Random
       (randomUniformProcessor,
        randomUniformIntProcessor,
        randomTriangularProcessor,
        randomNormalProcessor,
        randomLogNormalProcessor,
        randomExponentialProcessor,
        randomErlangProcessor,
        randomPoissonProcessor,
        randomBinomialProcessor,
        randomGammaProcessor,
        randomBetaProcessor,
        randomWeibullProcessor,
        randomDiscreteProcessor) where

import Simulation.Aivika.Trans.DES
import Simulation.Aivika.Trans.Generator
import Simulation.Aivika.Trans.Process
import Simulation.Aivika.Trans.Process.Random
import Simulation.Aivika.Trans.Processor

-- | When processing every input element, hold the process
-- for a random time interval distributed uniformly.
randomUniformProcessor :: MonadDES m
                          => Double
                          -- ^ the minimum time interval
                          -> Double
                          -- ^ the maximum time interval
                          -> Processor m a a
{-# INLINABLE randomUniformProcessor #-}
randomUniformProcessor :: Double -> Double -> Processor m a a
randomUniformProcessor Double
min Double
max =
  Process m () -> Processor m a a
forall (m :: * -> *) a.
MonadDES m =>
Process m () -> Processor m a a
withinProcessor (Process m () -> Processor m a a)
-> Process m () -> Processor m a a
forall a b. (a -> b) -> a -> b
$
  Double -> Double -> Process m ()
forall (m :: * -> *).
MonadDES m =>
Double -> Double -> Process m ()
randomUniformProcess_ Double
min Double
max

-- | When processing every input element, hold the process
-- for a random time interval distributed uniformly.
randomUniformIntProcessor :: MonadDES m
                             => Int
                             -- ^ the minimum time interval
                             -> Int
                             -- ^ the maximum time interval
                             -> Processor m a a
{-# INLINABLE randomUniformIntProcessor #-}
randomUniformIntProcessor :: Int -> Int -> Processor m a a
randomUniformIntProcessor Int
min Int
max =
  Process m () -> Processor m a a
forall (m :: * -> *) a.
MonadDES m =>
Process m () -> Processor m a a
withinProcessor (Process m () -> Processor m a a)
-> Process m () -> Processor m a a
forall a b. (a -> b) -> a -> b
$
  Int -> Int -> Process m ()
forall (m :: * -> *). MonadDES m => Int -> Int -> Process m ()
randomUniformIntProcess_ Int
min Int
max

-- | When processing every input element, hold the process
-- for a random time interval having the triangular distribution.
randomTriangularProcessor :: MonadDES m
                             => Double
                             -- ^ the minimum time interval
                             -> Double
                             -- ^ the median of the time interval
                             -> Double
                             -- ^ the maximum time interval
                             -> Processor m a a
{-# INLINABLE randomTriangularProcessor #-}
randomTriangularProcessor :: Double -> Double -> Double -> Processor m a a
randomTriangularProcessor Double
min Double
median Double
max =
  Process m () -> Processor m a a
forall (m :: * -> *) a.
MonadDES m =>
Process m () -> Processor m a a
withinProcessor (Process m () -> Processor m a a)
-> Process m () -> Processor m a a
forall a b. (a -> b) -> a -> b
$
  Double -> Double -> Double -> Process m ()
forall (m :: * -> *).
MonadDES m =>
Double -> Double -> Double -> Process m ()
randomTriangularProcess_ Double
min Double
median Double
max

-- | When processing every input element, hold the process
-- for a random time interval distributed normally.
randomNormalProcessor :: MonadDES m
                         => Double
                         -- ^ the mean time interval
                         -> Double
                         -- ^ the time interval deviation
                         -> Processor m a a
{-# INLINABLE randomNormalProcessor #-}
randomNormalProcessor :: Double -> Double -> Processor m a a
randomNormalProcessor Double
mu Double
nu =
  Process m () -> Processor m a a
forall (m :: * -> *) a.
MonadDES m =>
Process m () -> Processor m a a
withinProcessor (Process m () -> Processor m a a)
-> Process m () -> Processor m a a
forall a b. (a -> b) -> a -> b
$
  Double -> Double -> Process m ()
forall (m :: * -> *).
MonadDES m =>
Double -> Double -> Process m ()
randomNormalProcess_ Double
mu Double
nu
         
-- | When processing every input element, hold the process
-- for a random time interval having the lognormal distribution.
randomLogNormalProcessor :: MonadDES m
                            => Double
                            -- ^ the mean for a normal distribution
                            -- which this distribution is derived from
                            -> Double
                            -- ^ the deviation for a normal distribution
                            -- which this distribution is derived from
                            -> Processor m a a
{-# INLINABLE randomLogNormalProcessor #-}
randomLogNormalProcessor :: Double -> Double -> Processor m a a
randomLogNormalProcessor Double
mu Double
nu =
  Process m () -> Processor m a a
forall (m :: * -> *) a.
MonadDES m =>
Process m () -> Processor m a a
withinProcessor (Process m () -> Processor m a a)
-> Process m () -> Processor m a a
forall a b. (a -> b) -> a -> b
$
  Double -> Double -> Process m ()
forall (m :: * -> *).
MonadDES m =>
Double -> Double -> Process m ()
randomLogNormalProcess_ Double
mu Double
nu
         
-- | When processing every input element, hold the process
-- for a random time interval distributed exponentially
-- with the specified mean (the reciprocal of the rate).
randomExponentialProcessor :: MonadDES m
                              => Double
                              -- ^ the mean time interval (the reciprocal of the rate)
                              -> Processor m a a
{-# INLINABLE randomExponentialProcessor #-}
randomExponentialProcessor :: Double -> Processor m a a
randomExponentialProcessor Double
mu =
  Process m () -> Processor m a a
forall (m :: * -> *) a.
MonadDES m =>
Process m () -> Processor m a a
withinProcessor (Process m () -> Processor m a a)
-> Process m () -> Processor m a a
forall a b. (a -> b) -> a -> b
$
  Double -> Process m ()
forall (m :: * -> *). MonadDES m => Double -> Process m ()
randomExponentialProcess_ Double
mu
         
-- | When processing every input element, hold the process
-- for a random time interval having the Erlang distribution with
-- the specified scale (the reciprocal of the rate) and shape parameters.
randomErlangProcessor :: MonadDES m
                         => Double
                         -- ^ the scale (the reciprocal of the rate)
                         -> Int
                         -- ^ the shape
                         -> Processor m a a
{-# INLINABLE randomErlangProcessor #-}
randomErlangProcessor :: Double -> Int -> Processor m a a
randomErlangProcessor Double
beta Int
m =
  Process m () -> Processor m a a
forall (m :: * -> *) a.
MonadDES m =>
Process m () -> Processor m a a
withinProcessor (Process m () -> Processor m a a)
-> Process m () -> Processor m a a
forall a b. (a -> b) -> a -> b
$
  Double -> Int -> Process m ()
forall (m :: * -> *). MonadDES m => Double -> Int -> Process m ()
randomErlangProcess_ Double
beta Int
m

-- | When processing every input element, hold the process
-- for a random time interval having the Poisson distribution
-- with the specified mean.
randomPoissonProcessor :: MonadDES m
                          => Double
                          -- ^ the mean time interval
                          -> Processor m a a
{-# INLINABLE randomPoissonProcessor #-}
randomPoissonProcessor :: Double -> Processor m a a
randomPoissonProcessor Double
mu =
  Process m () -> Processor m a a
forall (m :: * -> *) a.
MonadDES m =>
Process m () -> Processor m a a
withinProcessor (Process m () -> Processor m a a)
-> Process m () -> Processor m a a
forall a b. (a -> b) -> a -> b
$
  Double -> Process m ()
forall (m :: * -> *). MonadDES m => Double -> Process m ()
randomPoissonProcess_ Double
mu

-- | When processing every input element, hold the process
-- for a random time interval having the binomial distribution
-- with the specified probability and trials.
randomBinomialProcessor :: MonadDES m
                           => Double
                           -- ^ the probability
                           -> Int
                           -- ^ the number of trials
                           -> Processor m a a
{-# INLINABLE randomBinomialProcessor #-}
randomBinomialProcessor :: Double -> Int -> Processor m a a
randomBinomialProcessor Double
prob Int
trials =
  Process m () -> Processor m a a
forall (m :: * -> *) a.
MonadDES m =>
Process m () -> Processor m a a
withinProcessor (Process m () -> Processor m a a)
-> Process m () -> Processor m a a
forall a b. (a -> b) -> a -> b
$
  Double -> Int -> Process m ()
forall (m :: * -> *). MonadDES m => Double -> Int -> Process m ()
randomBinomialProcess_ Double
prob Int
trials

-- | When processing every input element, hold the process
-- for a random time interval having the Gamma distribution
-- with the specified shape and scale.
randomGammaProcessor :: MonadDES m
                        => Double
                        -- ^ the shape
                        -> Double
                        -- ^ the scale (a reciprocal of the rate)
                        -> Processor m a a
{-# INLINABLE randomGammaProcessor #-}
randomGammaProcessor :: Double -> Double -> Processor m a a
randomGammaProcessor Double
kappa Double
theta =
  Process m () -> Processor m a a
forall (m :: * -> *) a.
MonadDES m =>
Process m () -> Processor m a a
withinProcessor (Process m () -> Processor m a a)
-> Process m () -> Processor m a a
forall a b. (a -> b) -> a -> b
$
  Double -> Double -> Process m ()
forall (m :: * -> *).
MonadDES m =>
Double -> Double -> Process m ()
randomGammaProcess_ Double
kappa Double
theta

-- | When processing every input element, hold the process
-- for a random time interval having the Beta distribution
-- with the specified shape parameters (alpha and beta).
randomBetaProcessor :: MonadDES m
                       => Double
                       -- ^ shape (alpha)
                       -> Double
                       -- ^ shape (beta)
                       -> Processor m a a
{-# INLINABLE randomBetaProcessor #-}
randomBetaProcessor :: Double -> Double -> Processor m a a
randomBetaProcessor Double
alpha Double
beta =
  Process m () -> Processor m a a
forall (m :: * -> *) a.
MonadDES m =>
Process m () -> Processor m a a
withinProcessor (Process m () -> Processor m a a)
-> Process m () -> Processor m a a
forall a b. (a -> b) -> a -> b
$
  Double -> Double -> Process m ()
forall (m :: * -> *).
MonadDES m =>
Double -> Double -> Process m ()
randomBetaProcess_ Double
alpha Double
beta

-- | When processing every input element, hold the process
-- for a random time interval having the Weibull distribution
-- with the specified shape and scale.
randomWeibullProcessor :: MonadDES m
                          => Double
                          -- ^ shape
                          -> Double
                          -- ^ scale
                          -> Processor m a a
{-# INLINABLE randomWeibullProcessor #-}
randomWeibullProcessor :: Double -> Double -> Processor m a a
randomWeibullProcessor Double
alpha Double
beta =
  Process m () -> Processor m a a
forall (m :: * -> *) a.
MonadDES m =>
Process m () -> Processor m a a
withinProcessor (Process m () -> Processor m a a)
-> Process m () -> Processor m a a
forall a b. (a -> b) -> a -> b
$
  Double -> Double -> Process m ()
forall (m :: * -> *).
MonadDES m =>
Double -> Double -> Process m ()
randomWeibullProcess_ Double
alpha Double
beta

-- | When processing every input element, hold the process
-- for a random time interval having the specified discrete distribution.
randomDiscreteProcessor :: MonadDES m
                           => DiscretePDF Double
                           -- ^ the discrete probability density function
                           -> Processor m a a
{-# INLINABLE randomDiscreteProcessor #-}
randomDiscreteProcessor :: DiscretePDF Double -> Processor m a a
randomDiscreteProcessor DiscretePDF Double
dpdf =
  Process m () -> Processor m a a
forall (m :: * -> *) a.
MonadDES m =>
Process m () -> Processor m a a
withinProcessor (Process m () -> Processor m a a)
-> Process m () -> Processor m a a
forall a b. (a -> b) -> a -> b
$
  DiscretePDF Double -> Process m ()
forall (m :: * -> *).
MonadDES m =>
DiscretePDF Double -> Process m ()
randomDiscreteProcess_ DiscretePDF Double
dpdf