J'écrivais une implémentation de transformation de Fourier simple et j'ai regardé l' équation DFT sur wikipedia pour référence , quand j'ai remarqué que je faisais quelque chose différemment, et après y avoir pensé, j'ai senti que la version wikipedia devait être incorrecte car il est très simple de penser à un signal que lorsque transformée de Fourier (avec cette équation) retournera un spectre incorrect: parce que l'équation enveloppe le signal autour du plan complexe une seule fois (en raison du avec ), tout signal qui est périodique un nombre pair de fois (tout en enveloppant le plan complexe) n'aura pas de spectre car les pics habituels (tout en faisant le tour du cercle unitaire) qui apparaîtraient pendant un DFT s'annuleraient mutuellement (lorsqu'un nombre pair d'entre eux apparaîtrait).
Pour vérifier cela, j'ai écrit du code qui a produit l'image suivante, qui semble confirmer ce que je pense.
"Le temps en utilisant l'équation" utilise l'équation avec un vecteur de temps (donc le temps auquel été échantillonné par exemple). Il peut être trouvé dans la fonction ci-dessous.
ft
L'équation wikipedia, liée ci-dessus, est copiée ici pour référence: Il peut être trouvé dans la fonction .
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()
De toute évidence, il semble plutôt improbable que j'aurais trouvé au hasard une erreur sur une page wiki aussi prestigieuse. Mais je ne vois pas d'erreur dans ce que j'ai fait?
la source
Réponses:
Vous avez un bug
ft2
. Vous incrémentezi
, etfreq
ensemble. Ce n'est pas ainsi que vous souhaitez que votre sommation fonctionne. Je me suis amusé à le réparer, mais c'est devenu compliqué. J'ai décidé de le réécrire dans une perspective discrète au lieu d'essayer d'utiliser la terminologie continue. Dans le DFT, le taux d'échantillonnage n'est pas pertinent. Ce qui compte, c'est le nombre d'échantillons utilisés (N
). Les nombres de cases (k
) correspondent alors à la fréquence en unités de cycles par trame. J'ai essayé de vous garder le code aussi intact que possible afin qu'il reste facilement compréhensible pour vous. J'ai également déroulé les boucles de calcul DFT pour, espérons-le, révéler un peu mieux leur nature.J'espère que cela t'aides.
Ced
la source
je ne vais pas regarder dans votre code. la page de wikipedia semble correct, mais il est un bon exemple de la « guerre des formats » ou « guerre de notation » ou « guerre de style » entre mathématiciens et ingénieurs électriciens. certains, je pense que les maths ont raison. Les EE n'auraient jamais dû adopter " " pour l'unité imaginaire. cela dit, c'est une meilleure expression de la DFT et l'inverse est:j
DFT:
iDFT:
parce que les ingénieurs électriciens qui utilisent DSP aiment utiliser comme séquence d'échantillons en "temps" et comme séquence d'échantillons discrets en "fréquence". les mathématiciens aimeraient mieux ceci:x[n] X[k]
DFT:
iDFT:
et c'est la même chose que la page wikipedia.
vous devrez peut-être accorder plus d'attention à l'utilisation de ou+ − dans l'exposant et comment cela se traduit par + ou − contre la sin(⋅) terme.
la source
J'y suis revenu et j'ai essayé de dériver la version discrète qui a aidé à donner plus de sens aux choses:
En quelque sortefktn=f(n,k,N)
Donc
Terminé!
la source