瞎讲:FFT三次变二次优化

2020年了我怎么还是没有学会任意模数NTT……
发现自己多项式的技能没有点的还有很多。


处理任意模数NTT有一系列的方法,其中有个看起来比较优的算法需要FFT三次变二次优化。
众所周知,普通的FFT长这样:
假设是多项式\(A(x)\)\(B(x)\)求卷积,首先求\(DFT(A)\)\(DFT(B)\),两者相乘后求\(IDFT\)
这样算了三次\(DFT\)
接下来的算法可以将三次\(DFT\)优化成两次。


\(P(x)=A(x)+iB(x)\)\(Q(x)=A(x)-iB(x)\)
推一波式子(设\(L\)表示长度,\(\theta=\frac{2\pi jk}{L}\)

\[DFT(P)_k=P(\omega^k)\\ =\sum_{j=0}^{L-1}(A_j+iB_j)\omega^{jk} \\ =\sum_{j=0}^{L-1}(A_j+iB_j)(\cos \theta + i\sin \theta) \\ =\sum_{j=0}^{L-1}(A_j\cos\theta-B_j\sin\theta)+i(A_j\sin\theta+B_j\cos\theta)\]

\[DFT(Q)_k=Q(\omega^k)\\ =\sum_{j=0}^{L-1}(A_j-iB_j)\omega^{jk} \\ =\sum_{j=0}^{L-1}(A_j-iB_j)(\cos \theta + i\sin \theta) \\ =\sum_{j=0}^{L-1}(A_j\cos\theta+B_j\sin\theta)+i(A_j\sin\theta-B_j\cos\theta) \\ =\sum_{j=0}^{L-1}(A_j\cos(-\theta)-B_j\sin(-\theta))-i(A_j\sin(-\theta)+B_j\cos(-\theta))\]

对比一下,可以发现\(DFT(Q)_k\)\(DFT(P)_{L-k}\)(即\(DFT(P)_{-k}\))共轭。
于是算出\(DFT(P)\),就可以在\(O(n)\)时间内求出\(DFT(Q)\)


显然\(A(x)=\frac{P(x)+Q(x)}{2}\)\(B(x)=-i\frac{P(x)-Q(x)}{2}\)
于是就可以求出\(DFT(A)\)\(DFT(B)\),进而求出\(DFT(A*B)\),然后\(IDFT\)回去。
这样就将\(DFT\)从调用三次优化到调用两次了。

猜你喜欢

转载自www.cnblogs.com/jz-597/p/12913398.html