Mapping 2 vectors - help to vectorize
在Matlab中工作,我有2个具有不同长度的x坐标向量。 例如:
1 2 | 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循环编写了一个简单的函数:
1 2 3 4 5 6 |
对于上面的示例是return
1 2 | xmap = 1 2 2 3 3 3 8 9 10 |
它可以正常工作,但对于较长的向量(超过100,000点)会花费一些时间。
有什么想法可以向量化此代码吗?
哦!另一种选择:由于您要查找两个排序列表之间的紧密对应关系,因此可以使用类似合并的算法同时浏览它们。这应该是O(max(length(xm),length(xn)))-ish。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 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的评论,以上代码并不完全正确!
考虑以下向量化解决方案:
我知道解决此问题的最快方法就是这个(可以编译为.mex文件的C代码;对我来说,它比接受的答案中rescdsk的代码快20倍)。令人惊讶的是,这种常见的操作不是MATLAB内置函数。
看起来您的输入向量已排序。使用二进制搜索找到最接近的匹配项。这将为您提供O(n ln n)运行时间。
正如David所说,利用排序的优势会更快,因为您有很多点,但是作为参考,向量化的一种方法是使用meshgrid:
请注意,这将在内存中创建两个100,000 x 100,000的数组,因此可能仅对较小的数据集可行。
您的xm和xn已排序。如果通常是这种情况,那么您可以比单步执行整个阵列做得更好。
对于xn中的每个值,将存在一系列值,其中xm中的值将比其他任何值更接近该数字。预先计算这些间隔,然后可以顺序地遍历两个数组。