使用 FFT 进行时域插值,最后填充零

信息处理 fft 自由度 插值
2022-02-04 07:21:24

我有一种情况,我想使用 FFT 对一些复杂的数据及时进行插值(无论如何我都需要进入频域来窗口化我的数据)。

这样做的概念性方法是采用 FFT,在类似 FFTW 的情况下,它将频率分量“有序”排列,这可以被视为首先具有正频率,然后是负频率。

F([abcdefgh])=[ABCDEFGH]

其中 ABCD 是正频率分量,EFGH 是负频率分量。

您可以将频率响应拆分为 D 和 E 之间的两个和零填充,但如果您的变换长度为奇数,并且可能拆分 nyquist 箱,则必须小心,从缓冲区杂耍的角度来看,它更麻烦也。如果我可以预先乘以 Fs/2 会更好,这将旋转频谱:

F(exp(j2πfs/2t)[abcdefgh])=[EFGHABCD]

然后它只是最后的零填充问题,然后回到时域。这可能就像转换为足够大的归零缓冲区一样简单。

但是,是回到时域让我绕着轴心。您当然可以进行反 FFT,然后乘以 -Fs/4 以将事情恢复到应有的方式,但如果可以的话,我宁愿避免后乘法(性能原因)。

我的直觉说,移位的频谱现在处于正确的顺序(再次在 FFTW 领域),只需对其进行前向 FFT,但这可能会时间反转数据,因此转换前的共轭可能是有序的,但是我不知道。谁能帮我解决这个问题?

2个回答

重要的是要记住,对于偶数 N,您同时拥有 F(0) 和 F(N/2) 点,它们都没有对应的点。因此,例如,当 N = 8 时,您有:

F(0), F(1), F(2), F(3), F(4), F(-3), F(-2), F(-1)

(有些人认为 N/2 点是负频率(即: F(-4) ),但我们会认为它是正的)

因此,要将 8 点 FFT 插值 2 倍,您可以使用以下方法进行 16 点逆 FFT:

F(0), F(1), F(2), F(3), F(4)/2, 0, 0, 0, 0, 0, 0, 0, F(4)/2, F( -3), F(-2), F(-1)

因此,您拆分正向 FFT 的 N/2 点,并在中心添加适当数量的零,然后进行逆运算。

现在,对于奇数 N,您没有 N/2 点(但您仍然有唯一的 0 点),并且拆分业务不会发生(但您仍然需要在中心添加适当的零)。

我建议您通过以下方式尝试 FFT/IFFT 方法: 一个真实的输入时域波形;复杂的输入时域波形;偶数和奇数 N;输入中的整数个周期;输入中的非整数周期数。然后将 FFT/IFFT 方法的结果与严格基于时域的插值生成的结果进行比较/对比(例如:将 A*cos(omega*t) 用于 FFT/IFFT 方法并与 A*cos(omega* t/2) 在时域中生成)。经验可以是启发性的。

至于你的乘法方法——我认为它不适用于偶数 N。除非你使用非常小的 FFT,否则 FFT/IFFT 时间可能会主导总运行时间(当然,你应该总是分析您的程序以确保)。

对于复值数据样本,这可能是一个棘手的问题。如果您有 MATLAB,该interpft()函数(其代码可使用edit interpft)显示如何进行插值。不过要小心,它假设您的数据是周期性的,就像 DFT/FFT 一样。