2014-10-22 3 views
0

У меня есть матрица вероятности (glcm) размером 256x256x20. Я изменил матрицу на 65536x20, так что я могу исключить один цикл (по третьему измерению).Matlab Vectorize

Я хочу сделать следующий расчет.

for y = 1:256 
    for x = 1:256 
     if (ismember((x + y),(2:2*256))) 
      p_xplusy((x+y),:) = p_xplusy((x+y),:) + glcm(((y-1)*256+x),:); 
     end 
    end 
end 

Так p_xplusy будет 511x20 матрица, каждый элемент является суммой диагонали матрицы NxN к югу (где п принадлежит 1: 256) исходной матрицы 256x256x20.

Этот код блокирует мою программу неэффективно, и я хочу векторизовать этот цикл. Любая помощь будет оценена по достоинству.

+0

'ismember' - довольно дорогой вызов функции. Просто взглянув на это, похоже, что вы можете заменить строку 'if (ismember ((x + y), (2: 2 * 256)))' с помощью 'if x + y <= 2 * 256 && x + y> 1 '. То, что я предлагаю, не векторизует, но может ускорить этот код до LOT. – chessofnerd

+1

Векторизация не обязательно быстрее в Matlab. При компиляции JIT для циклов часто бывают такие же быстрые, как и векторизованные методы, и часто лучше масштабируются при меньшем использовании памяти. Разумеется, это предполагает, что ваш цикл цикла написан разумно, а @chessofnerd уже обеспечил улучшение. – David

+0

Вы сказали: «p_xplusy будет 511x20», но он бросил мне ошибку с учетом значений «rand». Мне пришлось сделать это «rand (512,20)», чтобы заставить его работать. Не могли бы вы прояснить это? – Divakar

ответ

2

Поскольку ваш if оператор просто проверить ли x+y меньше или равно 256, просто заставить его быть всегда, и удалить лишние петли:

for y = 1:256 
    for x = 1:256-y 
     p_xplusy((x+y),:) = p_xplusy((x+y),:) + glcm(((y-1)*256+x),:); 
    end 
end 

Это должно обеспечить заметное ускорение для вашего код.

+0

есть .. спасибо за этот отзыв. Операция «if» не требуется. Удалено «if», а теперь время составляет 0,29 секунды (до удаления было 2,7 секунды). Большое спасибо за сохранение моего времени – shaaa

+1

Нужна ли '-x' во втором' for' заявлении? Я не уверен, что он даже действителен (но не может проверить его, потому что у меня нет MATLAB на моем текущем компьютере) – chessofnerd

+0

Не могли бы вы пояснить, что вы подразумеваете под '' remove over loops''. Если вы говорили об удалении условного оператора 'IF', это не цикл. – Divakar

0

Вы можете уменьшить сложность от O(n^2) к O(2*n) и тем самым повысить эффективность выполнения -

N = 256; 
for k1 = 1:N 
    idx_glcm = k1:N-1:N*(k1-1)+1; 
    p_xplusy(k1+1,:) = p_xplusy(k1+1,:) + sum(glcm(idx_glcm,:),1); 
end 

for k1 = 2:N 
    idx_glcm = k1*N:N-1:N*(N-1)+k1; 
    p_xplusy(N+k1,:) = p_xplusy(N+k1,:) + sum(glcm(idx_glcm,:),1); 
end 

Некоторые быстрые тесты во время выполнения, кажется, подтверждают нашу теорию эффективности тоже.

+0

Я предполагаю, что 'sum' является методом« O (N) ». Разве это не должно поднимать петлю до «O (n^2)»? Опять же, если это быстрее, то это быстрее! (: – chessofnerd

+0

@chessofnerd Я с удовольствием суммирую много столбцов за один раз, должен быть дешевле наивного для петли-суммирования, а также количество столбцов от 1 до Nxsqrt (2) и обратно от Nxsqrt (2) до 1. Итак , Я думаю, это может быть немного больше, чем 2 * N, но, безусловно, меньше, чем N^2 :) Хорошие моменты, поднятые там, хотя! – Divakar

Смежные вопросы