使用numpy.fft

时间:2017-01-26 17:09:21

标签: python numpy math physics

我想使用Python将傅里叶变换从时域到频域的模拟激光脉冲。我开始使用高斯函数,因为已知"时间带宽积" (当根据高斯的半高全宽度的术语来定义宽度时,时域中的宽度乘以频域中的宽度)是0.44

然而,当使用numpy.fft.fft时,我发现时间带宽乘积为0.88,是应有的两倍。

enter image description here 这是我的代码(前几行中的最小例子,其余的只是制作图表):

import numpy as np
import matplotlib.pyplot as plt

fwhm = 40e-15 # using a 40 femtosecond pulse

t  = np.linspace(-500e-15, 500e-15, 2000)
Et = np.exp( -t**2 / (2*(fwhm / 2.35482)**2) ) # gaussian function

Ef = np.abs(np.fft.fftshift( np.fft.fft(Et) )) # take the fourier transform
f  = np.fft.fftshift( np.fft.fftfreq(Ef.shape[0],t[1]-t[0]) ) # generate the frequencies

fwhm_fft = 2 * np.abs( f[ np.argmin(np.abs(0.5*np.max(Ef)-Ef)) ] ) # find the fwhm of the frequnecy-domain signal

print 'Observed time-bandwidth product: %.3f'%(fwhm*fwhm_fft)

# just making plots from here onwards:
fig, axs = plt.subplots(2,1, figsize=(6,8))

axs[0].set_title('Time domain')
axs[0].plot(t,Et)
axs[0].axvline(-fwhm*0.5, color='r', alpha=0.5, label='Full-width at half-maximum (FWHM) = %.1f fs'%(fwhm*1e15))
axs[0].axvline( fwhm*0.5, color='r', alpha=0.5)

axs[0].set_ylim(0,1.3)
axs[0].set_xlabel('Time (sec)')

axs[1].set_title('Frequency domain')
axs[1].plot(f,Ef)

axs[1].axvline(-0.44/fwhm*0.5, color='r', alpha=0.5, label='FWHM should be %.1f THz'%(0.44/fwhm*1e-12) )
axs[1].axvline( 0.44/fwhm*0.5, color='r', alpha=0.5)

axs[1].axvline(-fwhm_fft*0.5, color='g', alpha=0.5, label='FWHM is actually %.1f THz'%(fwhm_fft*1e-12) )
axs[1].axvline( fwhm_fft*0.5, color='g', alpha=0.5)

axs[1].set_xlim(-5e13,5e13)
axs[1].set_ylim(0,120)
axs[1].set_xlabel('Frequency (Hz)')

for ax in axs:
    ax.legend(fontsize=10)
    ax.set_ylabel('Electric field intensity (arbitrary units)')

plt.tight_layout()
plt.savefig('time-bandwidth-product.png', dpi=200)
plt.show()

2 个答案:

答案 0 :(得分:1)

编辑2:看来魔鬼是在物理学中,而不是数学,看Dan的自我回答。平方高斯实际上确实将半最大值的位置移动了1 / sqrt(2),因此一切都很好。仍然让我谦卑地毫无保留地向RP Photonics道歉。编辑结束2.

我很确定你要找的“bug”是0.44,你链接的参考看起来不是100%可靠。

因此,让我们自己来预测会发生什么。傅立叶变换有不同的定义; this one似乎是一个坚持不懈的人。在该惯例中,高斯及其傅里叶变换的标准偏差的乘积是1 /(2π)。具有SD西格玛的零均值高斯的半最大值为+/-西格玛sqrt(2log 2)。因此,FWHM的乘积是1 /(2pi)8 log 2 = 4 / pi log 2 = 0.8825 ...

换句话说:你所观察的是正确的。

编辑:为了公平对待RP Photonics,他们可能只是使用傅立叶变换的另一个定义并不一定错。

答案 1 :(得分:1)

@PaulPanzer走在正确的轨道上!当比较两个高斯函数的FWHM时,我们确实期望找到0.88作为时间带宽乘积。

但为什么大多数参考文献 [123]都说0.44是激光脉冲的时间带宽积?关键是我们实际观察到的是电场强度(I)(E),其中I = E ^ 2。因此,实际上,最有意义的是比较强度配置文件的宽度,而不是电场配置文件。当我们比较强度分布时,我们发现时间带宽乘积确实是0.44。

修订代码:

import numpy as np
import matplotlib.pyplot as plt

fwhm = 40e-15 # using a 40 femtosecond pulse

t  = np.linspace(-1000e-15, 1000e-15, 4000)
It = np.exp( -t**2 / (2*(fwhm / 2.35482)**2) ) # Intensity in the time domain
Et = np.sqrt(It)                               # E-field in the time domain

Ef = np.abs(np.fft.fftshift( np.fft.fft(Et) )) # FT to get E-field in frequency domain
If = Ef**2                                     # Intensity in the frequnecy domain
f  = np.fft.fftshift( np.fft.fftfreq(Ef.shape[0],t[1]-t[0]) ) # generate the frequencies

fwhm_fft = 2 * np.abs( f[ np.argmin(np.abs(0.5*np.max(If)-If)) ] ) # find the fwhm of the frequency-domain signal

print 'Observed time-bandwidth product: %.3f'%(fwhm*fwhm_fft)


# just making plots from here onwards:
fig, axs = plt.subplots(2,1, figsize=(6,8))

axs[0].set_title('Time domain')
axs[0].plot(t,It)
axs[0].axvline(-fwhm*0.5, color='r', alpha=0.5, label='Full-width at half-maximum (FWHM) = %.1f fs'%(fwhm*1e15))
axs[0].axvline( fwhm*0.5, color='r', alpha=0.5)

axs[0].set_xlim(-150e-15, 150e-15)
axs[0].set_ylim(0,1.3)
axs[0].set_xlabel('Time (sec)')

axs[1].set_title('Frequency domain')
axs[1].plot(f,If)

axs[1].axvline(-0.44/fwhm*0.5, color='r', alpha=0.5, label='FWHM should be %.1f THz'%(0.44/fwhm*1e-12) )
axs[1].axvline( 0.44/fwhm*0.5, color='r', alpha=0.5)

axs[1].axvline(-fwhm_fft*0.5, color='g', alpha=0.5, ls='dashed', label='FWHM is actually %.1f THz'%(fwhm_fft*1e-12) )
axs[1].axvline( fwhm_fft*0.5, color='g', alpha=0.5, ls='dashed')

axs[1].set_xlim(-2.0e13,2.0e13)
axs[1].set_ylim(0,30000)
axs[1].set_xlabel('Frequency (Hz)')

for ax in axs:
    ax.legend(fontsize=10)
    ax.set_ylabel('Electric field intensity (arbitrary units)')

plt.tight_layout()
plt.savefig('time-bandwidth-product.png', dpi=200)
plt.show()

enter image description here

PS:RP-Photonics是一个很棒的资源。它是激光和光子学领域的主要教科书之一。