Arrays 如何预分配随horzcat和vertcat一起增长的阵列

Arrays 如何预分配随horzcat和vertcat一起增长的阵列,arrays,performance,matlab,Arrays,Performance,Matlab,每当一个数组在循环中增长时,只要我们知道将要发生的迭代次数,我们就可以在循环之前轻松地预先分配它 然而,在某些情况下,我们根本不知道迭代的确切次数,例如,当我们有一个必须满足的条件来增加数组时 对于这种情况,因为我不知道输出数组的大小,所以我不知道如何预先分配 以以下伪代码为例: M = []; % Declare empty array. for i = 1:n % This loop performs n iterations. if(condition == true)

每当一个数组在循环中增长时,只要我们知道将要发生的迭代次数,我们就可以在循环之前轻松地预先分配它

然而,在某些情况下,我们根本不知道迭代的确切次数,例如,当我们有一个必须满足的条件来增加数组时

对于这种情况,因为我不知道输出数组的大小,所以我不知道如何预先分配

以以下伪代码为例:

M = []; % Declare empty array.

for i = 1:n % This loop performs n iterations.
    if(condition == true)
        % Computations take place here
        % and yield an array --> v

        M = horzcat(M,v'); % Concatenate v as a new column of M.
    end
end
在这种情况下,您将如何预先分配
M


请注意,
horzcat(M,v')
用于为满足条件的迭代按列增长
M
。因此,如果我们使用
vertcat(M,v)
将行连接起来,那么同样的情况也会发生。首先,重写代码,使其与预分配兼容。使用类似

M(k+1:k+numel(v))=v'
k=k+numel(v)
使用K来跟踪您真正使用的空间。在分配的额外空间的末端:

M=M(1:k)

现在,您可以尝试不同的策略,分配可能的最大值(如果已知),在数组已满时加倍大小等。分配预期或最可能的大小。这取决于你的问题

首先,重写代码以与预分配兼容。使用类似

M(k+1:k+numel(v))=v'
k=k+numel(v)
使用K来跟踪您真正使用的空间。在分配的额外空间的末端:

M=M(1:k)

现在,您可以尝试不同的策略,分配可能的最大值(如果已知),在数组已满时加倍大小等。分配预期或最可能的大小。这取决于你的问题

我原以为预先分配数组只会在循环之前发生一次,但正如我现在通过阅读您的答案所理解的那样,它也可以在循环中进行。这对我来说是非常困惑的,因为
M
数组的大小在每次迭代中都会增加!Matlab允许您“动态”分配额外的空间。假设你有1000个元素的
v
,但是你注意到你需要2000个元素。写入
v(2000)=0会导致matlab一步分配缺少的空间。请注意,阵列的每个扩展可能需要将整个阵列移动到新的内存地址,因此您希望避免此类步骤,但不必不惜一切代价避免它们。明白。我想这主要是关于直觉的。因此,在大多数情况下,在循环之前预先分配一个零数组是值得的,并使其足够大以确保有足够的空间可用,然后在循环之后,只需缩小数组,丢弃未使用的零…回到问题的原始问题,现在我明白了为什么如果我想填充预分配的数组,那么使用
horzcat
vertcat
是没有意义的:)我认为预分配数组只需在循环之前进行一次,但正如我现在读到的答案所理解的那样,它也可以在循环中随时完成。这对我来说是非常困惑的,因为
M
数组的大小在每次迭代中都会增加!Matlab允许您“动态”分配额外的空间。假设你有1000个元素的
v
,但是你注意到你需要2000个元素。写入
v(2000)=0会导致matlab一步分配缺少的空间。请注意,阵列的每个扩展可能需要将整个阵列移动到新的内存地址,因此您希望避免此类步骤,但不必不惜一切代价避免它们。明白。我想这主要是关于直觉的。因此,在大多数情况下,在循环之前预先分配一个零数组是值得的,并使其足够大以确保有足够的空间可用,然后在循环之后,只需缩小数组,丢弃未使用的零…回到问题的原始问题,现在我明白了,如果我想填充预分配的数组,为什么使用
horzcat
vertcat
毫无意义:)