Saya menulis jawaban tambahan ini untuk menjelaskan asal mula difusi paku saat menggunakan fft dan terutama membahas scipy.fftpack tutorial yang saya tidak setuju di beberapa titik.
Dalam contoh ini, waktu perekaman tmax=N*T=0.75
. Sinyalnya adalah sin(50*2*pi*x)+0.5*sin(80*2*pi*x)
. Sinyal frekuensi harus berisi 2 lonjakan pada frekuensi 50
dan 80
dengan amplitudo 1
dan 0.5
. Namun, jika sinyal yang dianalisis tidak memiliki bilangan bulat periode, difusi dapat muncul karena pemotongan sinyal:
- Pike 1:
50*tmax=37.5
=> frekuensi 50
bukan kelipatan 1/tmax
=> Adanya difusi akibat pemotongan sinyal pada frekuensi ini.
- Pike 2:
80*tmax=60
=> frekuensi 80
adalah kelipatan 1/tmax
=> Tidak ada difusi akibat pemotongan sinyal pada frekuensi ini.
Berikut adalah kode yang menganalisis sinyal yang sama seperti di tutorial ( sin(50*2*pi*x)+0.5*sin(80*2*pi*x)
) tetapi dengan sedikit perbedaan:
- Contoh asli scipy.fftpack.
- Contoh scipy.fftpack asli dengan nomor integer periode sinyal (
tmax=1.0
bukan0.75
untuk menghindari difusi pemotongan).
- Contoh asli scipy.fftpack dengan bilangan bulat periode sinyal dan di mana tanggal dan frekuensi diambil dari teori FFT.
Kode:
import numpy as np
import matplotlib.pyplot as plt
import scipy.fftpack
N = 600
tmax = 3/4
T = tmax / N
x1 = np.linspace(0.0, N*T, N)
y1 = np.sin(50.0 * 2.0*np.pi*x1) + 0.5*np.sin(80.0 * 2.0*np.pi*x1)
yf1 = scipy.fftpack.fft(y1)
xf1 = np.linspace(0.0, 1.0/(2.0*T), N//2)
tmax = 1
T = tmax / N
x2 = np.linspace(0.0, N*T, N)
y2 = np.sin(50.0 * 2.0*np.pi*x2) + 0.5*np.sin(80.0 * 2.0*np.pi*x2)
yf2 = scipy.fftpack.fft(y2)
xf2 = np.linspace(0.0, 1.0/(2.0*T), N//2)
tmax = 1
T = tmax / N
x3 = T * np.arange(N)
y3 = np.sin(50.0 * 2.0*np.pi*x3) + 0.5*np.sin(80.0 * 2.0*np.pi*x3)
yf3 = scipy.fftpack.fft(y3)
xf3 = 1/(N*T) * np.arange(N)[:N//2]
fig, ax = plt.subplots()
ax.plot(xf1, 2.0/N * np.abs(yf1[:N//2]), label='fftpack tutorial')
ax.plot(xf2, 2.0/N * np.abs(yf2[:N//2]), label='Integer number of periods')
ax.plot(xf3, 2.0/N * np.abs(yf3[:N//2]), label='Correct positionning of dates')
plt.legend()
plt.grid()
plt.show()
Keluaran:
Seperti yang bisa terjadi di sini, bahkan dengan menggunakan periode bilangan bulat beberapa difusi masih tetap ada. Perilaku ini disebabkan oleh posisi tanggal dan frekuensi yang buruk dalam tutorial scipy.fftpack. Karenanya, dalam teori transformasi Fourier diskrit:
- sinyal harus dievaluasi pada tanggal di
t=0,T,...,(N-1)*T
mana T adalah periode pengambilan sampel dan total durasi sinyal tmax=N*T
. Perhatikan bahwa kami berhenti di tmax-T
.
- frekuensi terkait adalah di
f=0,df,...,(N-1)*df
mana df=1/tmax=1/(N*T)
frekuensi sampling. Semua harmonisa sinyal harus multipel dari frekuensi sampling untuk menghindari difusi.
Dalam contoh di atas, Anda dapat melihat bahwa penggunaan arange
alih-alih linspace
memungkinkan untuk menghindari difusi tambahan dalam spektrum frekuensi. Selain itu, menggunakan linspace
versi juga mengarah pada offset paku yang terletak pada frekuensi yang sedikit lebih tinggi dari yang seharusnya seperti yang dapat dilihat pada gambar pertama di mana paku sedikit di sebelah kanan frekuensi 50
dan 80
.
Saya hanya akan menyimpulkan bahwa contoh penggunaan harus diganti dengan kode berikut (yang menurut saya kurang menyesatkan):
import numpy as np
from scipy.fftpack import fft
N = 600
T = 1.0 / 800.0
x = T*np.arange(N)
y = np.sin(50.0 * 2.0*np.pi*x) + 0.5*np.sin(80.0 * 2.0*np.pi*x)
yf = fft(y)
xf = 1/(N*T)*np.arange(N//2)
import matplotlib.pyplot as plt
plt.plot(xf, 2.0/N * np.abs(yf[0:N//2]))
plt.grid()
plt.show()
Output (lonjakan kedua tidak tersebar lagi):
Saya rasa jawaban ini masih memberikan beberapa penjelasan tambahan tentang bagaimana menerapkan transformasi Fourier diskrit dengan benar. Jelas sekali, jawaban saya terlalu panjang dan selalu ada hal tambahan untuk dikatakan (@ewerlopes berbicara singkat tentang aliasing misalnya dan banyak yang bisa dikatakan tentang windowing ) jadi saya akan berhenti. Menurut saya, sangat penting untuk memahami secara mendalam prinsip transformasi Fourier diskrit saat menerapkannya karena kita semua tahu banyak orang menambahkan faktor di sana-sini saat menerapkannya untuk mendapatkan apa yang mereka inginkan.