# 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]
```