我知道有很多关于bsxfun
应该如何比repmat
更快的问题,所以我希望这个问题不会过于冗余。
我正在使用带有repmat的短代码。此代码的目的是识别A
和B
之间的索引,其中行向量相同,以便稍后删除它们,但使用repmat
使用Matlab R2016a需要太长时间。
[~,i] = min(abs(dot(A',repmat(B,length(A),1)')./sqrt(sum(A'.^2))./norm(B)-1));
此处A
和B
的大小不一定相同,因此使用repmat
似乎无论如何都不会起作用。目前,A
和B
的大小为8020x3和21615x3。我发现这种方法可以使A
和B
的大小相同,但我也对其他方法持开放态度。
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))
,但它们不会输出相同的最终数组,所以我必须做错事。
如果可能的话,我想修改上面的代码,以便花费更少的时间来计算,并且A
和B
的大小也不同,如上所述,如果可能的话。如果有必要,我仍然可以使用相同大小的A
和B
,但它们都会更大,在这种情况下为571000x3,因此计算也需要更长的时间。
增加:
在评论中,讨论了intersect
是否有效。从理论上讲,应该使用函数A
{{B
(黑色)和T
定义为在较大的卷inpolyhedron
内的等值面(红色)内部或外部3}}。出于某种原因,inpolyhedron
的输出是等值面内的一组点,其中也有一些散点。使用inpolyhedron
查找值在之外的isosurface时,这些&#34; extra&#34;分散点不包含在集B
中,因此intersect
在输入A
和B
时会找到一个空集。 https://www.mathworks.com/matlabcentral/fileexchange/37856-inpolyhedron-are-points-inside-a-triangulated-volume-#comments
答案 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联系。