fft 的点积

jer*_*buk 4 matlab fft convolution dft ifft

根据卷积定理,时域中的卷积是fft域中的乘积。通过正确的零填充,它可以工作:

% convolution in time domain
a = [1 2 3];
b = [4 5 6];
c = conv(a,b);

a_padded=[a 0 0]; b_padded=[b 0 0];
c_bis=ifft(fft(a_padded).*fft(b_padded));
% we do find c_bis=c
Run Code Online (Sandbox Code Playgroud)

然而,这个定理也应该以相反的方式工作,时域中的乘积是 fft 域中的卷积。我不明白这部分:

d = a.*b;
D=conv(fft(a_padded),fft(b_padded));
d_bis=ifft(D);
Run Code Online (Sandbox Code Playgroud)

这给出了 d_bis 的复向量。如何使用频域中的卷积来反转时域中的逐点乘积?

Lui*_*ndo 5

有趣的问题!

错误(尽管是一个微妙的错误)是当你说

时域中的乘积是 FFT 域中的卷积

傅立叶变换也是如此。对于离散傅立叶变换(DFT 或 FFT),正确的公式

时域中的乘积是FFT 域中的循环卷积除以序列长度

所以你必须在d_bis计算中改变这一点:

  • 使用循环卷积,而不是卷积;
  • 除以序列长度;
  • 不应用填充。

如果您有信号处理工具箱,则可以使用它cconv来计算循环卷积:

N = length(a);
D = cconv(fft(a),fft(b), N)/N;
d_bis=ifft(D); %// now this equals d
Run Code Online (Sandbox Code Playgroud)

为了确保,第一种情况的正确公式(时域卷积给出频域乘积)还涉及循环卷积:

时域中的循环卷积是FFT域中的乘积

(在这种情况下不除以序列长度)

但由于您在时域中填充了零,所以正常卷积和循环卷积之间的差异消失了,并且您得到了正确的结果。如果没有填充,它将是:

c = cconv(a, b, N);
c_bis=ifft(fft(a).*fft(b)); %// this equals c
Run Code Online (Sandbox Code Playgroud)