我将重新表述问题所要求的内容,以使正在阅读的人受益。
OP 希望通过将矩阵拆分成一堆列来将矩阵分割成块。 cumsum 分别应用于每一行的每一列,然后连接在一起以构建最终矩阵。因此,给定这个源矩阵:
x =
1 2 3 4 5 6 7 8 9 10 11 12
13 14 15 16 17 18 19 20 21 22 23 24
假设我们希望按第 3、6、9 和 12 列分割矩阵,我们将有四个块可供使用。我们分别对每个块执行cumsum 并将最终结果拼凑在一起。所以结果如下:
xx =
1 3 6 4 9 15 7 15 24 10 21 33
13 27 42 16 33 51 19 39 60 22 45 69
首先,您需要确定要将矩阵分解为多少列。在您的情况下,我们希望将矩阵分割成 4 个块:第 1 - 3 列、第 4 - 6 列、第 7 - 9 列和第 10 - 12 列。因此,我将转到 reshape 这个矩阵,以便每一列都是这个矩阵中一个块的一个单独的行。然后我们将cumsum 应用到这个重构的矩阵上,然后我们将它重构回原来的样子。
因此,这样做:
num_chunks = 4; %// Columns 3, 6, 9, 12
divide_point = size(x,2) / num_chunks; %// Determine how many elements are in a row for a cumsum
x_reshape = reshape(x.', divide_point, []); %// Get reshaped matrix
xy = cumsum(x_reshape); %// cumsum over all columns individually
xx = reshape(xy, size(x,2), size(x,1)).'; %// Reconstruct matrix
在第三行代码中,x_reshape = reshape(x.', divide_point, []); 可能看起来有点吓人,但实际上并没有那么糟糕。我必须先转置矩阵,因为您想要获取块的每一行并将它们放入单独的列中,以便我们可以在每一列上执行 cumsum。当您在 MATLAB 中重塑某些东西时,它会收集 column-wise 值并将输入重塑为指定大小的输出。因此,为了收集行,我们需要收集row-wise,所以我们必须转置这个矩阵。接下来,divide_point 告诉您我们在一个块中的单行有多少个元素。因此,我们要构造一个大小为divide_point x N 的矩阵,其中divide_point 告诉您我们在一个块的一行中有多少个元素,N 是所有块的总行数。因为我不想计算有多少(实际上我相当懒惰......),[] 语法是自动推断这个数字,以便我们可以得到一个尊重元素总数的重构矩阵原始输入。然后我们对这些列中的每一列执行cumsum,然后我们需要将reshape 恢复为输入的原始形状。有了这个,我们在cumsum 结果上再次使用reshape,但是为了让它回到你想要的行顺序,我们必须确定转置,因为reshape 以列优先顺序取值,然后重新转置该结果。
我们得到:
xx =
1 3 6 4 9 15 7 15 24 10 21 33
13 27 42 16 33 51 19 39 60 22 45 69
一般来说,要对一行求和的元素总数需要能被矩阵包含的总列数整除。例如,鉴于上述情况,如果您尝试将此矩阵分割为 5 个块,您肯定会收到错误,因为到 cumsum 的行数不是对称的。
再举一个例子,假设我们想将矩阵分成 6 个块。因此,通过设置num_chunks = 6,我们得到:
xx =
1 3 3 7 5 11 7 15 9 19 11 23
13 27 15 31 17 35 19 39 21 43 23 47
您可以看到cumsum 在每隔一列重新启动,因为我们需要 6 个块,并且要获得 6 个块和 12 列矩阵,每隔一列创建一个块。