【问题标题】:Matlab: Avoid for-loop by using clever matrix indexing & find? How?Matlab:通过使用巧妙的矩阵索引和查找来避免 for 循环?如何?
【发布时间】:2013-04-19 09:46:41
【问题描述】:

我最近越来越多地接触 Matlab,在我最近的项目中出现了另一个问题。 我在一个整体边界内生成了几个矩形(或网格)。 这些网格可以有不同的间距/间隔。

我这样做是因为我想降低数字高程模型某些区域的网格/像素分辨率。到目前为止,一切正常。 但是因为可以在 GUI 中选择矩形,所以矩形可能会重叠。这种重叠是我想要找到并删除的。它们是否具有相同的间距,例如矩形 1&2 看起来像这样:

[t1x, t1y] = meshgrid(1:1:9,1:1:9);
[t2x, t2y] = meshgrid(7:1:15,7:1:15);
[t3x, t3y] = meshgrid(5:1:17,7:1:24);

在这种情况下,我可以只使用 unique 来查找重叠区域。 但是,它们看起来更像这样:

[t1x, t1y] = meshgrid(1:2:9,1:2:9);
[t2x, t2y] = meshgrid(7:3:15,7:3:15);
[t3x, t3y] = meshgrid(5:4:17,7:4:24);

因此,无法应用唯一性,因为网格 1 很可能与网格 2 重叠而没有相同的节点。为了方便和进一步处理,所有矩形/网格都被带入列符号并在我的代码中放入一个结果矩阵:

result = [[t1x(:), t1y(:)]; [t2x(:), t2y(:)]; [t3x(:), t3y(:)]];

现在我正在考虑使用 2 个嵌套的 for 循环来解决这个问题,就像这样(还不太好用):

res = zeros(length(result),1);
for i=1:length(result)
    currX = result(i,1);
    currY = result(i,2);
    for j=1:length(result)
        if result(j,1)< currX < result(j+1,1) && result(j,2)< currY < result(j+1,2)
              res(j) = 1;
        end
    end
end

但是:首先,这还不完全奏效,因为我得到了一个超出范围的错误,因为 length(result)=j+1 而且,res(j) = 1 似乎被循环覆盖了. 但这只是为了测试和演示。 因为这里显示的网格只是示例,而我使用的网格相当大,结果矩阵最多包含 2000x2000 = 4 个 mio 节点 --> 长度(结果)~4mio。 把它放到一个贯穿整个长度的嵌套 for 循环中很可能会扼杀我的记忆。

因此,我希望找到一个不需要嵌套循环但利用 Matlabs 查找和智能矩阵索引的复杂解决方案。 我想不出什么,但希望在这里得到帮助。

非常感谢您的讨论和帮助!

干杯,

西奥

【问题讨论】:

    标签: matlab vectorization


    【解决方案1】:

    以下是快速测试(未经广泛测试):

    % Example meshes
    [t1x, t1y] = meshgrid(1:2:9,1:2:9);
    [t2x, t2y] = meshgrid(7:3:15,7:3:15);
    
    % Group points for convenience
    A = [t1x(:), t1y(:)];
    B = [t2x(:), t2y(:)];
    
    % Compare which points of A within edges of B (and viceversa)
    idxA = A(:,1) >= B(1,1) & A(:,1) <= B(end,1) & A(:,2) >= B(1,2) & A(:,2) <= B(end,2);
    idxB = B(:,1) >= A(1,1) & B(:,1) <= A(end,1) & B(:,2) >= A(1,2) & B(:,2) <= A(end,2);
    
    % Plot result of identified points
    plot(A(:,1),A(:,2), '*r')
    hold on
    plot(B(:,1),B(:,2), '*b')
    plot([A(idxA,1); B(idxB,1)], [A(idxA,2); B(idxB,2)], 'sk')
    

    我对被识别为重叠的点进行平方:

    另外,与您的问题相关的是 TMW 的 Doug Hull 的 Puzzler: overlapping rectangles

    【讨论】:

    • 亲爱的奥列格, 非常感谢您提供这个想法和发布的链接!实际上,这在两个矩形的情况下非常有效。但我应该提到,我的问题涉及在同一平面上的任意数量的矩形,它们可能重叠,也可能不重叠,这使情况变得相当复杂。这就是为什么我有兴趣找到一种适用于一个长结果矩阵 nx2 的解决方案并检查该矩阵内的重叠,而不是必须测试每个单独的矩形与其他矩形相对应。这才是真正让我困惑的地方。编辑:我添加了另一个矩形以避免混淆
    • 我可以想到两种可能的解决方案:1)以最小的步长重新采样矩形,使所有原始点都包含在新的重新采样网格中,然后调用 unique 并转换回原始点。困难的部分是找到步骤。这种方法更占用 RAM。 2) 智能配对比较。首先,在元胞数组或结构中创建/存储您的矩形。为了加快速度,首先检查矩形是否完全重叠,然后注销那些已经被其他人覆盖的矩形(您可以执行单向 idx 而不是双向)。
    • 好的,非常感谢。我已经开始并且刚刚完成了与您的解决方案 2 相当的工作。我使用 rectint 查看哪些矩形的重叠区域 > 0,存储这些矩形,剥离双条目,然后运行您建议的逻辑操作。现在工作得体。再次感谢!
    猜你喜欢
    • 2021-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多