小小的研究快速傅里葉的原因是老師講完了快速傅里葉,還在雲里霧里時,老師讓人用C語言寫出來,覺得難得好笑,然后就點名到我了。
公式推導:從傅里葉到推導到快速傅里葉,這樣的公式推導書上,網上太多了,我就不在這里詳細推導了。會列出及重要的結果:幫助我使用快速傅里葉。
這個圖只有一維, 也是蝶形算法最基本最簡單的一個,最好理解。看第二個框圖,前端輸入是x(),右邊是X(),也就是傅里葉變換的結果,1框圖是詳細計算步驟,就這兩步,特別簡單,本身傅里葉特別復雜,計算量特別大,這個我們介紹的算法相比之下,計算量大大減小,減少多少看書就知道了。
上圖最基本的單位大概理解了,下面是基本的公式估計也就理解了:
不理解的話,小小的解釋下,左邊是傅里葉結果,右邊的輸入x1(k),x2(k),Wnk,,估計就Wnk不理解,另兩個就是從前端的輸入來的,Wnk,我就動手解釋下怎么算的:
上圖把Wnk轉化為復數,這樣那個Wnk才能真正的用於實踐,看了這個東西,估計也不會算,反正我只看了我也不會,先不管那個N,k,先看看八位蝶形算法:
原理最關鍵的就是這個,左端輸入,通過很多小的蝶形運算基本單位,就可以得到左端的結果。正常的人都可以發現出來的順序好像出問題了,規律直接告訴:
就是把所屬的序號轉化為二進制,進行log2N次圓周移位。這是我總結的,比書上的簡單,輸入自然序出來倒序,輸入倒序出來自然序。
講到這里,應該是懂了怎么算,但是為啥要這么算,得看書去,公式推導,我自己推估計也不行,但是知道怎么回事就行。
開始講程序了,程序里的注釋應該很簡單明了,根據上面的理解估計應該沒問題,加上我的文字解釋真的太簡單了。
這兩個頭文件,估計都知道,能運行C語言的環境基本上都有,這個沒問題。
定義兩個參數:N,就是輸入多少個點,也就是數據,必須滿足2的多少次方,8,16,64,128,等等;那個log2N,就是2的多少次方的那個多少,比如說,64,就是2的6次方。
先定義一個結構體,就是復數的實部real,虛部img,很多頭文件complex都有相關的定義,但是那個頭文件麻煩,兼容性不好,所以這里主動自己定義了。
x[N]這個結構體數組就是輸入的數組,虛部都是0,因為采樣回來的沒有虛部,順便說明下,下面的運算基本上都是復數的方式進行的。
這里定義了一個數組,按照道理來說,應該程序自己算啊,其實是這樣的,在實際的工程應用當中,這樣的運算是認為有點浪費資源的,而且應用當中輸入的點數也就是數據。都是固定的,所以直接計算好了定義成數組,方便高效。
這樣的數據哪里來的呢,方法有很多比如EXCEL,或者matlab,或者其他的,我推薦使用matlab,寫一個小程序就行了:如圖所示
多少位的改上面的參數就行了,順便說一下,這是我第一次使用matlab做那么一點有用的事。
這里定義幾個子函數,懂復數的人基本上都知道,如果忘了也沒關系,反正懂了這個久了不用也會忘記,會調用就行。
前面將原理的時候說了,輸入自然序出來倒序,輸入倒序,出來自然序,所以必須將倒倒序轉化為自然序,因為我們想要的肯定是輸入自然序,輸出自然序。
其實得到自然序,主要的就是這個位運算,要是熟悉代碼的人,一看就明白,不熟悉的自己下來仔細推導一下。
最后那個if可能很多人就不明白了,很簡單,比如八位的輸入01234567輸出04261537,這里發現,需要交換數據的1和4,3和6,只需要交換一次就可以。
最關鍵的就是這個算法了,就是所謂的蝶形運算,給了圖我覺得真的不容易懂,我反正看圖叫我寫出來也不可能,因為我根本不清楚,到底是怎樣得到輸出的。
下面說說我的理解,這段文字配合上面的蝶形運算的圖哈,其實就是算每一個節點,每一個節點都是利用,里面的每一個參數我都講了,我們計算的時候,如果想知道某一個輸出的結果,那個必須知道前一級對應的節點,然后前一級對應的節點又必須知道更前一級的某些節點,有些人可能還是不清楚怎樣才知道自己需要前一級的那些節點呢,有這樣疑問的同志估計還是不明白那個蝶形圖到底怎么回事,那個圖就是告訴咩一個數據對應的關系,前者箭頭指向后者就是后者需要前者,這很明了了。
這里說說算法的基本思想流程,先算第一級蝶形運算,,每一個第一級都要算完,然后再算
,每一級每一個數據都要算完,這樣才能算下一級,以此類推,算出最終結果。
算法里有三重運算,每一個變量也就是ijk,這三個循環變量的封頂的那個數據,其實很容易理解,先假設輸入八位數據,然后把相應的封頂數據算出來,再弄個16個數據的,規律自己就出來了,自己動手算一下,就明白了。
需要的函數都講完了,理解與否看造化。下面是主函數和輸出的結果。
這里的數據結果和matlab完全符合,matlab那個數據我沒有截圖,但是是完全正確的。