matlab - 简化 for 循环(matlab)

标签 matlab loops for-loop vectorization

我正在开发一个程序来计算飞机飞过目标区域时可以看到什么。当它越过该区域时,它可以遵循许多轨道之一,正常区域大小约为 100。我创建了一个大循环来查看飞机是否可以看到该区域的部分区域,但它的运行效率非常低。我已将区域定义为网格 1001x1001

xgrid 定义 x 值的变量 1001x1。

thelines 是一个 2 x 1001 x 轨道的变量,其中第一行是顶行对应 x 值处的 y 值。第二行是底线的 y 值。

这两条线之间是可见区域。如果可以看到,则将 seenarea(1001x1001) 上的点标记为 1。如果看不到,则标记为 0。

for M=1:tracks
    for f=1:1001
        for i=1:1001
            if xgrid(f,1)>thelines(i,1,M) && xgrid(f,1)<thelines(i,2,M);
                seenarea(f,i,M)=1; % This indicated the area has been seen
            else
                seenarea(f,i,M)=0; % This is not seen
            end
        end
    end
    fullbestinfo(1,M)={seenarea(:,:,M)}; % This stores the seen area in another cell
    if max(seenarea(:,:,M)) < 1 % No area seen, stop
        seenarea(:,:,M)=[];
        break
    end
end

我已经使用 matlab 探查器在我的程序的瓶颈处确定了这一点。任何帮助将非常感激。 谢谢,里奇

最佳答案

我不太清楚您要做什么,但我建议首先用逻辑索引替换内部循环。

seenarea = false(1001, 1001, tracks); #% preallocate matrix to 'false'
xgrid = repmat(1:1001, 1001, 1); #%same size as the first 2D of seenarea

for M=1:tracks
    border1 = thelines(:,ones(1,1001),M); #% same size as xgrid
    border2 = thelines(:,ones(1,1001)*2,M); #% same size as xgrid
    idx = xgrid > border1 & xgrid < border2; #% idx is a "logical index" 
             #%           ^--- single ampersand
    seenarea(idx,M)=true; 
end

使用逻辑索引,您可以用单个操作替换嵌套循环的数百万次迭代。

这里有另一个提示:使用逻辑矩阵而不是 double 矩阵来存储真/假值。

>>m1 = zeros(1001,1001,100);
>> m2 = false(1001,1001,100);
>> whos m1
  Name         Size                      Bytes  Class     Attributes

  m1        1001x1001x100            801600800  double              

>> whos m2
  Name         Size                      Bytes  Class      Attributes

  m2        1001x1001x100            100200100  logical 

如您所见,逻辑矩阵的内存使用量降低了 8 倍。

速度测试:我很好奇这会有多大的不同。下面是一个快速测试(好吧,只对其中一个实现快速)。向量化内部循环使我机器上的速度大约75 倍提高,将 10 条轨道的时间从 7 秒以上减少到大约 0.1 秒。

tic;
for rep=1:100
    for M=1:tracks
        for f=1:1001
            for i=1:1001
                if xgrid(f,1)>thelines(i,1,M) && xgrid(f,1)<thelines(i,2,M);
                    seenarea(f,i,M)=1; 
                else
                    seenarea(f,i,M)=0; 
                end
            end
        end
    end
end
disp(toc/100)
    7.3459

tic;
for rep=1:100
    for M=1:tracks
        border1 = thelines(:,ones(1,1001),M); 
        border2 = thelines(:,ones(1,1001)*2,M); 
        idx = xgrid > border1 & xgrid < border2;                     
        seenarea(idx,M)=true; 
    end
end
disp(toc/100)
    0.0964

>> 7.3459/.0964    
ans =    
   76.2023

关于matlab - 简化 for 循环(matlab),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10988122/

相关文章:

matlab - 将中间级别插入嵌套结构数组

matlab - 从乳腺 X 光筛查数字数据库 (DDSM) 获取数据

linux - 可能 "loop"和 "output"在我的 bash 脚本中无法正常工作

php - 如何在循环中输出 WordPress 帖子上的术语的永久链接?

java - 使用struts 1.3在一个表单中进行多次提交

matlab - 如何在 MATLAB 中实现分段函数,然后按特定间隔绘制它

matlab - 在字符串中添加撇号 - Matlab

ios - Swift for 循环不起作用

javascript - 如何恢复简单的 JavaScript 循环?

java - 将范围内的所有质数添加到数组中