FFT
快速傅里叶变换是利用DFT旋转因子的周期性、对称性、可约性,将长序列DFT分解为短序列DFT。其中基2时域抽取算法是按奇偶下标拆分序列。拆分到只剩下两个点时,可以很方便的计算出其DFT,而后通过蝶形运算可以很快的得到原序列DFT结果。
下标分组
将下标写成二进制形式,从最低位开始按位取0、取1分别是不同的组,迭代到最高位即分组完毕。
举个例子,比如16点FFFT,可用4位二进制表示,那么第一次分组可分为XXX0与XXX1,继续分组,XXX可分为XX0与XX1两组,XX又可分为X0与X1两组,X又可分为0与1两组,
所以分组结果如下:
程序实现
实现时与分组逻辑相反,分组时从低位开始到高位,程序实现是从高位开始。通过观察后发现一开始是0/1,第二组可表示为(0/1)*2与(0/1)*2+1,之后都是将前面的数据移位(+1),
vector<int> getTimeDomainSeq(long long N) {
int n = ceil(log2(N));
vector<int> res(pow(2,n),0);
for (int i =0; i < n; ++i) {
for (int k = 0; k < pow(2,i); ++k) {
res[k] <<= 1;
res[k +(1<<i)] = res[k] + 1;
}
}
//算法时间复杂度 O(N):等比数列前n项目和,结果为2^n-1=N-1
return res;
}
int main() {
auto res=getTimeDomainSeq(16);
for (auto k : res) {
cout << k<<" ";
}
return 0;
}
运行结果
算法复杂度
可以看出运算次数是一个等比数列和,经过运算发现,该算法复杂度位O(N),N为数据量。