3

私は、飛行機がターゲットエリア上を飛行するときに何が見えるかを計算するためのプログラムに取り組んでいます。エリアを通過すると、多くのトラックの1つをたどることができ、通常のエリアサイズでは約100になります。飛行機がエリアの一部を見ることができるかどうかを確認するために大きなループを作成しましたが、非常に非効率的に実行されます。エリアをグリッド1001x1001として定義しました

xgridはx値を定義する変数1001x1です。

thelinesは変数2x1001 xトラックであり、最初の行は一番上の行に対応するx値のy値です。2行目は、一番下の行のy値です。

これらの2つの線の間には、表示領域があります。表示されている場合は、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プロファイラーを使用して、プログラムのボトルネックでこの点を特定しました。どんな助けでも大歓迎です。ありがとう、リッチ

4

1 に答える 1

7

何をしようとしているのか正確にはわかりませんが、最初のステップとして、内側のループを論理インデックスに置き換えることをお勧めします。

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

論理インデックスを使用すると、ネストされたループの約 100 万回の反復を 1 回の操作で置き換えることができます。

もう 1 つのヒントを次に示します。真/偽の値を格納するには、二重マトリックスの代わりに論理マトリックスを使用します。

>>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 分の 1 です。

速度テスト:これがどれほど大きな違いを生むのか興味がありました. 以下は簡単なテストです (実装の 1 つについてのみ簡単です)。内側のループをベクトル化すると、マシンの速度が約 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
于 2012-06-11T22:34:18.107 に答える