假设我们有两个长度分别为 100 和 80 的向量 A 和 B 作为时间的函数。如果我们希望在傅里叶域中执行两个向量的卷积,我们需要将 A 和 B 的傅里叶变换相乘。为此,B 的长度必须与 A 相同。输出将具有相同的长度作为零填充后的 A 或 B。
我们应该在 B 的哪里做零填充,应该在 B 的开头还是在 B 的结尾?
我在读到通过 FFT 实现的卷积本质上是一个循环卷积。如果我们的愿望是得到一个线性卷积,我们如何保证输出是一个线性卷积,即逆FFT后应该从两端拒绝多少个端点?
假设我们有两个长度分别为 100 和 80 的向量 A 和 B 作为时间的函数。如果我们希望在傅里叶域中执行两个向量的卷积,我们需要将 A 和 B 的傅里叶变换相乘。为此,B 的长度必须与 A 相同。输出将具有相同的长度作为零填充后的 A 或 B。
我们应该在 B 的哪里做零填充,应该在 B 的开头还是在 B 的结尾?
我在读到通过 FFT 实现的卷积本质上是一个循环卷积。如果我们的愿望是得到一个线性卷积,我们如何保证输出是一个线性卷积,即逆FFT后应该从两端拒绝多少个端点?
很多好的评论和一个很好的答案,但我仍然觉得 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 章,上述所有知识都成为可能。
这是我以视频形式给出的答案: YouTube 上的循环与线性卷积
和博客文章: TheWolfSound.com 上的循环与线性卷积