Предварительное распределение в 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);
Другие вопросы по тегам