19.4 累积

在执行计算时,只要能够根据索引对数组元素进行分类,累积函数就能派上用场。

 
A = accumarray (subs, vals)
A = accumarray (subs, vals, sz)
A = accumarray (subs, vals, sz, fcn)
A = accumarray (subs, vals, sz, fcn, fillval)
A = accumarray (subs, vals, sz, fcn, fillval, issparse)

通过将向量元素累加到由其下标定义的位置来创建数组。

下标由矩阵 subs 的行定义,值由 vals 定义。subs 的每一行对应 vals 中的一个值。如果 vals 是标量,它将用于 subs 的每一行。如果 subs 是向量的元胞数组,则所有向量的长度必须相同,并且第 k 个向量中的下标必须对应于结果的第 k 个维度。

矩阵的大小将由下标本身决定。但是,如果定义了 sz,它将决定矩阵的大小。sz 的长度必须与 subs 的列数相对应。一个例外情况是:如果 subs 只有一列,则 sz 可以是向量的维度,而 subs 的下标将作为该向量的索引。

accumarray 的默认操作是对具有相同下标的元素求和。可以通过定义 fcn 函数来修改此行为。该函数应是一个接受列向量并返回标量的函数或函数句柄。函数的结果不应依赖于下标的顺序。

返回数组中没有下标与之关联的元素被设置为零。将 fillval 定义为其他值可以设置这些元素的值。然而,对于某些特定的 fcn 值,此行为会发生变化。如果 fcn@min(或 @max),则当 vals 为整数类型时,结果将填充最小(或最大)整数;当 vals 为逻辑类型时,结果将填充逻辑 false(或逻辑 true);当 fillval 为零且所有值均为非正(或非负)时,填充零;否则填充 NaN。

默认情况下,accumarray 返回一个满矩阵。如果 issparse 为逻辑真,则返回稀疏矩阵。

以下 accumarray 示例构建了一个频率表,该表的第一列统计第二列中每个数字出现的次数,数据来自向量 x。注意使用 uniquex 中所有重复元素分配相同的索引(另请参阅 unique)。

x = [91, 92, 90, 92, 90, 89, 91, 89, 90, 100, 100, 100];
[u, ~, j] = unique (x);
[accumarray(j', 1), u']
  ⇒   2    89
      3    90
      2    91
      2    92
      3   100

另一个示例,结果是多维三维数组,且输出中出现了默认值(零):

accumarray ([1, 1, 1;
             2, 1, 2;
             2, 3, 2;
             2, 1, 2;
             2, 3, 2], 101:105)
⇒   ans(:,:,1) = [101, 0, 0; 0, 0, 0]
⇒   ans(:,:,2) = [0, 0, 0; 206, 0, 208]

稀疏选项可用作 sparse 构造函数的替代方案(另请参阅 sparse)。因此

sparse (i, j, sv)

accumarray 可以写成

accumarray ([i, j], sv', [], [], 0, true)

对于重复索引,sparse 会累加对应的值。若要取最小值而非累加,可将 min 用作累加器函数:

accumarray ([i, j], sv', [], @min, 0, true)

对于非稀疏情况,accumarray 的复杂度通常为 O(M+N),其中 N 是下标的数量,M 是最大下标(在多维情况下线性化)。如果 fcn@sum(默认)、@max@min@(x) {x} 之一,则会使用优化的代码路径。请注意,对于通用归约函数,解释器开销可能占很大比重,执行多次 accumarray 调用并以向量化方式计算结果可能更高效。

另请参阅: accumdimuniquesparse

 
A = accumdim (subs, vals)
A = accumdim (subs, vals, dim)
A = accumdim (subs, vals, dim, n)
A = accumdim (subs, vals, dim, n, fcn)
A = accumdim (subs, vals, dim, n, fcn, fillval)

通过将数组的切片累积到沿指定维度由下标定义的位置来创建数组。

下标由索引向量 subs 定义。维度由 dim 指定。如果未给出,则默认为第一个非单一维度。subs 的长度必须等于 size (vals, dim)

结果矩阵在操作维度上的范围将由下标本身决定。但是,如果定义了 n,则由 n 决定该范围。

accumdim 的默认操作是对具有相同下标的子数组求和。可以通过定义 fcn 函数来修改此行为。该函数应是一个接受数组和一个维度,并沿该维度对数组进行归约的函数或函数句柄。作为一个特殊例外,可以直接使用内置的 minmax 函数,accumdim 会处理它们调用中使用的中间空参数。

返回数组中没有下标与之关联的切片被设置为零。将 fillval 定义为其他值可以设置这些元素的值。

accumdim 的使用示例如下:

accumdim ([1, 2, 1, 2, 1], [ 7, -10,   4;
                            -5, -12,   8;
                           -12,   2,   8;
                           -10,   9,  -3;
                            -5,  -3, -13])
⇒   [-10,-11,-1;-15,-3,5]

另请参阅: accumarray


版权所有 © 2024-2026 Octave中文网

ICP备案/许可证号:黑ICP备2024030411号-4