带嵌套if子句的Vectorize循环 [英] Vectorize loop with nested if-clause

查看:76
本文介绍了带嵌套if子句的Vectorize循环的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题

我正在尝试优化代码的运行时间,并在问了一个类似的问题之前,它包含了几个嵌套的if语句. 对嵌套的if语句进行矢量化

I am trying to optimize the runtime of my code and have asked a similar question before that included several nested if-statements. Vectorizing nested if-statements

由于我在此处发布的代码希望我能实现一些想法,所以该代码有点长,而我仍在为嵌套循环的矢量化实现而苦苦挣扎,我想再问一些简单的代码:

As the code I posted there hoping for some ideas I might implement was a bit long and I am still struggeling with the implementation of vectorization for nested loops I would like to ask again with some easier code:

代码

NB_list_all=zeros(length(BML),4);
for NB=1:length(BML);
    NB_list=zeros(4,1);
    %in +x direction
    if isempty(find(BML(:,2)==BML(NB,2)+x_blockdimension & BML(:,3)==BML(NB,3), 1));
        NB_list(1,1)=0;
    else
        NB_list(1,1)=find(BML(:,2)==(BML(NB,2)+x_blockdimension)& BML(:,3)==BML(NB,3));

    end
NB_list_z(NB,:)=NB_list;
end

% BML(:,2) stores the x-coordinate
% BML(:,3) stores the y-coordinate

一些示例数据

BML=
    1 1005  115
    2 1100  115
    3 1419  120
    4 1424  120
    5 660   115
    6 655   115

通知BML的尺寸为170 000 x 7.

Notice BML has a size of 170 000 x 7.

代码说明

我要用这段代码尝试的是在我的点云中找到"x_blockdimension"之外的下一个点.如果找不到任何内容,则将该条目设置为零.现在,由于要花费1800万点的大量时间(而且我不仅在一个方向上寻找东西),我正在寻找一种通过使用矢量化或逻辑索引来优化此方法的方法.如果有另一种方法可以改善运行时间,那么我将为您提供任何提示.

What I am trying with this code is finding the next point in my point cloud which is "x_blockdimension" away. If nothing can be found the entry is set to zero. Now as this takes a huge amount of time for 18 Million points (and I am not just looking in one direction) I am looking for a way to optimize this by either using vectorization or logical indexing. If there is another way to improve the runtime I would be happy for any tips.

我尝试过的事情

if isempty(find(BML(:,2)==BML(:,2)+x_blockdimension & BML(:,3)==BML(:,3), 1));
    NB_list(1,1)=0;
else
    NB_list(1,1)=find(BML(:,2)==(BML(:,2)+x_blockdimension)& BML(:,3)==BML(:,3));

end

但是它并没有真正按照我想要的去做.

But it is not really doing what I want it to do.

我希望有所帮助!

推荐答案

如果我正确理解了输入格式,则可以在

If I understood the format of inputs correctly, you can use broadcasting with bsxfun for a vectorized solution like so -

% Perform broadcasted comparison corresponding to the iterative comparison
% in original code to get a boolean array/mask. 
% Get the row, col indices for the mask, which will correspond to the index
% values and positions where those values are to be stored in the output. 
[R,C] = find(bsxfun(@eq,BML(:,2),BML(:,2).'+x_blockdimension) & ...
                                     bsxfun(@eq,BML(:,3),BML(:,3).'));

% Setup output array and store the indices at respcetive positions. 
NB_list_z_out = zeros(size(BML,1),numel(NB_list));
NB_list_z_out(C,1) = R;

请注意,似乎输出仅编辑输出数组中的第一列元素,因此在最后一步使用NB_list_z_out(C,1)进行索引.

Please note that it seemed that the output is only editing the first column elements in the output array and therefore indexing with NB_list_z_out(C,1) at the last step.

可以建议一种替代方法,着重于内存效率和附加性能,并获得RC,它们可以稍后使用,就像前面列出的方法中使用的那样.实现看起来像这样-

An alternative approach could be suggested with focus on memory efficiency and additionally performance too and get R and C, which could be used later on just like they were used in the approach listed earlier. The implementation would look something like this -

% Filter out with "bsxfun(@eq,BML(:,3),BML(:,3).'))".
[~,~,idx] = unique(BML(:,3),'stable');
vidx = find(ismember(idx,find(accumarray(idx(:),1)>1)));

% Filter out on remaining ones with valid indices (vidx)
[R1,C1] = find(bsxfun(@eq,BML(vidx,2),BML(vidx,2).'+x_blockdimension));
R = vidx(R1);
C = vidx(C1);

这篇关于带嵌套if子句的Vectorize循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆