快速傅里叶变换学习笔记

Part 0 复数的指数函数

0.1 指数函数的定义

这是一个普通的指数函数

\[f(x) = a^x,x\in \mathbb R \]

现在我们要把它的定义域扩展

\[f(x) = a^x,x\in\mathbb C \]

第一步,我们知道所有这样的指数函数都可以写成这样:

\[f(x) = a^x = e^{x\ln a} \]

又因为 \(e^{a+bi} = e^a\times e^{bi}\)
所以如果我们想计算复指数函数的话,我们只需要先定义出 \(e^{ki}\) 这样的函数就可以了。

怎么定义呢?我们翻开高等数学,发现里面提到了这个东西

\[e^x = \lim_{n\to +\infty} \left( 1+\frac{x}{n} \right)^n \]

把这里的实数 \(x\) 换成虚数 \(ki\) 就完美定义了复指数函数

\[e^{ki} = \lim_{n\to +\infty} \left( 1+\frac{ki}{n} \right)^n \]

接下来我们从得数的模长和辅角入手,将这个式子化简。

0.2 欧拉公式

首先是模长,我们知道复数相乘就是“模长相乘辐角相加”。 \(n\) 个复数相乘就会有 \(n\) 个模长相乘,所以模长可以拿到乘方里面。

\[\begin{align*} |e^{ki}| &= \left| \lim_{n\to +\infty} \left( 1+\frac{ki}{n} \right)^n \right|\\ &= \lim_{n\to +\infty} \left|\left( 1+\frac{ki}{n} \right) \right|^n \\ &= \lim_{n\to +\infty} \left(\sqrt{1+\left( \frac{k}{n} \right)^2}\right)^n \\ &= \lim_{n\to +\infty} \left( 1 + \frac{k^2}{n^2} \right)^{\frac{1}{2}n} \\ \end{align*} \]

接下来令新的 \(n\) 为原来的 \(\frac{1}{2}n\) ,代换后得到

\[\begin{align*} |e^{ki}| &= \lim_{n\to +\infty} \left( 1 + \frac{k^2}{4n^2} \right)^{n} \\ &= \lim_{n\to +\infty} \left( 1 + \frac{\frac{k^2}{4}}{n^2} \right)^{n} \\ \end{align*} \]

然后令 \(N=n^2\) ,代换

\[\begin{align*} |e^{ki}| &= \lim_{N\to +\infty} \left( 1 + \frac{\frac{k^2}{4}}{N} \right)^{\frac{N}{\sqrt{N}}}\\ &= \lim_{N\to +\infty} \left( \left( 1 + \frac{\frac{k^2}{4}}{N} \right)^N\right)^{\frac{1}{\sqrt{N}}} \\ \end{align*} \]

观察到,最外层指数位置和底数位置上的两个极限各自分别都是收敛的,我们可以拆开来计算

\[\begin{align*} |e^{ki}| &= \lim_{N\to +\infty} \left( \left( 1 + \frac{\frac{k^2}{4}}{N} \right)^N\right)^{\frac{1}{\sqrt{N}}} \\ &= \left( \lim_{N\to +\infty} \left( 1 + \frac{\frac{k^2}{4}}{N} \right)^N\right)^{\lim_{N\to +\infty}\frac{1}{\sqrt{N}}} \\ &= (e^{\frac{k^2}{4}})^0 \\ &= \textcolor{red}{1} \end{align*} \]

没错! \(e^{ki}\) 的模长为 \(1\) 。接下来轮到辐角了。

\(n\) 个复数相乘,对应地,就是 \(n\) 个辐角相加。

\[\begin{align*} \arg e^{ki} &= \arg \lim_{n\to +\infty} \left( 1+\frac{ki}{n} \right)^n\\ &=\lim_{n\to +\infty}n\times \arg \left( 1+\frac{ki}{n} \right) \\ &=\lim_{n\to +\infty}n\times \arctan \frac{k}{n} \\ \end{align*} \]

\(n\) 取倒数

\[\begin{align*} \arg e^{ki} &=\lim_{n\to 0^+}\frac{1}{n}\times \arctan nk \\ \end{align*} \]

根据基础的微积分知识,我们知道 \(\arctan kx\)\(x\to 0\) 时的等价无穷小是 \(kx\) ,所以

\[\begin{align*} \arg e^{ki} &=\lim_{n\to 0^+}\frac{1}{n}\times nk \\ &=\lim_{n\to 0^+}k \\ &= \textcolor{red}{k} \end{align*} \]

即, \(e^{ki}\) 的辐角为 \(k\) .

于是,我们得到了这么一个结论:

\[\begin{gather*} |e^{ki}| = 1\\ \arg e^{ki} = k \end{gather*} \]

接下来我们把它转回直角坐标表示

\[\begin{gather*} \Re(e^{ki}) = 1 \times \cos k \\ \Im(e^{ki}) = i \times \sin k \\ e^{ki} = \cos k + i\sin k \end{gather*} \]

给指数加上实部,就是著名的欧拉公式

\[e^{a+bi} = e^{a}(\cos b + i\sin b) \]

0.3 转圈圈

考虑这个函数

\[f(x) = e^{ix} \]

根据刚刚导出的欧拉公式,无论自变量 \(x\) 怎样增加,函数值的模长都为 \(1\) ,但函数值的辐角始终为 \(x\) . 而用几何的语言来说,就是【角度变化的同时,半径保持一致】。这也意味着,函数 \(f(x) = e^{ix}\) 的函数值永远位于复平面的单位圆上。

更进一步,如果把函数值视作复平面中的点,那么随着 \(x\) 的不断增大,它将从实轴正半轴开始,沿复平面的单位圆顺时针旋转。并且转过的弧度正好是自变量 \(x\) .

指数函数在复数域中变成了周期函数

举个例子,如果 \(x=\pi\) ,那么这个点正好转过半圈,也就是从实轴的正半轴转到负半轴。写出来就是

\[e^{i\pi} = -1 \]

相信这个东西大家都见过

再举个例子,我们令 \(\alpha = e^{\frac{i\pi}{3}}\) ,可以看出 \(\alpha\) 是一个旋转了 \(\frac{1}{6}\) 圈的单位向量。

如果随便挑一个复数 \(z\) ,并把它和 \(\alpha\) 相乘,会得到什么呢?

根据模长相乘辐角相加准则,不难看出,这个相乘的操作相当于把复平面上的 \(z\) 点绕着原点旋转 \(\frac{\pi}{6}\) 的弧度。

然后,我们开拓一下思路,不断把 \(\alpha\) 乘到复平面中的“单位向量”\(1+0i\) 上。显然每乘一次,这个单位向量就会绕原点旋转 \(120^{\circ}\) ,连续三次之后就会转回到原始位置 \(1+0i\) .

用公式表达出来,是这样的

\[\alpha^3 = 1 \]

没错,我们刚刚求出了方程 \(x^3 = 1\) 除了 \(x=1\) 的另一个根!

单位根

我们把方程 \(x^n=1\) 的解称作“\(n\)次单位根”,刚才的 \(\alpha\) 是一个 \(3\) 次单位根。

稍加思索,形如

\[\begin{align*} e^{i\frac{2\pi}{N}} \end{align*} \]

的值都会在 \(N\) 次方时变为 \(1\) ,他们也就都是 \(N\) 次单位根。

不过需要注意的是, \(N\) 次单位根不止有 \(1\)\(e^{i\frac{2\pi}{N}}\) 两个,实际上任何形如

\[\begin{align*} e^{ i\textcolor{red}{k}\frac{2\pi}{N} }\quad (k\in N^+) \end{align*} \]

的值都是 \(N\) 次单位根(因为对于任何正整数 \(k\) 都有, \(e^{2k\pi} = 1\))。

这些单位根中 \(k=1\) 的那个叫做 \(N\)本原单位根,记作 \(\omega_N\) .

于是,方程 \(x^N = 1\) 的所有解就可以表示为 \(N\) 次本原单位根 \(\omega_N\)\(0\)\(N\) 次方。( \(\omega_N^0=1\)

\[\left\{ 1,\omega_N,\omega_N^2,\cdots \omega_{N}^{N-1} \right\} \]

简而言之,\(N\) 次单位根就是从 \(1+0i\) 开始,把单位圆周平均分成 \(N\) 段的 \(N\) 个点。

由于单位根特殊的周期性,它具有如下的几个性质:

\[\begin{gather*} \omega^{x+y}_{y} = \omega_{y}^{x}\\ \omega^{x}_{y} = \omega^{kx}_{ky}\\ \omega^{x+y}_{2y} = -\omega^{x}_{2y} \end{gather*} \]

第一条:一个单位根旋转一整圈之后还是他自己

第二条:【一次走一步,每步走 \(k\) 米】和【一次迈 \(k\) 步,每步走一米】是等价的

第三条:一个单位根转过半圈相当于取他的相反数

Part 1 傅里叶变换

用不到的 傅里叶变换(FT)

傅里叶变换是对某一个连续函数(信号)进行的一种变换,可以表示某个频率的正弦/余弦波形在原信号中“占据”的“比重”。

傅里叶变换及其逆变换一般写作下面的形式:

\[\begin{align*} F(\omega) &= \int_{-\infty}^{+\infty} {f(x) e^{ -i\omega x } }\,\text d x \\ f(x) &= \frac{1}{2\pi} \int_{-\infty}^{+\infty} {F(\omega) e^{ i\omega x } }\,\text d \omega \\ \end{align*} \]

注意这其中 \(F(x)\) 的函数值是复数。

关于这个东西的更多细节,可以去看看 3Blue1Brown 的视频。

离散傅里叶变换(DFT)

在OI中,用到的一般是傅里叶变换的离散版本

\[\begin{align*} &F(k) = \sum_{x=0}^{N-1}{ f(x)\, e^{(-i\frac{2\pi}{N}k)\times x} }\\ &f(n) = \frac{1}{N} \sum_{k=0}^{N-1}{ f(x)\, e^{(i\frac{2\pi}{N}k)\times n} } \end{align*} \]

OI中最常见的写法会将上下两式的正负号颠倒一下,变成这样

\[\begin{align*} &F(k) = \sum_{x=0}^{N-1}{ f(x)\, e^{(i\frac{2\pi}{N}k)\times x} }\\ &f(n) = \frac{1}{N} \sum_{k=0}^{N-1}{ f(x)\, e^{(-i\frac{2\pi}{N}k)\times n} } \end{align*} \]

我也不知道为什么要这么做,但是大家都是这么写的

接下来简单介绍一下一下离散傅里叶逆变换的公式的来历。因为傅里叶变换是一个线性变换,所以它可以写成矩阵的形式,如下:

\[\begin{bmatrix} z^{0\times 0} & z^{0\times 1} & z^{0\times 2} &\cdots & z^{0\times N-2} & z^{0\times N-1}\\ z^{1\times 0} & z^{1\times 1} & z^{1\times 2} &\cdots & z^{1\times N-2} & z^{1\times N-1}\\ z^{2\times 0} & z^{2\times 1} & z^{2\times 2} &\cdots & z^{2\times N-2} & z^{2\times N-1}\\ \vdots &\vdots &\vdots &\vdots & \vdots &\vdots \\ z^{(N-1)\times0} & z^{(N-1)\times1} & z^{(N-1)\times2} & \cdots & z^{(N-1)\times(N-2)} & z^{(N-1)\times(N-1)} & \end{bmatrix}\\ \times \begin{bmatrix} f(0)\\f(1)\\f(2)\\\vdots\\f(N-1) \end{bmatrix} = \begin{bmatrix} F(0)\\F(1)\\F(2)\\\vdots\\F(N-1) \end{bmatrix} \]

为了方便起见,上式中的 \(z = e^{i\frac{2\pi}{N}}\) ,指数位置的第一个参数为 \(k\) ,第二个参数为 \(n\) .

现在只需要求出它的逆矩阵就能得到逆变换的公式了!根据基础的线性代数知识,这是一个范德蒙德矩阵,它的逆阵就是它的每一个位置取倒数并乘上 \(\frac{1}{N}\) .

似乎完全没有解释清楚呢

不过这部分不重要

快速傅里叶变换(FFT)

终于到重头戏了!我们观察一下 DFT 的式子,会发现强行计算他会用掉我们 \(O(N^2)\) 级别的时间,因此我们要寻找方法快速计算他。

首先对比一下 \(F(x)\)\(F(x+\frac{N}{2})\) 的计算式(暂且假设 \(N\) 为偶数)

\[\begin{align*} F(x) &= \sum_{n = 0}^{N-1}{ f(n)\,e^{(i\frac{2\pi}{N}x)\times n} }\\ F(x+\frac{N}{2}) &= \sum_{n = 0}^{N-1}{ f(n)\,e^{(i\frac{2\pi}{N}(x+N/2))\times n} } \end{align*} \]

然后,注意到式子里面的

\[\begin{gather*} e^{i\frac{2\pi}{N}} \end{gather*} \]

正好就是在 Part 0 中提到的 \(N\) 次单位根,利用这一点我们可以给式子换一个写法

\[\begin{align*} F(x) &= \sum_{n = 0}^{N-1}{ f(n)\times \left(\omega_{N}^{x}\right)^{n} }\\ F(x+\frac{N}{2}) &= \sum_{n = 0}^{N-1}{ f(n)\times \left(\omega_{N}^{x+N/2}\right)^{n} } \end{align*} \]

利用单位根的性质3,做出如下变换:

\[\begin{align*} F(x) &= \sum_{n = 0}^{N-1}{ f(n)\times \left(\omega_{N}^{x}\right)^{n} }\\ F(x+\frac{N}{2}) &= \sum_{n = 0}^{N-1}{ f(n)\times \left(-\omega_{N}^{x}\right)^{n} } \end{align*} \]

现在可以看出,这两个

此处施工中

Part 2 卷积

用不到的 普通卷积

卷积是对两个函数进行的一种运算,可以得到另一个函数,定义如下:

\[[f*g] (t)= \int_{-\infty}^{+\infty}f(x)g(t - x) \,\text dx \]

当然在 OI 中我们用到的一般是卷积的离散版本

离散卷积

只需要把上面式子中的 \(\int\) 改成 \(\sum\) .

\[[f*g] (t) = \sum_{k=0}^{N} f(k)g(t - k) \]

我们可以把它改成另一种形式

\[[f*g] (t) = \sum_{i+j=t}f(i)g(j) \]

其中 \(0 \leq i,j\leq N\) .

此处施工中

Part 3 数论变换

原根与单位根的对称性

我们知道如果模数为一个质数 \(p\) ,那么此模意义下总是存在一个原根 \(g\)

此处施工中

posted @ 2023-02-15 15:03  HMSF  阅读(190)  评论(0编辑  收藏  举报