DFT 和 FFT (python) 的不同结果?

问题描述

我正在使用 FFT 在我的博士论文中执行一些转换。由于我需要在某些频率上进行傅立叶变换,因此我想编写自己的 DFT(我不能使用 FFT,因为它的频率是由样本数和速率固定的)。

但我发现两种算法的输出之间存在差异。

这是一个最小的例子,它重现了 DFT 和 FFT 计算并输出了一些比较数据:

from scipy.fft import fft,fftshift,fftfreq
import numpy as np
import matplotlib.pyplot as plt

#Setting gaussian signal to perform example
N = 200 #sample number
x = np.linspace (-100,100,N) #axis to perform fft into
delta = x[1]-x[0] #space between samples
sigma = 10 #numerical value
freqs = fftshift(fftfreq(N,d=delta)) #FFT output frequencies. Will also be used in DFT to contrast results

#Calculating signal
signal = np.exp(-x**2/sigma**2)

#Plot input signal,for reference
plt.figure(figsize = (8,5))
plt.plot(x,signal)
plt.title("Input signal")
plt.show()

#Perform fft
output_fft = fftshift(fft(signal))

#Perform DFT in same frequencies as FFT
output_DFT1 = []
for fx in freqs:
    spec = np.sum(signal * np.exp(-1j*2*np.pi * fx * x))
    output_DFT1.append(spec)

#Plotting comparative results

#Real part 
plt.figure(figsize=(8,5))
plt.plot(freqs,np.real(output_fft),label='FFT')
plt.plot(freqs,np.real(output_DFT1),label='DFT1')
plt.legend(loc='upper right')
plt.title("Comparative on FFT and DFT real parts")
plt.show()

#Imaginary part
plt.figure(figsize=(8,np.imag(output_fft),np.imag(output_DFT1),label='DFT1')
plt.legend(loc='upper right')
plt.title("Comparative on FFT and DFT imag parts")
plt.show()

这是我的输出图像: Real part comparison Imaginary part comparison

为什么结果不同?

解决方法

我遵循了 this Wikipedia 中关于 DFT 的 Eq.1,结果与 scipy 中的两种方法相似; fft 和 dft。代码如下:

from scipy.fft import fft,fftshift,fftfreq
import numpy as np
import matplotlib.pyplot as plt

#Setting gaussian signal to perform example
N = 200 #sample number
x = np.linspace (-100,100,N) #axis to perform fft into
delta = x[1]-x[0] #space between samples
sigma = 10 #numerical value
freqs = fftshift(fftfreq(N,d=delta)) #FFT output frequencies. Will also be used in DFT to contrast results
freqs_no_shift = fftfreq(N,d=delta)

#Calculating signal
signal = np.exp(-x**2/sigma**2)

#Plot input signal,for reference
plt.figure(figsize = (8,5))
plt.plot(x,signal)
plt.title("Input signal")
plt.show()

#Perform fft
output_fft = fftshift(fft(signal))

#Perform DFT in same frequencies as FFT
output_DFT1 = []
for idx,fx in enumerate(freqs_no_shift):
    spec = 0
    for i,ampi in enumerate(signal):
        spec += ampi * np.exp(-1j*2*np.pi*idx*i/len(signal))
    output_DFT1.append(spec)
output_DFT1 = fftshift(np.array(output_DFT1))

from scipy.linalg import dft
m = dft(len(signal))
dft2 = m @ signal
dft2 = fftshift(dft2)

#Plotting comparative results

#Real part 
plt.figure(figsize=(8,5))
plt.plot(freqs,np.real(output_fft),label='FFT')
plt.plot(freqs,np.real(output_DFT1),label='DFT1')
plt.plot(freqs,np.real(dft2),label='DFT2')
plt.legend(loc='upper right')
plt.title("Comparative on FFT and DFT real parts")
plt.show()

#Imaginary part
plt.figure(figsize=(8,np.imag(output_fft),np.imag(output_DFT1),np.imag(dft2),label='DFT2')
plt.legend(loc='upper right')
plt.title("Comparative on FFT and DFT imag parts")
plt.show()

希望它能帮助您解决问题。