3

2つの1次元信号を畳み込む必要があります。1つは平均500ポイント(これはハニングウィンドウ関数です)、もう1つは125000です。1回の実行で、3回の畳み込み演算を適用する必要があります。私はすでにscipyのドキュメントに基づいて実行されている実装を持っています。必要に応じて、ここでコードを確認できます(Delphiコードを先に):

function Convolve(const signal_1, signal_2 : ExtArray) : ExtArray;
var
  capital_k : Integer;
  capital_m : Integer;
  smallest : Integer;
  y : ExtArray;
  n : Integer;
  k : Integer;
  lower, upper : Integer;
begin
  capital_k := Length(signal_1) + Length(signal_2) - 1;
  capital_m := Math.Max(Length(signal_1), Length(signal_2));
  smallest := Math.Min(Length(signal_1), Length(signal_2));
  SetLength(y, capital_k);
  for n := 0 to Length(y) - 1 do begin
    y[n] := 0;
    lower := Math.Max(n - capital_m, 0);
    upper := Math.Min(n, capital_k);
    for k := lower to upper do begin
      if (k >= Length(signal_1)) or (n - k >= Length(signal_2)) then
        Continue;
      y[n] := y[n] + signal_1[k] * signal_2[n - k];
    end;
  end;
  Result := Slice(y,
                  Floor(smallest / 2) - 1,
                  Floor(smallest / 2) - 1 + capital_m);
end;

問題は、この実装が遅すぎることです。全体の手順は約5分かかります。それを計算するより速い方法を見つけることができるかどうか疑問に思いました。

4

2 に答える 2

5

高速畳み込みは、FFTを使用して実行できます。(適切なゼロパディングを使用して)両方の入力信号のFFTを取得し、周波数領域で乗算してから、逆FFTを実行します。大きなN(通常はN> 100)の場合、これは直接法よりも高速です。

于 2011-05-18T09:57:25.747 に答える
5

そこには多くの高速畳み込みアルゴリズムがあります。それらのほとんどはFFTWなどのFFTルーチンを使用します。これは、(時間領域での)畳み込みのような操作が、周波数領域での(周波数領域表現の)乗算に還元されるためです。FFTルーチンを使用して畳み込みを実装すると、現在約5分かかる畳み込み操作(自分の見積もりによる)は、わずか数秒かかる場合があります。

また、フィルターの長さと信号の長さに大きな違いがある場合は、Overlap-SaveまたはOverlap-Addの使用を検討することもできます。詳細はこちら。Delphiでのコーディングが最優先の懸念事項ではない場合、FFTWおよびその他のライブラリがC / C++で利用できるという理由だけでC/ C ++を使用することをお勧めします(scipyまたはDelphiについてはわかりません)。

于 2011-05-18T10:21:47.797 に答える