日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java fft 频谱算法_快速傅里叶变换(FFT)算法原理及代码解析

發(fā)布時(shí)間:2025/4/5 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java fft 频谱算法_快速傅里叶变换(FFT)算法原理及代码解析 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

FFT與DFT關(guān)系:

快速傅里葉變換(Fast Fourier Transform)是離散傅里葉(DFT)變換的一種快速算法,簡(jiǎn)稱FFT,通過FFT可以將一個(gè)信號(hào)從時(shí)域變換到頻域;FFT(快速傅里葉變換)其本質(zhì)就是DFT,只不過可以快速的計(jì)算出DFT結(jié)果,它只是傅立葉變換算法實(shí)現(xiàn)過程的一種改進(jìn)。

要弄懂FFT,必須先弄懂DFT,DFT(DiscreteFourier Transform) 離散傅里葉變換的縮寫,咱們先來簡(jiǎn)單討論一下DFT。DFT(FFT)的作用:可以將信號(hào)從時(shí)域變換到頻域,而且時(shí)域和頻域都是離散的,通俗的說,可以求出一個(gè)信號(hào)由哪些正弦波疊加而成,求出的結(jié)果就是這些正弦波的幅度和相位。

DFT的公式:

其中X(k)表示DFT變換后的數(shù)據(jù),x(n)為采樣的模擬信號(hào),公式中的x(n)可以為復(fù)信號(hào),實(shí)際當(dāng)中x(n)都是實(shí)信號(hào),即虛部為0,此時(shí)公式可以展開為:

那么,對(duì)于一個(gè) 的序列進(jìn)行不斷分解,就可以得出如下所謂的蝶形圖:

FFT處理蝶形運(yùn)算

蝶形運(yùn)算的規(guī)律:同一級(jí)中所有蝶形的輸入點(diǎn)在同一豎直線上,意味著我們可以按級(jí)來運(yùn)算,對(duì)于M級(jí)的蝶形,編個(gè)M次循環(huán)就好了;所有數(shù)據(jù)點(diǎn)在運(yùn)算后不會(huì)竄位,即計(jì)算后可以將結(jié)果存入原來的地址空間。

每級(jí)N/2個(gè)蝶都需要用到系數(shù)WN,這里稱它為旋轉(zhuǎn)因子。我們來觀察旋轉(zhuǎn)因子WN的規(guī)律。以8點(diǎn)的蝶形圖為例:

可見,第L級(jí)的旋轉(zhuǎn)因子為:

可以看到,每個(gè)蝶的兩個(gè)輸入點(diǎn)下標(biāo)跨度是不一樣的。比如第一級(jí)中是相鄰兩個(gè)數(shù)據(jù)作蝶運(yùn)算,第二級(jí)中是兩個(gè)輸入點(diǎn)隔開一個(gè)點(diǎn),而第三級(jí)隔開三個(gè)點(diǎn)。不難找到規(guī)律:第L級(jí)中,第二個(gè)輸入點(diǎn)的坐標(biāo)是第一個(gè)點(diǎn)的坐標(biāo)+space,space=Math.Pow(2, L)=num。

FFT的算法是寫一個(gè)三重循環(huán):第一重循環(huán)對(duì)每一級(jí)運(yùn)算(每級(jí)含num=Math.Pow(2, L)個(gè)蝶形);

第二重對(duì)每一個(gè)旋轉(zhuǎn)因子對(duì)應(yīng)的蝶運(yùn)算, 那么有幾個(gè)蝶呢?很簡(jiǎn)單,每級(jí)都應(yīng)該有N/2個(gè)蝶,而每個(gè)因子對(duì)應(yīng)N/2 / num個(gè)蝶;

第三重循環(huán)對(duì)每個(gè)蝶進(jìn)行計(jì)算,需要注意的一是循環(huán)下標(biāo)起始點(diǎn)的位置,二是每次計(jì)算需要申明臨時(shí)變量來保存輸入數(shù)據(jù)點(diǎn)。

實(shí)現(xiàn)代碼:

FFT算法的原理是通過許多小的更加容易進(jìn)行的變換去實(shí)現(xiàn)大規(guī)模的變換,降低了運(yùn)算要求,提高了與運(yùn)算速度。FFT不是DFT的近似運(yùn)算,它們完全是等效的。

傅里葉變換的C語言編程

對(duì)于快速傅里葉變換FFT,第一個(gè)要解決的問題就是碼位倒序。假設(shè)一個(gè)N點(diǎn)的輸入序列,那么它的序號(hào)二進(jìn)制數(shù)位數(shù)就是t=log2N。碼位倒序要解決兩個(gè)問題:將t位二進(jìn)制數(shù)倒序;

將倒序后的兩個(gè)存儲(chǔ)單元進(jìn)行交換。如果輸入序列的自然順序號(hào)i用二進(jìn)制數(shù)表示,例如若最大序號(hào)為15,即用4位就可表示n3n2n1n0,則其倒序后j對(duì)應(yīng)的二進(jìn)制數(shù)就是n0n1n2n3。

代碼如下:

復(fù)數(shù)類型定義及其運(yùn)算

#define N 64 //64點(diǎn)

#define log2N 6 //log2N=6

/*復(fù)數(shù)類型*/

typedef struct

{

float real;

float img;

}complex;

complex xdata x[N]; //輸入序列

/*復(fù)數(shù)加法*/

complex add(complex a,complex b)

{

complex c;

c.real=a.real+b.real;

c.img=a.img+b.img;

return c;

}

/*復(fù)數(shù)減法*/

complex sub(complex a,complex b)

{

complex c;

c.real=a.real-b.real;

c.img=a.img-b.img;

return c;

}

/*復(fù)數(shù)乘法*/

complex mul(complex a,complex b)

{

complex c;

c.real=a.real*b.real - a.img*b.img;

c.img=a.real*b.img + a.img*b.real;

return c;

}

/***碼位倒序函數(shù)***/

void Reverse(void)

{

unsigned int i,j,k;

unsigned int t;

complex temp;//臨時(shí)交換變量

for(i=0;i

{

k=i;//當(dāng)前第i個(gè)序號(hào)

j=0;//存儲(chǔ)倒序后的序號(hào),先初始化為0

for(t=0;t

{

j<>

j|=(k&1);//j左移一位然后加上k的最低位

k>>=1;//k右移一位,次低位變?yōu)樽畹臀?/p>

}

if(j>i)//如果倒序后大于原序數(shù),就將兩個(gè)存儲(chǔ)單元進(jìn)行交換(判斷j>i是為了防止重復(fù)交換)

{

temp=x;

x=x[j];

x[j]=temp;

}

}

}

總結(jié):

FFT是離散傅立葉變換的快速算法,可以將一個(gè)信號(hào)變換到頻域。有些信號(hào)在時(shí)域上是很難看出什么特征的,但是如果變換到頻域之后,就很容易看出特征了。這就是很多信號(hào)分析采用FFT變換的原因。另外,FFT可以將一個(gè)信號(hào)的頻譜提取出來,這在頻譜分析方面也是經(jīng)常用的。

總結(jié)

以上是生活随笔為你收集整理的java fft 频谱算法_快速傅里叶变换(FFT)算法原理及代码解析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。