Numpy FFT 在 meshgrids 上失败?
Numpy FFT fails on meshgrids?
我 运行 使用带有 FFT 函数的 Numpy meshgrids 遇到了一个奇怪的问题。具体来说,在使用 meshgrids 构建的数组上使用时,fft2 或 ifft2 函数似乎会失败。
x = np.arange(-4, 4, .08)
y = np.arange(-4, 4, .08)
X, Y = np.meshgrid(x, y)
field = (X + i*Y)*np.exp(X**2 + Y**2)
作为在我继续我的项目之前的检查,我做了
fieldCheck1 = np.fft.fft2(field)
fieldCheck2 = np.fft.ifft2(fieldCheck1)
这应该返回我的原始数组,但实际上消除了实部(abs(fieldCheck2)**2
的图是平零,原来它是高斯)并完全扰乱了相位信息(相位图fieldCheck2
看起来像静态而不是相位斜坡)
我已经检查了文档,但我没有看到任何可以解释这一点的内容。任何对问题根源的洞察都会有所帮助。
问题(在您的代码中将 ^
替换为 **
之后)是您的最小值和最大值之间的对比接近 30 个数量级:
>>> abs(field).max() / abs(field).min()
8.8904389513698014e+28
浮点运算的精度有限,因此适用于 实数 数字的恒等式并不总是适用于 浮点数 数字。举个简单的例子:
>>> x = 1
>>> y = 1e30
>>> z = x + y
>>> x == z - y
False
FFT 本质上是一个更复杂的版本:你将非常小的数字加到非常大的数字上,当你再次减去非常大的数字时,你得到零而不是你期望的小数字。
添加@jakevdp 描述的问题,看起来你陷入了这整个混乱,因为你的函数(在你的代码中用 **
替换 ^
之后)
field = (X + 1.0j*Y)*np.exp(X**2 + Y**2)
您描述为高斯分布的实际上并非如此,如下图所示:
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot_surface(X,Y,np.abs(field));
要获得实际的二维高斯函数,请尝试:
x = np.arange(-4, 4, .08)
y = np.arange(-4, 4, .08)
X, Y = np.meshgrid(x, y)
field = np.exp(-(X**2 + Y**2)) # notice "-" sign in the exponent
这会给你图表:
以及往返变换的相应误差np.abs(fieldCheck2-field)
为(更符合预期的数值精度):
我 运行 使用带有 FFT 函数的 Numpy meshgrids 遇到了一个奇怪的问题。具体来说,在使用 meshgrids 构建的数组上使用时,fft2 或 ifft2 函数似乎会失败。
x = np.arange(-4, 4, .08)
y = np.arange(-4, 4, .08)
X, Y = np.meshgrid(x, y)
field = (X + i*Y)*np.exp(X**2 + Y**2)
作为在我继续我的项目之前的检查,我做了
fieldCheck1 = np.fft.fft2(field)
fieldCheck2 = np.fft.ifft2(fieldCheck1)
这应该返回我的原始数组,但实际上消除了实部(abs(fieldCheck2)**2
的图是平零,原来它是高斯)并完全扰乱了相位信息(相位图fieldCheck2
看起来像静态而不是相位斜坡)
我已经检查了文档,但我没有看到任何可以解释这一点的内容。任何对问题根源的洞察都会有所帮助。
问题(在您的代码中将 ^
替换为 **
之后)是您的最小值和最大值之间的对比接近 30 个数量级:
>>> abs(field).max() / abs(field).min()
8.8904389513698014e+28
浮点运算的精度有限,因此适用于 实数 数字的恒等式并不总是适用于 浮点数 数字。举个简单的例子:
>>> x = 1
>>> y = 1e30
>>> z = x + y
>>> x == z - y
False
FFT 本质上是一个更复杂的版本:你将非常小的数字加到非常大的数字上,当你再次减去非常大的数字时,你得到零而不是你期望的小数字。
添加@jakevdp 描述的问题,看起来你陷入了这整个混乱,因为你的函数(在你的代码中用 **
替换 ^
之后)
field = (X + 1.0j*Y)*np.exp(X**2 + Y**2)
您描述为高斯分布的实际上并非如此,如下图所示:
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot_surface(X,Y,np.abs(field));
要获得实际的二维高斯函数,请尝试:
x = np.arange(-4, 4, .08)
y = np.arange(-4, 4, .08)
X, Y = np.meshgrid(x, y)
field = np.exp(-(X**2 + Y**2)) # notice "-" sign in the exponent
这会给你图表:
以及往返变换的相应误差np.abs(fieldCheck2-field)
为(更符合预期的数值精度):