手寫fft演算法,和內建fft演算法對比

redufa發表於2024-10-29

好的,下面我將提供一個完整的Python示例,包括手寫FFT演算法(快速傅立葉變換)和使用NumPy的內建FFT演算法,然後對比兩者的結果並繪製圖形。

1. 手寫FFT演算法

我們將實現一個簡單的FFT演算法,即Cooley-Tukey演算法,這是一種最常用的FFT演算法。

2. NumPy內建FFT演算法

NumPy庫提供了一個非常高效的FFT實現,我們可以直接使用它來計算FFT。

3. 程式碼實現

首先,確保你已經安裝了NumPy和matplotlib庫。如果沒有安裝,可以透過以下命令安裝:

pip install numpy matplotlib

下面是完整的Python程式碼:

import numpy as np
import matplotlib.pyplot as plt

def fft_handwritten(x):
    N = len(x)
    if N <= 1: return x
    even = fft_handwritten(x[0::2])
    odd = fft_handwritten(x[1::2])
    T = [np.exp(-2j * np.pi * k / N) * odd[k] for k in range(len(odd))]
    return [even[k] + T[k] for k in range(len(even))] + [even[k] - T[k] for k in range(len(even))]

# 生成測試訊號
t = np.linspace(0, 1, 1024, False)
x = np.sin(2 * np.pi * 10 * t) + 0.5 * np.sin(2 * np.pi * 20 * t)

# 使用NumPy的FFT
fft_np = np.fft.fft(x)

# 手寫FFT
fft_hand = fft_handwritten(x)

# 繪製結果
plt.figure(figsize=(14, 6))

# 繪製NumPy的FFT結果
plt.subplot(1, 2, 1)
plt.stem(np.abs(fft_np), linefmt='C0-', markerfmt='C0o', basefmt='C3-')
plt.title('NumPy FFT')
plt.xlabel('Frequency Bins')
plt.ylabel('Amplitude')

# 繪製手寫FFT結果
plt.subplot(1, 2, 2)
plt.stem(np.abs(fft_hand), linefmt='C1-', markerfmt='C1o', basefmt='C3-')
plt.title('Handwritten FFT')
plt.xlabel('Frequency Bins')
plt.ylabel('Amplitude')

plt.tight_layout()
plt.show()

4. 程式碼解釋

  • fft_handwritten 函式實現了一個遞迴的FFT演算法。
  • 我們生成了一個包含兩個正弦波的測試訊號。
  • 使用NumPy的FFT函式和手寫的FFT函式計算FFT,並繪製結果的幅度。

5. 結果對比

執行上述程式碼,你將看到兩個圖:一個顯示NumPy FFT的結果,另一個顯示手寫FFT的結果。理論上,如果手寫FFT演算法實現正確,兩者的結果應該非常接近。然而,由於浮點數精度和演算法最佳化的差異,可能會有輕微的差異。

這個示例提供了一個基本的框架,你可以根據需要調整和擴充套件,例如處理更大的資料集或更復雜的訊號。

相關文章