什么是 FFT?
f(x)=1+2x+3x2+4x3
g(x)=4+3x+2x2+x3
如何求 f(x)⋅g(x)?逐项计算?O(n2)
还有别的计算方式吗?插值法
找到 n 个点 (x,f(x)),(x,g(x)) 则 f(x)⋅g(x) 由 (x,f(x),g(x))
找点时间复杂度?O(n2) 能否优化?
考虑把
f(x)=1+2x+3x2+4x3
奇次项与偶次项分离
f(x)=1+3x2+x(2+4x2)
令
fe(x)=1+3x
fo(x)=2+4x
则
f(x)=fe(x2)+x⋅fo(x2)
发现一个有意思的:如果 x 取 1 和 −1,
则只要算一次 fe(x2) 与 fo(x2) 就得到两个插值点
注意 1+3x 和 2+4x 也可以用类似的思路继续划分
fe(x)=1+3x=1+x⋅(3)
fe(1)=1+(1)⋅3=4fe(−1)=1+(−1)⋅3=−2
fo(x)=2+4x=2+x⋅(4)
fo(1)=2+(1)⋅4=6fo(−1)=2+(−1)⋅4=−2
我们知道 fe(1) 和 fo(1) 可以得出 f(1) 和 f(−1) 的值,那么 fe(−1) 和 fo(−1) 有什么用呢?
注意到一个 x2 可以开根号得到两个值 x 和 −x
他们平方值相同:(x)2=(−x)2=x
既然 1 可以拆成两个平方根,可否有 t2=(−t)2=−1 呢?
如果你学过复数,会立马思考到:i2=−1!
于是可得:
f(1)=fe(1)+fo(1)=4+6=10
f(i)=fe(−1)+i⋅fo(−1)=−2−2i
f(−1)=fe(1)−fo(1)=4−6=−2
f(−i)=fo(−1)−i⋅fo(−1)=−2+2i
孩子们,是复数,我们有救了。
graph LR;
subgraph A
A1[1]
A2[2]
A3[3]
A4[4]
end
subgraph Ae
Ae1[1]
Ae2[3]
end
A1-->Ae1
A3-->Ae2
subgraph Ao
Ao1[2]
Ao2[4]
end
A2-->Ao1
A4-->Ao2
subgraph Fe
Fe1[1+3=4]
Fe2[1-3=-2]
end
Ae1-->Fe1
Ae1-->Fe2
Ae2-->|-1|Fe2
Ae2-->|1|Fe1
subgraph Fo
Fo1[2+4=6]
Fo2[2-4=-2]
end
Ao1-->Fo1
Ao1-->Fo2
Ao2-->|-1|Fo2
Ao2-->|1|Fo1
subgraph F
F1[4+6=10]
F2["-2+(i)*(-2)=-2-2i"]
F3[4-6=-2]
F4["-2+(-i)*(-2)=-2+2i"]
end
Fe1-->F1
Fe1-->F3
Fe2-->F2
Fe2-->F4
Fo1-->|1|F1
Fo1-->|-1|F3
Fo2-->|i|F2
Fo2-->|-i|F4
f(1)=fe(1)+fo(1)
f(i)=fe(−1)+i⋅fo(−1)
f(−1)=fe(1)−fo(1)
f(−i)=fe(−1)−i⋅fo(−1)
根据欧拉公式,这些点分别有另一种表示形式 enk2πi
令 en=en12πi
则每个点分别为 enk
根据图还能发现 2 个结论:
enkmk=enmenk=−enk+2n
于是上面的方程变成
f(enk)=fe(en2k)+enkfo(en2k)=fe(e2nk)+enkfo(e2nk)
f(enk+2n)=fe(en(k+2n)2)+enk+2nfo(en(k+2n)2)=fe(en2k)+enk+2nfo(en2k)=fe(e2nk)−enkfo(e2nk)
(k<2n)