FFT直接的目的是两个多项式相乘,众所周知两个长度为n的多项式相乘, 一般性算法需要的时间复杂度是O(n^2)。而FFT算法则把多项式相乘的 时间复杂度降到了O(n log n),当n比较大时,性能上的差异是相当明显的, 尤其是对于音频信号的处理,n一般都在几万到几百万。 要了解FFT算法,首先需要了解多项式的表示。 我们一般表示一个多项式都是按照多项式的系数: y = anX^n+a(n-1)X^(n-1)+...+a1X+a0 同时我们又知道,平面坐标系下的一条n次曲线,可以由曲线上的n+1 个不同点唯一确定,一个n次多项式等价于一条n次曲线,于是,我们就可以
用平面上n+1个点的坐标唯一表示一个n次多项式: (x1,y1),(x2,y2),...,(xn+1,yn+1) 用n+1个点表示一个n次多项式的好处是,两个n次多项式相乘(即两个n次曲线) 相乘得到的曲线,即为把原两条曲线上每个相同x对应的两个y相乘得到的曲线。 这是一个O(n)的线性算法。 新的曲线是一个2n次的曲线,需要2n+1个点才能唯一确定,这意味这我们需要 对原曲线上的2n+1个点做对应相乘才能得到,不过这没有关系,在一条曲线上 是取n+1个点,还是取2n+1个点都是可以的。 于是关键的算法是如何高效的进行两个表达方式之间的互换。
通过巧妙的选取n个特定x的位置,我们可以构造一个O(n log n)的算法。
上面我们已经谈到能否利用关于点值形式表示的多项式的线性时间的乘法, 关键依赖能否快速把一个多项式从系数形式转化为点值形式(求值), 或从点值形式转化为系数形式。 我们可以用我们需要的任何点作为求指点,但通过精心挑选求指点的x, 我们可以把两种表示法之间的转换效率压缩到O(n log n)。 我们选择的求值点是单位元素的复根(就是复数平面里原点上的单位元的 n+1等分点),恰好是n+1个点,用这n+1个点作为求值点的x值会有很好的性质。 大家可能会有疑问,一般平面上的曲线为何x可以取到复数, 实际上到底取实数还是复数并没有关系,因为我们关心的仅仅是如何
唯一确定一个n次多项式,只要这n+1个复数点可以使多项式成立, 我们就可以采用它们。 下面我们看看这n+1个复数有什么性质: 为了方便讨论我们先假设是单位元上的m个等分点,从x轴的正方向开始 (第一个点是x轴的正方向上那个点的下一个点)逆时针排列下来, 第一个点我们称为单位元素的主m次根,它的值为: Wm = e ^ (2*pi*i / m) 于是单位元素的m次复根依次为: Wm^0 , Wm^1 , Wm^2 , ... , Wm ^ (m-1) 定理一:Wdm ^ dk = Wm ^ k 证明: Wdm
^ dk = [ e ^ (2*pi*i / dm) ] ^ dk = [ e ^ (2*pi*i / m ] ^ k = Wm ^ k 定理二:[Wm ^ (k+m/2)] ^ 2 = [Wm ^ k] ^ 2 证明:[Wm ^ (k+m/2)] ^ 2 = Wn ^ (2*k + m) = Wm ^ 2k * Wm ^ m = Wm ^ 2k = (Wm ^ k) ^ 2 下面我们进入主题, 我们希望求的是一个m-1次多项式在Wm^0 , Wm^1 , Wm^2 , ... , Wm ^ m的值 不失一般性,我们假设m是2的幂,因为次数是可以扩大的。
设A是一个多项式,假设已知A的系数形式:a = (a0,a1,...,an-1), 对于k=0,1,...,n-1,定义yk如下: yk = A(Wn ^ k),即x取Wn ^ k 时,多项式的值。 向量y = (y0,y1,...,yn-1)就是我们所求,我们称之为系数向量a=(...)的 离散傅立叶变换(Discrete Fourier Transform,简称DFT)。 而FFT就是称为快速傅立叶变换的方法
FFT
最新推荐文章于 2016-11-06 11:43:05 发布