2015-12-05 2 views
4

У меня двойная петля, которая очень неэффективна.Vectorize Double Loop - MATLAB

c is a [400,2000] matrix 
r is a [2000,1] matrix 
P is a [2000,1] matrix 
S is a [1, 400] matrix 


for i=1:400 
    for k=1:2000 
     c(i,k) = r(k,1) * max([0, P(k,1) - S(1,i)]); 
    end 
end 

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

ответ

8

Поскольку вы выполняете только элементарные операции, такие как - и .*, это требует решения с использованием bsxfun.

Использование

bsxfun(@minus,P,S) 

сделать поэлементное вычитание P(k,1) - S(1,i). Результатом будет матрица [2000,400]. Вы можете применить max(0,...) операцию на этой матрице, и, наконец, использовать bsxfun снова мультипликативный каждую строку, соответствующую r:

bsxfun(@times,max(bsxfun(@minus,P,S),0),r) 

Как ваш c должен быть размером [400,2000], добавить последнюю операцию транспонирования, и вы законченный.

c = bsxfun(@times,max(bsxfun(@minus,P,S),0),r).'; 

Небольшое сравнение времени: для цикла принимает

Elapsed time is 0.688408 seconds. 

в то время как bsxfun решения принимает только

Elapsed time is 0.007884 seconds. 

который является хорошим ускорением из 87 для точно такие же результаты.

+0

Работает безупречно. Большое спасибо. – phdstudent