Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Performance 使用嵌套的if子句对循环进行矢量化_Performance_Matlab_Vectorization - Fatal编程技术网

Performance 使用嵌套的if子句对循环进行矢量化

Performance 使用嵌套的if子句对循环进行矢量化,performance,matlab,vectorization,Performance,Matlab,Vectorization,问题 我试图优化我的代码的运行时,之前我问过一个类似的问题,其中包括几个嵌套的if语句。 由于我在那里发布的希望实现一些想法的代码有点长,我仍然在努力实现嵌套循环的矢量化,我想用一些更简单的代码再次询问: 代码 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_

问题

我试图优化我的代码的运行时,之前我问过一个类似的问题,其中包括几个嵌套的if语句。

由于我在那里发布的希望实现一些想法的代码有点长,我仍然在努力实现嵌套循环的矢量化,我想用一些更简单的代码再次询问:

代码

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

代码说明

我用这段代码尝试的是在我的点云中找到下一个点,即“x_blockdimension”。如果找不到任何内容,则条目设置为零。现在,由于这需要花费1800万点的大量时间(我不只是朝一个方向看),我正在寻找一种方法,通过使用矢量化或逻辑索引来优化这一点。如果有其他方法可以改进运行时,我很乐意提供任何提示

我尝试的

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
但它并不是真的在做我想让它做的事情


我希望能得到一些帮助

如果我正确理解了输入的格式,您可以使用广播来实现这样的矢量化解决方案-

% 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\u z_out(C,1)
进行索引


可以建议另一种方法,重点关注内存效率和额外的性能,并获得
R
C
,这两种方法可以在以后使用,就像在前面列出的方法中使用一样。实现看起来像这样-

% 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);

如果您知道BML中的每一行只有0或1个匹配项,那么您可以对它们进行排序并使用diff,而不是使用循环:

%%  Find matches for x dimension

% sort on x dimension using sortrows, then split the matrix again
BMLx= sortrows(BML(:,[2:end,1]));
sorted_xx = BMLx(:,1:end-1);
idx = BMLx(:,end);

diff_ = diff(sorted_xx);
x_diff_match = find(diff_(:,1)==x_blockdimension & (diff_(:,2:end)==0));
% or you might want to use abs(a-b)<told

% assign all zeros as default
NB_list_x=zeros(length(BML),1);
% alocate matches
NB_list_x(idx(x_diff_match)) = idx(x_diff_match+1)
%%查找x维度的匹配项
%使用sortrows对x维进行排序,然后再次拆分矩阵
BMLx=sortrows(BML(:,[2:end,1]);
排序的_xx=BMLx(:,1:end-1);
idx=BMLx(:,结束);
diff_uux=diff(已排序的_xx);
x_diff_match=find(diff_(:,1)==x_blockdimension&(diff_(:,2:end)==0);

%或者你可能想用abs(a-b)谢谢你的回答。。。我尝试实现它,但出现以下错误:''error使用bsxfun时内存不足。为您的选项键入帮助记忆。测试(第3行)bsxfun(@eq,BML(:,3),BML(:,3)中出现错误;'@KiW您实际案例的
BML
大小是多少?@Divakar大约170 000x7,我想为一个具有50万x 7的simlar流程实现它,第一个案例我需要运行4次(在+x-x+y-y方向)@Divakar:如果有帮助,我知道只有一个(或没有)BML中填充+x_blockdimension条件的每个元素的值,我需要找到该元素的索引。我尝试使用您的实现,我编辑了带有该问题的问题。我不确定我是否100%理解了你的代码,所以我想知道是否有一种方法可以按照需要的方式使用它。不过还是非常感谢嘿,谢谢你的回答。我知道,对于x+x维,只有一个值具有相同的y值,总的来说,有更多的值可以满足条件。如果我看你的代码,它似乎不在公司,或者我只是太慢,看不到它?对不起,误解了这个问题。现在检查其他差异(other_dimensions==0)我尝试实现您的解决方案,这看起来是个好主意,特别是对于大数据集,但我只得到零作为邻居。老实说我不知道为什么。。。如果您有时间,我将数据集上传到这里:s000.tinyupload.com/?file_id=05161766586627414815。。。那么可能更容易看到结果。我猜你的意思是´(diff_uz(:,2)=0)´,否则矩阵维数不一致。但是如果你知道为什么结果是零,我会很高兴的:/谢谢你的帮助!如果你有一个解决方案,我会非常高兴,因为你的方式似乎快了很多,我只是无法解决问题…嗨,KiW,我只是快速查看了你的tinyupload文件。问题可能是tinyupload文件的第一列包含大整数,而您的文章中的示例有1:end。如果这些是其他索引numebr,用1:length(BML)替换它们是否有效?否则,如果第一列实际上是x值,则在第一列之前的1:n向量上进行cat。