映射2个向量 - 帮助进行向量化

时间:2010-01-26 21:35:42

标签: performance matlab map vector vectorization

在Matlab中工作我有2个不同长度的x坐标向量。例如:

xm = [15 20 24 25 26 35 81 84 93];
xn = [14 22 26 51 55 59 70 75 89 96];

我需要将xm映射到xn,或者换句话说,找到xn中哪些坐标最接近xm。因此,如果我有与这些坐标相关联的值,我可以将此地图用作索引并关联这些值。

两个向量都已排序,每个向量中没有重复。

我用for循环写了一个简单的函数:

function xmap = vectors_map(xm,xn)
xmap = zeros(size(xm));
for k=1:numel(xm)
    [~, ind] = min(abs(xm(k)-xn));
    xmap(k) = ind(1);
end

上面的例子是返回

xmap =
    1     2     2     3     3     3     8     9    10

它工作正常,但需要一段时间才能使用长矢量(超过100,000点)。

有关如何对此代码进行矢量化的任何想法吗?

6 个答案:

答案 0 :(得分:5)

哦!另一个选择:既然你正在寻找两个排序列表之间的密切对应关系,你可以使用类似合并的算法同时浏览它们。这应该是O(max(长度(xm),长度(xn))) - ish。


match_for_xn = zeros(length(xn), 1);
last_M = 1;
for N = 1:length(xn)
  % search through M until we find a match.
  for M = last_M:length(xm)
    dist_to_curr = abs(xm(M) - xn(N));
    dist_to_next = abs(xm(M+1) - xn(N));

    if dist_to_next > dist_to_curr
      match_for_xn(N) = M;
      last_M = M;
      break
    else
      continue
    end

  end % M
end % N

编辑: 看@ yuk的评论,上面的代码并不完全正确!

答案 1 :(得分:4)

考虑这个矢量化解决方案:

[~, xmap] = min( abs(bsxfun(@minus, xm, xn')) )

答案 2 :(得分:3)

我知道解决这个问题的最快实现是this one(可以编译为.mex文件的C代码;对我来说,它比接受答案中的rescdsk代码快20倍)。令人惊讶的是,这种常见操作不是MATLAB内置函数。

答案 3 :(得分:1)

看起来您的输入向量已排序。使用二进制搜索查找最接近的匹配项。这将为您提供O(n ln n)运行时间。

答案 4 :(得分:0)

您的xm和xn已排序。如果通常是这种情况,那么你可以比跨越整个阵列做得更好。

对于xn中的每个值,将存在一系列值,xm中的值将比任何其他值更接近该值。事先计算这些间隔,然后按顺序逐步浏览两个数组。

答案 5 :(得分:0)

正如大卫所说,利用被排序的优势会更快,因为你有这么多的积分,但作为参考,一种方法来矢量化这将是使用meshgrid:

[X Y] = meshgrid(xn, xm);
diffs = X - y;
mins = min(diffs, [], 2);

请注意,这将在内存中创建两个100,000 x 100,000个数组,因此它可能仅适用于较小的数据集。