库利-图基快速傅里叶变换算法 (英語:Cooley–Tukey FFT algorithm )[ 1] 是最常見的快速傅里葉變換 算法。這一方法以分治法 為策略遞歸 地將長度為N = N 1 N 2 的DFT分解為長度分別為N 1 和N 2 的兩個較短序列的DFT,以及與旋轉因子的複數乘法。這種方法以及FFT的基本思路在1965年詹姆斯·庫利 和約翰·圖基 合作發表《An algorithm for the machine calculation of complex Fourier series 》之後開始為人所知。但後來發現,實際上這兩位作者只是重新發明了高斯 在1805年就已經提出的算法(此算法在歷史上數次以各種形式被再次提出)。
库利-图基算法最有名的應用,是將序列長為N的DFT分割為兩個長為N/2的子序列的DFT,因此這一應用只適用於序列長度為2的冪的DFT計算,即基2-FFT。實際上,如同高斯和库利與图基都指出的那樣,库利-图基算法也可以用於序列長度N為任意因數分解形式的DFT,即混合基FFT,而且還可以應用於其他諸如分裂基FFT等變種。儘管库利-图基算法的基本思路是採用遞歸的方法進行計算,大多數傳統的算法實現都將顯示的遞歸算法改寫為非遞歸的形式。另外,因為库利-图基算法是將DFT分解為較小長度的多個DFT,因此它可以同任一種其他的DFT算法聯合使用。
複雜度
離散傅立葉變換 的複雜度為
O
(
n
2
)
{\displaystyle {\mathcal {O}}(n^{2})}
(可參考大O符號 )
快速傅立葉變換 的複雜度為
O
(
N
log
N
)
{\displaystyle {\mathcal {O}}(N\log N)}
,分析可見下方架構圖部分,級數為
log
N
{\displaystyle \log N}
而每一級的複雜度為
N
{\displaystyle N}
,故複雜度為
O
(
N
log
N
)
{\displaystyle {\mathcal {O}}(N\log N)}
蝶形結
在FFT演算法中,使用到的蝶形結 可以分為Cooley-Tukey和Gentleman-Sande兩種,而他們進行的運算互為對方的逆運算,同時對應了DFT和IDFT當中會使用到的運算單元。
Cooley–Tukey Butterfly
Gentleman–Sande Butterfly
在Cooley-Tukey蝶形結 當中,上下兩列的輸出分別為:
a
+
c
∗
b
{\displaystyle a+c*b}
a
−
c
∗
b
{\displaystyle a-c*b}
而在Gentleman–Sande蝶形結 當中,上下兩列的輸出分別為:
a
+
b
{\displaystyle a+b}
(
a
−
b
)
∗
c
−
1
{\displaystyle (a-b)*c^{-}1}
可以注意到在進行完一次Cooley-Tukey蝶形結 和Gentleman–Sande蝶形結 的運算之後,原先輸入的(a, b)會變成(2a, 2b),而這項常數倍的差異可以在所有的蝶形結 運算結束後再處理,不需要直接改變這兩項蝶形結 運算單元的常數。
以下是這兩種蝶形運算應用在快速傅立葉轉換 中性質的比較。
Cooley-Tukey 蝶形運算:
輸入順序:以位元反轉順序(bit-reversed order)輸入資料。
輸出順序:產生以正常順序(normal order)輸出的結果,對應到分時快速傅立葉轉換 (Decimation-in-Time FFT)。
使用時機:由於輸入非按照正常順序,輸入端資料流控制較DIF-FFT更為複雜。
Gentleman-Sande 蝶形運算:
輸入順序:以正常順序(normal order)輸入資料。
輸出順序:產生以位元反轉順序(bit-reversed order)輸出的結果,對應到分頻快速傅立葉轉換 (Decimation-in-Frequency FFT)。
使用時機:由於輸入會按照正常順序,輸入端資料流控制較DIT-FFT更為簡單。
而Utsav Banerjee 等人在2019年發表的〈An Energy-Efficient Configurable Lattice Cryptography Processor for the Quantum-Secure Internet of Things〉[ 2] 提出了一個整合式蝶形運算單元的架構,同時包含了Cooley-Tukey蝶形結 和Gentleman–Sande蝶形結 的運算,以滿足在硬體實作上同時兼顧兩者的需求。
整合式蝶形運算:
組成:兩個加法器、兩個減法器、一個乘法器、和四個數據多工器 (MUX)。
原理:藉由數據多工器 (MUX)使得每次只有其中一個加法器和一個減法器的輸出會被使用,以此呈現原先Cooley-Tukey蝶形結 和Gentleman–Sande蝶形結 中的運算,在Cooley-Tukey蝶形結 中會跳過前半部分的加法器和減法器,使得乘法器放置在有效的加法器和減法器之前,而Gentleman–Sande蝶形結 則正好相反,跳過後半部分的加法器和減法器,使得乘法器放置在有效的加法器和減法器之後。而至於是要呈現哪一個運算單元的特性就可以根據當下輸入輸出等情況做選擇,藉此彌補硬體實作上和軟體設計相比缺乏彈性的問題,同時避免硬體資源的浪費。
優點:
節省資源:通過整合 Cooley-Tukey 和 Gentleman–Sande 的蝶形結構,減少硬體面積。
提升效能:避免處理位元反轉(bit reversal)等複雜操作,提升運算效率。
高度彈性:支援兩種變換類型以適用於多種不同應用情境。
由於蝶形運算單元的組成變得複雜而使得其電路面積(area)和延遲(latency)增加,但文章[ 3] 中指出由於關鍵路徑 不在該蝶形運算單元之內,因此並不會影響系統的整體表現,此外其造成的額外面積負擔在系統中也是微乎其微的。
時域/頻域抽取法
在FFT演算法中,針對輸入做不同方式的分組會造成輸出順序上的不同。如果我們使用時域抽取(Decimation-in-time),那麼輸入的順序將會是位元反轉排列(bit-reversed order),輸出將會依序排列。但若我們採取的是頻域抽取(Decimation-in-frequency),那麼輸出與輸出順序的情況將會完全相反,變為依序排列的輸入與位元反轉排列的輸出。
時域抽取法
我們可以將DFT公式中的項目在時域上重新分組,這樣就叫做時域抽取(Decimation-in-time),在這裡
e
−
j
(
2
π
n
k
N
)
{\displaystyle e^{-j(2\pi {\frac {nk}{N}})}}
將會被代換為旋轉因子 (twiddle factor)
W
N
n
k
{\displaystyle W_{N}^{nk}}
。
X
[
k
]
=
∑
n
=
0
N
−
1
x
[
n
]
e
−
j
(
2
π
n
k
N
)
k
=
0
,
1
,
…
,
N
−
1
{\displaystyle X[k]=\sum _{n=0}^{N-1}x[n]e^{-j(2\pi {\frac {nk}{N}})}\qquad k=0,1,\ldots ,N-1}
=
∑
n
e
v
e
n
x
[
n
]
W
N
n
k
+
∑
n
o
d
d
x
[
n
]
W
N
n
k
{\displaystyle =\sum _{n\ even}x[n]W_{N}^{nk}+\sum _{n\ odd}x[n]W_{N}^{nk}}
=
∑
r
=
0
(
N
/
2
)
−
1
x
[
2
r
]
W
N
2
r
k
+
∑
r
=
0
(
N
/
2
)
−
1
x
[
2
r
+
1
]
W
N
(
2
r
+
1
)
k
{\displaystyle =\sum _{r=0}^{(N/2)-1}x[2r]W_{N}^{2rk}+\sum _{r=0}^{(N/2)-1}x[2r+1]W_{N}^{(2r+1)k}}
=
∑
r
=
0
(
N
/
2
)
−
1
x
[
2
r
]
W
N
2
r
k
+
W
N
k
∑
r
=
0
(
N
/
2
)
−
1
x
[
2
r
+
1
]
W
N
2
r
k
{\displaystyle =\sum _{r=0}^{(N/2)-1}x[2r]W_{N}^{2rk}+W_{N}^{k}\sum _{r=0}^{(N/2)-1}x[2r+1]W_{N}^{2rk}}
=
∑
r
=
0
(
N
/
2
)
−
1
x
[
2
r
]
W
N
/
2
r
k
+
W
N
k
∑
r
=
0
(
N
/
2
)
−
1
x
[
2
r
+
1
]
W
N
/
2
r
k
{\displaystyle =\sum _{r=0}^{(N/2)-1}x[2r]W_{N/2}^{rk}+W_{N}^{k}\sum _{r=0}^{(N/2)-1}x[2r+1]W_{N/2}^{rk}}
=
G
[
k
]
+
W
N
k
H
[
k
]
{\displaystyle =G[k]+W_{N}^{k}H[k]}
在這邊我們要注意的是,我們所替換的G[k]與H[k]具有週期性:
{
G
[
k
+
N
2
]
=
G
[
k
]
H
[
k
+
N
2
]
=
H
[
k
]
{\displaystyle {\begin{cases}G[k+{\frac {N}{2}}]=G[k]\\H[k+{\frac {N}{2}}]=H[k]\end{cases}}}
还注意到系数具有对称性:
W
N
k
+
N
/
2
=
−
W
N
k
{\displaystyle W_{N}^{k+N/2}=-W_{N}^{k}}
上述的推導可以劃成下面的圖:
劃紅框處所示的
N
2
{\displaystyle {\frac {N}{2}}}
點DFT架構如下圖所示:
劃紅框處所示的
N
4
{\displaystyle {\frac {N}{4}}}
點DFT架構如下圖所示:
下圖是一個8點DIT FFT的完整架構圖。
頻域抽取法
我們可以將DFT公式中的項目在頻域上重新分組,這樣就叫做頻域抽取(Decimation-in-frequency)。
首先先觀察在頻域上偶數項的部分:
X
[
2
r
]
=
∑
n
=
0
N
−
1
x
[
n
]
W
N
n
(
2
r
)
r
=
0
,
1
,
⋯
,
N
2
−
1
{\displaystyle X[2r]=\sum _{n=0}^{N-1}x[n]W_{N}^{n(2r)}\ r=0,1,\cdots ,{\frac {N}{2}}-1}
=
∑
n
=
0
N
2
−
1
x
[
n
]
W
N
2
n
r
+
∑
n
=
N
2
N
−
1
x
[
n
]
W
N
2
n
r
{\displaystyle =\sum _{n=0}^{{\frac {N}{2}}-1}x[n]W_{N}^{2nr}+\sum _{n={\frac {N}{2}}}^{N-1}x[n]W_{N}^{2nr}}
=
∑
n
=
0
N
2
−
1
x
[
n
]
W
N
2
n
r
+
∑
n
=
0
N
2
−
1
x
[
n
+
N
2
]
W
N
2
r
[
n
+
N
2
]
{\displaystyle =\sum _{n=0}^{{\frac {N}{2}}-1}x[n]W_{N}^{2nr}+\sum _{n=0}^{{\frac {N}{2}}-1}x[n+{\frac {N}{2}}]W_{N}^{2r[n+{\frac {N}{2}}]}}
∵
W
N
2
r
[
n
+
N
2
]
=
W
N
2
r
n
W
N
r
N
=
W
N
2
r
n
{\displaystyle {\color {Gray}\because W_{N}^{2r[n+{\frac {N}{2}}]}=W_{N}^{2rn}W_{N}^{rN}=W_{N}^{2rn}}}
=
∑
n
=
0
N
2
−
1
x
[
n
]
W
N
2
r
n
+
∑
n
=
0
N
2
−
1
x
[
n
+
N
2
]
W
N
2
r
n
{\displaystyle =\sum _{n=0}^{{\frac {N}{2}}-1}x[n]W_{N}^{2rn}+\sum _{n=0}^{{\frac {N}{2}}-1}x[n+{\frac {N}{2}}]W_{N}^{2rn}}
=
∑
n
=
0
N
2
−
1
(
x
[
n
]
+
x
[
n
+
N
2
]
)
W
N
2
r
n
{\displaystyle =\sum _{n=0}^{{\frac {N}{2}}-1}(x[n]+x[n+{\frac {N}{2}}])W_{\frac {N}{2}}^{rn}}
=
∑
n
=
0
N
2
−
1
g
[
n
]
W
N
2
r
n
{\displaystyle =\sum _{n=0}^{{\frac {N}{2}}-1}g[n]W_{\frac {N}{2}}^{rn}}
再觀察在頻域上奇數項的部分:
X
[
2
r
+
1
]
=
∑
n
=
0
N
−
1
x
[
n
]
W
N
n
(
2
r
+
1
)
r
=
0
,
1
,
⋯
,
N
2
−
1
{\displaystyle X[2r+1]=\sum _{n=0}^{N-1}x[n]W_{N}^{n(2r+1)}\ r=0,1,\cdots ,{\frac {N}{2}}-1}
=
∑
n
=
0
N
2
−
1
x
[
n
]
W
N
n
(
2
r
+
1
)
+
∑
n
=
N
2
N
−
1
x
[
n
]
W
N
n
(
2
r
+
1
)
{\displaystyle =\sum _{n=0}^{{\frac {N}{2}}-1}x[n]W_{N}^{n(2r+1)}+\sum _{n={\frac {N}{2}}}^{N-1}x[n]W_{N}^{n(2r+1)}}
=
∑
n
=
0
N
2
−
1
x
[
n
]
W
N
n
(
2
r
+
1
)
+
∑
n
=
0
N
2
−
1
x
[
n
+
N
2
]
W
N
(
2
r
+
1
)
[
n
+
N
2
]
{\displaystyle =\sum _{n=0}^{{\frac {N}{2}}-1}x[n]W_{N}^{n(2r+1)}+\sum _{n=0}^{{\frac {N}{2}}-1}x[n+{\frac {N}{2}}]W_{N}^{(2r+1)[n+{\frac {N}{2}}]}}
∵
W
N
(
2
r
+
1
)
[
n
+
N
2
]
=
W
N
(
2
r
+
1
)
n
W
N
(
2
r
+
1
)
N
2
=
−
W
N
(
2
r
+
1
)
n
{\displaystyle {\color {Gray}\because W_{N}^{(2r+1)[n+{\frac {N}{2}}]}=W_{N}^{(2r+1)n}W_{N}^{(2r+1){\frac {N}{2}}}=-W_{N}^{(2r+1)n}}}
=
∑
n
=
0
N
2
−
1
x
[
n
]
W
N
(
2
r
+
1
)
n
−
∑
n
=
0
N
2
−
1
x
[
n
+
N
2
]
W
N
(
2
r
+
1
)
n
{\displaystyle =\sum _{n=0}^{{\frac {N}{2}}-1}x[n]W_{N}^{(2r+1)n}-\sum _{n=0}^{{\frac {N}{2}}-1}x[n+{\frac {N}{2}}]W_{N}^{(2r+1)n}}
=
∑
n
=
0
N
2
−
1
(
x
[
n
]
−
x
[
n
+
N
2
]
)
W
N
n
(
2
r
+
1
)
{\displaystyle =\sum _{n=0}^{{\frac {N}{2}}-1}(x[n]-x[n+{\frac {N}{2}}])W_{N}^{n(2r+1)}}
=
∑
n
=
0
N
2
−
1
(
x
[
n
]
−
x
[
n
+
N
2
]
)
W
N
n
W
N
2
n
r
{\displaystyle =\sum _{n=0}^{{\frac {N}{2}}-1}(x[n]-x[n+{\frac {N}{2}}])W_{N}^{n}W_{\frac {N}{2}}^{nr}}
=
∑
n
=
0
N
2
−
1
(
h
[
n
]
W
N
n
)
W
N
2
r
n
{\displaystyle =\sum _{n=0}^{{\frac {N}{2}}-1}(h[n]W_{N}^{n})W_{\frac {N}{2}}^{rn}}
上述的推導可以畫成下面的圖:
更進一步的拆解
N
2
{\displaystyle {\frac {N}{2}}}
-point DFT的架構
下圖為8點FFT下
N
4
{\displaystyle {\frac {N}{4}}}
-point DFT的架構
總結上述架構,完整的8點DIF FFT架構圖為
單一基底
利用库利-图基演算法進行離散傅立葉 拆解時,能夠依需求而以2, 4, 8…等2的冪次方為單位進行拆解,不同的拆解方法會產生不同層數快速傅里葉變換 的架構,基底越大則層數越少,複數乘法器也越少,但是每級的蝴蝶形架構則會越複雜,因此常見的架構為2基底、4基底與8基底這三種設計。
2基底
2基底-快速傅立葉演算法(Radix-2 FFT)是最廣為人知的一種库利-图基快速傅立葉演算法分支。此方法不斷地將N點的FFT拆解成兩個'N/2'點的FFT,利用旋轉因子
W
n
k
,
W
N
2
{\displaystyle W^{nk},W^{\frac {N}{2}}}
的對稱性藉此來降低DFT的計算複雜度,達到加速的功效。
而其實前述有關時域抽取或是頻域抽取的方法介紹,即為2基底的快速傅立葉轉換法。以下展示其他種2基底快速傅立葉演算法的連線方法,此種不規則的連線方法可以讓輸出與輸入都為循序排列,但是連線的複雜度卻大大的增加。
4基底
4基底快速傅立葉變換演算法則是承接2基底的概念,在此裡用時域 抽取的技巧,將原本的DFT公式拆解為四個一組的形式:
X
[
k
]
=
∑
n
=
0
N
−
1
x
[
n
]
e
−
j
(
2
π
n
k
N
)
k
=
0
,
1
,
…
,
N
−
1
{\displaystyle X[k]=\sum _{n=0}^{N-1}x[n]e^{-j(2\pi {\frac {nk}{N}})}\qquad k=0,1,\ldots ,N-1}
=
∑
n
=
0
N
4
−
1
x
[
4
n
+
0
]
W
N
(
4
n
+
0
)
k
+
∑
n
=
0
N
4
−
1
x
[
4
n
+
1
]
W
N
(
4
n
+
1
)
k
{\displaystyle =\sum _{n=0}^{{\frac {N}{4}}-1}x[4n+0]W_{N}^{(4n+0)k}+\sum _{n=0}^{{\frac {N}{4}}-1}x[4n+1]W_{N}^{(4n+1)k}}
+
∑
n
=
0
N
4
−
1
x
[
4
n
+
2
]
W
N
(
4
n
+
2
)
k
+
∑
n
=
0
N
4
−
1
x
[
4
n
+
3
]
W
N
(
4
n
+
3
)
k
{\displaystyle +\sum _{n=0}^{{\frac {N}{4}}-1}x[4n+2]W_{N}^{(4n+2)k}+\sum _{n=0}^{{\frac {N}{4}}-1}x[4n+3]W_{N}^{(4n+3)k}}
=
W
N
0
∑
n
=
0
N
4
−
1
x
[
4
n
+
0
]
W
N
4
n
k
+
W
N
1
k
∑
n
=
0
N
4
−
1
x
[
4
n
+
1
]
W
N
4
n
k
{\displaystyle =W_{N}^{0}\sum _{n=0}^{{\frac {N}{4}}-1}x[4n+0]W_{\frac {N}{4}}^{nk}+W_{N}^{1k}\sum _{n=0}^{{\frac {N}{4}}-1}x[4n+1]W_{\frac {N}{4}}^{nk}}
+
W
N
2
k
∑
n
=
0
N
4
−
1
x
[
4
n
+
2
]
W
N
4
n
k
+
W
N
3
k
∑
n
=
0
N
4
−
1
x
[
4
n
+
3
]
W
N
4
n
k
{\displaystyle +W_{N}^{2k}\sum _{n=0}^{{\frac {N}{4}}-1}x[4n+2]W_{\frac {N}{4}}^{nk}+W_{N}^{3k}\sum _{n=0}^{{\frac {N}{4}}-1}x[4n+3]W_{\frac {N}{4}}^{nk}}
W
N
0
F
0
(
k
)
+
W
N
k
F
1
(
k
)
+
W
N
2
k
F
2
(
k
)
+
W
N
3
k
F
3
(
k
)
{\displaystyle W_{N}^{0}F_{0}(k)+W_{N}^{k}F_{1}(k)+W_{N}^{2k}F_{2}(k)+W_{N}^{3k}F_{3}(k)}
在這裡再利用
W
n
k
+
N
4
=
−
W
n
k
+
3
N
4
=
−
j
W
n
k
{\displaystyle W^{nk+{\frac {N}{4}}}=-W^{nk+{\frac {3N}{4}}}=-jW^{nk}}
的特性來進行與2基數FFT類似的化減方法,以降低演算法複雜度。
8基底
在库利-图基算法裡,使用的基底(radix)越大,複數的乘法與記憶體的存取就越少,所帶來的好處不言而喻。但是隨之而來的就是實數的乘法與實數的加法也會增加,尤其計算單元的設計也就越複雜,對於可應用FFT之點數限制也就越嚴格。在表中我們可以看到在不同基底下所需的計算成本。
使用4096點FFT在不同基底下的計算量
動作
2基底
4基底
8基底
複數乘法
22528
15360
10752
實數乘法
0
0
8192
複數加法
49152
49152
49152
實數加法
0
0
8192
記憶體存取
49152
24576
16384
在DFT的公式中,我們重新定義x=[x(0),x(1),…,x(N-1)]T , X=[X(0),X(1),…,X(N-1)]T ,則DFT可重寫為X=FN ‧x。FN 是一個N×N的DFT矩陣,其元素定義為[FN ]ij =WNij (i,j ∈ [0,N-1]),當N=8時,我們可以得到以下的F8 矩陣並且進一步將其拆解。
在拆解成三個矩陣相乘之後,我們可以將複數運算的數量從56個降至24個複數的加法。底下是8基底的SFG。要注意的是所有的輸出與輸入都是複數的形式,而輸出與輸入的排序也並非規律排列,此種排列方式是為了要達到接線的最佳化。
混合基底
2/8基底
在2/8基底的演算法中,我們可以看到我們對於偶數項的輸出會使用2基底的分解法,對於奇數項的輸出採用8基底的分解法。這個做法充分利用了2基底與4基底擁有最少乘法數與加法數的特性。當使用了2基底的分解法後,偶數項的輸出如下所示。
C
2
k
=
∑
n
=
0
N
2
−
1
(
x
2
n
+
x
N
2
+
n
)
W
2
n
k
{\displaystyle C_{2k}=\sum _{n=0}^{{\frac {N}{2}}-1}(x_{2n}+x_{{\frac {N}{2}}+n})W^{2nk}}
奇數項的輸出則交由8基底分解來處理,如下四式所述。
C
8
k
+
1
=
∑
n
=
0
N
8
−
1
{
[
(
x
n
−
x
n
+
N
2
)
−
j
(
x
n
+
N
4
−
x
n
+
3
N
4
)
]
+
W
N
8
[
(
x
n
+
N
8
−
x
n
+
5
N
8
)
−
j
(
x
n
+
3
N
8
−
x
n
+
7
N
8
)
]
}
W
8
n
k
W
n
{\displaystyle C_{8k+1}=\sum _{n=0}^{{\frac {N}{8}}-1}{\begin{Bmatrix}[(x_{n}-x_{n+{\frac {N}{2}}})-j(x_{n+{\frac {N}{4}}}-x_{n+{\frac {3N}{4}}})]+W^{\frac {N}{8}}[(x_{n+{\frac {N}{8}}}-x_{n+{\frac {5N}{8}}})-j(x_{n+{\frac {3N}{8}}}-x_{n+{\frac {7N}{8}}})]\end{Bmatrix}}W^{8nk}W^{n}}
C
8
k
+
5
=
∑
n
=
0
N
8
−
1
{
[
(
x
n
−
x
n
+
N
2
)
−
j
(
x
n
+
N
4
−
x
n
+
3
N
4
)
]
−
W
N
8
[
(
x
n
+
N
8
−
x
n
+
5
N
8
)
−
j
(
x
n
+
3
N
8
−
x
n
+
7
N
8
)
]
}
W
8
n
k
W
5
n
{\displaystyle C_{8k+5}=\sum _{n=0}^{{\frac {N}{8}}-1}{\begin{Bmatrix}[(x_{n}-x_{n+{\frac {N}{2}}})-j(x_{n+{\frac {N}{4}}}-x_{n+{\frac {3N}{4}}})]-W^{\frac {N}{8}}[(x_{n+{\frac {N}{8}}}-x_{n+{\frac {5N}{8}}})-j(x_{n+{\frac {3N}{8}}}-x_{n+{\frac {7N}{8}}})]\end{Bmatrix}}W^{8nk}W^{5n}}
C
8
k
+
3
=
∑
n
=
0
N
8
−
1
{
[
(
x
n
−
x
n
+
N
2
)
+
j
(
x
n
+
N
4
−
x
n
+
3
N
4
)
]
+
W
3
N
8
[
(
x
n
+
N
8
−
x
n
+
5
N
8
)
+
j
(
x
n
+
3
N
8
−
x
n
+
7
N
8
)
]
}
W
8
n
k
W
3
n
{\displaystyle C_{8k+3}=\sum _{n=0}^{{\frac {N}{8}}-1}{\begin{Bmatrix}[(x_{n}-x_{n+{\frac {N}{2}}})+j(x_{n+{\frac {N}{4}}}-x_{n+{\frac {3N}{4}}})]+W^{\frac {3N}{8}}[(x_{n+{\frac {N}{8}}}-x_{n+{\frac {5N}{8}}})+j(x_{n+{\frac {3N}{8}}}-x_{n+{\frac {7N}{8}}})]\end{Bmatrix}}W^{8nk}W^{3n}}
C
8
k
+
7
=
∑
n
=
0
N
8
−
1
{
[
(
x
n
−
x
n
+
N
2
)
+
j
(
x
n
+
N
4
−
x
n
+
3
N
4
)
]
−
W
3
N
8
[
(
x
n
+
N
8
−
x
n
+
5
N
8
)
+
j
(
x
n
+
3
N
8
−
x
n
+
7
N
8
)
]
}
W
8
n
k
W
7
n
{\displaystyle C_{8k+7}=\sum _{n=0}^{{\frac {N}{8}}-1}{\begin{Bmatrix}[(x_{n}-x_{n+{\frac {N}{2}}})+j(x_{n+{\frac {N}{4}}}-x_{n+{\frac {3N}{4}}})]-W^{\frac {3N}{8}}[(x_{n+{\frac {N}{8}}}-x_{n+{\frac {5N}{8}}})+j(x_{n+{\frac {3N}{8}}}-x_{n+{\frac {7N}{8}}})]\end{Bmatrix}}W^{8nk}W^{7n}}
以上式子就是2/8基底的FFT快速演算法。在架構圖上可化為L型的蝴蝶運算架構,如下圖所示。
而下圖表示的是一個64點的FFT使用2/8基底的架構圖。雖然2/8基底的演算法縮減了
W
N
8
,
W
3
N
8
{\displaystyle W^{\frac {N}{8}},W^{\frac {3N}{8}}}
的乘法量,但是這種演算法最大的缺點是跟其他固定基底或是混合基底比較起來,他的架構較為不規則。所以在硬體上比4基底或是2基底更難實現。
2/4/8基底
為了改進Radix 2/8在架構上的不規則性,我們在這裡做了一些修改,如下圖4.。此修改可讓架構更加規則,且所使用的加法器與乘法器數量更加減少,如下表所示。
8n 點FFT在不同演算法下所需複數乘法量
N=8n
2基底
4基底
2/4混合基底
2/4/8基底
8
2
-
2
0
64
98
76
72
48
512
1538
-
1082
824
4096
18434
13996
12774
10168
在這裡我們最小的運算單元稱為PE(Process Element),PE內部包含了2/8基底、2/4基底、2基底的運算,簡化過的信號處理流程與蝴蝶型架構圖可見下圖
22 基底
基底的選擇越大會造成蝴蝶形架構更加複雜,控制電路也會複雜化。因此Shousheng He和Mats Torkelson在1996提出了一個2^2基底的FFT演算法,利用旋轉因子的特性:
W
N
4
=
−
j
{\displaystyle W_{\frac {N}{4}}=-j}
。而–j的乘法基本上只需要將被乘數的實部虛部對調,然後將虛部加上負號即可,這樣的負數乘法被定義為'簡單乘法',因此可以用很簡單的硬體架構來實現。利用上面的特性,22 基底FFT能用串接的方式將旋轉因子以4為單位對DFT公式進行拆解,將蝴蝶形架構層數降到log4N,大幅減少複數乘法器的用量,而同時卻維持了2基底蝴蝶形架構的簡單性,在效能上獲得改進。22 基底DIF FFT演算法的拆解方法如下列公式所述:
N點DFT公式:
X
(
k
)
=
∑
n
=
0
N
−
1
x
(
n
)
W
N
n
k
,
0
≦
k
<
N
{\displaystyle X(k)=\sum _{n=0}^{N-1}x(n)W_{N}^{nk},0\leqq k<N}
利用線性映射將n與k映射到三個維度上面
{
n
=<
N
2
n
1
+
N
4
n
2
+
n
3
>
N
k
=<
k
1
+
2
k
2
+
4
k
3
>
N
{\displaystyle {\begin{cases}n=<{\frac {N}{2}}n_{1}+{\frac {N}{4}}n_{2}+n_{3}>_{N}\\k=<k_{1}+2k_{2}+4k_{3}>_{N}\end{cases}}}
然後套用Common Factor Algorithm(CFA)
X
(
k
1
+
2
k
2
+
4
k
3
)
=
∑
n
3
=
0
N
4
−
1
∑
n
2
=
0
1
∑
n
1
=
0
1
x
(
N
2
n
1
+
N
4
n
2
+
n
3
)
W
N
(
N
2
n
1
+
N
4
n
2
+
n
3
)
(
k
1
+
2
k
2
+
4
k
3
)
{\displaystyle X(k_{1}+2k_{2}+4k_{3})=\sum _{n_{3}=0}^{{\frac {N}{4}}-1}\sum _{n_{2}=0}^{1}\sum _{n_{1}=0}^{1}x({\frac {N}{2}}n_{1}+{\frac {N}{4}}n_{2}+n_{3})W_{N}^{({\frac {N}{2}}n_{1}+{\frac {N}{4}}n_{2}+n_{3})(k_{1}+2k_{2}+4k_{3})}}
=
∑
n
3
=
0
N
4
−
1
∑
n
2
=
0
1
{
B
N
2
k
1
W
N
(
N
4
n
2
+
n
3
)
k
1
}
W
N
(
N
4
n
2
+
n
3
)
(
2
k
2
+
4
k
3
)
{\displaystyle =\sum _{n_{3}=0}^{{\frac {N}{4}}-1}\sum _{n_{2}=0}^{1}{\begin{Bmatrix}B_{\frac {N}{2}}^{k_{1}}W_{N}^{({\frac {N}{4}}n_{2}+n_{3})k_{1}}\end{Bmatrix}}W_{N}^{({\frac {N}{4}}n_{2}+n_{3})(2k_{2}+4k_{3})}}
而蝴蝶型架構會變成以下形式
B
N
2
k
1
=
x
(
N
4
n
2
+
n
3
)
+
(
−
1
)
k
1
x
(
N
4
n
2
+
n
3
+
N
2
)
{\displaystyle B_{\frac {N}{2}}^{k_{1}}=x({\frac {N}{4}}n_{2}+n_{3})+(-1)^{k_{1}}x({\frac {N}{4}}n_{2}+n_{3}+{\frac {N}{2}})}
利用旋轉因子
W
N
4
=
−
j
{\displaystyle W_{\frac {N}{4}}=-j}
的特性,可以觀察出
W
N
(
N
4
n
2
+
n
3
)
(
k
1
+
2
k
2
+
4
k
3
)
=
W
N
N
n
2
n
3
W
N
N
4
n
2
(
k
1
+
2
k
2
)
W
N
n
3
(
k
1
+
2
k
2
)
W
N
4
n
3
k
3
{\displaystyle W_{N}^{({\frac {N}{4}}n_{2}+n_{3})(k_{1}+2k_{2}+4k_{3})}=W_{N}^{Nn_{2}n_{3}}W_{N}^{{\frac {N}{4}}n_{2}(k_{1}+2k_{2})}W_{N}^{n_{3}(k_{1}+2k_{2})}W_{N}^{4n_{3}k_{3}}}
=
(
−
j
)
n
2
(
k
1
+
2
k
2
)
W
N
n
3
(
k
1
+
2
k
2
)
W
N
4
n
3
k
3
{\displaystyle =(-j)^{n_{2}(k_{1}+2k_{2})}W_{N}^{n_{3}(k_{1}+2k_{2})}W_{N}^{4n_{3}k_{3}}}
再將此公式帶入原式中可以得到
X
(
k
1
+
2
k
2
+
4
k
3
)
=
∑
n
3
=
0
N
4
−
1
[
H
(
k
1
,
k
2
,
n
3
)
W
N
n
3
(
k
1
+
2
k
2
)
]
W
N
4
n
3
k
3
{\displaystyle X(k_{1}+2k_{2}+4k_{3})=\sum _{n_{3}=0}^{{\frac {N}{4}}-1}[H(k_{1},k_{2},n_{3})W_{N}^{n_{3}(k_{1}+2k_{2})}]W_{N}^{4n_{3}k_{3}}}
H
(
k
1
,
k
2
,
n
3
)
=
B
F
2
I
[
x
(
n
3
)
+
(
−
1
)
k
1
(
n
3
+
N
2
)
]
⏞
+
(
−
j
)
k
1
+
2
k
2
B
F
2
I
[
x
(
n
3
+
N
4
)
+
(
−
1
)
k
1
(
n
3
+
3
N
4
)
]
⏞
⏟
B
F
2
I
I
{\displaystyle H(k_{1},k_{2},n_{3})={\begin{matrix}\underbrace {{\begin{matrix}BF2I\\\overbrace {[x(n_{3})+(-1)^{k_{1}}(n_{3}+{\frac {N}{2}})]} \end{matrix}}{\begin{matrix}\\\\+(-j)^{k_{1}+2k_{2}}\end{matrix}}{\begin{matrix}BF2I\\\overbrace {[x(n_{3}+{\frac {N}{4}})+(-1)^{k_{1}}(n_{3}+{\frac {3N}{4}})]} \end{matrix}}} \\BF2II\end{matrix}}}
如上述公式所示,原本的DFT公式會被拆解成多個
H
(
k
1
,
k
2
,
n
3
)
{\displaystyle H(k_{1},k_{2},n_{3})}
,而
H
(
k
1
,
k
2
,
n
3
)
{\displaystyle H(k_{1},k_{2},n_{3})}
又可分為BF2I與BF2II兩個階層,分別會對應到之後所介紹的兩種硬體架構。
一個16點的DFT公式經過一次上面所述之拆解之後可得下面的FFT架構
可以看出上圖的架構保留了2基底的簡單架構,然而複數乘法卻降到每兩級才出現一次,也就是
l
o
g
4
N
{\displaystyle log_{4}N}
次。而BF2I以及BF2II所對應的硬體架構下圖:
其中BF2II硬體單元中左下角的交叉電路就是用來處理-j的乘法。
一個256點的FFT架構可以由下面的硬體來實現:
其中圖下方的為一7位元寬的計數器,而此架構的控制電路相當單純,只要將計數器的各個位元分別接上BF2I與BF2II單元即可。
下表將2基底、4基底與22 基底演算法做一比較,可以發現22 基底演算法所需要的乘法氣數量為2基底的一半,加法棄用量是4基底的一半,並維持一樣的記憶體用量和控制電路的簡單性。
乘法器與加法器數量比較
乘法數
加法數
記憶體大小
控制電路
R2SDF
2(log4 N-1)
4log4 N
N-1
簡單
R4SDF
log4 N -1
8log4 N
N-1
中等
R22 SDF
log4 N -1
4log4 N
N-1
簡單
23 基底
如上所述,22 演算法是將旋轉因子
W
N
4
=
−
j
{\displaystyle W^{\frac {N}{4}}=-j}
視為一個簡單乘法,進而由公式以及硬體上的化簡獲得硬體需求上的改進。而藉由相同的概念,Shousheng He和Mats Torkelson進一步將旋轉因子
W
N
8
=
2
2
(
1
−
j
)
{\displaystyle W^{\frac {N}{8}}={\frac {\sqrt {2}}{2}}(1-j)}
的乘法化簡成一個簡單乘法,而化簡的方法將會在下面講解。
2
2
{\displaystyle {\frac {\sqrt {2}}{2}}}
乘法化簡
在2基數FFT演算法中的基本概念是利用旋轉因子
W
n
k
,
W
N
2
{\displaystyle W^{nk},W^{\frac {N}{2}}}
的對稱性,4基數演算法則是利用
W
n
k
+
N
4
=
−
W
n
k
+
3
N
4
=
−
j
W
n
k
{\displaystyle W^{nk+{\frac {N}{4}}}=-W^{nk+{\frac {3N}{4}}}=-jW^{nk}}
的特性。但是我們會發現在這些旋轉因子 的對稱特性中─
W
N
8
=
−
W
5
N
8
=
2
2
(
1
−
j
)
,
W
3
N
8
=
−
W
7
N
8
=
−
2
2
(
1
+
j
)
{\displaystyle W^{\frac {N}{8}}=-W^{\frac {5N}{8}}={\frac {\sqrt {2}}{2}}(1-j),W^{\frac {3N}{8}}=-W^{\frac {7N}{8}}=-{\frac {\sqrt {2}}{2}}(1+j)}
─並沒有被利用到。主要是因為
2
2
(
1
−
j
)
{\displaystyle {\frac {\sqrt {2}}{2}}(1-j)}
的乘法運算會讓整個FFT變得複雜,但是如果藉由近似的方法,我們便可以將此一運算化簡為12個加法。
2
2
=
0.70710678
=
2
−
1
+
2
−
3
+
2
−
4
+
2
−
6
+
2
−
8
+
2
−
9
{\displaystyle {\frac {\sqrt {2}}{2}}=0.70710678=2^{-1}+2^{-3}+2^{-4}+2^{-6}+2^{-8}+2^{-9}}
我們可以從上式注意到,
2
2
{\displaystyle {\frac {\sqrt {2}}{2}}}
可以被近似為五個加法的結果,所以
2
2
(
1
+
j
)
{\displaystyle {\frac {\sqrt {2}}{2}}(1+j)}
就可以被簡化為只有六個加法,再算入實部與虛部的計算,總共只需12個加法器就可以運用到此一簡化特性。
經由與22 基底類似的推導,並用串接的方式將旋轉因子 以8為單位對DFT公式進行拆解,23 基底FFT演算法進一步將複數乘法器的用量縮減到log8 N,並同時維持硬體架構的簡單性。
推導的方法與22 基底相當類似。藉由這樣的方法,23 基底能將乘法器的用量縮減到2基底的1/3,並同時維持一樣的記憶體用量以及控制電路的簡單性。
除了常在應用中見到與
2
{\displaystyle 2}
相關基底的拆解法,對於更加一般性的
N
=
N
1
N
2
{\displaystyle N=N_{1}N_{2}}
點離散傅立葉變換 問題,
我們也有辦法在理論上進行拆解,將問題化為數個
N
1
{\displaystyle N_{1}}
與
N
2
{\displaystyle N_{2}}
點離散傅立葉變換 問題,並可對計算量進行估計。
而特別的是,透過互質 在數論 上的特性,對於
N
1
{\displaystyle N_{1}}
與
N
2
{\displaystyle N_{2}}
互質的情況,可以進一步節省一些運算,
在下面會特別分開討論。
N
1
N
2
{\displaystyle N_{1}N_{2}}
非互質
為了避免之後的符號混淆,我們先將
N
1
N
2
{\displaystyle N_{1}N_{2}}
置換為
P
1
P
2
{\displaystyle P_{1}P_{2}}
,也就是說接著要將
N
=
P
1
P
2
{\displaystyle N=P_{1}P_{2}}
點離散傅立葉變換 ,
想辦法拆解為數個
P
1
{\displaystyle P_{1}}
與
P
2
{\displaystyle P_{2}}
點離散傅立葉變換 問題。
接著定義要拆分的問題,要拆分的問題為
N
{\displaystyle N}
點離散傅立葉變換 ,將
f
[
n
]
{\displaystyle f[n]}
轉換至
F
[
m
]
{\displaystyle F[m]}
:
F
[
m
]
=
∑
n
=
0
N
−
1
e
−
i
2
π
N
m
n
f
[
n
]
m
,
n
=
0
,
1
,
…
,
N
−
1
{\displaystyle F[m]=\sum _{n=0}^{N-1}e^{-i{\frac {2\pi }{N}}mn}f[n]\qquad m,n=0,1,\ldots ,N-1}
直觀地說,這個
N
{\displaystyle N}
點離散傅立葉變換 ,將由
n
{\displaystyle n}
作為參數的函數
f
[
n
]
{\displaystyle f[n]}
,轉換成由
m
{\displaystyle m}
作為參數的函數
F
[
m
]
{\displaystyle F[m]}
,
並且
m
,
n
{\displaystyle m,n}
都有
N
{\displaystyle N}
個可能的數值。
待定義好要拆分的問題,便可以開始討論如何進行拆分,基本概念是將有
N
{\displaystyle N}
個可能的數值的
m
,
n
{\displaystyle m,n}
,
分別化為個使用兩個參數進行描述的函數
m
=
[
m
1
,
m
2
]
,
n
=
[
n
1
,
n
2
]
{\displaystyle m=[m_{1},m_{2}],n=[n_{1},n_{2}]}
,並藉此將原問題化為二維度離散傅立葉變換 ,
便可使用數個較小的離散傅立葉變換 問題描述整個過程。
而一種很直覺的轉換方式,便是透過將
m
,
n
{\displaystyle m,n}
分別除以
P
2
,
P
1
{\displaystyle P_{2},P_{1}}
,
以商數 與餘數 來做為參數描述
m
,
n
{\displaystyle m,n}
的值:
n
=
n
1
P
1
+
n
2
m
=
m
1
+
m
2
P
2
{\displaystyle n=n_{1}P_{1}+n_{2}\qquad m=m_{1}+m_{2}P_{2}}
n
1
,
m
1
=
0
,
1
,
…
,
P
2
−
1
n
2
,
m
2
=
0
,
1
,
…
,
P
1
−
1
{\displaystyle n_{1},m_{1}=0,1,\ldots ,P_{2}-1\qquad n_{2},m_{2}=0,1,\ldots ,P_{1}-1}
其中
n
1
{\displaystyle n_{1}}
作為將
n
{\displaystyle n}
除以
P
1
{\displaystyle P_{1}}
的商數,與作為
m
{\displaystyle m}
除以
P
2
{\displaystyle P_{2}}
的餘數的
m
1
{\displaystyle m_{1}}
相同,
具有
P
2
{\displaystyle P_{2}}
個可能數值,同理
n
2
{\displaystyle n_{2}}
與
m
2
{\displaystyle m_{2}}
有
P
1
{\displaystyle P_{1}}
個可能數值。
將上述的參數代換及
N
=
P
1
P
2
{\displaystyle N=P_{1}P_{2}}
帶入原式,可以得到:
F
[
m
1
+
m
2
P
2
]
=
∑
n
1
=
0
P
2
−
1
∑
n
2
=
0
P
1
−
1
e
−
i
2
π
P
1
P
2
(
m
1
+
m
2
P
2
)
(
n
1
P
1
+
n
2
)
f
[
n
1
P
1
+
n
2
]
{\displaystyle F[m_{1}+m_{2}P_{2}]=\sum _{n_{1}=0}^{P_{2}-1}\sum _{n_{2}=0}^{P_{1}-1}e^{-i{\frac {2\pi }{P_{1}P_{2}}}(m_{1}+m_{2}P_{2})(n_{1}P_{1}+n_{2})}f[n_{1}P_{1}+n_{2}]}
將右式的指數部分乘開並分項化簡可以得到:
F
[
m
1
+
m
2
P
2
]
=
∑
n
1
=
0
P
2
−
1
∑
n
2
=
0
P
1
−
1
f
[
n
1
P
1
+
n
2
]
e
−
i
2
π
P
2
m
1
n
1
e
−
i
2
π
P
1
m
2
n
2
e
−
i
2
π
P
1
P
2
m
1
n
2
e
−
i
2
π
m
2
n
1
{\displaystyle F[m_{1}+m_{2}P_{2}]=\sum _{n_{1}=0}^{P_{2}-1}\sum _{n_{2}=0}^{P_{1}-1}f[n_{1}P_{1}+n_{2}]e^{-i{\frac {2\pi }{P_{2}}}m_{1}n_{1}}e^{-i{\frac {2\pi }{P_{1}}}m_{2}n_{2}}e^{-i{\frac {2\pi }{P_{1}P_{2}}}m_{1}n_{2}}e^{-i2\pi m_{2}n_{1}}}
最後透過
e
−
i
2
π
=
1
{\displaystyle e^{-i2\pi }=1}
與
P
1
P
2
=
N
{\displaystyle P_{1}P_{2}=N}
,可以得到:
F
[
m
1
+
m
2
P
2
]
=
∑
n
2
=
0
P
1
−
1
∑
n
1
=
0
P
2
−
1
f
[
n
1
P
1
+
n
2
]
e
−
i
2
π
P
2
m
1
n
1
e
−
i
2
π
N
m
1
n
2
e
−
i
2
π
P
1
m
2
n
2
{\displaystyle F[m_{1}+m_{2}P_{2}]=\sum _{n_{2}=0}^{P_{1}-1}\sum _{n_{1}=0}^{P_{2}-1}f[n_{1}P_{1}+n_{2}]e^{-i{\frac {2\pi }{P_{2}}}m_{1}n_{1}}e^{-i{\frac {2\pi }{N}}m_{1}n_{2}}e^{-i{\frac {2\pi }{P_{1}}}m_{2}n_{2}}}
觀察上式,並加上括號輔助釐清運算順序我們可以得到:
F
[
m
1
+
m
2
P
2
]
=
∑
n
2
=
0
P
1
−
1
{
{
∑
n
1
=
0
P
2
−
1
f
[
n
1
P
1
+
n
2
]
e
−
i
2
π
P
2
m
1
n
1
}
e
−
i
2
π
N
m
1
n
2
}
e
−
i
2
π
P
1
m
2
n
2
{\displaystyle F[m_{1}+m_{2}P_{2}]=\sum _{n_{2}=0}^{P_{1}-1}\left\{\left\{\sum _{n_{1}=0}^{P_{2}-1}f[n_{1}P_{1}+n_{2}]e^{-i{\frac {2\pi }{P_{2}}}m_{1}n_{1}}\right\}e^{-i{\frac {2\pi }{N}}m_{1}n_{2}}\right\}e^{-i{\frac {2\pi }{P_{1}}}m_{2}n_{2}}}
最內層的運算可以視為將雙參數函數
f
[
n
1
,
n
2
]
{\displaystyle f[n_{1},n_{2}]}
中的一個參數
n
1
{\displaystyle n_{1}}
,透過離散傅立葉變換 取代為由
m
1
{\displaystyle m_{1}}
描述,
得到一個新函數
G
1
[
m
1
,
n
2
]
{\displaystyle G_{1}[m_{1},n_{2}]}
(這步因為對每個不同
n
2
{\displaystyle n_{2}}
,都需要做一次將
n
1
{\displaystyle n_{1}}
取代為
m
1
{\displaystyle m_{1}}
的轉換,
共需要
P
1
{\displaystyle P_{1}}
個
P
2
{\displaystyle P_{2}}
點離散傅立葉變換 ):
F
[
m
1
+
m
2
P
2
]
=
∑
n
2
=
0
P
1
−
1
{
G
1
[
m
1
,
n
2
]
e
−
i
2
π
N
m
1
n
2
}
e
−
i
2
π
P
1
m
2
n
2
{\displaystyle F[m_{1}+m_{2}P_{2}]=\sum _{n_{2}=0}^{P_{1}-1}\left\{G_{1}[m_{1},n_{2}]e^{-i{\frac {2\pi }{N}}m_{1}n_{2}}\right\}e^{-i{\frac {2\pi }{P_{1}}}m_{2}n_{2}}}
下一層的運算則可視為單純的乘法,將
G
1
[
m
1
,
n
2
]
{\displaystyle G_{1}[m_{1},n_{2}]}
與
e
−
i
2
π
N
m
1
n
2
{\displaystyle e^{-i{\frac {2\pi }{N}}m_{1}n_{2}}}
相乘,得到
G
2
[
m
1
,
n
2
]
{\displaystyle G_{2}[m_{1},n_{2}]}
(這步需要的計算量視
m
1
n
2
N
{\displaystyle {\frac {m_{1}n_{2}}{N}}}
的特殊性而會有變化):
F
[
m
1
+
m
2
P
2
]
=
∑
n
2
=
0
P
1
−
1
G
2
[
m
1
,
n
2
]
e
−
i
2
π
P
1
m
2
n
2
{\displaystyle F[m_{1}+m_{2}P_{2}]=\sum _{n_{2}=0}^{P_{1}-1}G_{2}[m_{1},n_{2}]e^{-i{\frac {2\pi }{P_{1}}}m_{2}n_{2}}}
最後的運算可以視為將函數
G
2
[
m
1
,
n
2
]
{\displaystyle G_{2}[m_{1},n_{2}]}
中
n
2
{\displaystyle n_{2}}
,透過離散傅立葉變換 取代為由
m
2
{\displaystyle m_{2}}
描述,
得到一個新函數
G
3
[
m
1
,
m
2
]
{\displaystyle G_{3}[m_{1},m_{2}]}
(這步因為對每個不同
m
1
{\displaystyle m_{1}}
,都需要做一次將
n
2
{\displaystyle n_{2}}
取代為
m
2
{\displaystyle m_{2}}
的轉換,
共需要
P
2
{\displaystyle P_{2}}
個
P
1
{\displaystyle P_{1}}
點離散傅立葉變換 ):
F
[
m
(
=
m
1
+
m
2
P
2
)
]
=
G
3
[
m
1
,
m
2
]
{\displaystyle F[m(=m_{1}+m_{2}P_{2})]=G_{3}[m_{1},m_{2}]}
就成功僅使用
P
1
{\displaystyle P_{1}}
與
P
2
{\displaystyle P_{2}}
點離散傅立葉變換 ,描述了原先的
N
{\displaystyle N}
點離散傅立葉變換 。
而在這樣的分解下,我們使用了
P
1
{\displaystyle P_{1}}
個
P
2
{\displaystyle P_{2}}
點離散傅立葉變換 與
P
2
{\displaystyle P_{2}}
個
P
1
{\displaystyle P_{1}}
點離散傅立葉變換 與一些額外的乘法,
並且這些額外使用的複數 乘法
G
1
[
m
1
,
n
2
]
×
e
−
i
2
π
N
m
1
n
2
{\displaystyle G_{1}[m_{1},n_{2}]\times e^{-i{\frac {2\pi }{N}}m_{1}n_{2}}}
,
在電腦的運算架構中,如果
m
1
n
2
N
{\displaystyle {\frac {m_{1}n_{2}}{N}}}
是
1
4
{\displaystyle {\frac {1}{4}}}
的倍數則不需要使用乘法,
如果
m
1
n
2
N
{\displaystyle {\frac {m_{1}n_{2}}{N}}}
是
1
8
,
1
12
{\displaystyle {\frac {1}{8}},{\frac {1}{12}}}
的倍數則僅需兩個實數 乘法,
其他則需三個實數乘法,所以總運算量可以如下方式表示:
P
2
B
1
+
P
1
B
2
+
3
D
3
+
2
D
2
{\displaystyle P_{2}B_{1}+P_{1}B_{2}+3D_{3}+2D_{2}}
其中
B
1
{\displaystyle B_{1}}
是
P
1
{\displaystyle P_{1}}
傅立葉所需乘法數,
B
2
{\displaystyle B_{2}}
是
P
2
{\displaystyle P_{2}}
傅立葉所需乘法數,
D
3
{\displaystyle D_{3}}
是需三個實數乘法
m
1
n
2
{\displaystyle m_{1}n_{2}}
組合個數,
D
2
{\displaystyle D_{2}}
是需兩個實數乘法
m
1
n
2
{\displaystyle m_{1}n_{2}}
組合個數。
而常見以
2
{\displaystyle 2}
為基底的分解則是為了使離散傅立葉變換 所需乘法數為零,這樣就僅需考慮上面提到的額外乘法,可以提高效率也有較簡單的結構。
N
1
N
2
{\displaystyle N_{1}N_{2}}
互質
在
N
1
N
2
{\displaystyle N_{1}N_{2}}
互質 的情況下,仍是採取和上面相近的思路來將問題進行拆分,首先,為了避免之後的符號混淆,我們同樣將
N
1
N
2
{\displaystyle N_{1}N_{2}}
置換為
P
1
P
2
{\displaystyle P_{1}P_{2}}
。
接著同樣定義要拆分的問題:
F
[
m
]
=
∑
n
=
0
N
−
1
e
−
i
2
π
N
m
n
f
[
n
]
m
,
n
=
0
,
1
,
…
,
N
−
1
{\displaystyle F[m]=\sum _{n=0}^{N-1}e^{-i{\frac {2\pi }{N}}mn}f[n]\qquad m,n=0,1,\ldots ,N-1}
接著就是和上面的算法有最大差異的部分,在將
m
,
n
{\displaystyle m,n}
化為個使用兩個參數進行描述的函數
m
=
[
m
1
,
m
2
]
,
n
=
[
n
1
,
n
2
]
{\displaystyle m=[m_{1},m_{2}],n=[n_{1},n_{2}]}
時,
最直覺的作法便是使用商數和餘數,但在
P
1
,
P
2
{\displaystyle P_{1},P_{2}}
互質的情況下,可以有一些其他更具技巧性的選擇。
當
P
1
,
P
2
{\displaystyle P_{1},P_{2}}
互質,對所有
n
=
0
,
1
,
…
,
N
−
1
{\displaystyle n=0,1,\ldots ,N-1}
我們可以找到唯一且不重複的一組
n
1
,
n
2
{\displaystyle n_{1},n_{2}}
使得:
n
=
(
(
n
1
P
1
+
n
2
P
2
)
)
N
=
n
1
P
1
+
n
2
P
2
+
c
1
N
0
≤
n
1
<
P
2
0
≤
n
2
<
P
1
{\displaystyle n=((n_{1}P_{1}+n_{2}P_{2}))_{N}=n_{1}P_{1}+n_{2}P_{2}+c_{1}N\qquad 0\leq n_{1}<P_{2}\qquad 0\leq n_{2}<P_{1}}
其中
(
(
a
)
)
N
=
a
mod
N
{\displaystyle ((a))_{N}=a\mod N}
,代表取餘數的意思,
c
1
{\displaystyle c_{1}}
是一個整數。
例如假設
N
=
15
,
P
1
=
3
,
P
2
=
5
{\displaystyle N=15,P_{1}=3,P_{2}=5}
,則
n
=
1
{\displaystyle n=1}
對應到的
(
n
1
,
n
2
)
{\displaystyle (n_{1},n_{2})}
就是
(
2
,
2
)
{\displaystyle (2,2)}
,
有
2
×
3
+
2
×
5
mod
15
=
16
mod
15
=
1
{\displaystyle 2\times 3+2\times 5\mod 15=16\mod 15=1}
。
並且對所有
n
1
,
n
2
{\displaystyle n_{1},n_{2}}
的組合(有
P
1
×
P
2
=
N
{\displaystyle P_{1}\times P_{2}=N}
組),都對應到一個特定不重複的
n
{\displaystyle n}
。
同理我們可以把
m
=
0
,
1
,
…
,
N
−
1
{\displaystyle m=0,1,\ldots ,N-1}
表示為
m
1
,
m
2
{\displaystyle m_{1},m_{2}}
的雙參數函數:
m
=
(
(
m
1
P
1
+
m
2
P
2
)
)
N
=
m
1
P
1
+
m
2
P
2
+
c
2
N
0
≤
m
1
<
P
2
0
≤
m
2
<
P
1
{\displaystyle m=((m_{1}P_{1}+m_{2}P_{2}))_{N}=m_{1}P_{1}+m_{2}P_{2}+c_{2}N\qquad 0\leq m_{1}<P_{2}\qquad 0\leq m_{2}<P_{1}}
將上述的參數代換及
N
=
P
1
P
2
{\displaystyle N=P_{1}P_{2}}
帶入原式,可以得到:
F
[
(
(
m
1
P
1
+
m
2
P
2
)
)
N
]
=
∑
n
1
=
0
P
2
−
1
∑
n
2
=
0
P
1
−
1
e
−
i
2
π
N
(
m
1
P
1
+
m
2
P
2
+
c
2
N
)
(
n
1
P
1
+
n
2
P
2
+
c
1
N
)
f
[
(
(
n
1
P
1
+
n
2
P
2
)
)
N
]
{\displaystyle F[((m_{1}P_{1}+m_{2}P_{2}))_{N}]=\sum _{n_{1}=0}^{P_{2}-1}\sum _{n_{2}=0}^{P_{1}-1}e^{-i{\frac {2\pi }{N}}(m_{1}P_{1}+m_{2}P_{2}+c_{2}N)(n_{1}P_{1}+n_{2}P_{2}+c_{1}N)}f[((n_{1}P_{1}+n_{2}P_{2}))_{N}]}
接著透過一次的展開化簡及應用
e
−
i
2
π
=
1
{\displaystyle e^{-i2\pi }=1}
可得:
F
[
(
(
m
1
P
1
+
m
2
P
2
)
)
N
]
=
∑
n
1
=
0
P
2
−
1
∑
n
2
=
0
P
1
−
1
e
−
i
2
π
N
(
m
1
P
1
+
m
2
P
2
)
(
n
1
P
1
+
n
2
P
2
)
e
−
i
2
π
c
2
(
n
1
P
1
+
n
2
P
2
+
c
1
N
)
e
−
i
2
π
c
1
(
m
1
P
1
+
m
2
P
2
+
c
2
N
)
e
−
i
2
π
c
1
c
2
N
f
[
(
(
n
1
P
1
+
n
2
P
2
)
)
N
]
=
∑
n
1
=
0
P
2
−
1
∑
n
2
=
0
P
1
−
1
e
−
i
2
π
N
(
m
1
P
1
+
m
2
P
2
)
(
n
1
P
1
+
n
2
P
2
)
f
[
(
(
n
1
P
1
+
n
2
P
2
)
)
N
]
{\displaystyle {\begin{aligned}F[((m_{1}P_{1}+m_{2}P_{2}))_{N}]&=\sum _{n_{1}=0}^{P_{2}-1}\sum _{n_{2}=0}^{P_{1}-1}e^{-i{\frac {2\pi }{N}}(m_{1}P_{1}+m_{2}P_{2})(n_{1}P_{1}+n_{2}P_{2})}e^{-i2\pi c_{2}(n_{1}P_{1}+n_{2}P_{2}+c_{1}N)}e^{-i2\pi c_{1}(m_{1}P_{1}+m_{2}P_{2}+c_{2}N)}e^{-i2\pi c_{1}c_{2}N}f[((n_{1}P_{1}+n_{2}P_{2}))_{N}]\\&=\sum _{n_{1}=0}^{P_{2}-1}\sum _{n_{2}=0}^{P_{1}-1}e^{-i{\frac {2\pi }{N}}(m_{1}P_{1}+m_{2}P_{2})(n_{1}P_{1}+n_{2}P_{2})}f[((n_{1}P_{1}+n_{2}P_{2}))_{N}]\end{aligned}}}
再將
N
=
P
1
P
2
{\displaystyle N=P_{1}P_{2}}
帶入並再透過一次的展開化簡及應用
e
−
i
2
π
=
1
{\displaystyle e^{-i2\pi }=1}
可得:
F
[
(
(
m
1
P
1
+
m
2
P
2
)
)
N
]
=
∑
n
1
=
0
P
2
−
1
∑
n
2
=
0
P
1
−
1
f
[
(
(
n
1
P
1
+
n
2
P
2
)
)
N
]
e
−
i
2
π
P
2
m
1
P
1
n
1
e
−
i
2
π
P
1
m
2
P
2
n
2
e
−
i
2
π
m
1
n
2
e
−
i
2
π
m
2
n
1
=
∑
n
1
=
0
P
2
−
1
∑
n
2
=
0
P
1
−
1
f
[
(
(
n
1
P
1
+
n
2
P
2
)
)
N
]
e
−
i
2
π
P
2
m
1
P
1
n
1
e
−
i
2
π
P
1
m
2
P
2
n
2
{\displaystyle {\begin{aligned}F[((m_{1}P_{1}+m_{2}P_{2}))_{N}]&=\sum _{n_{1}=0}^{P_{2}-1}\sum _{n_{2}=0}^{P_{1}-1}f[((n_{1}P_{1}+n_{2}P_{2}))_{N}]e^{-i{\frac {2\pi }{P_{2}}}m_{1}P_{1}n_{1}}e^{-i{\frac {2\pi }{P_{1}}}m_{2}P_{2}n_{2}}e^{-i2\pi m_{1}n_{2}}e^{-i2\pi m_{2}n_{1}}\\&=\sum _{n_{1}=0}^{P_{2}-1}\sum _{n_{2}=0}^{P_{1}-1}f[((n_{1}P_{1}+n_{2}P_{2}))_{N}]e^{-i{\frac {2\pi }{P_{2}}}m_{1}P_{1}n_{1}}e^{-i{\frac {2\pi }{P_{1}}}m_{2}P_{2}n_{2}}\end{aligned}}}
觀察上式,並加上括號輔助釐清運算順序我們可以得到:
F
[
(
(
m
1
P
1
+
m
2
P
2
)
)
N
]
=
∑
n
2
=
0
P
1
−
1
{
∑
n
1
=
0
P
2
−
1
f
[
(
(
n
1
P
1
+
n
2
P
2
)
)
N
]
e
−
i
2
π
P
2
m
1
P
1
n
1
}
e
−
i
2
π
P
1
m
2
P
2
n
2
{\displaystyle F[((m_{1}P_{1}+m_{2}P_{2}))_{N}]=\sum _{n_{2}=0}^{P_{1}-1}\left\{\sum _{n_{1}=0}^{P_{2}-1}f[((n_{1}P_{1}+n_{2}P_{2}))_{N}]e^{-i{\frac {2\pi }{P_{2}}}m_{1}P_{1}n_{1}}\right\}e^{-i{\frac {2\pi }{P_{1}}}m_{2}P_{2}n_{2}}}
內層的運算可以視為將雙參數函數
f
[
(
(
n
1
P
1
+
n
2
P
2
)
)
N
]
{\displaystyle f[((n_{1}P_{1}+n_{2}P_{2}))_{N}]}
中的一個參數
n
1
{\displaystyle n_{1}}
,
透過離散傅立葉變換 取代為由一個與
m
1
{\displaystyle m_{1}}
有關的變數
m
3
=
(
(
m
1
P
1
)
)
P
2
{\displaystyle m_{3}=((m_{1}P_{1}))_{P_{2}}}
描述,
得到一個新函數
G
1
[
m
3
,
n
2
]
{\displaystyle G_{1}[m_{3},n_{2}]}
(這步因為對每個不同
n
2
{\displaystyle n_{2}}
,都需要做一次將
n
1
{\displaystyle n_{1}}
取代為
m
3
{\displaystyle m_{3}}
的轉換,
共需要
P
1
{\displaystyle P_{1}}
個
P
2
{\displaystyle P_{2}}
點離散傅立葉變換 ):
F
[
(
(
m
1
P
1
+
m
2
P
2
)
)
N
]
=
∑
n
2
=
0
P
1
−
1
G
1
[
m
3
,
n
2
]
e
−
i
2
π
P
1
m
2
P
2
n
2
{\displaystyle F[((m_{1}P_{1}+m_{2}P_{2}))_{N}]=\sum _{n_{2}=0}^{P_{1}-1}G_{1}[m_{3},n_{2}]e^{-i{\frac {2\pi }{P_{1}}}m_{2}P_{2}n_{2}}}
外層的運算可以視為將函數
G
1
[
m
3
,
n
2
]
{\displaystyle G_{1}[m_{3},n_{2}]}
中的參數
n
2
{\displaystyle n_{2}}
,
透過離散傅立葉變換 取代為由一個與
m
2
{\displaystyle m_{2}}
有關的變數
m
4
=
(
(
m
2
P
2
)
)
P
1
{\displaystyle m_{4}=((m_{2}P_{2}))_{P_{1}}}
描述,
得到一個新函數
G
2
[
m
3
,
m
4
]
{\displaystyle G_{2}[m_{3},m_{4}]}
(這步因為對每個不同
m
3
{\displaystyle m_{3}}
,都需要做一次將
n
2
{\displaystyle n_{2}}
取代為
m
4
{\displaystyle m_{4}}
的轉換,
共需要
P
2
{\displaystyle P_{2}}
個
P
1
{\displaystyle P_{1}}
點離散傅立葉變換 ):
F
[
m
]
=
F
[
(
(
m
1
P
1
+
m
2
P
2
)
)
N
]
=
G
2
[
m
3
,
m
4
]
=
G
2
[
(
(
m
1
P
1
)
)
P
2
,
(
(
m
2
P
2
)
)
P
1
]
{\displaystyle F[m]=F[((m_{1}P_{1}+m_{2}P_{2}))_{N}]=G_{2}[m_{3},m_{4}]=G_{2}[((m_{1}P_{1}))_{P_{2}},((m_{2}P_{2}))_{P_{1}}]}
最後透過
F
{\displaystyle F}
與
G
2
{\displaystyle G_{2}}
在不同
m
1
,
m
2
{\displaystyle m_{1},m_{2}}
時的點點數值對應關係,
就成功僅使用
P
1
{\displaystyle P_{1}}
與
P
2
{\displaystyle P_{2}}
點離散傅立葉變換 ,描述了原先的
N
{\displaystyle N}
點離散傅立葉變換 。
而這個方法透過聰明的選取表達
m
,
n
{\displaystyle m,n}
的方式,使得拆解的過程中完全不需要多餘的乘法運算,
總運算量可以簡單表示為:
P
2
B
1
+
P
1
B
2
+
3
D
3
+
2
D
2
{\displaystyle P_{2}B_{1}+P_{1}B_{2}+3D_{3}+2D_{2}}
其中
B
1
{\displaystyle B_{1}}
是
P
1
{\displaystyle P_{1}}
傅立葉所需乘法數,
B
2
{\displaystyle B_{2}}
是
P
2
{\displaystyle P_{2}}
傅立葉所需乘法數。
雖然這個方法可以較上面的方法節省運算量,
但這個方法也牽涉較為複雜的
m
,
n
{\displaystyle m,n}
與
m
1
,
m
2
,
n
1
,
n
2
{\displaystyle m_{1},m_{2},n_{1},n_{2}}
轉換,較為不直覺且不易理解,
也會遇到許多需要取餘數的運算,可能會需要較大的空間建表進行查表法。
最後關於實際上要如何求得
n
{\displaystyle n}
與
n
1
,
n
2
{\displaystyle n_{1},n_{2}}
的轉換關係,
可以先透過輾轉相除法 取得一對特定的
n
11
,
n
21
{\displaystyle n_{11},n_{21}}
使得:
(
(
n
11
P
1
+
n
21
P
2
)
)
N
=
1
{\displaystyle ((n_{11}P_{1}+n_{21}P_{2}))_{N}=1}
然後我們可以知道對於任意整數
0
≤
k
<
N
{\displaystyle 0\leq k<N}
有:
(
(
k
n
11
P
1
+
k
n
21
P
2
)
)
N
=
k
=
(
(
k
n
11
P
1
−
c
1
N
+
k
n
21
P
2
−
c
2
N
)
)
N
=
(
(
(
k
n
11
−
c
1
P
2
)
P
1
+
(
k
n
21
−
c
2
P
1
)
P
2
)
)
N
{\displaystyle ((kn_{11}P_{1}+kn_{21}P_{2}))_{N}=k=((kn_{11}P_{1}-c_{1}N+kn_{21}P_{2}-c_{2}N))_{N}=(((kn_{11}-c_{1}P_{2})P_{1}+(kn_{21}-c_{2}P_{1})P_{2}))_{N}}
然後就可以得到:
n
1
k
=
(
(
k
n
11
)
)
P
2
n
2
k
=
(
(
k
n
21
)
)
P
1
{\displaystyle n_{1k}=((kn_{11}))_{P_{2}}\qquad n_{2k}=((kn_{21}))_{P_{1}}}
滿足:
(
(
n
1
k
P
1
+
n
2
k
P
2
)
)
N
=
k
0
≤
n
1
k
<
P
2
0
≤
n
2
k
<
P
1
{\displaystyle ((n_{1k}P_{1}+n_{2k}P_{2}))_{N}=k\qquad 0\leq n_{1k}<P_{2}\qquad 0\leq n_{2k}<P_{1}}
參考資料
Widhe, T., J. Melander, et al. (1997). Design of efficient radix-8 butterfly PEs for VLSI. Circuits and Systems, 1997. ISCAS '97., Proceedings of 1997 IEEE International Symposium on.
Lihong, J., G. Yonghong, et al. (1998). A new VLSI-oriented FFT algorithm and implementation. ASIC Conference 1998. Proceedings. Eleventh Annual IEEE International.
Duhamel, P. and H. Hollmann (1984). "Split-radix FFT algorithm." Electronics Letters 20(1): 14-16.
Vetterli, M. and P. Duhamel (1989). "Split-radix algorithms for length-pm DFT's." Acoustics, Speech and Signal Processing, IEEE Transactions on 37(1): 57-64.
Richards, M. A. (1988). "On hardware implementation of the split-radix FFT." Acoustics, Speech and Signal Processing, IEEE Transactions on 36(10): 1575-1581.
Shousheng, H. and M. Torkelson (1996). A new approach to pipeline FFT processor. Parallel Processing Symposium, 1996., Proceedings of IPPS '96, The 10th International.
Shousheng, H. and M. Torkelson (1998). Designing pipeline FFT processor for OFDM (de)modulation. Signals, Systems, and Electronics, 1998. ISSSE 98. 1998 URSI International Symposium on.