【问题标题】:removal of for loop from this code从此代码中删除 for 循环
【发布时间】:2013-09-05 16:36:49
【问题描述】:

我有问题。

我有两个矩阵 nbd_new 和 nbd_old,它们存储像 phi_new 和 phi_old 这样的 2D 矩阵的线性索引号。 phi_old 和 phi_new 的大小相同。我需要做的是计算集合 nbd_new 中但不在集合 nbd_old 中的所有位置。然后对于每个这样的位置,我必须以这种方式更新 phi_new:如果该位置的 phi_old 大于 0,则将 phi_new 放在该位置 = width+1 否则将 phi_new 放在该位置 = -(width+1)

我写过这样的代码:

    C = setdiff(nbd_new,nbd_old);
    for k=1:length(C)
        if phi_old(C(k))>0
            phi_new(C(k))=(width+1);
        else
            phi_new(C(k))=-(width+1);
        end
    end

此代码可以运行,但由于循环和 if-then-else 语句而非常慢。这段代码可以进一步优化吗?

提前谢谢大家!!

编辑:请检查 phi_old 和 phi_new 是否都是二维矩阵,矩阵 C 是该矩阵的线性索引(位置)的集合。如果我事先不清楚,我很抱歉。错误地,我写了 u 而不是 phi。两者都是一样的。

【问题讨论】:

  • 如果u_new没有事先初始化,代码也可能会很慢。
  • 请检查编辑 & u_new 或 phi_new 在这种情况下确实已初始化。
  • 你实际上并没有使用 C 的值,只是它的长度。这是故意的吗?
  • @Peter 是的,这确实是故意的。 C 仅包含二维矩阵 phi_old 和 phi_new 的线性索引或位置,我将要比较和更改其值。我使用变量 k 将循环从 1 运行到 C 的长度。然后我使用 k 访问二维矩阵 phi_old 和 phi_new 的所需元素。明白了吗?
  • 没有。如果 C 中有线性索引(假设为 [3 9 17]),则 k 从 1:3 开始迭代,并且您在 (1)、(2) 和 (3) 处引用 phi_new。如果忽略结果,setdiff 有什么用?

标签: matlab optimization image-processing vectorization


【解决方案1】:

不需要循环,使用logical indexing:

phi_new = zeros(size(phi_old)); % preallocate memory
phi_new(C(phi_old(C)>0)) =   (width+1);
phi_new(C(phi_old(C)<0)) = - (width+1);

【讨论】:

  • 我很抱歉造成误解,但请您重新检查我编辑的问题。我犯了一个错误并纠正了它。矩阵 u 或 phi(在这种情况下)实际上是一个二维矩阵,C 存储了该矩阵的线性索引位置。
  • 然后只需使用适当的 2D 尺寸预先分配 phi_new。例如phi_new=zeros(size(M)) 查看我对答案的编辑...
  • 你没有“检查”整个phi_old,因为逻辑条件集是phi_old(C)&gt;0,正如我的回答中所写的那样。
  • -1:此解决方案失败。请注意,phi_old(C)&lt;0 是一个与C 大小相同的逻辑数组,而不是phi_old。因此,假设C 有两个元素,它只会影响phi_new 的前两个元素。
  • 感谢您发现此错误,我没有注意到 setdiff 在此特定问题中的输出可能是较小的数组大小。答案,即“逻辑索引”仍然有效,并且现在没有错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-01-22
  • 2014-08-13
  • 2018-03-27
  • 1970-01-01
  • 2012-12-03
  • 2020-10-15
  • 1970-01-01
相关资源
最近更新 更多