傅立叶变换是物理学家、数学家、工程师和计算机科学家常用的最有用的工具之一。本篇文章我们将使用Python来实现一个连续函数的傅立叶变换。
我们使用以下定义来表示傅立叶变换及其逆变换。
设 f: ℝ → ℂ 是一个既可积又可平方积分的复值函数。那么它的傅立叶变换,记为 f̂,是由以下复值函数给出:
同样地,对于一个复值函数 ĝ,我们定义其逆傅立叶变换(记为 g)为
这些积分进行数值计算是可行的,但通常是棘手的——特别是在更高维度上。所以必须采用某种离散化的方法。
在Numpy文档中关于傅立叶变换如下,实现这一点的关键是离散傅立叶变换(DFT):
根据Numpy文档,一个具有 n 个元素的序列 a₀, …, aₙ₋₁ 的 DFT 计算如下:
我们将积分分解为黎曼和。在 n 个不同且均匀间隔的点 xₘ = x₀ + m Δx 处对 x 进行采样,其中 m 的范围从 0 到 n-1,x₀ 是任意选择的最左侧点。然后就可以近似表示积分为
现在对变量 k 进行离散化,在 n 个均匀间隔的点 kₗ = l Δk 处对其进行采样。然后积分变为:
这使得我们可以用类似于 DFT 的形式来计算函数的傅立叶变换。这与DFT的计算形式非常相似,这让我们可以使用FFT算法来高效计算傅立叶变换的近似值。
最后一点是将Δx和Δk联系起来,以便指数项变为-2π I ml/n,这是Numpy的实现方法;
这就是不确定性原理,所以我们得到了最终的方程
我们可以对逆变换做同样的处理。在Numpy中,它被定义为
1/n是归一化因子:
概念和公式我们已经通过Numpy的文档进行了解了,下面开始我们自己的Python实现
我们来通过一些例子看看我们自己实现是否正确。
第一个例子:阶跃函数
函数在-1/2和1/2之间是1,在其他地方是0。它的傅里叶变换是
画出傅里叶变换,以及在k的采样值和整个连续体上计算的解析解:
看起来是没问题的,然后我们把它转换回来:
我们可以清楚地看到不连续边缘处的 Gibbs 现象——这是傅里叶变换的一个预期特征。
第二个例子:高斯PDF
傅里叶变换
下面,我们绘制数值傅里叶变换和解析值:
以及傅里叶逆变换与原函数的对比
可以看到,我们的实现没有任何问题
最后,如果你对机器学习的基础计算和算法比较感兴趣,可以多多关注Numpy和SK-learn的文档(还有scipy但是这个更复杂),这两个库不仅有很多方法的实现,还有这些方法的详细解释,这对于我们学习是非常有帮助的。
例如本文的一些数学的公式和概念就是来自于Numpy的文档,有兴趣的可以直接看看
https://numpy.org/doc/stable/reference/routines.fft.html