數字訊號處理/快速傅立葉變換 (FFT) 演算法
外觀
< 數字訊號處理
快速傅立葉變換 (FFT) 是一種用於計算離散傅立葉變換 (DFT) 的演算法,使用更少的乘法次數。
庫利-圖基演算法是最常見的快速傅立葉變換 (FFT) 演算法。它將較大的 DFT 分解成較小的 DFT。庫利-圖基演算法最著名的應用是將 N 點變換分解成兩個 N/2 點變換,因此它僅限於 2 的冪大小。
該演算法可以透過兩種不同的方式實現,使用所謂的
- 時間抽取 (DIT)
- 頻率抽取 (DIF)
下圖表示一個 16 點 DIF FFT 電路圖

在圖中,係數由
其中 N 是 FFT 的點數。它們在單位圓的下半部分均勻分佈,並且 .
以下 python 指令碼允許測試上面說明的演算法
#!/usr/bin/python3
import math
import cmath
# ------------------------------------------------------------------------------
# Parameters
#
coefficientBitNb = 8 # 0 for working with reals
# ------------------------------------------------------------------------------
# Functions
#
# ..............................................................................
def bit_reversed(n, bit_nb):
binary_number = bin(n)
reverse_binary_number = binary_number[-1:1:-1]
reverse_binary_number = reverse_binary_number + \
(bit_nb - len(reverse_binary_number))*'0'
reverse_number = int(reverse_binary_number, bit_nb-1)
return(reverse_number)
# ..............................................................................
def fft(x):
j = complex(0, 1)
# sizes
point_nb = len(x)
stage_nb = int(math.log2(point_nb))
# vectors
stored = x.copy()
for index in range(point_nb):
stored[index] = complex(stored[index], 0)
calculated = [complex(0, 0)] * point_nb
# coefficients
coefficients = [complex(0, 0)] * (point_nb//2)
for index in range(len(coefficients)):
coefficients[index] = cmath.exp(-j * index/point_nb * 2*cmath.pi)
coefficients[index] = coefficients[index] * 2**coefficientBitNb
# loop
for stage_index in range(stage_nb):
# print([stored[i].real for i in range(point_nb)])
index_offset = 2**(stage_nb-stage_index-1)
# butterfly additions
for vector_index in range(point_nb):
isEven = (vector_index // index_offset) % 2 == 0
if isEven:
operand_a = stored[vector_index]
operand_b = stored[vector_index + index_offset]
else:
operand_a = - stored[vector_index]
operand_b = stored[vector_index - index_offset]
calculated[vector_index] = operand_a + operand_b
# coefficient multiplications
for vector_index in range(point_nb):
isEven = (vector_index // index_offset) % 2 == 0
if not isEven:
coefficient_index = (vector_index % index_offset) \
* (stage_index+1)
# print( \
# "(%d, %d) -> %d" \
# % (stage_index, vector_index, coefficient_index) \
# )
calculated[vector_index] = \
coefficients[coefficient_index] * calculated[vector_index] \
/ 2**coefficientBitNb
if coefficientBitNb > 0:
calculated[vector_index] = complex( \
math.floor(calculated[vector_index].real), \
math.floor(calculated[vector_index].imag) \
)
# storage
stored = calculated.copy()
# reorder results
for index in range(point_nb):
calculated[bit_reversed(index, stage_nb)] = stored[index]
return calculated
# ------------------------------------------------------------------------------
# Main program
#
source = [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0]
transformed = fft(source)
amplitude = [0.0] * len(source)
amplitude_print = ''
for index in range(len(transformed)):
amplitude[index] = abs(transformed[index])
amplitude_print = amplitude_print + "%5.3f " % amplitude[index]
print()
print(amplitude_print)
它有一個特殊的引數,coefficientBitNb,它允許確定使用僅整數的電路的計算結果。