Предварительное размещение в 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 в цикле, предыдущая память, которую я предварительно выделил, перезаписывается и удаляется, что по своей сути означает, что предварительное выделение, которое я сделал, становится бесполезным.


person Anthony    schedule 29.06.2018    source источник


Ответы (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

Я вижу в вашем вопросе тег vectorization. Обратите внимание, что find напрямую применим к матрицам, поэтому вы можете избежать loop (вы должны сделать это для более простой задачи, подобной этой) просто с помощью этого:

[row_indices, ~] = find(M);
person Sardar Usama    schedule 29.06.2018