带嵌套if子句的Vectorize循环 [英] Vectorize loop with nested if-clause
问题描述
问题
我正在尝试优化代码的运行时间,并在问了一个类似的问题之前,它包含了几个嵌套的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.
可以建议一种替代方法,着重于内存效率和附加性能,并获得R
和C
,它们可以稍后使用,就像前面列出的方法中使用的那样.实现看起来像这样-
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屋!