快速傅里叶变换FFT的代码实现
本文將根據(jù)離散傅里葉變換的快速算法編寫代碼
1,首先列出DFT的變換式和快速計(jì)算公式
2,假定N=2^L,那么采用基拆分具有如下樹狀規(guī)律
3,下面在表格里面列出快速算法的一般規(guī)律:
| ? | 左子樹 | 右子樹 | 序列分組 | 組內(nèi)分對(duì) | W(N,k) |
| 第1層 | b[L-1]=0 | b[L-1]=1 | 2^(L-1) | 2^(1-1) | N=2^1,k=[0~2^(1-1)-1] |
| 第2層 | b[L-2]=0 | b[L-2]=1 | 2^(L-2) | 2^(2-1) | N=2^2,k=[0~2^(2-1)-1] |
| ... | ... | ... | ... | ... | ... |
| 第i層 | b[L-i]=0 | b[L-i]=1 | 2^(L-i) | 2^(i-1) | N=2^i,k=[0~2^(i-1)-1] |
| ... | ... | ... | ... | ... | ? |
| 第L層 | b[L-L]=0 | b[L-L]=1 | 2^(L-L) | 2^(L-1) | N=2^L,k=[0~2^(L-1)-1] |
| ? | ? | ? | ? | ? | ? |
?
?
?
?
?
?
?
?
?
?
4,運(yùn)算的時(shí)候,從序號(hào)的高位進(jìn)行,向低位滑行。需要注意的是取k值,即是藍(lán)色區(qū)域的數(shù)值需要按位逆序運(yùn)算。完整的代碼如下:
function X_k=fft2_dit(x_n)
? ? N1 =length(x_n);
? ? L ?=ceil(log2(N1));
? ? N ?=2^L;
? ? X_t=zeros(1,N);
? ? %如果序列不是2整數(shù)次冪,那么進(jìn)行補(bǔ)零處理
? ? for m=1:N
? ? ? ? if(m<=N1)
? ? ? ? ? ? X_t(m)=x_n(m);
? ? ? ? else
? ? ? ? ? ? X_t(m)=0;
? ? ? ? end
? ? end
? ? for m=1:L %層級(jí)循環(huán)
? ? ? ? N ? ? =2^m;%W(N,k)中N值
? ? ? ? k_max =N/2 -1;%W(N,k)中最大k值
? ? ? ? g_max =2^(L-m);%一層有多少組獨(dú)立的蝶形圖
? ? ? ?for g=1:g_max %層內(nèi)分組 ? ?
? ? ? ? ? ? for p=0:k_max %組內(nèi)分對(duì) ? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? k=0; %k值逆序運(yùn)算
? ? ? ? ? ? ? ? for n=1:m-1
? ? ? ? ? ? ? ? ? ? k=bitshift(k,1) + bitget(p,n); ? ? ?
? ? ? ? ? ? ? ? end ? ?
? ? ? ? ? ? ? ? num_1 ? ? =(2*p+0)*g_max+ g;
? ? ? ? ? ? ? ? num_2 ? ? =(2*p+1)*g_max+ g;?
? ? ? ? ? ? ? ? X1 ? ? ? ?=X_t(num_1) + X_t(num_2)*exp(-1j*2*pi*k/N);
? ? ? ? ? ? ? ? X2 ? ? ? ?=X_t(num_1) - X_t(num_2)*exp(-1j*2*pi*k/N);
? ? ? ? ? ? ? ? X_t(num_1)=X1;
? ? ? ? ? ? ? ? X_t(num_2)=X2; ? ? ? ? ? ? ? ??
? ? ? ? ? ? end
? ? ? ?end
? ? end
? ?
? ? X_k=zeros(1,N); ? ?
? ? for m=0:2^L-1
? ? ? ? k=0; %輸出逆序運(yùn)算 ? ?
? ? ? ? for n=1:L
? ? ? ? ? ? k=bitshift(k,1) + bitget(m,n); ? ? ?
? ? ? ? end
? ? ? ? X_k(m+1)=X_t(k+1);
? ? end
end
5,下面測(cè)試按時(shí)間基2拆分的正確性
x_n =[0 1 2 3 4 5 6 7];
Xk ?=fft2_dit(x_n);%測(cè)試輸出
Xp ?=fft(x_n);%使用matlab自帶的函數(shù)
Xk =Xk.'
Xp =Xp.'
測(cè)試結(jié)果如下
Xk =
? 28.0000 ? ? ? ? ?
? -4.0000 + 9.6569i
? -4.0000 + 4.0000i
? -4.0000 + 1.6569i
? -4.0000 ? ? ? ? ?
? -4.0000 - 1.6569i
? -4.0000 - 4.0000i
? -4.0000 - 9.6569i
Xp =
? 28.0000 ? ? ? ? ?
? -4.0000 + 9.6569i
? -4.0000 + 4.0000i
? -4.0000 + 1.6569i
? -4.0000 ? ? ? ? ?
? -4.0000 - 1.6569i
? -4.0000 - 4.0000i
? -4.0000 - 9.6569i
6,首先列出DFT的變換式和快速計(jì)算公式
7,分析之后可以發(fā)現(xiàn),每進(jìn)行一層蝶形計(jì)算之后,序列對(duì)折一半。顯然對(duì)折的比特位從最高位開始,直到最低位結(jié)束,層層依次迭代。因?yàn)槊窟M(jìn)行一層運(yùn)算,頻域值得序號(hào)進(jìn)行一次奇偶交換,等于頻域值對(duì)折的比特位從最低位開始,直到最高位結(jié)束。需要注意的是k值不會(huì)有逆序的操作。最后得到的頻域值,進(jìn)行一次逆序操作。程序如下:
function X_k=fft2_dif(x_n)
? ? N1 =length(x_n);
? ? L ?=ceil(log2(N1));
? ? N ?=2^L;
? ? X_t=zeros(1,N);
? ? %如果序列不是2整數(shù)次冪,那么進(jìn)行補(bǔ)零處理
? ? for m=1:N
? ? ? ? if(m<=N1)
? ? ? ? ? ? X_t(m)=x_n(m);
? ? ? ? else
? ? ? ? ? ? X_t(m)=0;
? ? ? ? end
? ? end
? ? for m=1:L %層級(jí)循環(huán)
? ? ? ? N ? ? =2^(L-m+1);%W(N,k)中N值
? ? ? ? k_max =N/2-1;%W(N,k)中最大k值
? ? ? ? g_max =2^(m-1);%一層有多少組獨(dú)立的蝶形圖
? ? ? ?for g=0:g_max-1 %層內(nèi)分組 ? ?
? ? ? ? ? ? for k=0:k_max %組內(nèi)分對(duì) ? ? ? ? ? ? ? ??
? ? ? ? ? ? ? ? num_1 ? ? =(2*g+0)*2^(L-m)+ k+1;
? ? ? ? ? ? ? ? num_2 ? ? =(2*g+1)*2^(L-m)+ k+1;?
? ? ? ? ? ? ? ? X1 ? ? ? ?=X_t(num_1) + X_t(num_2);
? ? ? ? ? ? ? ? X2 ? ? ? ?=(X_t(num_1) - X_t(num_2))*exp(-1j*2*pi*k/N);
? ? ? ? ? ? ? ? X_t(num_1)=X1;
? ? ? ? ? ? ? ? X_t(num_2)=X2; ? ? ? ? ? ? ? ??
? ? ? ? ? ? end
? ? ? ?end
? ? end
? ?
? ? X_k=zeros(1,N); ? ?
? ? for m=0:2^L-1
? ? ? ? k=0; %輸出逆序運(yùn)算 ? ?
? ? ? ? for n=1:L
? ? ? ? ? ? k=bitshift(k,1) + bitget(m,n); ? ? ?
? ? ? ? end
? ? ? ? X_k(m+1)=X_t(k+1);
? ? end
end
8,下面測(cè)試按頻率基2拆分的正確性
x_n =[0 1 2 3 4 5 6 7 8 7 6 5 4 3 2 1];
Xk ?=fft2_dit(x_n);%測(cè)試輸出
Xp ?=fft(x_n);%使用matlab自帶的函數(shù)
Xk ?=Xk.'
Xp ?=Xp.'
測(cè)試結(jié)果如下
Xk =
? 64.0000 ? ? ? ? ?
?-26.2741 - 0.0000i
? ? ? ? 0 ? ? ? ? ?
? -3.2398 - 0.0000i
? ? ? ? 0 ? ? ? ? ?
? -1.4465 + 0.0000i
? ? ? ? 0 ? ? ? ? ?
? -1.0396 + 0.0000i
? ? ? ? 0 ? ? ? ? ?
? -1.0396 + 0.0000i
? ? ? ? 0 ? ? ? ? ?
? -1.4465 + 0.0000i
? ? ? ? 0 ? ? ? ? ?
? -3.2398 + 0.0000i
? ? ? ? 0 ? ? ? ? ?
?-26.2741 - 0.0000i
Xp =
? ?64.0000
? -26.2741
? ? ? ? ?0
? ?-3.2398
? ? ? ? ?0
? ?-1.4465
? ? ? ? ?0
? ?-1.0396
? ? ? ? ?0
? ?-1.0396
? ? ? ? ?0
? ?-1.4465
? ? ? ? ?0
? ?-3.2398
? ? ? ? ?0
? -26.2741
自此,快速傅里葉算法研究到此結(jié)束,如果對(duì)你有所幫助,請(qǐng)點(diǎn)一個(gè)贊,謝謝。
總結(jié)
以上是生活随笔為你收集整理的快速傅里叶变换FFT的代码实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 抑菌洗手液做MSDS中英文报告详细说明
- 下一篇: Git 常用的命令之避免尴尬