Da es keinen Artikel gab, der sich mit [Formel → Implementierung] befasste, werde ich ihn buchstabieren. Dieses Mal werde ich die einfachste Cooley - Tukey Typ FFT namens Radix-2 vorstellen.
Zunächst wird DFT (diskrete Fourier-Transformation) durch die folgende Gleichung ausgedrückt.
Durch Verwendung von $ (6) (7) (8) $ für $ (5) $ kann die DFT schließlich wie folgt umgeschrieben werden.
Da $ F_ {gerade} (t) $ und $ F_ {ungerade} (t) $ gemeinsam sind, werden $ F (t) $ und $ F (t + \ frac {N} {2}) $ gleichzeitig berechnet. Deshalb willst du es. Dies ist der Mechanismus zum Reduzieren des Rechenaufwands.
Fahren wir auf der Grundlage der obigen Ausführungen mit der Implementierung fort.
Schreiben wir eine FFT-Funktion in Python. Hier ist die Grundidee. Teilen Sie die Eingabedaten in gerade und ungerade Elemente, führen Sie eine FFT (rekursiv) wie $ (3) (4) $ durch und verwenden Sie dann $ (9) (10) $ bis 0 ~ (N / 2) - Berechnen Sie die 1. und N / 2 ~ N-1. Daher ist FFT eine rekursive Funktion.
def FFT(f):
#f:Eingabedaten der Größe N.
N = len(f)
if N == 1: #Wenn N 1 ist, werden die Eingabedaten so zurückgegeben, wie sie sind
return f[0]
f_even = f[0:N:2] #Gerades Element von f
f_odd = f[1:N:2] #Das ungerade Element von f
F_even = FFT(f_even) #(3)FFT am geraden Element
F_odd = FFT(f_odd) #(4)FFT am geraden Element
W_N = np.exp(-1j * (2 * np.pi * np.arange(0, N // 2)) / N) #t ist 0~N/2-Ein Array, das W bis zum ersten berechnet
F = np.zeros(N, dtype ='complex') #FFT-Ausgang
F[0:N//2] = F_even + W_N * F_odd #(9)Berechnung(t:0~N/2-1)
F[N//2:N] = F_even - W_N * F_odd #(10)Berechnung(t:N/2~N-1)
return F
Lassen Sie uns prüfen, ob wir die gleiche Ausgabe wie die FFT von numpy erhalten können. Erstellen Sie eine zusammengesetzte Welle aus zwei Sinuswellen mit den folgenden Parametern und verwenden Sie diese als Eingabe.
import numpy as np
import matplotlib.pyplot as plt
N = 64 #Die Anzahl der Daten
n = np.arange(N)
f1 = 2 #Zyklus 1
f2 = 5 #Zyklus 2
A1 = 3 #Amphitheater 1
A2 = 5 #Amphitheater 2
INPUT_f = A1 * np.sin(f1 * 2 * np.pi * (n/N)) + A2 * np.sin(f2 * 2 * np.pi * (n/N)) #Synthese zweier Sinuswellen
#Anzeige
plt.figure(figsize=(10, 5))
plt.style.use('seaborn')
plt.plot(INPUT_f)
Führen Sie FFT aus. Da die Ausgabe von FFT eine komplexe Zahl ist, ist hier eine Visualisierung der Amplitudenkomponente, die durch Multiplizieren mit einem absoluten Wert extrahiert wurde.
OUTPUT_F_numpy = np.fft.fft(INPUT_f) #numpy Version
OUTPUT_F_original = FFT(INPUT_f) #Selbstgemachte Version
plt.figure(figsize=(10, 5))
plt.subplot(1,2,1) #Anzeige der Oszillationskomponenten(numpy Version)
plt.title('numpy_ver')
plt.plot(np.abs(OUTPUT_F_numpy))
plt.subplot(1,2,2) #Anzeige der Oszillationskomponenten(Selbstgemachte Version)
plt.title('original')
plt.plot(np.abs(OUTPUT_F_original))
Ich habe das gleiche Ergebnis sicher erhalten.
Recommended Posts