matlab - 带 fft 的点积

标签 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

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

d = a.*b;
D=conv(fft(a_padded),fft(b_padded));
d_bis=ifft(D);

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

最佳答案

有趣的问题!

错误(虽然是一个微妙的错误)是当你说

A product in the time domain is a convolution in the FFT domain

傅里叶变换也是如此。用Discrete Fourier transforms (DFT,或 FFT),correct formulation

A product in the time domain is a circular convolution in the FFT domain, divided by the sequence length

所以你必须在你的d_bis 计算中改变这个:

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

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

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

为了确保,correct formulation在第一种情况下(时域卷积给出频域乘积)还涉及循环卷积:

A circular convolution in the time domain is a product in the FFT domain

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

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

c = cconv(a, b, N);
c_bis=ifft(fft(a).*fft(b)); %// this equals c

关于matlab - 带 fft 的点积,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21865918/

相关文章:

matlab - 调试时如何使用曲线拟合工具?

fft - STFT 澄清(实时输入的 FFT)

c++ - 二维卷积 - 与 opencv 输出相比的错误结果

python - 沿着 3D NumPy 数组的后 2 个维度移动窗口以获得 3D block

MATLAB FFT -> 均衡器 -> iFFT

python - 线性分离高斯滤波器并使用 Numpy 进行计算

Matlab - 更好地理解 FFT 并找到 Pitch

matlab - Mat循环的for循环矢量处理RGB图像中的像素

matlab - matlab的opencv模块无法正常工作

python - 如何在脉冲信号上使用 Numpy.FFT