【问题标题】:How do I get all the rows meeting some criteria out of a big matrix?如何从大矩阵中获取满足某些条件的所有行?
【发布时间】:2014-01-23 19:24:08
【问题描述】:

我有一个大矩阵(大约 1GB),其中每一行代表我在表面采样的点的 (x,y) 坐标及其 z 高度。

如何获得距离 (x,y) 坐标小于某个欧几里得距离的所有点?

目前我正在做这件可怕的事情:


% mtx_pointList is a large matrix with each row containing a sample: [x y z]. 
% We want to get all the samples whose (x,y) point is less than dDistance 
%   away from the vector: v_center = [x y].

mtx_regionSamples = zeros(0,3); for k=1:length(mtx_pointList(:,1)) if( norm( mtx_pointList(k,[1 2])-v_center ) < dDistance^2 ) mtx_regionSamples = [ mtx_regionSamples mtx_pointList(k,:) ] end end

...但在我的应用程序中,这个循环必须运行大约 25 万次。

如何让它更快地做同样的事情?

【问题讨论】:

    标签: performance matlab if-statement for-loop matrix


    【解决方案1】:

    使用pdist2(其默认选项是欧几里得距离):

    ind = pdist2(mtx_pointList(:,[1 2]), v_center) < dDistance; %// logical index
    result = mtx_pointList(ind,:);
    

    如果矩阵太大,则将其划分为内存允许的行数,然后循环遍历这些块。

    【讨论】:

      【解决方案2】:

      bsxfun

      如果您没有pdist2(统计工具箱),这里有一种使用bsxfun 计算距离的方法:

      da = bsxfun(@minus,mtx_pointList(:,[1 2]),permute(v_center,[3 2 1]));
      distances = sqrt(sum(da.^2,2));
      

      然后找到符合您条件的点:

      distThresh = 0.5; % for example
      indsClose = distances < distThresh
      result = mtx_pointList(indsClose,:);
      

      另类

      您还可以使用欧几里得(2-范数)距离的另一种形式,

      ||A-B|| = sqrt ( ||A||^2 + ||B||^2 - 2*A.B )
      

      在 MATLAB 代码中:

      a = mtx_pointList(:,[1 2]); b = v_center;
      aa = dot(a,a,2); bb = dot(b,b,2); ab=a*b.'; %' or sum(a.*a,2)
      distances = sqrt(aa + bb - 2*ab); % bsxfun needed if b is more than one point
      

      正如 Luis Mendo 指出的那样,如果您以 distThresh^2 为阈值,则不需要 sqrt

      【讨论】:

      • +1 删除 sqrt 并与 distThresh^2 比较会更有效
      • @LuisMendo 好建议(再次!)。
      • 看到了吗?还不错:-P
      猜你喜欢
      • 2020-02-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-02
      • 2011-10-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多