概述
2020年了我怎么还是没有学会任意模数NTT……
发现自己多项式的技能没有点的还有很多。
处理任意模数NTT有一系列的方法,其中有个看起来比较优的算法需要FFT三次变二次优化。
众所周知,普通的FFT长这样:
假设是多项式
A
(
x
)
A(x)
A(x)和
B
(
x
)
B(x)
B(x)求卷积,首先求
D
F
T
(
A
)
DFT(A)
DFT(A)和
D
F
T
(
B
)
DFT(B)
DFT(B),两者相乘后求
I
D
F
T
IDFT
IDFT
这样算了三次
D
F
T
DFT
DFT。
接下来的算法可以将三次
D
F
T
DFT
DFT优化成两次。
设
P
(
x
)
=
A
(
x
)
+
i
B
(
x
)
P(x)=A(x)+iB(x)
P(x)=A(x)+iB(x),
Q
(
x
)
=
A
(
x
)
−
i
B
(
x
)
Q(x)=A(x)-iB(x)
Q(x)=A(x)−iB(x)
推一波式子(设
L
L
L表示长度,
θ
=
2
π
j
k
L
theta=frac{2pi jk}{L}
θ=L2πjk)
D
F
T
(
P
)
k
=
P
(
ω
k
)
=
∑
j
=
0
L
−
1
(
A
j
+
i
B
j
)
ω
j
k
=
∑
j
=
0
L
−
1
(
A
j
+
i
B
j
)
(
cos
θ
+
i
sin
θ
)
=
∑
j
=
0
L
−
1
(
A
j
cos
θ
−
B
j
sin
θ
)
+
i
(
A
j
sin
θ
+
B
j
cos
θ
)
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 + isin theta) \ =sum_{j=0}^{L-1}(A_jcostheta-B_jsintheta)+i(A_jsintheta+B_jcostheta)
DFT(P)k=P(ωk)=j=0∑L−1(Aj+iBj)ωjk=j=0∑L−1(Aj+iBj)(cosθ+isinθ)=j=0∑L−1(Ajcosθ−Bjsinθ)+i(Ajsinθ+Bjcosθ)
D
F
T
(
Q
)
k
=
Q
(
ω
k
)
=
∑
j
=
0
L
−
1
(
A
j
−
i
B
j
)
ω
j
k
=
∑
j
=
0
L
−
1
(
A
j
−
i
B
j
)
(
cos
θ
+
i
sin
θ
)
=
∑
j
=
0
L
−
1
(
A
j
cos
θ
+
B
j
sin
θ
)
+
i
(
A
j
sin
θ
−
B
j
cos
θ
)
=
∑
j
=
0
L
−
1
(
A
j
cos
(
−
θ
)
−
B
j
sin
(
−
θ
)
)
−
i
(
A
j
sin
(
−
θ
)
+
B
j
cos
(
−
θ
)
)
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 + isin theta) \ =sum_{j=0}^{L-1}(A_jcostheta+B_jsintheta)+i(A_jsintheta-B_jcostheta) \ =sum_{j=0}^{L-1}(A_jcos(-theta)-B_jsin(-theta))-i(A_jsin(-theta)+B_jcos(-theta))
DFT(Q)k=Q(ωk)=j=0∑L−1(Aj−iBj)ωjk=j=0∑L−1(Aj−iBj)(cosθ+isinθ)=j=0∑L−1(Ajcosθ+Bjsinθ)+i(Ajsinθ−Bjcosθ)=j=0∑L−1(Ajcos(−θ)−Bjsin(−θ))−i(Ajsin(−θ)+Bjcos(−θ))
对比一下,可以发现
D
F
T
(
Q
)
k
DFT(Q)_k
DFT(Q)k和
D
F
T
(
P
)
L
−
k
DFT(P)_{L-k}
DFT(P)L−k(即
D
F
T
(
P
)
−
k
DFT(P)_{-k}
DFT(P)−k)共轭。
于是算出
D
F
T
(
P
)
DFT(P)
DFT(P),就可以在
O
(
n
)
O(n)
O(n)时间内求出
D
F
T
(
Q
)
DFT(Q)
DFT(Q)。
显然
A
(
x
)
=
P
(
x
)
+
Q
(
x
)
2
A(x)=frac{P(x)+Q(x)}{2}
A(x)=2P(x)+Q(x),
B
(
x
)
=
−
i
P
(
x
)
−
Q
(
x
)
2
B(x)=-ifrac{P(x)-Q(x)}{2}
B(x)=−i2P(x)−Q(x)
于是就可以求出
D
F
T
(
A
)
DFT(A)
DFT(A)和
D
F
T
(
B
)
DFT(B)
DFT(B),进而求出
D
F
T
(
A
∗
B
)
DFT(A*B)
DFT(A∗B),然后
I
D
F
T
IDFT
IDFT回去。
这样就将
D
F
T
DFT
DFT从调用三次优化到调用两次了。
最后
以上就是爱笑紫菜为你收集整理的瞎讲:FFT三次变二次优化的全部内容,希望文章能够帮你解决瞎讲:FFT三次变二次优化所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复