【问题标题】:Avoiding for-loops in matrix operations with cell elements在使用单元格元素的矩阵运算中避免 for 循环
【发布时间】:2014-02-17 17:43:23
【问题描述】:

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

如何抑制for循环?我的直觉是使用带有 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

感谢指点。谢谢

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

【问题讨论】:

  • 回答你的后续问题:请不要再担心矢量化了!如前所述,您的内部循环由对大型矩阵的计算组成,Matlab 已经尽可能快地完成了。与此相比,小型 for 循环的开销完全可以忽略不计。只有在分析器告诉您代码很慢时才将时间浪费在优化代码上。
  • 谢谢巴斯。取点。这个循环被 Profiler 标记为红色,而不仅仅是粉红色,这就是我试图改变这些单元阵列的编程效率的原因。
  • 您必须将元胞数组视为一个微小的 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 部分由探查器划红线。因此,不希望通过改进代码来进一步加快速度。下周我要买一本新笔记本。感谢您在分配效率低下的责任方面提供的帮助。

标签: matlab matrix cell elements operations


【解决方案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

【讨论】:

  • 将执行时间减少到原始执行时间的 1/3。
  • 很高兴听到,但我有点惊讶。如果我正确理解了您的代码,则执行时间应该由大型 500x500 矩阵上的数学计算决定,与此相比,所有其余部分(for-loop、单元数组索引)应该可以忽略不计。
猜你喜欢
  • 1970-01-01
  • 2017-01-29
  • 1970-01-01
  • 2022-11-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-24
  • 1970-01-01
相关资源
最近更新 更多