bsxfun vs repmat使用不同大小的矩阵输入来匹配索引

时间:2018-06-06 17:49:42

标签: matlab indexing match bsxfun

我知道有很多关于bsxfun应该如何比repmat更快的问题,所以我希望这个问题不会过于冗余。

我正在使用带有repmat的短代码。此代码的目的是识别AB之间的索引,其中行向量相同,以便稍后删除它们,但使用repmat使用Matlab R2016a需要太长时间。

[~,i] = min(abs(dot(A',repmat(B,length(A),1)')./sqrt(sum(A'.^2))./norm(B)-1));

此处AB的大小不一定相同,因此使用repmat似乎无论如何都不会起作用。目前,AB的大小为8020x3和21615x3。我发现这种方法可以使AB的大小相同,但我也对其他方法持开放态度。

if isequal(size(A),size(B))==1

else
    a = size(A,1);
    b = size(B,1);

    if a<b
        A = [A;nan(abs(B-A),3)];
    else
        B = [B;nan(abs(B-A),3)];
    end
end

我正在查看bsxfun文档以及此Mathworks网站https://www.mathworks.com/matlabcentral/answers/297088-speed-up-indexing-repmat-operation,看起来我应该能够将repmat(B,length(A),1)'替换为bsxfun(@times, B, length(A)),但它们不会输出相同的最终数组,所以我必须做错事。

如果可能的话,我想修改上面的代码,以便花费更少的时间来计算,并且AB的大小也不同,如上所述,如果可能的话。如果有必要,我仍然可以使用相同大小的AB,但它们都会更大,在这种情况下为571000x3,因此计算也需要更长的时间。

增加: 在评论中,讨论了intersect是否有效。从理论上讲,应该使用函数A {{B(黑色)和T定义为在较大的卷inpolyhedron内的等值面(红色)内部或外部3}}。出于某种原因,inpolyhedron的输出是等值面内的一组点,其中也有一些散点。使用inpolyhedron查找值之外的isosurface时,这些&#34; extra&#34;分散点不包含在集B中,因此intersect在输入AB时会找到一个空集。 https://www.mathworks.com/matlabcentral/fileexchange/37856-inpolyhedron-are-points-inside-a-triangulated-volume-#comments

1 个答案:

答案 0 :(得分:0)

因此,事实证明inpolyhedron的创建者拥有一个“补丁”,可以大部分解决此问题。

基本上,您需要将点移动一小部分。

假设我的所有观点都在名为TestPoints的数组中。

TestPoints = combvec(x',y',z')';  % x, y, and z are column vectors
NudgedPoints = TestPoints + repmat([1e-10 1e-10 0],length(TestPoints),1);

根据数据创建具有面和顶点的曲面

[F,V] = isosurface(X,Y,Z,A,-3);   % you can use any value, and X, Y, and Z are positions from a meshgrid
in = inpolyhedron(F,V,NudgedPoints,'FlipNormals',false);
TestPoints_in = TestPoints(in,:);

此解决方案的全部功劳归于inpolyhedron的创建者Sven。您可以与他here联系。