Cumulate
Cumulate(X, I)
Returns an array with each element being the sum of all of the elements of «X» along dimension «I» up to, and including, the corresponding element of «X».
- Cumulate(X: Array[I]; I: Index, passNull: optional Boolean, reset: optional Array)
Library
Array Functions
Examples
I := [1, 2, 3, 4, 5, 6]
X := Array(I, [8, 2, 0, 5, -3, 7])
Cumulate(X, I) → Array( I, [8, 10, 10, 15, 12, 19])
Flattened ragged array example
One use for Cumulate arises when using a flattened representation of highly non-rectangular (i.e., ragged) 2-D data. The first dimension is J
, but the number of items along the second dimensions varies with J
. So the flattened representation concatenates all the array elements into to 1-D array indexed by K
, and then performs its computations using the 1-D array. You start with a vector on J
that tells you how many elements there are for each J
, e.g.,
Index J := [1,2,3,4,5]
Variable sizes := Array( J, [12, 2356, 3, 19342, 234 ] )
Index K := 1..Sum(sizes, J)
To use this flattened representation, you need to know where along K
the elements for a given J
start and where they end. Cumulate gives you the last position along K
directly:
Variable LastPos := Cumulate( sizes, J ) → Array(J, [ 12, 2368, 2371, 21713, 21947 ] )
The starting position along K
is obtained as
Variable FirstPos := Cumulate( sizes[@J=@J-1,defval:1], J ) → Array(J, [ 1, 13, 2369, 2372, 21714 ] )
Optional Parameters
PassNull
«PassNull» is an optional boolean parameter that defaults to False
. When it is omitted or explicitly set to False
, Cumulate ignores Null values. In that case they have essentially the same effect as a zero, unless they happen to be the first value in «X», in which case they are passed since no numeric values are yet obtained.
When «passNull» is set to True
, then Null values are passed through as Null in the result.
For example:
X := [«null», «null», 4, 1, «null», «null», 1, 9, 3, 2, «null»]
Cumulate(X, I) →
Cumulate(X, I, passNull: false) →
[«null», «null», 4, 5, 5, 5, 6, 15, 18, 20, 20]
Cumulate(X, I, passNull: true) →
[«null», «null», 4, 5, «null», «null», 6, 15, 18, 20, «null»]
Reset
The optional «reset» parameter accepts an array of boolean values indexed by «I». At the positions where «reset» is true, Cumulate starts over: It sets the sum of previous values to zero, so that the result at that position is the same as the value in «X».
For example:
I := [1, 2, 3, 4, 5, 6, 7]
X := [8, 2, 0, 5, -3, 7, 5]
R := [0, 0, 1, 0, 0, 1, 0]
Cumulate(X, I, reset: R) →
[8, 10, 0, 5, 2, 7, 12]
Suppose State
contains a number or text value designating the state of a system over I
. You can calculate how long the system has been in each state using Cumulate with «Reset» set to True
whenever the state changes compare to its previous value:
Cumulate(1, I, Reset: State[@I = @I - 1] <> State)
Details
Recumulate
In Analytica 4.2 and earlier, the functionality of the «reset» parameter can be obtained using the Recumulate library function, which resets the total to zero at selected points. This usage is:
Recumulate(x, b, I)
where b
is an array of booleans indexed by I
, having 1 at each point where the cumulation is to be reset to zero. Recumulate is implemented as a User-Defined Function in the example Recumulate example.ana. A clever usage of this function computes the number of time steps that the system has been in the same state (see the example).
Use in Dynamic Functions
If objects 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)
For more information on dynamic functions, see Dynamic.
Enable comment auto-refresher