Алгоритм быстрой свертки - PullRequest
3 голосов
/ 18 мая 2011

Мне нужно свернуть два одномерных сигнала, один имеет в среднем 500 точек (это оконная функция Хеннинга), другой 125000. За цикл мне нужно применить операцию свертки три раза. У меня уже есть реализация, основанная на документации 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;

Проблема в том, что эта реализация слишком медленная. Вся процедура занимает около пяти минут. Мне было интересно, смогу ли я найти более быстрый способ вычисления этого.

Ответы [ 2 ]

5 голосов
/ 18 мая 2011

Существует множество быстрых алгоритмов свертки.Большинство из них используют процедуры FFT, такие как FFTW .Это происходит потому, что операция, подобная свертке (во временной области), сводится к умножению (представлений в частотной области) в частотной области.Операция свертки, которая в настоящее время занимает около 5 минут (по вашим собственным оценкам), может занять всего несколько секунд после того, как вы реализуете свертку с подпрограммами FFT.

Также, если есть большая разница между длиной вашего фильтра и длиной вашего сигнала, вы также можете рассмотреть возможность использования Overlap-Save или Overlap-Add.Больше информации здесь .Если кодирование в Delphi не является первостепенной задачей, вы можете использовать C / C ++, хотя бы по той причине, что FFTW и некоторые другие библиотеки доступны в C / C ++ (не уверен насчет scipy или Delphi).

3 голосов
/ 18 мая 2011

Быстрая свертка может быть выполнена с использованием БПФ.Возьмите БПФ обоих входных сигналов (с соответствующим заполнением нулями), умножьте в частотной области, затем выполните обратное БПФ.Для больших N (обычно N> 100) это быстрее, чем прямой метод.

...