3

私はいくつかのmatlabコードを書いていて、機能するアルゴリズムを書いていますが、特に効率的だとは思いません。プログラミングスキルを向上させようとしているので、これを行うより効率的な方法があるかどうかを知りたい.

順序付けされていないが、範囲 [-100, 100] 内に収まる (かなり大きい ~ E07) 値のマトリックスがあります。次のルールを使用して、最初のマトリックスに基づいて 2 番目のマトリックスを作成します。

  1. ポイントの値が 70 を超える場合、ポイントの値を 70 に設定する必要があります。
  2. ポイントの値が -70 未満の場合、ポイントの値を -70 に設定する必要があります。
  3. 他のすべての値は、最も近い 5 の倍数に丸める必要があります。

これが私が現在行っていることです:

data = 100*(-1+2*rand(1,10000000)); % create random dataset for stackoverflow
new_data = zeros(1,length(data));

for i = 1:length(data)
    if (data(i) > 70)
        new_data(i) = 70;
    elseif (data(i) < -70)
        new_data(i) = -70;
    else
        new_data(i) = round(data(i)/5.0)*5.0;
    end
end

より効率的な方法はありますか?論理インデックスを使用してこれを行う方法があるはずだと思いますが、それらは私にとって新しい発見です...

4

3 に答える 3

8

ループはまったく必要ありません。

data = 100*(-1+2*rand(1,10000000)); % create random dataset for stackoverflow
new_data = zeros(1,length(data)); % note that this memory allocation is not necessary at this point

new_data = round(data/5.0)*5.0;
new_data(data>70) = 70;    
new_data(data<-70) = -70;
于 2012-10-11T13:37:33.397 に答える
5

さらに簡単なのは、maxとminを使用することです。1行でそれを行います。

new_data = round(5*max(-70,min(70,data)))/5;
于 2012-10-11T14:27:37.233 に答える
2

H.Muster と woodchips による 2 つの回答は、もちろんそれを行う方法ですが、まだ小さな改善点があります。パフォーマンスを求めている場合は、問題の詳細を利用することをお勧めします。たとえば、出力データは integers-100 <= x <= 100です。これは明らかに 8 ビットの符号付き整数データ型に適しています。int8このコード (任意の倍精度データからの明示的なキャストに注意してください)

% your double precision input data
data = 100*(-1+2*rand(1,10000000));

% cast to int8 - matlab does usual round here
data = int8(data);
new_data = 5*(max(-70,min(70,data))/5);

は次の 2 つの理由で最速です。

  • 1 つのデータ要素は 8 バイトではなく 1 バイトです。ここではメモリ帯域幅が制限要因であるため、多くの改善が得られます。
  • ラウンドはもう必要ありません

H.Muster、ウッドチップ、および私の小さな修正のコードからのいくつかのタイミングを次に示します。

H.Muster    Elapsed time is 0.235885 seconds.
woodchips   Elapsed time is 0.167659 seconds.
my code     Elapsed time is 0.023061 seconds.

違いはかなり顕著です。MATLAB はどこでも double を使用しますが、可能な場合は整数データ型を使用するようにしてください。

編集これは、matlab が整数演算を実装する方法のために機能します。C とは異なり、double から int へのキャストはround操作を意味します。

a = 0.1;
int8(a)

ans =
  0

a = 0.9;
int8(a)

ans =
  1
于 2012-10-11T16:36:26.873 に答える