【问题标题】:Matlab - Vectorizing nested loops when the inner loop depends on the outer onesMatlab - 当内部循环依赖于外部循环时矢量化嵌套循环
【发布时间】:2013-05-25 18:10:00
【问题描述】:

我正在研究一个函数,它以 n×1 数组(称为“ts”)作为输入并创建一个 n×n 矩阵(称为“V”),其中 V 的每个元素是0 或 1。

现在将“ts”想象成一个图:如果可以使用一条直线将任意点(例如 ts(5))与另一个任意点(例如 ts(47))连接起来而不与时间序列相交,那么矩阵元素 V(5,47) 和 V(47,5) 应为 1。如果两个点在不与时间序列相交的情况下无法连接,则矩阵中的相应元素应为 0。应该这样做"ts" 中所有可能的点对。

函数如下:它可以工作,但效率很低(尤其是因为三个嵌套循环)。有没有办法对这段代码进行矢量化?

function V = someFunction(ts)
len = length(ts);
V = zeros(len, len);
for a = 1:len,
   for b = 1:len,
       intersection = [];
       for c = min(a,b)+1 : max(a,b)-1,
           t_a = a;
           y_a = ts(a);
           t_b = b;
           y_b = ts(b);
           t_c = c;
           y_c = ts(c);

           if (y_c < y_b + (y_a - y_b) * ((t_b - t_c) / (t_b - t_a))),
               intersection = [intersection; 0];
           else
               intersection = [intersection; 1];
           end
       end
       if all(intersection==0),
           V(a,b) = 1;
       end
   end
end
end

【问题讨论】:

  • 你正在增长交叉点,你应该预先分配它。
  • @OlegKomarov - 可以完全删除。

标签: matlab loops for-loop vectorization


【解决方案1】:

几件事:

  1. 当您点击else 子句时,无需创建数组intersection,您知道V(a,b) 为零。
  2. 由于V 是对称的,您只能计算.5*n*(n-1) 条目而不是n^2(相同的 O(n^2),但仍然少得多)。
  3. Oleg 的另一个观察是:“如果线段长度为 3 点,则无需执行任何检查,在这种情况下,构造不会有任何交叉点”

新代码

V = ones(len,len); % default for all
for a = 1:(len-3),
   for b = (a+3):len,
      for c = min(a,b)+1 : max(a,b)-1,
          t_a = a;
          y_a = ts(a);
          t_b = b;
          y_b = ts(b);
          t_c = c;
          y_c = ts(c);

          if (y_c < y_b + (y_a - y_b) * ((t_b - t_c) / (t_b - t_a))),
              % do nothing
          else
              V(a,b) = 0; % intersect
              V(b,a) = 0;
              break; % stop the inner loop the moment an intersection was found
          end
      end
   end
end

【讨论】:

  • @Shai,原来的代码总是产生一个对称矩阵,而你的却没有。尝试使用输入 ts = [-1 5 20 -1] 运行两者。
  • 您还可以包括我的评论(来自我已删除的答案),即三点的段不能通过构造相交,因此具有a = 1:len-3b = a+3:len
  • @OlegKomarov - 我将您的评论合并到代码中。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-28
  • 2017-02-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多