Matlab 用单元元素避免矩阵运算中的循环

Matlab 用单元元素避免矩阵运算中的循环,matlab,matrix,cell,elements,operations,Matlab,Matrix,Cell,Elements,Operations,这个问题的维度是:model.nlf=4。Kuu或kugamma的每个{r}都是500x500个数据矩阵 如何抑制for循环?我的直觉是使用cellfun和logdet函数 logDetKuu = 0; for r=1:model.nlf, if isfield(model, 'gamma') && ~isempty(model.gamma) [model.Kuuinv{r}, model.sqrtKuu{r}] = pdinv(model.KuuGamm

这个问题的维度是:model.nlf=4。Kuu或kugamma的每个{r}都是500x500个数据矩阵

如何抑制for循环?我的直觉是使用cellfun和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
感谢你的指点。谢谢

后续问题:可以对单元格元素上的以下类型的for循环进行矢量化吗? 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

如果所有矩阵都非常大,并且只执行了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

将执行时间减少到原来执行时间的1/3。很高兴听到这个消息,但我有点惊讶。如果我正确理解了您的代码,那么执行时间应该由大500x500矩阵上的数学决定,与此相比,所有其余的(循环、单元数组索引)应该可以忽略不计。回答您的后续问题:请停止担心矢量化!如前所述,您的内部循环包括对大型矩阵的计算,而Matlab已经尽可能快地完成了这些计算。与此相比,小型for循环的开销完全可以忽略不计。如果探查器告诉您代码太慢,那么只会在优化代码上浪费时间。我明白了。这个循环被分析器标记为红色,而不仅仅是粉红色,这就是为什么我试图改变这些单元格数组的编程效率。你必须把单元格数组看作一个小小的4x16指针矩阵。这应该很快。需要花费时间的是150x650矩阵计算。但是要自己测试:将for循环中的长表达式拆分为单独的部分:
temp1=model.Kuuinv{r};temp2=model.Kyu{k,r};temp2=temp2';temp3=temp1*temp2;model.KuuinvKuy{r,k}=temp3,每行一个,然后再次运行探查器。如果没有意外,大部分时间应该花在最后一行。在这种情况下,没有希望进一步加速,矩阵乘法应该是超快速的。正确。正如您所预测的,探查器对temp3=temp1*temp2零件进行了红线标记。因此,没有希望通过改进代码来进一步加快速度。我下周要买一本新笔记本。感谢您在分配低效率责任方面提供的帮助。