Векторизация циклов for - PullRequest
       5

Векторизация циклов for

0 голосов
/ 11 декабря 2011

Этот фрагмент кода работает так, как я хочу, но в духе хорошего кода MATLAB, есть ли способ векторизации этого (предыдущий - вектор k x 1):

start = zeros(k,1);
for i = 2:length(previous)
    if (previous(i-1) == -1)
        start(previous(i))= start(previous(i))+1;
    end    
end

Каков в целом интуитивный способ векторизации кода в MATLAB?

Ответы [ 3 ]

2 голосов
/ 11 декабря 2011

Используйте команду find в MATLAB, которая возвращает индекс (i), для которого вектор равен TRUE. Итак:

% precache indices i where previous(i-1) == 1
idx = find(previous==-1)+1;
start(previous(idx)) = start(previous(idx))+1;

Причина, по которой я кеширую idx, заключается в том, что previous - большой вектор, а выполнение find занимает некоторое время. В противном случае вы могли бы просто сделать

start( find(previous==-1)+1 ) = start( find(previous==-1) ) + 1;
1 голос
/ 11 декабря 2011

Вы можете сделать это без find, для максимальной производительности:

I = [false; previous(1:end-1) == -1];
idx = previous(I);
start(idx) = start(idx) + 1;

Это также позволяет избежать риска, что previous(end) == -1, что приведет к ошибке индекса вне допустимого диапазона в альтернативе.

Обратите внимание, что это не работает так же, как ваш оригинал, если idx содержит дублированные индексы.

0 голосов
/ 11 декабря 2011

Я бы сделал что-то вроде:

prev_is_minus1 = [false; previous(1:end-1)==-1]
start = accumarray(previous(prev_is_minus1), 1, k)

Я считаю, что это имеет тот же эффект, что и цикл кода, который вы опубликовали.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...