使用 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而言,物理色散关系确实应该出现在“负频率”中..
------------ 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而言,物理色散关系确实应该出现在“负频率”中..