2014-02-16 93 views
0

此問題的尺寸爲:model.nlf = 4. Kuu或KuuGamma的每個{r}都是500x500的數據矩陣。使用單元格元素避免矩陣運算中的for循環

如何抑制for-loop?我的直覺就是使用具有logdet功能的cellfun。

logDetKuu = 0; 
for r=1:model.nlf, 
    if isfield(model, 'gamma') && ~isempty(model.gamma) 
     [model.Kuuinv{r}, model.sqrtKuu{r}] = pdinv(model.KuuGamma{r}); 
     model.logDetKuu{r} = logdet(model.KuuGamma{r}, model.sqrtKuu{r}); 
    else 
     [model.Kuuinv{r}, model.sqrtKuu{r}] = pdinv(model.Kuu{r}); 
     model.logDetKuu{r} = logdet(model.Kuu{r}, model.sqrtKuu{r}); 
    end 
    logDetKuu = logDetKuu + model.logDetKuu{r}; 
end 

感謝指點。謝謝

後續問題:單元格元素的以下類型的循環可以矢量化嗎? nlf = 4; nout = 16;每個KuuinvKuy {1,1}是150x650

for k =1: model.nout, 
    for r =1: model.nlf, 
     model.KuuinvKuy{r,k} = model.Kuuinv{r}*model.Kyu{k,r}'; 
    end 
end 
+0

要回答你的後續問題:請不要擔心矢量化!如前所述,您的內部循環由大型矩陣上的計算組成,該Matlab已儘可能快地完成。與此相比,小型for循環的開銷完全可以忽略不計。如果分析器告訴您速度很慢,那麼只需浪費時間優化代碼。 –

+0

謝謝Bas。採取的點。這個循環被Profiler標記爲紅色而不僅僅是粉紅色,這就是爲什麼我試圖改變這些單元陣列的編程效率。 – user2015897

+0

你必須看到單元陣列就像一個微小的4×16指針矩陣。索引應該很快。應該花費的時間是150x650矩陣計算。但是要測試自己:將for循環中的長表達式拆分爲不同的部分:'temp1 = model.Kuuinv {r}; temp2 = model.Kyu {k,r}; temp2 = temp2'; temp3 = temp1 * temp2; model.KuuinvKuy {r,k} = temp3;',每個都在一個單獨的行上,然後再次運行分析器。如果沒有意外,大部分時間應該花在最後一行上。在這種情況下,沒有希望加速它,矩陣乘法應該是超快的。 –

回答

1

如果所有的矩陣是如此之大,你執行你的只有4 for循環的時間,那就沒有理由刪除的for循環,因爲它會不會導致任何加速。我唯一的看法是,if的條件似乎與循環無關,所以在循環之前移動if會更清晰。這樣的事情:

if isfield(model, 'gamma') && ~isempty(model.gamma) 
    myKuu = model.KuuGamma; 
else 
    myKuu = model.Kuu; 
end 

logDetKuu = 0;  
for r=1:model.nlf, 
    [model.Kuuinv{r}, model.sqrtKuu{r}] = pdinv(myKuu{r}); 
    model.logDetKuu{r} = logdet(myKuu{r}, model.sqrtKuu{r}); 
    logDetKuu = logDetKuu + model.logDetKuu{r}; 
end 
+0

將執行時間縮短至原始執行時間的1/3。 – user2015897

+0

很高興聽到,但我有點驚訝。如果我正確理解你的代碼,那麼執行時間應該由大500x500矩陣中的數學決定,其餘所有(for-loop,cell-array indexing)應該可以忽略不計。 –

相關問題