FFTを学ぶときに見かけるNTTって一体なんなの
前書き
regiです。この記事ではあくまでもNTT(数論変換)のみを取り上げるため、FFT(高速フーリエ変換)について全く知らない方でもある程度知っている方でも関係なく、ただNTTって何なのかだけざっくり押さえておきたい!と思っている方を対象としています。しかし、備忘録という意味合いが強いため、今のところでは細かい事や実装例等は取り上げていないのでご了承ください。その代わり、私が参考にさせて頂いた他の方のFFTやNTTに関する記事を適宜紹介したいと思っています。また、この記事内で誤った情報、誤字、誤植等を見かけた場合、直ちに訂正するのでTwitterで教えて欲しいです...お願いします🙏(TwitterID -> @Re_code_A)
FFTで用いられる数について
正確に言うと、FFTを行う際に行われるDFT(離散フーリエ変換)で用いられる数であり、という複素数が用いられています。は必ずのべき乗とします。これはの原始乗根と呼ばれる乗して初めてになる数のことであり、などが原始乗根に該当します。そもそもなぜこのような数がFFTで用いられているかというと、は重要な性質を持っているからであり、それは以下のようなものです。
なぜこの性質は重要かというと、単純に、FFTはこのような性質を持つ数を用いることで行うことが可能になるからです。
複素数の概要及び上記の性質の証明等はこちらの記事が大変参考になりました。
https://qiita.com/ageprocpp/items/0d63d4ed80de4a35fe79
NTTとは
先ほど、FFTにはという複素数が用いられると言いましたが、この場合小数が出てくるために誤差を考慮する必要があるため、その点では複素数を扱うのは不便です。また、上記の性質を持つ数を用いることでFFTを行うことが可能になるとも言いましたが、これを言い換えると、この性質さえ持つ数であればFFTで用いる数として代用できるということで、つまり、上記の性質を満たした整数があるとすると、それを用いれば誤差に怯えることなくFFTを行うことができるということです。このような整数は特別な素数を法とすることで設けることができます。NTTとは、その特別な素数を法とした上で上記の性質を満たした整数を用いてFFTを行う手法のことです。
どのような素数や整数を用いるのか具体的に紹介すると、まず特別な素数とはある正の整数を用いてと表すことのできる素数(以下)であり、を法とすると、乗して初めてと合同になる整数を設けることができます。このは法の下で以下のような性質を持っています。(ただし、であることが必要です。)
確かにはFFTを行うために必要な性質を持っていることが分かります。
証明等はこちらのパワーポイントが大変参考になりました。
https://hcpc-hokudai.github.io/archive/math_fft_002.pdf
少し余談ですが、プログラミングコンテスト等で見かけるという謎の素数は、と、の十分大きいという形にすることができます。そのため、法の下で解く問題とNTTを用いたFFTは相性が良いです。ちなみにこの場合はなどがに該当します。
まとめ
FFTを行うためにはという重要な性質を満たす複素数が用いられているが、小数が出てきてしまうため誤差が怖い。それを解決する手法である、ある特別な素数を法とすることで、整数を用いてFFTを行えるようにする手法がNTTである。
後書き
私自身がNTTについて初めて学んだとき、このようなところでも整数論が活躍していることにかなり驚きました。その他、NTTに関して参考にさせて頂いた記事を紹介します。
http://kirika-comp.hatenablog.com/entry/2018/03/12/210446
私自身もまだまだ勉強している途中なので、進み次第、いろいろ追記していく予定です。