Matlab - 当内循环依赖于外循环时,矢量化嵌套循环

时间:2013-05-30 08:42:13

标签: matlab loops for-loop vectorization

我正在研究一个函数,该函数将一个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

1 个答案:

答案 0 :(得分:3)

几件事:

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

    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