【问题标题】:"extended" IFFT“扩展”IFFT
【发布时间】:2013-02-19 09:08:57
【问题描述】:

如果我有一个波形x 比如

x = [math.sin(W*t + Ph) for t in range(16)]

用任意的WPh,我计算它的(Real) FFT f

f = numpy.fft.rfft(x)

我可以得到原始的x

numpy.fft.irfft(f)

现在,如果我需要将恢复波形的范围向左和向右扩展多个样本,该怎么办? IE。波形y 使得len(y) == 48y[16:32] == xy[0:16], y[32:48] 是原始波形的周期性扩展。

换句话说,如果 FFT 假设它的输入是一个无限函数 f(t)t = 0, 1, ... N-1 上采样,如何恢复 f(t)t<0t>=N 的值?强>

注意:我以完美的正弦波为例,但实际上x 可以是任何信号:任意信号,例如x = range(16)x = np.random.rand(16),或任意长度的段取自一个随机的.wav 文件。

【问题讨论】:

标签: python numpy signal-processing fft ifft


【解决方案1】:

以下示例应该可以让您很好地了解如何去做:

>>> x1 = np.random.rand(4)
>>> x2 = np.concatenate((x1, x1))
>>> x3 = np.concatenate((x1, x1, x1))
>>> np.fft.rfft(x1)
array([ 2.30410617+0.j        , -0.89574460-0.26838271j, -0.26468792+0.j        ])
>>> np.fft.rfft(x2)
array([ 4.60821233+0.j        ,  0.00000000+0.j        ,
       -1.79148921-0.53676542j,  0.00000000+0.j        , -0.52937585+0.j        ])
>>> np.fft.rfft(x3)
array([ 6.91231850+0.j        ,  0.00000000+0.j        ,
        0.00000000+0.j        , -2.68723381-0.80514813j,
        0.00000000+0.j        ,  0.00000000+0.j        , -0.79406377+0.j        ])

当然,获得三个周期的最简单方法是在时域中连接 3 个逆 FFT 副本:

np.concatenate((np.fft.irfft(f),) * 3)

但如果您想或必须在频域中这样做,您可以执行以下操作:

>>> a = np.arange(4)
>>> f = np.fft.rfft(a)
>>> n = 3
>>> ext_f = np.zeros(((len(f) - 1) * n + 1,), dtype=f.dtype)
>>> ext_f[::n] = f * n
>>> np.fft.irfft(ext_f)
array([ 0.,  1.,  2.,  3.,  0.,  1.,  2.,  3.,  0.,  1.,  2.,  3.])

【讨论】:

  • 谢谢。如果原始波形没有相位对齐,这个解决方案是否仍然有效?比如说,x = [math.sin(W*i + Ph) for i in range(16)] 与任意 WPh。时域连接当然不会。
  • x = range(16)x = np.random.rand(16) 等任意波形呢?
  • @MartinBlech 我认为sellibitze 的回答涵盖了您在此评论中提出的新问题。 FFT 非常适合周期性函数,但如果您想将其输入 [0, 1, 2, 3] 并返回 [-4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7],那么您将不得不寻找其他地方。您需要做的第一件事是以明确的方式定义您的问题。 FFT 通过连接原始数据来进行周期性扩展,这是一种非常合理的方法。如果这不是您想要的,您究竟希望它如何完成?
  • 由于我自己的无知,我无法正确地提出我的问题。从sellibitze 的回答看来,线性预测器是我一直在寻找但不知道名称的东西。
【解决方案2】:

现在,如果我需要将恢复波形的范围向左和向右扩展多个样本,该怎么办? IE。波形 y 使得 len(y) == 48, y[16:32] == x 和 y[0:16], y[32:48] 是原始波形的周期性扩展。

periodic 扩展也只是 x,因为它是 periodic 扩展。

换句话说,如果 FFT 假设其输入是在 t = 0, 1, ... N-1 上采样的无限函数 f(t),我如何恢复 t 的 f(t) 值=N?

“N 点 FFT 假设”您的信号是周期性的,周期为 N。这是因为您的模块分解成的所有谐波基函数都是周期性的,就像前 N 个和随后的 N 个样本只是一个主要 N 个样本的副本。

如果您允许 W 的任何值,您的输入正弦曲线将不是周期性的,周期为 N。但这并不能阻止 FFT 函数将其分解为许多周期性正弦曲线的总和。并且周期为N的周期正弦波之和也将具有周期N。

显然,您必须重新考虑问题。

也许您可以利用线性预测。根据片段的加窗自相关和 Levinson-Durbin 递归计算几个线性预测系数,并使用这些预测系数进行外推。然而,对于一个稳定的预测滤波器,预测会收敛到零,收敛速度取决于你有什么样的信号。例如,白噪声的完美线性预测系数全为零。在这种情况下,您将向左侧和右侧“外推”零。但是您对此无能为力。如果您有白噪声,那么您的片段中就没有关于周围样本的信息,因为所有样本都是独立的(这就是白噪声的意义所在)。

这种线性预测实际上能够完美地预测正弦样本。因此,如果您的输入是任意 W 和 p 的 sin(W*t+p),则您只需要二阶线性预测。对于更复杂的信号,我建议使用 10 或 16 的顺序。

【讨论】:

  • 看起来线性预测器是我一直在寻找的东西。我的问题没有明确表述,我的无知使我误以为 FFT 是这项工作的工具,但是您以某种方式阅读了所有这些噪音并发现了我的问题。谢谢!
【解决方案3】:

对于在 FFT 孔径或长度上呈周期性的固定波形,您可以只循环重复该波形,或 IFFT(FFT()) 重新合成等效波形,以在时域中扩展它们。对于从 FFT 孔径或长度中非周期性的源在时间上分离的波形,FFT 结果将是与 Sinc 函数卷积的频谱。因此,将需要某种等效于去卷积的方法来恢复原始的非窗口光谱内容。由于这种反卷积是困难的或不可能的,因此最常见的是使用分析/重新合成方法来代替,例如相位声码器过程或其他频率估计器。然后,那些可能与单个原始 FFT 结果的 bin 中的频率不同的估计频率可以馈送到一组正弦合成器、相位修改 IFFT 的混合或其他重新合成方法,以创建更长的光谱内容大致相同的波形。

【讨论】:

    猜你喜欢
    • 2018-03-15
    • 2013-01-15
    • 1970-01-01
    • 2019-02-25
    • 2020-09-10
    • 2014-09-23
    • 2013-07-02
    • 2020-12-11
    • 1970-01-01
    相关资源
    最近更新 更多