快速數論變換
簡介
數論變換(number-theoretic transform, NTT)是離散傅里葉變換(DFT)在數論基礎上的實現;快速數論變換(fast number-theoretic transform, FNTT)是 快速傅里葉變換(FFT)在數論基礎上的實現。
數論變換 是一種計算卷積(convolution)的快速算法。最常用算法就包括了前文提到的快速傅里葉變換。然而快速傅立葉變換具有一些實現上的缺點,舉例來説,資料向量必須乘上覆數係數的矩陣加以處理,而且每個複數係數的實部和虛部是一個正弦及餘弦函數,因此大部分的係數都是浮點數,也就是説,必須做複數而且是浮點數的運算,因此計算量會比較大,而且浮點數運算產生的誤差會比較大。
NTT 解決的是多項式乘法帶模數的情況,可以説有些受模數的限制,數也比較大。目前最常見的模數是 998244353。
前置知識
學習數論變換需要前置知識:離散傅里葉變換、生成子羣、原根、離散對數。相關知識可以在對應頁面中學習,此處不再贅述。
定義
數論變換
在數學中,NTT 是關於任意 環 上的離散傅立葉變換(DFT)。在有限域的情況下,通常稱為數論變換(NTT)。
數論變換(NTT)是通過將離散傅立葉變換化為 \(F={\mathbb {Z}/p}\),整數模質數 \(p\)。這是一個 有限域,只要 \(n\) 可除 \(p-1\),就存在本原 \(n\) 次方根,所以我們有 \(p=\xi n+1\) 對於 正整數 \(ξ\)。具體來説,對於質數 \(p=qn+1, (n=2^m)\),原根 \(g\) 滿足 \(g^{qn} \equiv 1 \pmod p\), 將 \(g_n=g^q\pmod p\) 看做 \(\omega_n\) 的等價,則其滿足相似的性質,比如 \(g_n^n \equiv 1 \pmod p, g_n^{n/2} \equiv -1 \pmod p\)。
因為這裏涉及到數論變化,所以 \(N\)(為了區分 FFT 中的 \(n\),我們把這裏的 \(n\) 稱為 \(N\))可以比 FFT 中的 \(n\) 大,但是隻要把 \(\frac{qN}{n}\) 看做這裏的 \(q\) 就行了,能夠避免大小問題。
常見的有:
就是 \(g^{qn}\) 的等價 \(\mathrm{e}^{2\pi n}\)。
迭代到長度 \(l\) 時 \(g_l = g^{\frac{p-1}{l}}\),或者 \(\omega_n = g_l = g_N^{\frac{N}{l}} = g_N^{\frac{p-1}{l}}\)。
快速數論變換
快速數論變換(FNTT)是數論變換(NTT)增加分治操作之後的快速算法。
快速數論變換使用的分治辦法,與快速傅里葉變換使用的分治辦法完全一致。這意味着,只需在快速傅里葉變換的代碼基礎上進行簡單修改,即可得到快速數論變換的代碼。
在算法競賽中常提到的 NTT 一詞,往往實際指的是快速數論變換,一般默認「數論變換」是指「快速數論變換」。
這樣簡寫的邏輯與快速傅里葉變換相似。事實上,「快速傅里葉變換」(FFT)一詞指的是「快速離散傅里葉變換」(FDFT),但由於「快速」只能作用於離散,甚至是本原單位根階數為 \(2\) 的冪的特殊情形,不能作用於連續,因此「離散」一詞被省略掉,FDFT 變為 FFT,即 FFT 永遠指的是特殊的離散情形。
數論變換或快速數論變換是在取模意義下進行的操作,不存在連續的情形,永遠是離散的,自然也無需提到離散一詞。
在算法領域,不進行提速的操作是無意義的。在快速傅里葉變換中介紹 DFT 一詞,是因為 DFT 在信號處理、圖像處理領域也有其他的具體應用,同時 DFT 也是 FFT 的原理或前置知識。
在不引起混淆的情形下,常用 NTT 來代指 FNTT。為了不引起下文進一步介紹的混淆,下文的 NTT 與 FNTT 兩個詞進行了分離。
DFT、FFT、NTT、FNTT 的具體關係是:
-
在 DFT 與 NTT 的基礎上,增加分治操作,得到 FFT 與 FNTT。分治操作的辦法與原理,可以參見快速傅里葉變換一文。
-
在 DFT 與 FFT 的基礎上,將複數加法與複數乘法替換為模 \(p\) 意義下的加法和乘法,一般大小限制在 \(0\) 到 \(p-1\) 之間;將本原單位根改為模 \(p\) 意義下的相同階數的本原單位根,階數為 \(2\) 的冪,即可得到 NTT 與 FNTT。
由於替換的運算只涉及加法和乘法,因此 DFT、FFT、NTT、FNTT 擁有相同的原理,均在滿足加法與乘法的環上進行,無需域上滿足除法運算的更加嚴格的條件。
事實上,只要擁有原根,即羣論中的生成元,該模數下的 NTT 或 FNTT 即可進行。考慮到模數為 \(1\)、\(2\) 和 \(4\) 的情形太小,不具有實際意義,對於奇素數 \(p\) 和正整數 \(\alpha\),只要給出模數為 \(p^\alpha\) 和 \(2p^\alpha\) 的原根 \(g\),採用同樣的辦法,則 NTT 或 FNTT 仍然可以進行。
模板
下面是一個大數相乘的模板,參考來源。
參考代碼
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | |
參考資料與拓展閲讀
- FWT(快速沃爾什變換)零基礎詳解 qaq(ACM/OI)
- FFT(快速傅里葉變換)0 基礎詳解!附 NTT(ACM/OI)
- Number-theoretic transform(NTT) - Wikipedia
- Tutorial on FFT/NTT—The tough made simple. (Part 1)
本页面最近更新:,更新历史
发现错误?想一起完善? 在 GitHub 上编辑此页!
本页面贡献者:ChungZH, Yukimaikoriya, tigerruanyifan, isdanni, Saisyc, 383494, Tiphereth-A
本页面的全部内容在 CC BY-SA 4.0 和 SATA 协议之条款下提供,附加条款亦可能应用