700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 快速傅立叶变换(FFT)算法(原来这就是蝶形变换)

快速傅立叶变换(FFT)算法(原来这就是蝶形变换)

时间:2023-05-27 13:26:56

相关推荐

快速傅立叶变换(FFT)算法(原来这就是蝶形变换)

快速傅立叶变换(FFT)算法(原来这就是蝶形变换)

为了实现FFT的海面模拟,不得不先撸个FFT算法实现。

离散傅立叶变换(DFT)

学习FFT之前,首先要先了解什么是DFT,我们都知道傅立叶变换是将时域转换为频域。但是我们计算机是没办法处理连续的点,因此就有了离散傅立叶变换DFT。

标准DFT公式:

我们令:

W的一些性质

证明:

证明方法同上。

快速傅立叶变换(FFT)

我们将X(k)按照奇偶组合,在,有:

因为是常数,所以X(k)可以更改为:

即:

我们令

可得在时,

我们这里发现F,G为X的递归函数。

然后计算,:

根据以上公式:,

我们发现想要求与,只需要要求出与就可以了,这两条公式也就是我们所说的蝶形运算式。

我们令N=4,这时候出现了一幅熟悉的图,4-point FFT蝴蝶变换图:

说实话,我第一次看这个看了半天没看懂,就像瞎比划出来的东西,然而,我们只要举个例子就明白了:

我们首先计算k=0的情况:

其中,为F的递归函数。,为G的递归函数。

所以我们的为:

首先公式:

过程如下图所示(其中):

下面两条公式:

图解为:

由于我们求出与也能求出的值,其完成的图为:

到这里,就是我们标准的傅立叶变换了,我们的算法复杂度从变成了。

bitreverse算法

然而,我们的FFT还可以使用非递归的版本,如我们的4-point FFT计算X[0],X[1],X[2],X[3]最后对应的输入为x[0],x[2],x[1],x[3]。

再看8-point FFT计算过程x的位置变化:

0 1 2 3 4 5 6 7

0 2 4 6 1 3 5 7

0 4 2 6 1 5 3 7

bitreverse算法则是从中发现了x[i]在几号位,只要将i转化为(N-point FFT)位二进制,然后将bit反序再转回10进制即可,所得的数就是在第几位。比如在8-point FFT中我们想知道x(4)在几号位,我们只要将2转化为位二进制100,然后反序得001,即10进制的1。所以x(4)最后的位置为1号位(从0开始)。

所以我们的FFT便可以写成迭代的版本了(即上面蝶形变换图从左往右推)。贴上代码:

//其中a为x[i],omg为WNkvoid fft(cp *a, cp *omg){int lim = 0;while((1 << lim) < n) lim++;//logN //二进制反序for(int i = 0; i < n; i++){int t = 0;for(int j = 0; j < lim; j++)//每当该位上的值为1时,t和该位反转后的值进行或运算if((i >> j) & 1) t |= (1 << (lim - j - 1));if(i < t) swap(a[i], a[t]); // i < t 的限制使得每对点只被交换一次}//FFT计算for(int l = 2; l <= n; l *= 2){int m = l / 2;for(cp *p = a; p != a + n; p += l)for(int i = 0; i < m; i++){//蝶形变换cp t = omg[n / l * i] * p[i + m];p[i + m] = p[i] - t;p[i] += t;}}}

其中FFT计算的第一层循环为下图所示分块计算:

第二层循环为如下分块计算:

我们的蝶形变换就是按下图:

每次迭代到下一次的g'(x)都可由当前的g(x)自计算获得。

到这里我们的FFT就全部结束啦,接下来可以拿他做FFT海面模拟啦,先上个图:

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。