两点之间的范围和距离内的Matlab元素

计算科学 matlab 矩阵 表现
2021-12-24 18:27:43

我有一个坐标矩阵。我想在范围内找到矩阵的元素,如下所示:53534×3xyz

% coordinate range;
x1(x<-25|x>0);
x2(x<0|x>25);
y1(y<-40|y>0);
y2(y<0|y>40);
z1(z<45|z>0);
z2(z<0|z>82);

并将它们插入到一个新的矩阵中,这样它就变成了

point1=[x1, y1, z1];
point2=[x2, y2, z2];

我需要找到两点之间的距离。

% define points;
xd=x2-x1;
yd=y2-y1;
zd=z2-z1;
Distance=sqrt(xd*xd+yd*yd+zd*zd);

循环最好是有效的吗?

2个回答

我怀疑至少在某些条件句中有错字。例如,z<45|z>0是微不足道的。但是我会假装它不是并且无论如何都要写出代码,这样如果你纠正它(也许z<-45|z>0)你仍然会有正确的结构。

x  = A(:,1); y = A(:,2); z = A(:,3); 
i1 = find((x<-25|x>0)&(y<-40|y>0)&(z<45|z>0),1,'first'); 
i2 = find((x<0|x>25)&(y<0|y>40)&(z<0|z>82),1,'first'); 
point1 = A(i1,:); 
point2 = A(i2,:); 
Distance = norm(point1-point2);

正如 Sam 博士所展示的,for在 MATLAB 中使用紧密循环对性能来说确实是灾难性的。显然,正如 Wolfgang 所指出的,MATLAB 在for内部使用优化循环来迭代向量的元素,但这是编译后的代码。如果您使用已编译的 C 来执行此操作,那么您也将使用for循环,并避免 MATLAB 在这里执行的大量临时生成。

我在一个稍微不同的例子上做了一些测试(你可以很容易地适应你的需要):我在 Matlab (7.9.0) 中生成一个 53534x3 随机矩阵

R = rand(53534,3);

我尝试提取所有三个坐标都大于 0.5 的行索引。我用循环制作了第一个版本:

I1=[];
for i=1:53534
    if ( R(i,1)>0.5 && R(i,2)>0.5 && R(i,3)>0.5 )
       I1 = [I1; i];
    end
end

和第二个版本没有循环但有find功能

I2 = find( (R(:,1) > 0.5) .* (R(:,2)> 0.5) .* (R(:,3)>0.5) )

(这里的元素乘积替换了 AND)。两个代码给出完全相同的结果。

现在有趣的部分是两个代码运行所需的时间:

  • 带循环的版本大约需要0.05 秒
  • 没有循环的版本大约需要0.004 秒

所以,它们之间有一个数量级!所以,至少在我的例子中,循环并不是最有效的实现

有人可能会争辩说您对循环有更大的灵活性。例如,如果您知道只有一个索引,您可以只运行循环直到找到它(不能直到最后)。但是,这使您(平均而言)只赢了 2 倍,并且该find功能也有类似的东西(查看帮助)。