accumulate (:A)

Syntax

accumulate(func, X, [init], [consistent=false])

or

[init] <operator>:A X (where conssitent is false)

or

[init] <operator>:AC X (where conssitent is false)

or

func:A([init], X, [consistent=false])

Arguments

func is a function for iteration.

X is data or iteration rule.

init is the initial value to be passed to func.

consistent is a Boolean value specifying how the data types and forms of the iteration results are determined. The default value is false, meaning the data types and forms are determined by the result of each iteration. Otherwise, they are the same as the first output. Note that if the data forms of iteration results are different, consistent must be set to false.

Details

The accumulate template applies func to init and X for accumulating iteration (i.e. the result of an iteration is passed forward to the next). Unlike the template reduce that returns only the last result, the template accumulate outputs result of each iteration.

(1) When func is a unary function, X can be a non-negative integer, a unary function or NULL. In all these cases, init must be specified.

The function first returns init as the initial value, then applies func iteratively until a certain condition specified in X is satisfied.

  • If X is an integer, func iterates X times, outputting (X+1) elements. Note that when X is negative, it is treated as 0.

  • If X is a unary function, it must return a Boolean value to determine the termination of iteration. The iteration continues until X returns false for the current output.

  • If X is unspecified or NULL, the iteration continues until the next output is the same as the current one.

(2) When func is a binary function, X can be a vector, matrix or table.

The function first applies func to init and X[0], and then iterates over the current output and the next element in X. If init is unspecified, the first output is X[0].

accumulate is equivalent to the execution of the pseudo code below:

ret[0]=<function>(init,X[0]);

for(i:1~size(X)){

    result[i]=<function>(result[i-1], X[i]);

}

return result;

(3) When func is a ternary function, X must be a tuple with 2 elements. The iteration rule is the same as that of a binary function.

Examples

func is a unary function:

//define a unary function
$ def func1(x){
$ if(x<5){
$         return x*3
$ }
$ else{
$         return x+3
$ }
$ }
//when X is an integer, the size of the result is X + 1
$ accumulate(func1, 5, 1)
 [1,3,9,12,15,18]
//X is a unary function "condition". As condition returns false during the 3rd iteration, the system stops iteration and outputs the results of the first two iterations.
$ def condition(x){
$ return x<9
$ }
$ accumulate(func1, condition, 1)
[1,3,9]

//when X is NULL or unspecified, define a UDF func2 for iteration.
$ def func2(x){
$ if(x<5){
$         return x*3
$ }
$ else{
$         return 6
$ }
$ }
//As the results of the 3rd and 4th iterations are the same, the function stops iteration and outputs the results of the first three iterations.
$ accumulate(func2,NULL,1)
[1,3,9,6]

accumulate on a vector:

$ x = 1 2 3;
$ accumulate(add, 1 2 3);
[1,3,6]
// equivalent to [1, 1+2, 3+3]

$ 1 +:A x;
[2,4,7]
// equivalent to [1+1, 2+2, 4+3]

$ accumulate(-, 2, x);
[1,-1,-4]
// equivalent to [2-1, 1-2, -1-3]

$ accumulate(mul, x);
[1,2,6]
// equivalent to [1, 1*2, 2*3]

$ def facts(a) {return 1*:A 1..a;};
$ facts 5;
[1,2,6,24,120]
// calculate cumulative factorization

$ def f1(a,b): a+log(b);
$ accumulate(f1, 1..5, 0);
[0,0.693147,1.791759,3.178054,4.787492]
// the example above calculates cumulative sum of log(1) to log(i)
// note the result from the previous step will be given to the first parameter of the function.
// 0+log(1)=0, 0+log(2)=0.693147, 0.693147+log(3)=1.791759, ......

$ accumulate(f1, 1..5);
[1,2,3,4,6]
// since the initial condition is ignored here, the data type of the first element of the input vector determines the date type of the result.

accumulate on a matrix:

$ x=1..12$3:4;
$ x;

col1

col2

col3

col4

1

4

7

10

2

5

8

11

3

6

9

12

$ + :A x;

col1

col2

col3

col4

1

5

12

22

2

7

15

26

3

9

18

30

When func is a ternary function:

$ def fun3(x,y,z){
$   return x+y+z
$ }
$ accumulate(fun3,[[1,2,3],[10,10,10]],5)
[16,28,41]