1. 程式人生 > 其它 >【whk向】初識複數

【whk向】初識複數

1. 定義

複數是形如 \(a+bi\) 的數,其中 \((a,b)\in \mathbb{R}\)

  • 複平面:我們把複數 \(a+bi\) 看作二維平面上的一個點 \((a,b)\),這個二維平面稱為複平面。複平面上的點和複數一一對應,如同數軸上的點一一對應一樣。以下我們有時會以 \((a,b)\) 指代 \(a+bi\)
  • 複數 \((a,b)\) 可以視作複平面上一個 \((0,0)\rightarrow (a,b)\) 的向量。

\(\text{Re} (a,b)=a,\text{Im (a,b)}=b\),可以理解為實部和虛部。

2. 基本性質與運算

複數最基本的代數運算有兩條:

  • 加法:\((a,b)+(c,d)=(a+b,c+d)\)
  • 乘法:\((a,b)\times (c,d)=(ac-bd,ad+bc)\)

可以說明:加法的單位元有且僅有 \((0,0)\),乘法的單位元有且僅有 \((1,0)\)

複數相反數的定義是自然的,也就是 \(z=(a,b)\) 的加法逆元為 \(-z=(-a,-b)\)

除了 \((0,0)\),一切複數皆存在乘法逆元:對於實數 \((a,b)\),解方程 \((a,b)(u,v)=(1,0)\) 後解得 \(u=\frac{a}{a^2+b^2},v=-\frac{b}{a^2+b^2}\)

換言之 \(z=(a,b)\) 的逆元即為 \(z^{-1}=(\frac{a}{a^2+b^2},-\frac{b}{a^2+b^2})\)

容易說明 \(zz^{-1}=1\) 以及 \((z^{-1})^{-1}=z\) 兩條性質。

由逆元的存在,我們可以定義複數的減法以及除法運算:

  • 減法: \((a,b)-(c,d)=(a-b,c-d)\)

  • 除法:\(\frac{(a,b)}{(c,d)}=(a,b)(\frac{c}{c^2+d^2},-\frac{d}{c^2+d^2})=(\frac{ac+bd}{c^2+d^2},\frac{bc-ad}{c^2+d^2})\)

複數的很多代數性質和實數是一樣的:加法交換律,結合律;乘法交換律,結合律,分配律全部滿足。


有一類複數對比較特殊:它們形如 \(z=(a,b)\)

以及 \(\overline{z}=(a,-b)\),我們稱這樣的複數是共軛複數。

共軛複數的特殊之處在於良好的運算性質:\(z+\overline{z}=(2a,0)\) 以及 \(z-\overline{z}=(0,2b)\),對於乘法,則有 \(z\times \overline{z}=(a^2+b^2,0)\),由此我們可以看出很重要的一條性質:

\[z\times \overline{z}=|z|^2 \]

共軛複數的良好性質也讓我們不用死記硬背 \(\frac{(a,b)}{(c,d)}\) 的公式了,因為我們可以上下同乘 \((c,-d)\)。事實上利用這個想法(而不是先記憶複數逆再去乘法)去做複數除法效率是很快的。

3. 幾何意義初探

現在我們回到定義一節中複平面的相關內容上。

我們可以自然地把一個複數看作一個向量 \(z=(0,0)\rightarrow (a,b)\),我們知道向量有模長 \(|z|\),很顯然,有 \(|z|=\sqrt{a^2+b^2}\)

回顧複數的加法運算,我們會發現其與向量的加法運算是完全一致的,而我們又知道向量相加遵循三角形定則,根據兩點之間直線最短,我們匯出:

\[|a+b|\le |a|+|b| \]

這個式子取等,當且僅當 \(a,b\) 平行。

我們知道三角形不等式還有減法版本,在這裡一樣成立:

\[||a|-|b|| \le |a+b| \]

取等條件同上。

我們可以遞迴地證明:\(|a_1+a_2+...+a_n|\le |a_1|+|a_2|+...+|a_n|\)

4. 再談幾何意義

複數的加法擁有良好的幾何意義,那麼複數的乘法呢?

在繼續談論複數之前,我們需要一些基礎的代數知識。

尤拉公式(\(\text{Eular's formula}\)):

\[e^{i\times \theta}=\cos \theta + i\times \sin \theta \]

證明其實很容易(我不確定是否屬於後證前,但這個是我所瞭解的比較方便的證明方式?),我們把三項全部泰勒展開:

\[e^{i\times \theta}=\sum_{n\ge 0}\frac{(i\times \theta)^n}{n!} \\ \cos \theta = \sum_{n\ge 0}(-1)^{n}\frac{\theta^{2n}}{(2n)!} \\ \sin \theta = \sum_{n\ge 0}(-1)^{n}\frac{\theta^{2n+1}}{(2n+1)!} \]

一一比對 \([\theta^n]\) 的係數,容易發現確實是相等的。

尤拉公式比較著名的形式是 \(\theta = \pi\)(實際上,也就是 \(\cos\theta\) 以及 \(\sin \theta\) 比較簡單的時候),此時有 \(e^{i\pi}+1=0\)


現在我們回到複數上,我們前面利用平面直角座標系定義了複平面上 \(z=(a,b)\) 的位置,現在我們換用極座標系來定義,則每個複數 \(z\) 都可以看作從原點 \((0,0)\),以角度 \(\theta\) 引一條射線,距離原點距離為 \(r\) 的位置,其中 \(r\) 為模長 \(|z|\)

這裡顯然有 \(r\ge 0\)\(r\in \mathbb{R}\),不過我們知道弧度座標制裡 \(\theta\) 可以是任意大的,因為 \(\theta\)\(\theta+2\pi\) 都是一個角。為了規範,我們認為 \(\theta\in (-\pi,\pi]\),對於複數 \(z\),我們把它的這個 \(\theta\) 記作 \(\text{Arg}(z)\),而把集合 \(\{\theta+2k\pi \mid k\in \mathbb{Z}\}\) 記作 \(\arg(z)\)

首先我們知道 \(x=r\times \cos \theta\) 以及 \(y=r\times \sin \theta\) 成立,所以有複數 \(a+bi=r\times (\cos \theta + i\times \sin \theta)\) 成立。

觀察 \(r\) 後面的內容,我們意識到這恰好出現在了尤拉公式中。

也就是有 \(a+bi=r\times e^{i\theta}\),這是一種全新的,簡潔的表示複數的形式。

對於兩個複數: \(z_1=r_1\times e^{i\theta_1},z_2=r_2\times e^{i\theta_2}\),那麼將它們相乘,我們將看到: \(z_1\times z_2=(r_1\times r_2)\times e^{i(\theta_1+\theta_2)}\)

觀察新的複數,其模長為 \(r_1\times r_2\),其角度變為 \(\theta_1+\theta_2\)

由此,我們總結出了複數相乘的幾何意義,也就是所謂的 ”模長相乘,幅角相加“,也就是 \(|a\times b|=|a|\times |b|,\text{arg}(|a|\times |b|)=\text{arg}(|a|)+\text{arg}(|b|)\)

事實上證明這件事情並不只有這一條路,然而這個方法幾乎是從代數角度完美的證明了一種幾何意義。

5. 幾何意義說開去

我們如何描述一個圓?圓的兩要素是圓心以及半徑,我們先從圓心是原點的情況說開去。

顯然,設半徑為 \(r\),則該圓上的所有點和 \(\{z=re^{i\theta} \mid \theta\in (-\pi,\pi]\}\) 一一對應。

更一般的呢?如果我們的圓心是一個任意點,我們記作 \(z_0\),則我們會看到該圓上所有點和 \(\{z=z_0+re^{i\theta} \mid \theta\in (-\pi,\pi]\}\) 一一對應。


三角函式有很多公式,比如和差化積,比如二倍角,三倍角。我們在學習的時候通常不學習其證明,而且一段時間不用還經常會出現忘記的情況。

事實上,利用尤拉公式,我們是可以直接推出這些公式的。

\[e^{i\theta_1}\times e^{i\theta_2}=e^{i(\theta_1+\theta_2)} \\ (\cos \theta_1+i\sin \theta_1)(\cos\theta_2+i\sin \theta_2)=\\ \cos (\theta_1\theta_2)-\sin (\theta_1\theta_2)+i\sin \theta_1\cos \theta_2+i\sin \theta_2\cos \theta_1=\\ \cos (\theta_1+\theta_2)+i\sin (\theta_1+\theta_2) \]

觀察倒數第二行的四項:前兩項是實數,後兩項是虛數;最後一行中,第一項是實數,第二項是虛數,由此,我們推出:

\[\begin{cases} \sin(\theta_1+\theta_2)=\sin \theta_1\cos \theta_2+\sin \theta_2\cos \theta_1 \\ \cos(\theta_1+\theta_2)=\cos (\theta_1\theta_2)+\sin (\theta_1\theta_2) \end{cases} \]

這就是我們所熟知的和角公式;差角公式當然是一樣的推法。

現在我們來看倍角公式,首先要知道的是棣莫佛公式(\(\text{de Moivre's Fomula}\)):

\[(\cos \theta+i\sin \theta)^n=\cos(n\theta)+i\sin(n\theta) \]

證明其實非常簡單:

\[(e^{i\theta})^n=e^{in\theta} \\ \]

將兩邊的 \(e^x\) 通過尤拉公式展開即可。

\(n=2\),則有:

\[(\cos \theta+i\sin \theta)^2=\cos(2\theta)+i\sin(2\theta)\\ \cos^2\theta-\sin^2\theta+2i\cos\theta\sin\theta=\cos(2\theta)+i\sin(2\theta) \]

依舊是利用實部和虛部的不同,我們得到:

\[\begin{cases} \sin(2\theta)=2\cos\theta\sin\theta \\ \cos(2\theta)=\cos^2\theta-\sin^2\theta \end{cases} \]

6. 單位根

接下來是最後一節,我們將闡述單位根相關的一些內容。

我們定義根的概念:對於一個複數 \(z_0=r_0e^{i\theta_0}\),我們稱 \(z\)\(r_0\) 的 $\text{n-th root} $(不會翻譯了)當且僅當 \(z^n=z_0\) 成立。

根據代數基本定理我們都知道這樣的 \(z\) 會有 \(n\) 個。

如何找到所有的 \(z\)?設 \(z=re^{i\theta}\),則其是我們要找的根,當且僅當:

\[\begin{cases} r^n=r_0 \\ n\theta=\theta_0+2k\pi\,(k\in \mathbb{Z}) \end{cases} \]

所以所有的根,它們的 \(r\) 都應該是 \(\sqrt[n]{r_0}\)(注意 \(r\) 永遠是非負的),而 \(\theta\) 形如 \(\frac{\theta_0}{n}+\frac{2k\pi}{n}(k\in \mathbb{Z})\)

而本質不同的 \(z\) 也確實只有 \(n\) 個,也就是 \(k\in [1,n]\) 的時候的 \(n\) 個根。

因此:

\[z=\sqrt[n]{r_0}\exp(i\frac{\theta_0}{n})\exp(i\frac{2k\pi}{n})(k\in \mathbb{Z}) \]

對於任何的 \(z\)\(n\),我們都能找到 \(z\)\(n\) 個根。當 \(z=1\) 的時候,這 \(n\) 個根是最特殊的,我們稱其(\(x^n=1\) 的所有解)為 \(n\) 次單位根:

\[\omega_n^k=\exp(i\frac{2k\pi}{n})(k\in \mathbb{Z}) \]

我們設 \(z_0\) 的第 \(k\) 個根是 \(c_k(k\in [0,n)\)。則顯然有:

\[c_k=c_0\omega_{n}^{k} \]

單位根的一些代數性質(單位根本身是 \(e\) 的若干次冪,因此單位根的運算有良好性質):

  • \(\omega_n^k=(\omega_n^1)^k\)
  • \((\omega_n^1)^2=(\omega_{n/2}^1)\),這是因為 \(\exp(i\frac{2k\pi}{n})^2=\exp(i\frac{2k\pi}{n/2})\)

我們可以把單位根 \(\omega_{n}^{k}\) 的下標看作是模 \(n\) 意義下的,那麼就有 \(\omega_{n}^{x}\omega_{n}^{y}=\omega_{n}^{x+y}\)

Bonus:快速傅立葉變換

其實 \(\text{FFT}\) 是老生常談的東西了,但還是覺得不徹底推一次就不太合適。

\(\text{FFT}\) 的基本思想:

考慮兩個係數形式的多項式 \(A(x),B(x)\),不妨設它們的次數較大的是 \(n\)

我們計算 \(A\times B\) 的係數形式,直接做是 \(O(n^2)\) 的。

如果我們能在低於 \(O(n^2)\) 的時間內求出 \(A(x)\)\(B(x)\) 在至少 \(2n+1\) 個點處的值,然後分別相乘,就得到了 \((A\times B)(x)\) 在這 \(\ge 2n+1\) 個點處的值,然後我們再設法插值回去,得到那個唯一的多項式。

\(\text{FFT}\) 的核心,就是快速求出那若干個點值,以及快速插值回去的方法。

離散傅立葉變換 (\(\text{Discrete Fourier Transform,DFT}\)

\(N\) 是大於等於 \(2n+1\) 的一個數,且 \(N=2^m\),顯然最小的 \(N\)\(O(n)\) 級別的。

具體來說,我們計算 \(A\)\(B\) 同理)在 \(\omega_{N}^{0},\omega_{N}^{1},...,\omega_{N}^{N-1}\)\(N\) 個點的點值。

\[A(\omega_{n}^k)=\sum_{i=0}^{N-1}a_i\omega_{n}^{ki} \]

我們把下標按照奇偶分類:

\[A(\omega_{N}^k)=\sum_{i=0}^{\frac{N}{2}-1}a_{2i}\omega_{N}^{2ki}+\omega_{N}^{k}\sum_{i=0}^{\frac{N}{2}-1}a_{2i+1}\omega_{N}^{2ki} \]

這樣的話,\(i\) 的下標被分治了,但是問題是,我們每次分治以後,還是要對 \(\omega_{N}^{0}\sim \omega_{N}^{N-1}\) 都去求值,這樣時間複雜度其實沒有任何變化,因此我們遞迴的次數是 \(T(N)=2T(\frac{N}{2})+O(1)=O(N)\) 級別的,而每次都要去算 \(N\) 個點值。

如果我們能做到:分治下去以後,兩邊分別只算 \(\frac{N}{2}\) 個點值,這樣時間複雜度就真的變成了 \(T(N)=2T(\frac{N}{2})+O(1)=O(N\log N)\) 了。我們仔細觀察兩個和式中的單位根,我們會發現:

\[\omega_{N}^{2ki}=\omega_{N/2}^{ki} \]

在第 \(\text{6}\) 節已經提及這件事情!

現在,我們的式子變成了:

\[A(\omega_{N}^k)=\sum_{i=0}^{\frac{N}{2}-1}a_{2i}\omega_{N/2}^{ki}+\omega_{N}^{k}\sum_{i=0}^{N/2-1}a_{2i+1}\omega_{N/2}^{ki} \]

我們會注意到我們把關於 \(\omega_{N}^k\) 的轉變成了關於 \(\omega_{N/2}^{k}\) 的;那麼,當 \(k\ge N/2\) 的時候,其實就等價於轉變成了關於 \(\omega_{N/2}^{k-N/2}\) 的。具體而言,\(A(\omega_{N}^{k})\)\(A(\omega_{N}^{k+N/2})\) 應該是相近的(\(k\in [0,\frac{N}{2})\)

\[A(\omega_{N}^{k})=A_L(\omega_{N/2}^{k})+\omega_{N}^{k}A_R(\omega_{N/2}^{k}) \\ A(\omega_{N}^{k+N/2})=A_L(\omega_{N/2}^{k})-\omega_{N}^{k}A_R(\omega_{N/2}^k) \]

注意到有 \(\omega_{N}^{k+N/2}=-\omega_{N}^{k}\),值得一提的是這隻在 \(N\) 是偶數的時候成立。

總而言之,我們在 \(O(N\log N)\) 的時間複雜度內完成了 \(\text{DFT}\)

傅立葉逆變換(\(\text{IDFT}\)

現在問題變成了快速插值,亦即:給出 \(N\) 個點,試還原出一個 \(N-1\) 次的唯一多項式。

這相當於解線性方程組:

\[\left[ \begin{array}{l} (\omega_{N}^{0})^0 & (\omega_{N}^{0})^1 & ... & (\omega_{N}^{0})^{N-1} \\ (\omega_{N}^{1})^0 & (\omega_{N}^{1})^1 & ... & (\omega_{N}^{1})^{N-1} \\ ... \\ (\omega_{N}^{N-1})^0 & (\omega_{N}^{N-1})^1 & ... & (\omega_{N}^{N-1})^{N-1} \end{array} \right] \times \left[ \begin{array}{l} a_0 \\ a_1 \\ ... \\ a_{N-1} \end{array} \right] = \left[ \begin{array}{l} A(\omega_{N}^{0}) \\ A(\omega_{N}^{1}) \\ ... \\ A(\omega_{N}^{N-1}) \end{array} \right] \]

記左邊的這個矩陣是 \(U\),也就是 \(U_{i,j}=\omega_{N}^{ij}\)

記矩陣 \(V\) 是滿足 \(V_{i,j}=\omega_{N}^{-ij}\) 的矩陣,則兩個方陣相乘,\(V\times U=E\),的結果非常特殊:

\[E_{i,j}=\sum_{k}V_{i,k}U_{k,j}=\sum_{k}\omega_{N}^{k(j-i)} \]

\(i=j\) 時,\(E_{i,j}=N\),否則根據等比數列求和,分子是 \(1-\omega_{N}^{N(j-i)}=0\),所以 \(E=nI\)

因此如果我們在兩邊同時左乘 \(V\),會得到:

\[nIa=VA \\ a=\frac{1}{n}VA \]

所以我們只需要算出向量 \(V\times A\),然後每一項都除以 \(n\),就是我們想要的結果了。

\(V\times A\) 實質上就是把 \(\text{DFT}\) 的過程中所有的 \(\omega_{N}^{i}\) 換成了 \(\omega_{N}^{-i}\),我們令 \(\phi_{N}^{i}=\omega_{N}^{-i}\),則 \(\phi_N\) 同樣滿足:

  • \(\phi_{N}^0\sim \phi_{N}^{N-1}\) 互不相同。

  • \(\phi_{N}^{2i}=\phi_{N/2}^{i}\)

  • \(\phi_{N}^{N}=1\)

  • \(\phi_{N}^{n/2+k}=-\phi_{N}^{k}\)

這些是我們能進行 \(\text{DFT}\) 的基礎,既然全部滿足,那麼也就可以成功在 \(O(n\log n)\) 的時間內進行 \(\text{IDFT}\)

位逆序置換

寫出遞迴版本的 \(\text{FFT}\) 並不難,問題就在於這樣常數太大了。

把遞迴換成迭代版本是一個不錯的選擇,問題在於如果我們想”自下而上“地使用迭代實現,就必須預處理出每個 \(a_i\) 在最終狀態被分配到了哪裡。

實質上,最後的 \(b_i\) 應該是 \(a_{p_i}\)\(p_i\) 是把 \(i\) 的二進位制表示反轉(不是 \(\text{0/1}\) 互換,是從後往前讀的意思)後的結果。

顯然 \(p\) 是可以 \(O(N)\) 求的:我們從小到大求 \(p\),那麼根據 \(p_{\left\lfloor \frac{n}{2} \right\rfloor}\) 的結果,我們可以得到 \(n\) 除了最低位以外,其餘位反轉的結果,所以我們只需要知道最低位反轉的結果即可。

for(int i=0;i<N;i++){
    p[i]=p[i>>1]>>1;
    if(i&1)p[i]|=(N>>1)
}

然後我們令 \(b_i=a_{p_i}\),對 \(b\) 直接進行 \(\text{DFT}\) 即可。這樣我們的 \(\text{FFT}\) 常數會大大降低。

快速數論變換(\(\text{Fast Number-Theoretic Transform,NTT}\)

我們可以在取模意義下實現 \(\text{FFT}\)

我們前面探討了 \(\text{IDFT}\) 想要和 \(\text{DFT}\) 一樣做,\(\phi\) 需要滿足的條件。那麼我們此時不光要滿足這些條件(這樣你能做 \(\text{DFT}\)),還應該滿足 \(E_{i,j}=n\times [i=j]\) 的條件(這樣我們能把 \(\text{IDFT}\) 轉成 \(\text{DFT}\))。

可以驗證的是,當 \(p\) 是形如 \(k\times 2^n+1\) 的素數時,取 \(p\) 的一原根 \(g\),令 \(\omega_{n}^{1}=g^k\),此時我們的”單位根“是滿足上面所有條件的。

最常見的情形是 \(p=998244353\),此時有 \(g=3\)\(p\) 的原根。

我們還可以拓展到任意模數的情況(\(\text{MTT}\))。首先注意到,如果兩個長度為 \(n\) 的多項式在模 \(p\) 意義下相乘,則每一項的係數不會超過 \(n(p-1)^2\),我們選取若干個 \(\text{NTT}\) 模數,它們的積大於 \(n(p-1)^2\),設有 \(k\) 個,我們做 \(k\)\(\text{NTT}\),最後利用 \(\text{CRT}\) 合併每一項的 \(k\) 個結果即可。