Предварительное распределение в 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 в цикле, предыдущая память, которую я предварительно выделил, перезаписывается и удаляется, что по сути означает, что выполненное мной предварительное распределение становится бесполезным.
1 ответ
Вы правильно распределили память в соответствии с окончательным размером 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
Я вижу тег векторизации в вашем вопросе. Обратите внимание, что find
непосредственно применимо к матрицам, так что вы можете избежать цикла (вы должны сделать это для более простой задачи, такой как эта) просто следующим образом:
[row_indices, ~] = find(M);