使用 imshow 显示时空频谱:在对列进行 FFT 后,频率的顺序是什么?

Displaying a spatio-temporal spectrum with imshow: what order are the frequencies in after taking an FFT down columns?

------------ Summary ----------

如果我有 2D 数据 psi_hat_kxt 并且我将其 FFT 向下提取列并对结果 np.fft.fftshift(np.fft.fft(psi_hat_kxt, axis=0)) 进行 FFT 移位,负频率位于何处?它们不应该在结果数组的上半部分吗?如果是这样,当我使用 imshow 绘制结果(逐元素平方以获得真实数据)时,某处是否存在隐式上下翻转?

------------ Detailed ----------

我有一个模拟在空间傅立叶 space (k-space) 中演化一个场,我想显示每个 k 的频率内容。也就是说,我要绘制spatio-temporal spectrum、a.k.a。 k-omega 图,通过在时间方向上进行 FFT、平方和绘图。我在 NumPy 中做所有这些,

import numpy as np
from matplotlib import pyplot as plt
# other code that assigns variables like Nt, Nx, Deltat, dx etc.

我的数据[Edit:它是复数值]被排列成包含k-space数据的行,并且时间沿着每一行向下移动。我从一个外部二进制文件中读入这个然后重塑:

fname = open('../output/ky0slices.bin','rb')
psi_hat_kxt_vec = np.fromfile(fname, dtype=np.complex_)
fname.close()
psi_hat_kxt  = np.reshape(psi_hat_kxt_vec , (Nt,Nx))

然后我对列进行 FFT、移位和平方以获得实数:

komega_spec = np.abs( np.fft.fftshift (np.fft.fft(psi_hat_kxt, axis=0)) )**2.0

最后我使用 imshow 绘图:

om_ax = 2*np.pi * np.fft.fftshift( np.fft.fftfreq(Nt,d=Deltat) )
k_ax  = 2*np.pi * np.fft.fftshift( np.fft.fftfreq(Nx,d=dx) )
log_komega_spec = np.log(komega_spec)

extnt=[k_ax[0], k_ax[-1] , om_ax[0], om_ax[-1] ]

fig, ax = plt.subplots()
im = plt.imshow(log_komega_spec, extent=extnt , aspect='auto')

最后我得到一张看起来正确的图像,

但我不明白为什么它实际上是正确的。

也就是说,通过阅读文档,我认为在 fftshift 之后,负时间频率应该在 fft 数据的顶行中有它们的傅立叶系数,即 komega_spec[0,:] 应该包含一行所有傅立叶系数对应于频率 -Nt/2.

但是从图的形状来看,这一行似乎对应于正频率 Nt/2-1。 (好像是这样因为抛物线是凸的,因为物理原因应该是凸的,请忽略欧米伽轴刻度,因为它们是由extnt控制的。)

imshow 是不是在做一个隐含的 flipud

简而言之:为什么 komega_spec 的上半部分包含正频率数据?

是的.. imshow 正在做一个隐含的 flipud。尝试以下操作,问题应该得到解决:

im = plt.imshow(np.flipud(log_komega_spec), extent=extnt , aspect='auto')

答案是我们需要做变换omega -> - omega在色散关系的物理omega = k^2之间转换 (在我们扩展平面波函数的意义上 psi(x,t) = Sum psi_hat(k, omega) * exp[i(k*x-omega*t)]
) omega 是 FFT 输出的参数 (在 FFT 计算的意义上 F(omega) = Sum f(t) * exp[ +i(omega*t) ]

所以就FFT而言,物理色散关系确实应该出现在“负频率”中..