Fast convolution algorithm

谁都会走 提交于 2019-12-01 05:38:39

问题


I need to convolve two one dimensional signals, one has on average 500 points (This one is a Hanning window function), the other 125000. Per run, I need to apply three times the convolution operation. I already have an implementation running based on the documentation of scipy. You can see the code here if you want to (Delphi code ahead):

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;

The problem is, this implementation is too slow. The whole procedure takes about five minutes. I was wondering if I can find a faster way of computing that.


回答1:


Fast convolution can be carried out using FFTs. Take the FFT of both input signals (with appropriate zero padding), multiply in the frequency domain, then do an inverse FFT. For large N (typically N > 100) this is faster than the direct method.




回答2:


There are a lot of fast convolution algorithms out there. Most of them use FFT routines such as FFTW. This is because an operation like convolution (in the time domain) reduces to multiplication (of the frequency domain representations) in the frequency domain. A convolution operation that currently takes about 5 minutes (by your own estimates) may take as little as a few seconds once you implement convolution with FFT routines.

Also, if there is a big difference between the length of your filter and the length of your signal, you may also want to consider using Overlap-Save or Overlap-Add. More information here. If coding in Delphi is not an overriding concern, you might want to use C/C++ if only for the reason that FFTW and some other libraries are available in C/C++ (not sure about scipy or Delphi).



来源:https://stackoverflow.com/questions/6042833/fast-convolution-algorithm

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!