Dynamic
This page needs work. A better introductory reference for now is the Analytica User Guide chapter 17 on Dynamic Simulation.
Dynamic( initial1, initial2, ..., initialN, expr )
The dynamic function performs dynamic simulation, calculating its value at each element of Time. Time is a special system index that is built into Analytica, and is the only index that Dynamic can operate over in this fashion. The result of Dynamic is an array indexed by the system index Time.
When the Dynamic function is used, it must appear as the topmost function in the definition. It can contain one or more initial value parameters, containing the values at @Time=1, @Time=2, ... @Time=N, and then an expression that is used to compute all subsequent values. The expression can the values of variables at previous time points by using the syntax:
- ident[Time-k]
When the value for @Time=t is being computed, X[Time-1] refers to the value of X at the previous time period, i.e., at @Time=t-1. What is especially useful is that the value of X[Time-1] is allowed to depend (directly or indirectly) on the variable that is defined by the Dynamic function. This makes it possible to have cyclic loops within your model, where a variable depends on itself, as long as there is an offset to a previous time point somewhere within the dynamic loop.
The syntax X[Time-k] is equivalent to X[@Time=@Time-k] and Slice(X,Time,@Time-k). The offset k can be a constant, or it can be computed; however, it is not allowed to refer to a position before the beginning of Time -- e.g., in which @Time-k < 1, or to a future time point (in which k<0). A zero offset is allowed, however, at least one positive offset must occur before the loop returns to the original Dynamic variable.
You can also make use of Subscript operations to earlier time points with Dynamic, such as in
- X[Time=Ceil(Time/2)]
or equivalently, Subscript(X,Time,Time/2). You should beware of the difference between identifying a time point by position and identifying a time point by label (associationally). If the elements of your Time index are in increments other than 1, then X[Time-1] and X[@Time=@Time-1] refer to the previous time point, while X[Time=Time-1] may refer to a time point that doesn't even exist, or to a point other than the immediately previous time point.
When the identifier of a variable X is used in the definition for Y, and both X and Y belong to the same dynamic loop, then the identifier X in Y's definition implicitly refers to the value of X at the current time period. Although the final value of X may be indexed by time, the value as seen during the evaluation of Y does not have that dimension. Because of this, you can can refer to the current time point being evaluated by simply using the identifier Time, and you can refer to the position along the time index as @Time. Any identifier (except those appearing in a slice or subscript operation) used in an expression is equivalent to X[Time-0] or Slice(X,Time,@Time).
If X and Y belong to the same dynamic loop, then the definition of Y should never perform an operation over the Time index on the value of X. When you write such an expression, you presumably intend to operate over the entire Time-indexed array for X, which would thus implicitly refer to future points in time that have not yet been computed, and would therefore be disallowed. However, in reality, the use of X in Y's definition refers to the value of X at the current time point, so that an expression such as Cumulate(X,Time) would actually be cumulating a constant value over time. While that is not disallowed, it is probably not what is intended, and Analytica will issue a warning in this case. You can usually expression operations over Time directly using Dynamic, for example, instead of Cumulate(X,Time) you would define CumX as
Dynamic(X,Self[Time-1] + X)
As this example shows, the keyword Self can be used to refer to the current variable that is defined by Dynamic.
User-Defined Functions inside Dynamic Loops
new to Analytica 4.2
In the rare event that a User-Defined Function is part of a dynamic loop, then how the value for variable named in the definition is obtained depends on a number of factors. These rules are designed to allow a UDF to implement array operations across the dynamic index, while co-existing within a recurrence. The ability to embed a UDF within a dynamic loop is new to Analytica 4.2.
When a global variable identifier is evaluated from within a User-Defined Functions, the current dynamic context is dropped if the variable does not belong to the same dynamic loop as the UDF. In contrast, the dynamic context passed through to the evaluation of the variable if the variable belongs to the same dynamic loop as the UDF. The following example illustrates.
Time=1..10 Variable V := 100 * 1.06^(@Time-1) Variable X := Dynamic(1,F(V)) Variable Y := Dynamic(0,X[Time-1]) Function F(z) := Sum(Z+V+Y,Time)
Here V is not part of any dynamic loop, and X→Y→F()→X forms a dynamic loop.
Consider the evaluation of V in X's definition when Time=2. Since a variable always preserved dynamic context, V[Time=2] is obtained (= 106). So F(106) is called. Inside F, when Z+V+Y is evaluated, these are obtained as Z=106, V (indexed by Time) and Y[Time=2] =1. The full time-indexed value for V is used since it does not belong to the dynamic loop. So at Time=2, F computes (106+V,Time).
(in progress)
Enable comment auto-refresher