优化嵌套for循环以计算矩阵行的xcorr

时间:2017-12-14 11:28:10

标签: matlab performance optimization vectorization bsxfun

我有2个嵌套循环,它们执行以下操作:

  • 获取两行矩阵
  • 检查指数是否符合条件
  • 如果他们这样做:计算两行之间的xcorr并将其放入新的向量
  • 找到子矢量最大值的索引,并用此值替换LAG矩阵的元素

我不知道如何通过矢量化或其他方式加快此代码的速度。

b=size(data,1);
F=size(data,2);
LAG= zeros(b,b);  

for i=1:b
    for j=1:b
        if j>i
            x=data(i,:);
            y=data(j,:);
            d=xcorr(x,y);
            d=d(:,F:(2*F)-1); 
            [M,I] = max(d);
            LAG(i,j)=I-1;
            d=xcorr(y,x);
            d=d(:,F:(2*F)-1);
            [M,I] = max(d);
            LAG(j,i)=I-1;
        end
    end
end

1 个答案:

答案 0 :(得分:1)

首先,关于浮点精度的说明......

您在评论中提到您的数据包含整数0,1和2.因此,您希望cross-correlation给出整数结果。但是,由于计算是在double-precision中完成的,因此似乎引入了一些floating-point error。此错误可能导致结果略大于或小于整数值。

由于您的计算涉及查找maxima的位置,因此如果存在重复的具有添加的精度错误的最大整数值,则可能会得到略微不同的结果。例如,假设您期望值10为最大值,并显示在向量d的索引2和4中。您可以单向计算d并获得d(2) = 10d(4) = 10.00000000000001,但会增加一些精度错误。因此,最大值将位于索引4中。如果您使用其他方法计算d,则可能会得到d(2) = 10d(4) = 9.99999999999999,错误的方向相反,导致最大值位于索引2中。

解决方案?首先Round您的互相关数据:

d = round(xcorr(x, y));

这将消除浮点错误,并为您提供预期的整数结果。

现在,谈到实际的解决方案......


解决方案1:非循环选项

您可以将矩阵传递给xcorr,它将为每个成对的列组合执行互相关。使用它,你可以完全放弃你的循环:

d = round(xcorr(data.'));
[~, I] = max(d(F:(2*F)-1,:), [], 1);
LAG = reshape(I-1, b, b).';


解决方案2:改进的循环选项

对于上述解决方案,data的大小有限,因为它会产生超过maximum array size available的大型中间变量和输出变量。在这种情况下,循环可能是不可避免的,但您可以改进上面的for循环解决方案。具体来说,您可以为一对(x, y)计算一次互相关,然后只需翻转(y, x)对的结果:

% Loop over rows:
for row = 1:b

  % Loop over upper matrix triangle:
  for col = (row+1):b

    % Cross-correlation for upper triangle:
    d = round(xcorr(data(row, :), data(col, :)));
    [~, I] = max(d(:, F:(2*F)-1));
    LAG(row, col) = I-1;

    % Cross-correlation for lower triangle:
    d = fliplr(d);
    [~, I] = max(d(:, F:(2*F)-1));
    LAG(col, row) = I-1;

  end

end