Saya sedang menulis implementasi transformasi fourier sederhana dan melihat persamaan DFT di wikipedia untuk referensi , ketika saya perhatikan bahwa saya melakukan sesuatu yang berbeda, dan setelah memikirkannya merasa bahwa versi wikipedia pasti salah karena sangat mudah untuk memikirkan sebuah sinyal bahwa ketika fourier ditransformasikan (dengan persamaan itu) akan mengembalikan spektrum yang salah: Karena persamaan membungkus sinyal di sekitar bidang kompleks hanya sekali (karena dengan ), setiap sinyal yang periodik beberapa kali genap (saat membungkus bidang kompleks) tidak akan memiliki spektrum seperti puncak biasa (saat mengelilingi lingkaran unit) yang akan muncul selama DFT akan membatalkan satu sama lain (ketika angka genap dari mereka muncul).
Untuk memeriksa ini saya menulis beberapa kode yang menghasilkan gambar berikut, yang sepertinya mengkonfirmasi apa yang saya pikirkan.
"Waktu menggunakan persamaan" menggunakan persamaan dengan vektor waktu (jadi waktu di mana disampel misalnya). Ini dapat ditemukan pada fungsi di bawah ini.
ft
Persamaan wikipedia, ditautkan di atas, disalin di sini untuk referensi: Dapat ditemukan dalam fungsi .
ft2
import numpy as np
import matplotlib.pyplot as plt
plt.style.use('ggplot')
def ft(t, s, fs):
freq_step = fs / len(s)
freqs = np.arange(0, fs/2 + freq_step, freq_step)
S = []
for freq in freqs:
real = np.sum(s * np.cos(2*np.pi*freq * t))
compl = np.sum(- s * np.sin(2*np.pi*freq * t))
tmpsum = (real**2 + compl**2) ** 0.5
S.append(tmpsum)
return S, freqs
def ft2(s, fs): # Using wikipedia equation
nump=len(s)
freq_step = fs / nump
freqs = np.arange(0, fs/2 + freq_step, freq_step)
S = []
for i, freq in enumerate(freqs):
real = np.sum(s * np.cos(2*np.pi*freq * i/nump))
compl = np.sum(- s * np.sin(2*np.pi*freq * i/nump))
tmpsum = (real**2 + compl**2) ** 0.5
S.append(tmpsum)
return S, freqs
def main():
f = 5
fs = 100
t = np.linspace(0, 2, 200)
y = np.sin(2*np.pi*f*t) + np.cos(2*np.pi*f*2*t)
fig = plt.figure()
ax = fig.add_subplot(311)
ax.set_title('Signal in time domain')
ax.set_xlabel('t')
ax.plot(t, y)
S, freqs = ft(t, y, fs)
ax = fig.add_subplot(312)
ax.set_xticks(np.arange(0, freqs[-1], 2))
ax.set_title('Time using equation')
ax.set_xlabel('frequency')
ax.plot(freqs, S)
S, freqs = ft2(y, fs)
ax = fig.add_subplot(313)
ax.set_title('Using Wiki equation')
ax.set_xlabel('frequency')
ax.set_xticks(np.arange(0, freqs[-1], 2))
ax.plot(freqs, S)
plt.tight_layout()
plt.show()
main()
Jelas sepertinya agak tidak mungkin bahwa saya akan secara acak menemukan kesalahan pada halaman wiki profil tinggi. Tetapi saya tidak dapat melihat kesalahan dalam apa yang telah saya lakukan?
sumber
Jawaban:
Anda memiliki bug di
ft2
. Anda bertambahi
, danfreq
bersama - sama. Bukan itu yang Anda inginkan agar penjumlahan Anda bekerja. Saya bermain-main dengan memperbaikinya, tetapi itu menjadi berantakan. Saya memutuskan untuk menulis ulang dari perspektif diskrit alih-alih mencoba menggunakan terminologi berkelanjutan. Dalam DFT, laju pengambilan sampel tidak relevan. Yang penting adalah berapa banyak sampel yang digunakan (N
). Nomor bin (k
) kemudian sesuai dengan frekuensi dalam satuan siklus per frame. Saya mencoba untuk menjaga kode Anda semaksimal mungkin sehingga akan tetap mudah dipahami oleh Anda. Saya juga membuka loop perhitungan DFT untuk mudah-mudahan mengungkapkan sifat mereka sedikit lebih baik.Semoga ini membantu.
Ced
sumber
saya tidak akan melihat kode Anda. halaman wikipedia terlihat oke, tetapi ini adalah contoh yang bagus dari "perang format" atau "perang notasi" atau "perang gaya" antara matematikawan dan insinyur listrik. beberapa di antaranya, saya pikir orang matematika benar. EE seharusnya tidak pernah diadopsi "j "untuk unit imajiner. Yang mengatakan, ini adalah ekspresi DFT yang lebih baik dan kebalikannya adalah:
DFT:
iDFT:
karena insinyur listrik yang melakukan DSP suka menggunakanx [ n ] sebagai urutan sampel dalam "waktu" dan X[ k ] sebagai urutan sampel diskrit dalam "frekuensi". ahli matematika mungkin lebih suka ini:
DFT:
iDFT:
dan itu sama dengan halaman wikipedia.
Anda mungkin perlu lebih memperhatikan penggunaan+ atau - dalam eksponen dan bagaimana artinya + atau - melawan dosa( ⋅ ) istilah.
sumber
Saya kembali ke ini dan mencoba menurunkan versi diskrit yang membantu membuat segalanya lebih masuk akal:
Entah bagaimanafktn= f( n , k , N)
Begitu
Selesai!
sumber