换个角度看:快速傅里叶变换算法(FFT)

如大家所熟悉的,傅里叶变换是一种广泛用于信号处理和图像处理的数学工具。它将一个信号分解成一组基本频率,这些频率以一定的振幅和相位出现。傅里叶变换的计算复杂度为 O(n^2) ,其中 n 是信号长度。这使得它在实际应用中往往不太实用。

快速傅里叶变换(FFT) 算法则是一种高效的计算傅里叶变换的方法。它的原理是利用分治策略将 DFT 的计算复杂度从 O(n^2) 降低到 O(nlogn) 。

下面是一个Python实现示例:

复制代码
import cmath

def fft(x):
    n = len(x)
    if n == 1:
        return x
    else:
        x_even = fft(x[::2])
        x_odd = fft(x[1::2])
        factor = [cmath.exp(-2j * cmath.pi * k / n) * x_odd[k] for k in range(n//2)]
        return [x_even[k] + factor[k] for k in range(n//2)] + [x_even[k] - factor

这个函数接受一个长度为 n 的复数数组 x 作为输入,并返回 x 的 DFT 向量。它使用递归算法将 x 分解为两个长度为 n/2 的信号 x_even 和 x_odd ,并分别计算它们的 DFT 。

然后,它将 x_even 和 x_odd 的 DFT 组合起来得到 x 的 DFT 向量。

接下来我们将进一步探讨 FFT 算法的原理。

FFT 算法基于分治策略。假设我们有一个长度为 n 的信号 x ,我们可以将其分解为两个长度为 n/2 的信号 x1 和 x2 。然后,我们可以使用递归算法计算 x1 和 x2 的 DFT(离散傅里叶变换),并将它们组合成 x 的 DFT 。

具体来说,假设我们有一个长度为 n 的信号 x ,其中 x(i) 表示第 i 个采样点的值。我们可以将 x 分解为两个长度为 n/2 的信号 x1 和 x2 ,其中:

x1(i) = x(2i-1)

x2(i) = x(2i)

然后,我们可以计算 x1 和 x2 的 DFT ,分别得到长度为 n/2 的 DFT 向量 X1 和 X2 。最后,我们可以将 X1 和 X2 组合成 x 的 DFT 向量 X ,其中:

X(k) = X1(k) + w(k)X2(k)

X(k + n/2) = X1(k) - w(k)X2(k)

其中,w(k) 是旋转因子,定义为:

w(k) = exp(-2πik/n)

FFT 算法的关键在于如何计算旋转因子。一种常见的方法是使用旋转因子的递归定义,如下所示:

w(k) = w(k+n/2)^2

这意味着我们可以使用递归算法计算旋转因子。在每个递归层次中,我们将旋转因子平方,并在下一层次中重复使用它。这使得我们只需计算O(nlogn) 个旋转因子,而不是 O(n^2) 个。