0

The dimensions of this problem are: model.nlf = 4. Each {r} of Kuu or KuuGamma are 500x500 matrices of data.

How to suppress the for-loop? my intuition goes toward using cellfun with a function for logdet.

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

Grateful for pointers. Thanks

Follow up question: Can the following type of for-loops on cell elements be vectorized? nlf = 4; nout = 16; each KuuinvKuy{1,1} are 150x650

for k =1: model.nout,
    for r =1: model.nlf,
        model.KuuinvKuy{r,k} = model.Kuuinv{r}*model.Kyu{k,r}';
    end
end
  • To answer your follow-up question: please stop worrying about vectorization! As said before, your inner loop consists of calculations on large matrices, which Matlab already does as fast as possible. The overhead of a small for-loop is totally negligible compared to that. Only waste time on optimizing code if the profiler tells you that it is slow. – Bas Swinckels Feb 17 '14 at 09:52
  • Thank you Bas. Point taken. This loop is flagged in red, not just pink, by the Profiler and this is why I am trying to change the programming efficiency of these cell arrays. – user2015897 Feb 17 '14 at 12:11
  • You must see the cell arrays just as a tiny 4x16 matrix of pointers. Indexing that should be pretty fast. What should cost time is the 150x650 matrix computation. But do test yourself: split the long expression in your for-loop into separate parts: `temp1 = model.Kuuinv{r}; temp2 = model.Kyu{k,r}; temp2 = temp2'; temp3 = temp1 * temp2; model.KuuinvKuy{r,k} = temp3;`, each on a separate line, and run the profiler again. If there are no surprises, most time should be spent on the last line. In that case, there is no hope to speed it up any further, matrix multiplication should be super-fast. – Bas Swinckels Feb 17 '14 at 13:54
  • Correct. As you predicted, the temp3 = temp1*temp2 part is red lined by the profiler. Hence, no hope to speed it up further by improving the code. I am getting a new notebook next week. Thank you for your help on assigning responsibilities for inefficiencies. – user2015897 Feb 17 '14 at 14:34

1 Answers1

0

If all your matrices are so large, and you execute your for-loop only 4 times, then there is no reason to remove the for-loops, since it will not lead to any speedup. My only observation is that the condition of the if seems to be independent of the loop, so it is cleaner to move that if before the loop. Something like this:

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
Bas Swinckels
  • 18,095
  • 3
  • 45
  • 62
  • Reduced execution time to 1/3 of original exec time. – user2015897 Feb 17 '14 at 09:35
  • Good to hear, but I am a bit surprised. If I understand your code correctly, the execution time should be dominated by the math on the large 500x500 matrices, all the rest (for-loop, cell-array indexing) should be negligible compared to that. – Bas Swinckels Feb 17 '14 at 09:46