在MATLAB中进行预分配

时间:2018-06-29 10:14:44

标签: matlab matrix vectorization indices pre-allocation

问题

我有一个矩阵M,该矩阵如下:

   M =  [1, 1, 0, 1, 0, 0, 0;
         0, 1, 1, 0, 1, 0, 0;
         0, 0, 1, 1, 0, 1, 0;
         0, 0, 0, 1, 1, 0, 1;
         1, 0, 0, 0, 1, 1, 0;
         0, 1, 0, 0, 0, 1, 1;
         1, 0, 1, 0, 0, 0, 1];  

所有列中的总数为21:

 Total_ones_in_cols = 21; 

然后我要预先分配内存以查找M中每一列的行索引:

row_indices = zeros(1,Total_ones_in_cols); 

下一步是找到所有列的行索引:

for i = 1:7
     Temp = find(M(:,i)); 
     row_indices = [row_indices, Temp.'];
end 

问题

尽管对row_indices进行了预分配,但是MATLAB仍建议在循环内为row_indices预先分配速度。有人可以解释为什么会这样吗?我的猜测是,由于我在循环内不断更改row_indices的大小,因此我已经预分配的先前内存将被覆盖并被丢弃,这从本质上意味着我所做的预分配变得无用。

1 个答案:

答案 0 :(得分:3)

您已经根据row_indices的最终大小正确分配了内存,但是没有将循环中的结果存储在预分配的索引中,而是在末尾附加了它们。追加总是会终止预分配,因此MATLAB告诉您执行预分配,因为循环结束时row_indices的大小为[1 42](MATLAB假定您想要此结果)而不是{{1} },您已对其进行了预分配(并且实际上正在寻找)。

要修复您的代码,应为:

[1 21]

我在您的问题中看到了标签。请注意,find直接适用于矩阵,因此只需以下操作即可避免循环(对于类似这样的简单任务应执行此操作):

row_indices = zeros(1,Total_ones_in_cols); 
for ii = 1:7 %i is for imaginary numbers; don't use i (and j) as variable name(s)
     Temp = find(M(:,ii)); 
     row_indices(3*ii-2 : 3*ii) = Temp;  %Storing results at their specific indices
end 
%This assumes that you already know that there are 3 ones in each column