假设我们在MATLAB中运行无限循环,并且要将迭代值存储在向量中。我们如何在不知道向量大小的情况下声明向量?
setting -> Apps
答案 0 :(得分:2)
请首先注意,这是一种不好的做法,您应该在可能的情况下进行预分配。
话虽如此,使用end
关键字是将数组扩展为单个元素的最佳选择:
z = [];
for ii = 1:x
z(end+1, 1) = ii; % Index to the (end+1)th position, extending the array
end
您还可以连接先前迭代的结果,由于您在equals运算符的两边都具有赋值变量,因此这往往会比较慢
z = [];
for ii = 1:x
z = [z; ii];
end
Sadar commented直接超出范围(如其他答案所暗示),索引已被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
答案 1 :(得分:1)
根据您的用例,您可能不知道实际的迭代次数,因此也不知道矢量元素,但是您可能知道最大可能的迭代次数。如前所述,在每次循环迭代中调整向量的大小可能是一个真正的性能瓶颈,您可能会考虑如下情况:
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或您选择的任何其他字母用作循环索引变量名称功能;)
答案 2 :(得分:0)
您可以使用声明一个空矩阵
z = []
这将创建一个0x0矩阵,当您向其中写入数据时会调整大小。 在您的情况下,它将增长为向量ix1。
请记住,这比用zeros(dim,dim)函数预先初始化向量要慢得多。
因此,如果有办法找出i的最大值,则应使用z = zeros(i,1)
欢呼声, 西蒙
答案 3 :(得分:0)
您可以将z初始化为一个空数组,它会在循环过程中自动展开...如下所示:
z = [];
for i = 1:Inf
z(i) = i;
if (condition)
break;
end
end
但是这看起来很讨厌(并发出警告:警告:FOR循环索引太大。截断为922337203685477575807),我会在这里做一会儿(true)或条件本身,然后手动递增。
z = [];
i = 0;
while !condition
i=i+1;
z[i]=i;
end
和/或如果您的示例确实是您最后所需的内容,请使用类似以下内容的方法替换数组的重新创建:
while !condition
i=i+1;
end
z = 1:i;
答案 4 :(得分:0)
正如在该线程中多次提到的那样,数组的大小调整需要大量处理,并且可能要花费大量时间。
如果处理时间不是问题:
然后像@Wolfie这样的东西就足够了。在每次迭代中,数组长度都会增加,即:
z = [];
for ii = 1:x
%z = [z; ii];
z(end+1) = ii % Best way
end
如果处理时间有问题:
如果处理时间是一个很大的因素,并且您希望它尽可能平稳地运行,则需要进行预分配。如果您对将要运行的最大迭代次数有一个大概的了解,则可以使用@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
希望这会有所帮助!