aivika-transformers-2.1: Transformers for the Aivika simulation library

Simulation.Aivika.Trans.SystemDynamics

Description

Tested with: GHC 7.8.3

This module defines integrals and other functions of System Dynamics.

Synopsis

# Equality and Ordering

(.==.) :: (MonadComp m, Eq a) => Dynamics m a -> Dynamics m a -> Dynamics m Bool Source

Compare for equality.

(./=.) :: (MonadComp m, Eq a) => Dynamics m a -> Dynamics m a -> Dynamics m Bool Source

Compare for inequality.

(.<.) :: (MonadComp m, Ord a) => Dynamics m a -> Dynamics m a -> Dynamics m Bool Source

Compare for ordering.

(.>=.) :: (MonadComp m, Ord a) => Dynamics m a -> Dynamics m a -> Dynamics m Bool Source

Compare for ordering.

(.>.) :: (MonadComp m, Ord a) => Dynamics m a -> Dynamics m a -> Dynamics m Bool Source

Compare for ordering.

(.<=.) :: (MonadComp m, Ord a) => Dynamics m a -> Dynamics m a -> Dynamics m Bool Source

Compare for ordering.

maxDynamics :: (MonadComp m, Ord a) => Dynamics m a -> Dynamics m a -> Dynamics m a Source

Return the maximum.

minDynamics :: (MonadComp m, Ord a) => Dynamics m a -> Dynamics m a -> Dynamics m a Source

Return the minimum.

ifDynamics :: MonadComp m => Dynamics m Bool -> Dynamics m a -> Dynamics m a -> Dynamics m a Source

Implement the if-then-else operator.

# Ordinary Differential Equations

Arguments

 :: (MonadComp m, MonadFix m) => Dynamics m Double the derivative -> Dynamics m Double the initial value -> Simulation m (Dynamics m Double) the integral

Return an integral with the specified derivative and initial value.

To create a loopback, you should use the recursive do-notation. It allows defining the differential equations unordered as in mathematics:

```model =
mdo a <- integ (- ka * a) 100
b <- integ (ka * a - kb * b) 0
c <- integ (kb * b) 0
let ka = 1
kb = 1
runDynamicsInStopTime \$ sequence [a, b, c]
```

Arguments

 :: (MonadComp m, MonadFix m) => Dynamics m (Either Double Double) either set a new `Left` integral value, or use a `Right` derivative -> Dynamics m Double the initial value -> Simulation m (Dynamics m Double)

Like `integ` but allows either setting a new `Left` integral value, or integrating using the `Right` derivative directly within computation.

This function always uses Euler's method.

Arguments

 :: (MonadComp m, MonadFix m) => Dynamics m Double the value to smooth over time -> Dynamics m Double time -> Dynamics m Double the initial value -> Simulation m (Dynamics m Double) the first order exponential smooth

Return the first order exponential smooth.

To create a loopback, you should use the recursive do-notation with help of which the function itself is defined:

```smoothI x t i =
mdo y <- integ ((x - y) / t) i
return y
```

Arguments

 :: (MonadComp m, MonadFix m) => Dynamics m Double the value to smooth over time -> Dynamics m Double time -> Simulation m (Dynamics m Double) the first order exponential smooth

Return the first order exponential smooth.

This is a simplified version of the `smoothI` function without specifing the initial value.

Arguments

 :: (MonadComp m, MonadFix m) => Dynamics m Double the value to smooth over time -> Dynamics m Double time -> Dynamics m Double the initial value -> Simulation m (Dynamics m Double) the third order exponential smooth

Return the third order exponential smooth.

To create a loopback, you should use the recursive do-notation with help of which the function itself is defined:

```smooth3I x t i =
mdo y  <- integ ((s2 - y) / t') i
s2 <- integ ((s1 - s2) / t') i
s1 <- integ ((x - s1) / t') i
let t' = t / 3.0
return y
```

Arguments

 :: (MonadComp m, MonadFix m) => Dynamics m Double the value to smooth over time -> Dynamics m Double time -> Simulation m (Dynamics m Double) the third order exponential smooth

Return the third order exponential smooth.

This is a simplified version of the `smooth3I` function without specifying the initial value.

Arguments

 :: (MonadComp m, MonadFix m) => Dynamics m Double the value to smooth over time -> Dynamics m Double time -> Int the order -> Dynamics m Double the initial value -> Simulation m (Dynamics m Double) the n'th order exponential smooth

Return the n'th order exponential smooth.

The result is not discrete in that sense that it may change within the integration time interval depending on the integration method used. Probably, you should apply the `discreteDynamics` function to the result if you want to achieve an effect when the value is not changed within the time interval, which is used sometimes.

Arguments

 :: (MonadComp m, MonadFix m) => Dynamics m Double the value to smooth over time -> Dynamics m Double time -> Int the order -> Simulation m (Dynamics m Double) the n'th order exponential smooth

Return the n'th order exponential smooth.

This is a simplified version of the `smoothNI` function without specifying the initial value.

Arguments

 :: (MonadComp m, MonadFix m) => Dynamics m Double the value to conserve -> Dynamics m Double time -> Dynamics m Double the initial value -> Simulation m (Dynamics m Double) the first order exponential delay

Return the first order exponential delay.

To create a loopback, you should use the recursive do-notation with help of which the function itself is defined:

```delay1I x t i =
mdo y <- integ (x - y / t) (i * t)
return \$ y / t
```

Arguments

 :: (MonadComp m, MonadFix m) => Dynamics m Double the value to conserve -> Dynamics m Double time -> Simulation m (Dynamics m Double) the first order exponential delay

Return the first order exponential delay.

This is a simplified version of the `delay1I` function without specifying the initial value.

Arguments

 :: (MonadComp m, MonadFix m) => Dynamics m Double the value to conserve -> Dynamics m Double time -> Dynamics m Double the initial value -> Simulation m (Dynamics m Double) the third order exponential delay

Return the third order exponential delay.

Arguments

 :: (MonadComp m, MonadFix m) => Dynamics m Double the value to conserve -> Dynamics m Double time -> Simulation m (Dynamics m Double) the third order exponential delay

Return the third order exponential delay.

This is a simplified version of the `delay3I` function without specifying the initial value.

Arguments

 :: (MonadComp m, MonadFix m) => Dynamics m Double the value to conserve -> Dynamics m Double time -> Int the order -> Dynamics m Double the initial value -> Simulation m (Dynamics m Double) the n'th order exponential delay

Return the n'th order exponential delay.

Arguments

 :: (MonadComp m, MonadFix m) => Dynamics m Double the value to conserve -> Dynamics m Double time -> Int the order -> Simulation m (Dynamics m Double) the n'th order exponential delay

Return the n'th order exponential delay.

This is a simplified version of the `delayNI` function without specifying the initial value.

Arguments

 :: (MonadComp m, MonadFix m) => Dynamics m Double the value to forecast -> Dynamics m Double the average time -> Dynamics m Double the time horizon -> Simulation m (Dynamics m Double) the forecast

Return the forecast.

The function has the following definition:

```forecast x at hz =
do y <- smooth x at
return \$ x * (1.0 + (x / y - 1.0) / at * hz)
```

Arguments

 :: (MonadComp m, MonadFix m) => Dynamics m Double the value for which the trend is calculated -> Dynamics m Double the average time -> Dynamics m Double the initial value -> Simulation m (Dynamics m Double) the fractional change rate

Return the trend.

The function has the following definition:

```trend x at i =
do y <- smoothI x at (x / (1.0 + i * at))
return \$ (x / y - 1.0) / at
```

# Difference Equations

Arguments

 :: (MonadComp m, MonadFix m, Unboxed m a, Num a) => Dynamics m a the difference -> Dynamics m a the initial value -> Simulation m (Dynamics m a) the sum

Retun the sum for the difference equation. It is like an integral returned by the `integ` function, only now the difference is used instead of derivative.

As usual, to create a loopback, you should use the recursive do-notation.

Arguments

 :: (MonadComp m, MonadFix m, Unboxed m a, Num a) => Dynamics m (Either a a) either set the `Left` value for the sum, or add the `Right` difference to the sum -> Dynamics m a the initial value -> Simulation m (Dynamics m a) the sum

Like `diffsum` but allows either setting a new `Left` sum value, or adding the `Right` difference.

# Table Functions

Lookup `x` in a table of pairs `(x, y)` using linear interpolation.

Lookup `x` in a table of pairs `(x, y)` using stepwise function.

# Discrete Functions

Arguments

 :: MonadComp m => Dynamics m a the value to delay -> Dynamics m Double the lag time -> Dynamics m a the delayed value

Return the delayed value using the specified lag time.

Arguments

 :: MonadComp m => Dynamics m a the value to delay -> Dynamics m Double the lag time -> Dynamics m a the initial value -> Simulation m (Dynamics m a) the delayed value

Return the delayed value using the specified lag time and initial value. Because of the latter, it allows creating a loop back.

Arguments

 :: MonadComp m => Dynamics m Double the height -> Dynamics m Double the step time -> Dynamics m Double

Computation that returns 0 until the step time and then returns the specified height.

Arguments

 :: MonadComp m => Dynamics m Double the time start -> Dynamics m Double the interval width -> Dynamics m Double

Computation that returns 1, starting at the time start, and lasting for the interval width; 0 is returned at all other times.

Arguments

 :: MonadComp m => Dynamics m Double the time start -> Dynamics m Double the interval width -> Dynamics m Double the time period -> Dynamics m Double

Computation that returns 1, starting at the time start, and lasting for the interval width and then repeats this pattern with the specified period; 0 is returned at all other times.

Arguments

 :: MonadComp m => Dynamics m Double the slope parameter -> Dynamics m Double the time start -> Dynamics m Double the end time -> Dynamics m Double

Computation that returns 0 until the specified time start and then slopes upward until the end time and then holds constant.

# Financial Functions

Arguments

 :: (MonadComp m, MonadFix m) => Dynamics m Double the stream -> Dynamics m Double the discount rate -> Dynamics m Double the initial value -> Dynamics m Double factor -> Simulation m (Dynamics m Double) the Net Present Value (NPV)

Return the Net Present Value (NPV) of the stream computed using the specified discount rate, the initial value and some factor (usually 1).

It is defined in the following way:

```npv stream rate init factor =
mdo let dt' = liftParameter dt
df <- integ (- df * rate) 1
accum <- integ (stream * df) init
return \$ (accum + dt' * stream * df) * factor
```

Arguments

 :: (MonadComp m, MonadFix m) => Dynamics m Double the stream -> Dynamics m Double the discount rate -> Dynamics m Double the initial value -> Dynamics m Double factor -> Simulation m (Dynamics m Double) the Net Present Value End (NPVE)

Return the Net Present Value End of period (NPVE) of the stream computed using the specified discount rate, the initial value and some factor.

It is defined in the following way:

```npve stream rate init factor =
mdo let dt' = liftParameter dt
df <- integ (- df * rate / (1 + rate * dt')) (1 / (1 + rate * dt'))
accum <- integ (stream * df) init
return \$ (accum + dt' * stream * df) * factor
```