使用 Numpy 和奈奎斯特频率的 FFT 导数
FFT derivatives using Numpy and the Nyquist frequency
我无法理解 Numpy 关于奈奎斯特频率的行为。考虑以下示例:
import numpy as np
x=np.linspace(0, 2*np.pi, 21)[:-1]
k=np.fft.rfftfreq(len(x), d=x[1]-x[0])
FFT=np.fft.rfft(x)
x1=np.fft.irfft(1j*k*FFT)
FFT[-1]+=1e5
x2=np.fft.irfft(1j*k*FFT)
print(np.allclose(x1,x2))
打印 True
。所以显然我在 FFT
中用奈奎斯特频率做什么并不重要,结果总是一样的,变化被忽略了。奇怪的是,当试图恢复函数(没有推导)时,这不会发生:
x1=np.fft.irfft(FFT)
FFT[-1]+=1e5
x2=np.fft.irfft(FFT)
print(np.allclose(x1,x2))
打印 False
.
我可能误解了这里的奈奎斯特频率(维基百科和其他来源不是很有帮助)但是这两个结果难道不应该受到奈奎斯特频率变化的影响吗?我能找到的最接近的解释是奈奎斯特频率应该是一个实数,但似乎仍然不能解释这两种行为。
我问这个问题的原因是因为我试图从 Fortran code 中重现我知道正确的结果,该 Fortran code 确实对奈奎斯特频率做了一些微分。我的结果总是大约 1% 的折扣,我猜这是罪魁祸首。
np.fft.rfft()
中的r
表示您在真实输入上使用DFT。但如果那不是 True,您将得到 意外的 行为,就像这样。只需对复数值使用 fft
函数。作为旁注,请始终尝试检查您的数据。
EDIT(补充说明):
特别是,当您计算 "DFT for real inputs" 时,您正在对数据强制执行某些属性,即实值函数的 (D)FT,意味着 (D)FT 变换是 Hermitian 对称的,因此,负 (D)FT 系数是多余的,因此 rfft
和后来的 irfft
针对此假设下的计算进行了优化。
有关详细信息,请参阅他们的文档 np.fft.rfft()
and np.fft.irfft()
。
简而言之,由于这种预期的奇偶校验,np.fft.rfft()
不会计算你的一半系数(负系数),并且由于 (D)FT 变换的奇偶校验,第一个分量是纯实数(根据定义)最后一个组件也是纯真实的(为方便起见)。
由于 1j
乘法,在随后的 irfft
调用中,纯实数现在变成纯虚数(反之亦然)。
由于 irfft()
将忽略第一个和最后一个分量的虚部,因此您的语句不会影响其结果。
我无法理解 Numpy 关于奈奎斯特频率的行为。考虑以下示例:
import numpy as np
x=np.linspace(0, 2*np.pi, 21)[:-1]
k=np.fft.rfftfreq(len(x), d=x[1]-x[0])
FFT=np.fft.rfft(x)
x1=np.fft.irfft(1j*k*FFT)
FFT[-1]+=1e5
x2=np.fft.irfft(1j*k*FFT)
print(np.allclose(x1,x2))
打印 True
。所以显然我在 FFT
中用奈奎斯特频率做什么并不重要,结果总是一样的,变化被忽略了。奇怪的是,当试图恢复函数(没有推导)时,这不会发生:
x1=np.fft.irfft(FFT)
FFT[-1]+=1e5
x2=np.fft.irfft(FFT)
print(np.allclose(x1,x2))
打印 False
.
我可能误解了这里的奈奎斯特频率(维基百科和其他来源不是很有帮助)但是这两个结果难道不应该受到奈奎斯特频率变化的影响吗?我能找到的最接近的解释是奈奎斯特频率应该是一个实数,但似乎仍然不能解释这两种行为。
我问这个问题的原因是因为我试图从 Fortran code 中重现我知道正确的结果,该 Fortran code 确实对奈奎斯特频率做了一些微分。我的结果总是大约 1% 的折扣,我猜这是罪魁祸首。
np.fft.rfft()
中的r
表示您在真实输入上使用DFT。但如果那不是 True,您将得到 意外的 行为,就像这样。只需对复数值使用 fft
函数。作为旁注,请始终尝试检查您的数据。
EDIT(补充说明):
特别是,当您计算 "DFT for real inputs" 时,您正在对数据强制执行某些属性,即实值函数的 (D)FT,意味着 (D)FT 变换是 Hermitian 对称的,因此,负 (D)FT 系数是多余的,因此 rfft
和后来的 irfft
针对此假设下的计算进行了优化。
有关详细信息,请参阅他们的文档 np.fft.rfft()
and np.fft.irfft()
。
简而言之,由于这种预期的奇偶校验,np.fft.rfft()
不会计算你的一半系数(负系数),并且由于 (D)FT 变换的奇偶校验,第一个分量是纯实数(根据定义)最后一个组件也是纯真实的(为方便起见)。
由于 1j
乘法,在随后的 irfft
调用中,纯实数现在变成纯虚数(反之亦然)。
由于 irfft()
将忽略第一个和最后一个分量的虚部,因此您的语句不会影响其结果。