FFT算法

FFT算法

分類: 信號處理 2582人閱讀 評論(1) 收藏 舉報
這幾天,我一直在看FFT算法,下面分享一下我這幾天學到的東西   
    
  1。直接計算離散傅立葉變換具有n^2的複雜度,而cooley   和tukey在1965年發現了一種計算離散傅立葉變換的快速算法(即通   
    
  常所說的FFT算法),這個算法在計算變換長度n=2^k的離散傅立葉變換時,具有   n*k   的複雜度,即O(n)=n*log2(n),   下面以此   
    
  爲例,講講快FFT的特點。   
      1)複數運算:傅立葉變換是基於複數的,因此首先知道複數的運算規則,在FFT算法中,只涉及複數的加、減和乘法三種運   
    
  算。一個複數可表示爲   c=(   x,yi),   x   爲複數的實部,y爲複數的虛部,i爲虛數單位,等於-1的平方根。複數的運算規則是:   
    
  若c1   表示爲   (x1,y1),c2   表示爲(x2,y2),   則   (x1+x2,y1+y2)和(x1-x2,y1-y2)分別等於c1+c2的和,c1-c2的差,複數的乘法   
    
  相對複雜一些,c1*c2   的積爲   (x1*x2-y1*y2,x1*y2+x2*y1).   
        
        2)蝶形變換:普通的FFT算法稱爲基2的FFT算法,這種算法的核心是蝶形變換   長度爲n=2^k1的變換共需要做   k1   *   n/2   次   
    
  蝶形變換,若需變換數據表示爲一個複數數組c[],則每次蝶形變換有2個輸入   c[i],c[i+s],兩個輸出:c[i],c[i+s],s成爲翅   
    
  間距。   每個變換的基本算法是:   
        
      t=wr   *   c[i+s];     
      c[i+s]=c[i]-t;   
      c[i]=c[i]+t;   
    
        前面說過,長度爲n=2^k1的變換共需要做   k1   *     
    
  n/2次變換,實際的程序是一個3層循環,共需要k1*k2*(k3/2)次變換(k2*k3/2=n/2)。前面的wr是w的整數次方,w=e^(-2*PI/k3   
    
  )   (k3=2,4,8,16...n,PI是圓周率),也成爲旋轉因子,例如n=32的變換需要log2(32)=5趟變換:   
        第1趟變換需要16*1次變換,翅間距是1,     若w=e^(-2*PI/2),   則wr=w^1   
        第2趟變換需要8*2次變換,   翅間距是2,     若w=e^(-2*PI/4),   則wr=w^1,w^2   
        第3趟變換需要4*2次變換,   翅間距是4,     若w=e^(-2*PI/8),   則wr=w^1,w^2,w^3,w^4     
        第4趟變換需要2*8次變換,   翅間距是8,     若w=e^(-2*PI/16),則wr=w^1,w^2,w^3,w^4,w^5,w^6,w^7,w^8   
        第5趟變換需要16*1次變換,翅間距是16,   若w=e^(-2*PI/32),則wr=w^1,w^2,w^3,w^4,w^5...w^15,w^16   
    
      3)w數組,w   的實部=cos(2*PI/k3),w的虛部=   -sin(2*PI/k3),計算出w,則wr數組就好求了,不斷即相乘即可,當然也可以通   
    
  過三角函數直接求。w^p   的實部=cos(2*PI/K3*p),虛部=-sin(2*PI/k3*p)   
    
    4)複數數組排序,在基2的蝶形變換中,複數數組需要重新排序,c[i]   要放置到數組c的第   reverse(c[i])     
    
  的位置,m=reverse(n)   函數的算法是這樣的,若   n的   k位2進制的爲b[],   b[k-1],B[k-2],...b[2],b[1],b[0],(   b[i]   等於1   
    
  或者0,b[0]爲最低bit).   則m=reverse(n)的2進制的爲   b[0],b[1],b[2],b[3],...b[k-1]   (b[k-1]爲最低bit).   
    
        更復雜的變換算法:基2的蝶形變換算法不止一種,它可分爲2類,一類爲基2時分傅立葉變換,另一類爲基2頻分傅立葉變   
    
  換。上例的變爲基2時分算法,在每一趟變換中,翅間距依次變大,第一趟爲2,最後一趟爲n/2,數組重排在變換之前進行,基   
    
  2頻分算法正好相反,翅間距依次縮小,起於n/2,止於2,數組重排在蝶形變換之後進行。   在<傅立葉變換>一書中,提到3   
    
  種基2時分變換,3種基2頻分變換。上述算法稱爲基2時分FFT第二種算法。我在看你的這個程序的同時,還看到朱志剛寫的一   
    
  個FFT程序,這個程序的算法是基2時分FFT第一種算法,它比經典的算法更復雜,需要對wr數組進行逆序排列。   
    
  ///這個程序不太直觀的地方。   
      
    
  在計算wp是,虛部使用sin函數直接計算,但是實部沒有直接計算,按照數學公式cos(x)=1-2*sin(x/2)^2,這裏,wpr只取-2*s   
    
  in(x/2),比實際值小1,故在計算w時,採用以下算式:   
                      wr   =   wr   *   wpr   -   wi   *   wpi   +   wr;   
                      wi   =   wi   *   wpr   +   wtemp   *   wpi   +   wi;   
                    wr*wpr-wi*wpi+wr   -->   wr*(1+wpr)-wi*wpi,可以看到這裏將1重新補上了。   
    
    
  //更復雜的FFT算法,除了基2   的FFT算法外,還有更加複雜的基4算法,基8算法,甚至基3,基5算法,純粹的基4算法只能計算   
    
  長度爲4^k的變換,但它比基2的算法速度更高。爲了提高速度,很多FFT算法使用混合基算法。如我看到的2個效率很高程序均   
    
  使用了混合基算法。第一個程序是來自:http://momonga.t.u-tokyo.ac.jp/~ooura/fft.html,它使用了基2,基4,甚至基8混   
    
  合算法,共提供了6同樣功能的算法。可對長度爲2^k的序列做FFT,這個程序的寫的很複雜,我現在尚不能完全看懂。另一個   
    
  程序來自:http://hjem.get2net.dk/jjn/fft.htm。相對於前者,這個程序相對簡單一點。它使用了基2,基3,基4,基5,基8,   
    
  基10   混合算法,幾乎可以計算任意長度的FFT。具體的,當序列長度n爲2,3,5,7,11,13,17,19,23,29,31,37等小素數時,或   
    
  者n的最大素因數小於等於37時,可計算這個序列的FFT。   
    
    關於FFT算法的其它文檔:http://www.jjj.de/fxt/fxtbook.pdf,   websuite:   http://www.jjj.de/fxt/,   這是我見過的關於變換算法的最全面的文檔。 
發佈了14 篇原創文章 · 獲贊 4 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章