Stability experimental David Sorokin Safe-Inferred

Simulation.Aivika.SystemDynamics

Description

Tested with: GHC 7.6.3

This module defines integrals and other functions of System Dynamics.

Synopsis

# Equality and Ordering

(.==.) :: Eq a => Dynamics a -> Dynamics a -> Dynamics BoolSource

Compare for equality.

(./=.) :: Eq a => Dynamics a -> Dynamics a -> Dynamics BoolSource

Compare for inequality.

(.<.) :: Ord a => Dynamics a -> Dynamics a -> Dynamics BoolSource

Compare for ordering.

(.>=.) :: Ord a => Dynamics a -> Dynamics a -> Dynamics BoolSource

Compare for ordering.

(.>.) :: Ord a => Dynamics a -> Dynamics a -> Dynamics BoolSource

Compare for ordering.

(.<=.) :: Ord a => Dynamics a -> Dynamics a -> Dynamics BoolSource

Compare for ordering.

maxDynamics :: Ord a => Dynamics a -> Dynamics a -> Dynamics aSource

Return the maximum.

minDynamics :: Ord a => Dynamics a -> Dynamics a -> Dynamics aSource

Return the minimum.

ifDynamics :: Dynamics Bool -> Dynamics a -> Dynamics a -> Dynamics aSource

Implement the if-then-else operator.

# Ordinary Differential Equations

Arguments

 :: Dynamics Double the derivative -> Dynamics Double the initial value -> Simulation (Dynamics 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 :: Simulation [Double]
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

 :: Dynamics Double the value to smooth over time -> Dynamics Double time -> Dynamics Double the initial value -> Simulation (Dynamics 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

 :: Dynamics Double the value to smooth over time -> Dynamics Double time -> Simulation (Dynamics 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

 :: Dynamics Double the value to smooth over time -> Dynamics Double time -> Dynamics Double the initial value -> Simulation (Dynamics 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

 :: Dynamics Double the value to smooth over time -> Dynamics Double time -> Simulation (Dynamics 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

 :: Dynamics Double the value to smooth over time -> Dynamics Double time -> Int the order -> Dynamics Double the initial value -> Simulation (Dynamics 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

 :: Dynamics Double the value to smooth over time -> Dynamics Double time -> Int the order -> Simulation (Dynamics 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

 :: Dynamics Double the value to conserve -> Dynamics Double time -> Dynamics Double the initial value -> Simulation (Dynamics 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

 :: Dynamics Double the value to conserve -> Dynamics Double time -> Simulation (Dynamics 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

 :: Dynamics Double the value to conserve -> Dynamics Double time -> Dynamics Double the initial value -> Simulation (Dynamics Double) the third order exponential delay

Return the third order exponential delay.

Arguments

 :: Dynamics Double the value to conserve -> Dynamics Double time -> Simulation (Dynamics 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

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

Return the n'th order exponential delay.

Arguments

 :: Dynamics Double the value to conserve -> Dynamics Double time -> Int the order -> Simulation (Dynamics 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

 :: Dynamics Double the value to forecast -> Dynamics Double the average time -> Dynamics Double the time horizon -> Simulation (Dynamics 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

 :: Dynamics Double the value for which the trend is calculated -> Dynamics Double the average time -> Dynamics Double the initial value -> Simulation (Dynamics 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

 :: (Num a, Unboxed a) => Dynamics a the difference -> Dynamics a the initial value -> Simulation (Dynamics 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.

# 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

 :: Dynamics a the value to delay -> Dynamics Double the lag time -> Dynamics a the initial value -> Dynamics a the delayed value

Return the delayed value.

If you want to apply the result recursively in some loopback then you should use one of the memoization functions such as `memoDynamics` and `memo0Dynamics`.

# Financial Functions

Arguments

 :: Dynamics Double the stream -> Dynamics Double the discount rate -> Dynamics Double the initial value -> Dynamics Double factor -> Simulation (Dynamics 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 df <- integ (- df * rate) 1
accum <- integ (stream * df) init
return \$ (accum + dt * stream * df) * factor
```

Arguments

 :: Dynamics Double the stream -> Dynamics Double the discount rate -> Dynamics Double the initial value -> Dynamics Double factor -> Simulation (Dynamics 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 df <- integ (- df * rate / (1 + rate * dt)) (1 / (1 + rate * dt))
accum <- integ (stream * df) init
return \$ (accum + dt * stream * df) * factor
```