这种傅立叶变换有什么问题? (使用python)

时间:2019-07-02 19:10:34

标签: python numpy fft pyfftw

正如阅读过我以前在此站点上发布的帖子的人所知,我一直在尝试实现在Python中使用FFT的PDE求解器。大部分编程工作都是在程序中完成的,但是程序会产生一个(非常适合该站点的)溢出错误(基本上,它会变得非常大,直到变成NaN)。

在排除了所有其他可能性之后,我将问题归结为FFT以及尝试做导数的方式,因此我决定测试两个不同的FFT(numpy的{​​{1}}模块和fft软件包),其代码如下:

pyFFTW

在这里,我认为import pyfftw import numpy as np import matplotlib.pyplot as plt def fftw_(y: np.ndarray) -> np.ndarray: a = pyfftw.empty_aligned((N, N), dtype=np.float64) b = pyfftw.empty_aligned((N, N//2+1), dtype=np.complex128) fft_object = pyfftw.FFTW(a, b, axes=(0, 1), direction='FFTW_FORWARD', flags=('FFTW_MEASURE',), threads=12) y_hat = fft_object(y) return y_hat def ifftw_(y_hat: np.ndarray) -> np.ndarray: a = pyfftw.empty_aligned((N, N//2+1), dtype=np.complex128) b = pyfftw.empty_aligned((N, N), dtype=np.float64) fft_object = pyfftw.FFTW(a, b, axes=(0, 1), direction='FFTW_BACKWARD', flags=('FFTW_MEASURE',), threads=12) y = fft_object(y_hat) return y def func(x: np.ndarray, y: np.ndarray) -> np.ndarray: return np.exp(x)*np.sin(y) dx = 0.02 x = np.arange(-1, 1, dx) y = np.arange(-1, 1, dx) X, Y = np.meshgrid(x, y) N = len(x) kxw, kyw = np.meshgrid(np.fft.rfftfreq(N, dx), np.fft.fftfreq(N, dx)) Lapw = -4*np.pi**2*(kxw**2+kyw**2) kxnp, kynp = np.meshgrid(np.fft.fftfreq(N, dx), np.fft.fftfreq(N, dx)) Lapnp = -4*np.pi**2*(kxnp**2+kynp**2) z = func(X, Y) lap_z_w = ifftw_(Lapw*fftw_(z)) lap_z_np = np.fft.ifft2(Lapnp*np.fft.fft2(z)) lap_z_np_mag = np.abs(lap_z_np) lap_z_np_ang = np.angle(lap_z_np) plt.imshow(z, cmap='plasma') plt.colorbar() plt.savefig("f.png", dpi=200) plt.clf() plt.imshow(lap_z_w, cmap='plasma') plt.colorbar() plt.savefig("Lap_fftw.png", dpi=200) plt.clf() plt.imshow(lap_z_np_mag, cmap='plasma') plt.colorbar() plt.savefig("Lap_np_mag.png", dpi=200) plt.clf() plt.imshow(lap_z_np_ang, cmap='plasma') plt.colorbar() plt.savefig("Lap_np_ang.png", dpi=200) plt.clf() 的命名为np.ndarrayLapw是离散的拉普拉斯算子。我选择的函数eˣsin(y)是谐波函数,因此其拉普拉斯算子为零。

但是该程序的结果与预期值相差很远。特别是我得到:

原始功能f The original funciton

使用pyFFTW的f的“拉普拉斯语” The "Laplacian" of f with pyFFTW

带有Numpy的f的“拉普拉斯算子”的大小和相位 The magnitude The phase

查看这些图的值(请注意色条中的范围,以及20000并不是对0的任何体面近似这一事实)可以清楚地说明我制作的程序为什么会出现溢出,但我却没有不知道该如何纠正。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:1)

这里的错误是您对功能的假设不正确。 e ^ x sin(y)似乎是谐波,但您只针对-1 fft会隐式地周期性地继续它,即,您在函数的所有边缘都将出现不连续性。如果函数不连续,则不是谐波,尤其是在傅立叶变换中会发散。这就是使FFT在边缘发散的原因。除此之外,结果离边缘很远。