在 Python 中证明傅里叶变换运算

Proving Fourier transform operation in Python

我有一个时域表达式

f = -1j*H(t) * exp(-(1j*a+b)*t)

可以使用 known properties 进行傅里叶分析变换(H 是海维赛德阶跃函数)。这个FT运算的结果是

F = (w-a-1j*b)/((w-a)**2+b**2)

其中 w 是频率。

现在我正在使用this article中的技巧对Python中的f进行数值傅里叶变换,并确认我确实得到了相同的分析结果F:

import numpy as np
import matplotlib.pyplot as plt

t = np.linspace(-10,10,1e4) # time
w = np.linspace(-10,10,1e4) # frequency

b = 0.1
a = 1

H = lambda x: 1*(x>0) # heaviside function

# function in time
f = -1j*H(t)*np.exp(-(1j*a+b)*t)

# function in frequency (analytical work)
F = (w-a-1j*b)/((w-a)**2+b**2)

hann = np.hanning(len(t))  # hanning window

# function in frequency (numerical work)
F2 = 2/len(t)*np.fft.fft(hann*f)

plt.figure()
plt.plot(w,F.real,'b',label='analytical')
plt.plot(w,F2.real,'b--',label='fft')
plt.xlabel(r'$\omega$')
plt.ylabel(r'Re($F(\omega)$)')
plt.legend(loc='best')

plt.figure()
plt.plot(w,F.imag,'g',label='analytical')
plt.plot(w,F2.imag,'g--',label='fft')
plt.xlabel(r'$\omega$')
plt.ylabel(r'Im($F(\omega)$)')
plt.legend(loc='best')

plt.show()

然而 Python 的 FFT 函数似乎给我一些完全错误的东西。当绘制 FF2 时,这一点很明显。

编辑:这是情节...

这些图中并不明显,但如果放大 w=-1010 区域,会出现小的振荡,可能是由于 fft 算法。

FFT 算法计算 DFT,它在第一个样本上具有原点(空间域和频域)。您需要移动您的信号(在应用 Hanning window 之后),以便 t=0 是最左边的样本,并且在计算 FFT 之后您必须进行反向移动。

MATLAB 有 ifftshiftfftshift,它们实现了这两个班次。 NumPy 一定有类似的功能。

您的代码的另一个问题是您计算了 DFT,并将其绘制在您计算的 w 给定的位置,但与计算 DFT 的实际频率无关。

这是您的代码,已转换为 MATLAB,并已修复以正确计算 F2w *。我希望这是有用的。需要注意的一件事是您的 FF2 不匹配,我相信这不是由于 F2 的错误,而是您计算 F 的错误].形状相似,但 F 缩放和镜像不同。

N = 1e3;
t = linspace(-100,100,N); % time
Fs = 1/(t(2)-t(1));
w = Fs * (-floor(N/2):floor((N-1)/2)) / N; % NOTE proper frequencies

b = 0.1;
a = 1;

H = @(x)1*(x>0); % Heaviside function

% function in time
f = -1j*H(t).*exp(-(1j*a+b)*t);

% function in frequency (analytical work)
F = (w-a-1j*b)./((w-a).^2+b.^2);

% hanning window
hann = 0.5*(1-cos(2*pi*linspace(0,1,N)));

% function in frequency (numerical work)
F2 = fftshift(fft(ifftshift(hann.*f))); % NOTE shifting of origin

figure

subplot(2,1,1), hold on
plot(w,real(F),'b-')
plot(w,real(F2),'r-')
xlabel('\omega')
ylabel('Re(F(\omega))')
legend({'analytical','fft'},'Location','best')

subplot(2,1,2), hold on
plot(w,imag(F),'b-')
plot(w,imag(F2),'r-')
xlabel('\omega')
ylabel('Im(F(\omega))')
legend({'analytical','fft'},'Location','best')

脚注:
* 我也改了颜色,MATLAB的绿色太浅了