2014-02-16 130 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)应该可以忽略不计。 –

相关问题