Ich schrieb eine einfache Fourier-Transformations-Implementierung und betrachtete die DFT-Gleichung auf Wikipedia als Referenz , als ich bemerkte, dass ich etwas anders machte, und nachdem ich darüber nachgedacht hatte, hatte ich das Gefühl, dass die Wikipedia-Version falsch sein muss, weil es sehr einfach ist, an eine zu denken signalisieren, dass bei einer Fourier-Transformation (mit dieser Gleichung) ein falsches Spektrum zurückgegeben wird: Da die Gleichung das Signal nur einmal um die komplexe Ebene wickelt (aufgrund der mit ), jedes periodische Signal Eine gerade Anzahl von Malen (beim Umwickeln der komplexen Ebene) hat kein Spektrum, da sich die üblichen Peaks (beim Umrunden des Einheitskreises), die während einer DFT auftreten würden, gegenseitig aufheben (wenn eine gerade Anzahl von ihnen auftritt).0 < n < N - 1
Um dies zu überprüfen, habe ich einen Code geschrieben, der das folgende Bild erzeugt, das meine Gedanken zu bestätigen scheint.
"Zeit unter Verwendung der Gleichung" verwendet die Gleichung mit einem Vektor der Zeit (so zum Beispiel die Zeit zu der abgetastet wurde). Es kann in der Funktion unten gefunden werden.t t n x n
ft
Die oben verlinkte Wikipedia-Gleichung wird hier als Referenz kopiert: Es kann in der Funktion gefunden werden .
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()
Offensichtlich ist es eher unwahrscheinlich, dass ich zufällig einen Fehler auf einer so hochkarätigen Wiki-Seite gefunden hätte. Aber ich kann keinen Fehler in dem sehen, was ich getan habe?
quelle
Antworten:
Du hast einen Fehler
ft2
. Sie erhöheni
undfreq
zusammen. So soll Ihre Summierung nicht funktionieren. Ich habe herumgespielt, um es zu reparieren, aber es wurde chaotisch. Ich beschloss, es aus einer diskreten Perspektive neu zu schreiben, anstatt zu versuchen, die fortlaufende Terminologie zu verwenden. In der DFT spielt die Abtastrate keine Rolle. Entscheidend ist, wie viele Proben verwendet werden (N
). Die Bin-Nummern (k
) entsprechen dann der Frequenz in Einheiten von Zyklen pro Frame. Ich habe versucht, Ihren Code so intakt wie möglich zu halten, damit er für Sie leicht verständlich bleibt. Ich habe auch die DFT-Berechnungsschleifen entfaltet, um hoffentlich ihre Natur ein bisschen besser zu enthüllen.Hoffe das hilft.
Ced
quelle
und das ist das gleiche wie auf der Wikipedia-Seite.
quelle
Ich bin darauf zurückgekommen und habe versucht, die diskrete Version abzuleiten, die dazu beigetragen hat, die Dinge sinnvoller zu machen:
Damit
Erledigt!
quelle