傅里叶域中的线性和圆形卷积 (DFT)

信息处理 离散信号 傅里叶变换 卷积 时频 反卷积
2022-02-14 16:41:35

假设我们有两个长度分别为 100 和 80 的向量 A 和 B 作为时间的函数。如果我们希望在傅里叶域中执行两个向量的卷积,我们需要将 A 和 B 的傅里叶变换相乘。为此,B 的长度必须与 A 相同。输出将具有相同的长度作为零填充后的 A 或 B。

  1. 我们应该在 B 的哪里做零填充,应该在 B 的开头还是在 B 的结尾?

  2. 我在读到通过 FFT 实现的卷积本质上是一个循环卷积。如果我们的愿望是得到一个线性卷积,我们如何保证输出是一个线性卷积,即逆FFT后应该从两端拒绝多少个端点?

3个回答

很多好的评论和一个很好的答案,但我仍然觉得 OP 的问题可能没有得到回答。

A是长度为100的序列,B是长度为80的序列。所以conv(A,B)线性卷积运算会产生一个 179 长度的序列。要记住的重要一点是,生成的序列长度为 179。

现在,来到这些序列的 DFT(记住 FFT 只是实现离散傅里叶变换,DFT 的众多方法之一,但我在这里互换使用这两个术语),DFT 假设基础序列是周期性的,因此 DFT 的乘积为 2序列是这两个序列的周期性卷积(又名循环卷积)。由于 A 和 B 有 2 个不同的长度,我们将取较大的长度作为 DFT 大小并将它们的 DFT 相乘。所以我们要做的是用 20 个零填充 B 以匹配 B 的长度。现在,我将在末尾添加零(稍后我会回答如果我们在开头添加会发生什么)。

所以现在我们有 2 100 点序列,其 DFT 及其逆 DFT 相乘得到一个 100 点序列,即 A 和 B 的循环卷积。请记住,线性卷积输出为 179 点。在这里,我们采用了 100 点逆 DFT。所以这将导致时域中的混叠。这就像制作 179 点序列的无限副本并以 100 的间隔重叠它们。178 处的样本(最后一个样本)将与 178-100 = 78 处的样本混叠。同样,100 处的样本将与 0 处的样本(100 -100 = 0)。所以在得到的 100 点序列中,前 79 点将是不正确的。只有 79 到 99 的样本是正确的。更不用说我们丢失的样本 100 到 178。

在此处输入图像描述 这就是为什么在其他答案中,我们采用了 179 点 FFT。这就是我们如何确保得到的循环卷积等效于线性卷积。这里两个序列都是 179 点,IFFT 之后的结果序列是 179 点。但大多数值在 357 点线性卷积中为零。只有前 179 个点(从 0 到 178 的样本)是非零的(其余的都是零,直到 356)。因此,179 处的样本将与 0 处的样本(179-179)重叠,但我们知道 179 处的样本为零,因此没有影响。因此,如果 FFT 长度大于或等于 179,我们是安全的。

回答第一个问题,如果我们一开始就加了零,这就像将序列延迟了 20 个样本。这将导致输出中的等效延迟(请记住,这些是 LTI 操作 - 因此输入中的延迟将导致输出中的等效延迟)。但是现在您的序列将是 100 点序列(不是 80 点,因为您在开头添加了零)。所以你需要相应地改变你的计算。

由于 Alan Oppenheim 的书(离散时间信号处理)中的第 8 章,上述所有知识都成为可能。

以下 matlab/octave 代码使用频域给出线性卷积结果:

A = ((-1).^[0:79]').*hamming(80);    % input one
B = blackman(100);   % input two

C1 = conv(A,B);     % A * B (convolution) in time domain
C2 = real( ifft( fft(A,179).*fft(B,179) ) ); % convolution using freq domain

输出将与长度 179 个样本相同:

在此处输入图像描述

这是我以视频形式给出的答案: YouTube 上的循环与线性卷积

和博客文章: TheWolfSound.com 上的循环与线性卷积