accumulate (:A)

语法

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

[init] <operator>:A X(表示 consistent 为 false)

New in version 1.30.21.

[init] <operator>:AC X (表示 consistent 为 true)

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

参数

func 函数。

  • func 是一元函数时,X 可以是非负整数、一元函数或空值。init 表示 func 的参数,必须指定。

  • func 是二元函数时,X 是向量、矩阵或表。init 表示初始值。

  • func 是三元函数时,X 必须是一个 Tuple,包含2个元素,分别表示 func 的后两个参数。

consistent 布尔值,默认 false,表示每次迭代输出的数据类型由实际计算结果决定。否则,每次迭代输出的数据类型将与第一次迭代输出值的数据类型保持一致。 注意,若迭代结果的数据形式不一致,只能指定 consistent = false,否则会报错。

其他相关的 cum 系列函数的参数说明和窗口计算规则请参考: 累计窗口系列(cum 系列)

详情

  • 当 func 是一元函数时,accumulate 先输出 init,再应用 funcinit 上,然后迭代地应用 func 到前一个结果上,直至满足 X 指定地迭代条件后输出结果。

    • X 为整数时,表示 func 进行迭代的次数,输出结果包含 X + 1 个元素。注意,X 为负数时,将按0处理。

    • X 为一元函数时,表示终止条件,返回结果必须为一个布尔标量。若 X 应用在前一个结果上的返回值为 true,func 继续迭代;否则,func 停止迭代。

    • X 没有设置或为 NULL,func 将进行迭代计算直至输出的结果与前一个结果相同时停止迭代。

  • func 是二元函数时,accumulate 先应用函数 / 运算符在 initX[0] 上,再迭代地应用函数 / 运算符在前一个结果和当前元素上。当 init 缺失时,accumulate 返回值的第一个元素是 X[0]。accumulate 等同于下面伪代码的执行过程:

    ret[0]=<function>(init,X[0]);
    
    for(i:1~size(X)){
    
        result[i]=<function>(result[i-1], X[i]);
    
    }
    
    return result;
    
  • func 是三元函数时,其迭代规则等同于二元函数。

reduce 返回最后一个结果不同,accumulate 输出所有中间结果。

例子

func 是一元函数时:

//定义一个一元函数
$ def func1(x){
$ if(x<5){
$         return x*3
$ }
$ else{
$         return x+3
$ }
$ }
//当 X 为整数时,输出结果长度为 X + 1
$ accumulate(func1, 5, 1)
[1,3,9,12,15,18]
//当 X 为一元函数 condition 时,第3次迭代时因 condition 返回false,停止迭代并输出前2次迭代结果。
$ def condition(x){
$ return x<9
$ }
$ accumulate(func1, condition, 1)
[1,3,9]

//当 X 为 NULL(或不指定)时,自定义函数 func2 作为迭代的函数。
$ def func2(x){
$ if(x<5){
$         return x*3
$ }
$ else{
$         return 6
$ }
$ }

//因第4次迭代结果和第3次相同,停止迭代并输出前3次迭代结果。
$ accumulate(func2,NULL,1)
[1,3,9,6]

func 是二元函数时,在一个向量上执行 accumulate:

$ x = 1 2 3;
$ accumulate(add, 1 2 3);
[1,3,6]
// 等同于 [1, 1+2, 3+3]

$ 1 +:A x;
[2,4,7]
// 等同于 [1+1, 2+2, 4+3]

$ accumulate(-, x, 2);
[1,-1,-4]
// 等同于 [2-1, 1-2, -1-3]

$ accumulate(mul, x);
[1,2,6]
// 等同于 [1, 1*2, 2*3]

$ def facts(a) {return 1*:A 1..a;};
$ facts 5;
[1,2,6,24,120]
// 计算累积因式分解。

$ def f1(a,b): a+log(b);
$ accumulate(f1, 1..5, 0);
[0,0.693147,1.791759,3.178054,4.787492]
// 上述例子计算了 log(1) 到 log(i) 之间的累加和,
// 注意到前一步的结果被当作函数的第一个参数。
// 0+log(1)=0, 0+log(2)=0.693147, 0.693147+log(3)=1.791759, ......

$ accumulate(f1, 1..5);
[1,2,3,4,6]
// 因为这里忽略了初始条件,输入向量的第一个元素的数据类型决定了返回值的数据类型

对一个矩阵执行 accumulate:

$ 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

func 是三元函数时:

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