在 matlab 中声明一个我们不知道其大小的向量

Declaring a vector in matlab whose size we don't know

假设我们是 运行 MATLAB 中的无限 for 循环,我们想将迭代值存储在一个向量中。我们如何在不知道向量大小的情况下声明向量?

z=??
for i=1:inf
    z(i,1)=i;
    if(condition)%%condition is met then break out of the loop
        break;
    end;
end;

你可以只用

声明一个空矩阵
z = []

这将创建一个 0x0 矩阵,当您向其写入数据时,该矩阵会调整大小。 在您的情况下,它将增长为向量 ix1.

请记住,这比使用 zeros(dim,dim) 函数预先初始化向量要慢得多。 因此,如果有任何方法可以计算出 i 的最大值,您应该使用 z = zeros(i,1)

对其进行初始化

干杯, 西蒙

您可以将 z 初始化为一个空数组,它会在循环过程中自动扩展...类似于:

z = [];
for i = 1:Inf
 z(i) = i;
 if (condition)
    break;
 end
end

但是这看起来很讨厌(并发出警告:警告:FOR 循环索引太大。截断为 9223372036854775807),我会在这里做一会儿(真)或条件本身并手动递增。

z = [];
i = 0;
while !condition
 i=i+1;
 z[i]=i;
end

And/or 如果您的示例最终确实是您所需要的,请将数组的重新创建替换为类似以下内容:

while !condition
 i=i+1;
end
z = 1:i;

根据您的用例,您可能不知道实际的迭代次数和矢量元素,但您可能知道最大可能的迭代次数。如前所述,在每次循环迭代中调整向量的大小可能是一个真正的性能瓶颈,您可能会考虑这样的事情:

maxNumIterations = 12345;
myVector = zeros(maxNumIterations, 1);

for n = 1:maxNumIterations
    myVector(n) = someFunctionReturningTheDesiredValue(n);

    if(condition)
        vecLength = n;
        break;
    end
end

% Resize the vector to the length that has actually been filled
myVector = myVector(1:vecLength);

顺便提一下,我建议您不要习惯在 Matlab 程序中使用 i 作为索引,因为这会掩盖虚数单位 i。通过这样做,我 运行 在循环内部的复杂计算中遇到了一些讨厌的错误,所以我建议即使您不处理,也只需将 n 或您选择的任何其他字母作为您的首选循环索引变量名函数中的复杂值 ;)

请首先注意这是一种不好的做法,您应该尽可能预先分配。

也就是说,使用 end 关键字是通过单个元素扩展数组的最佳选择:

z = [];
for ii = 1:x
    z(end+1, 1) = ii; % Index to the (end+1)th position, extending the array
end

您还可以连接以前迭代的结果,这往往会更慢,因为您在等号运算符的两边都有赋值变量

z = [];
for ii = 1:x
    z = [z; ii];
end

Sadar MathWorks 贬低了直接索引越界(正如其他答案所暗示的那样),我不确定这方面的来源。


如果您的 condition 计算与输出计算是分开的,您可以先获得所需的大小

k = 0;
while ~condition
    condition = true; % evaluate the condition here
    k = k + 1;
end

z = zeros( k, 1 ); % now we can pre-allocate
for ii = 1:k
    z(ii) = ii; % assign values
end

正如本帖中多次提到的,调整数组大小需要大量处理,可能会花费很多时间。

如果处理时间不是问题:

然后像@Wolfie 提到的那样就足够了。在每次迭代中,数组长度都会增加,即:

z = [];
for ii = 1:x
    %z = [z; ii];
    z(end+1) = ii % Best way
end

如果处理时间有问题:

如果处理时间是一个很大的因素,并且您希望它 运行 尽可能平滑,那么您需要 preallocating.If 大致了解最大迭代次数will 运行 然后你可以使用@PluginPenguin 的建议。但是仍然可能会发生达到预设限制的变化,这将破坏(或严重减慢)程序。

我的建议:

如果您的循环 运行 无限循环直到您停止它,您可以偶尔调整大小。本质上是边走边扩大尺寸,但只是偶尔做一次。例如每 100 次循环:

z = zeros(100,1);
for i=1:inf
    z(i,1)=i;

    fprintf("%d,\t%d\n",i,length(z)); % See it working

    if i+1 >= length(z)  %The array as run out of space
        %z = [z; zeros(100,1)];   % Extend this array (note the semi-colon)
        z((length(z)+100),1) = 0; % Seems twice as fast as the commented method
    end

    if(condition)%%condition is met then break out of the loop
        break;
    end;
end

这意味着循环可以运行永远,数组会随之增加,但只是每隔一段时间。这意味着命中的处理时间将是 最小

编辑:

正如@Cris 亲切提到的那样,MATLAB 已经完成了我在内部提出的建议。这使我的两个评论完全错误。所以最好遵循@Wolfie 和@Cris 所说的:

z(end+1) = i

希望对您有所帮助!