MATLAB 中的预分配
Preallocation in MATLAB
问题
我有一个矩阵 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 的大小,因此我预先分配的先前内存被覆盖并被丢弃,这本质上意味着我所做的预分配变得无用。
您已根据 row_indices
的最终大小正确分配了内存,但是您没有将循环结果存储在预分配的索引处,而是将它们附加在末尾。追加总是会终止预分配,因此 MATLAB 告诉您进行预分配,因为循环结束时 row_indices
的大小是 [1 42]
(MATLAB 假定您想要此结果)而不是 [1 21]
您预先分配的(并且实际上正在寻找)。
要修复您的代码,应该是:
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
我看到 vectorization tag in your question. Note that find
直接适用于矩阵,所以你可以避免循环(你应该为这样一个更简单的任务这样做),只需这样做:
[row_indices, ~] = find(M);
问题
我有一个矩阵 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 的大小,因此我预先分配的先前内存被覆盖并被丢弃,这本质上意味着我所做的预分配变得无用。
您已根据 row_indices
的最终大小正确分配了内存,但是您没有将循环结果存储在预分配的索引处,而是将它们附加在末尾。追加总是会终止预分配,因此 MATLAB 告诉您进行预分配,因为循环结束时 row_indices
的大小是 [1 42]
(MATLAB 假定您想要此结果)而不是 [1 21]
您预先分配的(并且实际上正在寻找)。
要修复您的代码,应该是:
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
我看到 vectorization tag in your question. Note that find
直接适用于矩阵,所以你可以避免循环(你应该为这样一个更简单的任务这样做),只需这样做:
[row_indices, ~] = find(M);