3

行間および列間で単調に増加する数値を含むMATLABで大きな行列にインデックスを付けようとしています。つまり、行列が呼び出されたA場合(i,j)、、、A(i+1,j) > A(i,j)およびA(i,j+1) > A(i,j)

乱数を作成しnて行列Aの値と比較し、その乱数を行列Aのどこに配置するかを確認する必要があります。つまり、nの値は行列の内容のいずれとも等しくない可能性があります。 、ただし、任意の2行と任意の2列の間にある可能性があり、Aでの位置を識別する「ビン」を決定します。この位置を見つけたら、Aと同じサイズの新しいマトリックスで対応するインデックスをインクリメントします。 。

問題は、これを1,000,000回やりたいということです。乱数を100万回作成し、これらの各数値のインデックスチェックを行う必要があります。これは、画面に着地したポイントから来る100万個のフォトンのモンテカルロシミュレーションです。行列Aは球面座標の角度で構成され、乱数は各入射光子の立体角です。

これまでの私のコードは次のようになります(詳細は重要ではないため、ここにコピーして貼り付けていません)。

for k = 1:1000000  
    n = rand(1,1)*pi;  
    for i = length(A(:,1))  
        for j = length(A(1,:))  
            if (n > A(i-1,j)) && (n < A(i+1,j)) && (n > A(i,j-1)) && (n < A(i,j+1))  

                new_img(i,j) = new_img(i,j) + 1;   % new_img defined previously as zeros

            end
        end
    end
end

「if」ステートメントは、nの境界を形成するAのインデックスを見つけるためにチェックしているだけです。

これは完全に正常に機能しますが、特に私のマトリックスAが11856 x 11000のサイズの画像であるため、途方もなく長い時間がかかります。これを行うためのより速く/賢く/より簡単な方法はありますか?

前もって感謝します。

4

3 に答える 3

2

のすべての要素に対して一度に計算を実行することにより、内部ループを取り除くことができますA。また、一度に1つずつではなく、一度に乱数を作成することもできます。の最も外側のピクセルがnew_imgゼロと異なることは決してないことに注意してください。

randomNumbers = rand(1,1000000)*pi;
new_img = zeros(size(A));
tmp_img = zeros(size(A)-2);

for r = randomNumbers
    tmp_img = tmp_img + A(:,1:end-2)<r & A(:,3:end)>r & A(1:end-1,:)<r & A(3:end,:)>r;
end

new_img(2:end-1,2:end-1) = tmp_img;

/ aside:配列が小さければbsxfun、比較に使用しましたが、OPの配列サイズを使用すると、アプローチのメモリが不足します。

于 2012-12-31T16:32:48.393 に答える
2

Aビンのエッジの値はありますか?つまりA、グリッドを指定しますか?この場合、を使用してAにすばやくデータを入力できますhist3

次に例を示します。numRand=1en = randi(100,1e6,1); nMatrix = [floor(data./10)、mod(data、10)];

edges = {0:1:9, 0:10:99};

A = hist3(dataMat, edges);

Aグリッドを指定しない場合は、すべてのランダム値を一度作成して並べ替える必要があります。次に、それらの値を繰り返し処理します。

n(i) >= n(i-1)小さすぎるビンをチェックする必要がないことを知っているからですn(i-1)。これは、ほとんどの冗長なチェックを最適化するための非常に簡単な方法です。

于 2012-12-31T16:41:45.530 に答える
1

これは、内側のループで大いに役立つはずのスニペットです。これは、よりも小さい最大のポイントの場所を見つけますvalue

idx1 = A<value
idx2 = A(idx1) == max(A(idx1))

正確な場所を見つけたい場合は、で囲むことができますfind

于 2012-12-31T16:36:12.267 に答える