Puisqu'il n'y avait pas d'article portant sur [Formule → Implémentation], je vais l'épeler. Cette fois, je vais vous présenter la FFT de type Cooley - Tukey la plus simple appelée radix-2.
Premièrement, la DFT (transformée de Fourier discrète) est exprimée par l'équation suivante.
En utilisant $ (6) (7) (8) $ pour $ (5) $, le DFT peut enfin être réécrit comme suit.
Puisque $ F_ {pair} (t) $ et $ F_ {impair} (t) $ sont communs, $ F (t) $ et $ F (t + \ frac {N} {2}) $ sont calculés en même temps. C'est pourquoi vous le voulez. C'est le mécanisme pour réduire la quantité de calcul.
Sur la base de ce qui précède, passons à la mise en œuvre.
Écrivons une fonction FFT en Python. Voici l'idée de base. Divisez les données d'entrée en éléments pairs et en éléments impairs, effectuez une FFT (récursive) comme $ (3) (4) $, puis utilisez $ (9) (10) $ à 0 ~ (N / 2) - Calculez le 1er et N / 2 ~ N-1th. Par conséquent, FFT est une fonction récursive.
def FFT(f):
#f:Données d'entrée de taille N
N = len(f)
if N == 1: #Lorsque N vaut 1, les données d'entrée sont renvoyées telles quelles
return f[0]
f_even = f[0:N:2] #Even-th élément de f
f_odd = f[1:N:2] #L'élément impair de f
F_even = FFT(f_even) #(3)FFT sur élément pair
F_odd = FFT(f_odd) #(4)FFT sur élément pair
W_N = np.exp(-1j * (2 * np.pi * np.arange(0, N // 2)) / N) #t vaut 0~N/2-Un tableau qui calcule W jusqu'au premier
F = np.zeros(N, dtype ='complex') #Sortie FFT
F[0:N//2] = F_even + W_N * F_odd #(9)Calculer(t:0~N/2-1)
F[N//2:N] = F_even - W_N * F_odd #(10)Calculer(t:N/2~N-1)
return F
Vérifions si nous pouvons obtenir le même résultat que la FFT de numpy. Créez une onde composite de deux ondes sinusoïdales avec les paramètres suivants et utilisez-la comme entrée.
import numpy as np
import matplotlib.pyplot as plt
N = 64 #Le nombre de données
n = np.arange(N)
f1 = 2 #Cycle 1
f2 = 5 #Cycle 2
A1 = 3 #Amphithéâtre 1
A2 = 5 #Amphithéâtre 2
INPUT_f = A1 * np.sin(f1 * 2 * np.pi * (n/N)) + A2 * np.sin(f2 * 2 * np.pi * (n/N)) #Synthèse de deux ondes de péché
#afficher
plt.figure(figsize=(10, 5))
plt.style.use('seaborn')
plt.plot(INPUT_f)
Exécutez FFT. Comme la sortie de FFT est un nombre complexe, voici une visualisation de la composante d'amplitude extraite en la multipliant par une valeur absolue.
OUTPUT_F_numpy = np.fft.fft(INPUT_f) #version numpy
OUTPUT_F_original = FFT(INPUT_f) #Version faite maison
plt.figure(figsize=(10, 5))
plt.subplot(1,2,1) #Affichage des composants d'oscillation(version numpy)
plt.title('numpy_ver')
plt.plot(np.abs(OUTPUT_F_numpy))
plt.subplot(1,2,2) #Affichage des composants d'oscillation(Version faite maison)
plt.title('original')
plt.plot(np.abs(OUTPUT_F_original))
J'ai obtenu le même résultat en toute sécurité.
Recommended Posts