1

I = 6100x6300x72関数に適用される配列 があり、結果Icorにはゼロに置き換えたい負の値が含まれています。これはよくある質問ですが、私の場合、RAM の制約によりタスクが少し難しくなります。例を見てみましょう:

I=rand(6100,6300,72); %# example size of I
[x,y,z]=size(I); %# get the dimensions for later reshaping
I=reshape(I,x*y,z); %# reshape to columns
Icor=function(I) %# apply a function to I, result Icor
Icor(Icor < 0)=0; %# Icor has negatives which need removing
Icor=reshape(Icor,x,y,z); %# reshape back to same size as I (original size)

Icor(Icor < 0)=0;私の問題は、RAM が最大になる論理インデックス作成ステップにあります。これを回避する創造的な方法はありますか?(または、本当に明らかなことを見逃している場合はご容赦ください)。

4

2 に答える 2

3

vectorized最後の次元をループします。これは、論理インデックスを使用するのと同じくらい効率的です。最初の 2 つはメモリに連続して格納されるため、最後の次元をループする必要があります。そのため、このようなアクセスが最も効率的です。

% forgive my lack of memory ;)
I = rand(610,630,72)-0.5;
s = size(I);

% temporary variables for the test
I1 = reshape(I, [], s(3));
I2 = I1;

% method 1
tic;
I1(I1<0) = 0;
toc

% method 2
tic;
for i=1:s(3)
    I2(I2(:,i)<0,i) = 0;
end
toc

isequal(I1, I2)

Elapsed time is 0.321225 seconds.
Elapsed time is 0.282395 seconds.

ans =

 1

ご覧のとおり、ループは実際には高速であるため、双方にとってメリットのある状況です。

于 2012-12-05T15:24:11.290 に答える
0

メモリが不足し始めると、通常、メモリの使用量を元に戻すためにかなり大きな変更を加える必要があります。

ただし、マスク呼び出しに相当するループを具体的に見つけたい場合は、次のコードを試してください。

完全にベクトル化された呼び出し (現在のように)

Icor(Icor < 0)=0;

行ごとに相当 (2D マトリックスを想定)

for ix = 1:size(Icor,1)
    Icor(Icor(ix,1)<0,  1) = 0;
end

元素当量あたり

for ix = 1:numel(Icor)
    if iCor(ix) < 0
        iCor(ix) = 0;
    end
end
于 2012-12-05T15:16:40.607 に答える