在使用pyfftw和scipy.fft进行ifft操作的过程中,会出现相位不连续的情况。

问题描述 投票:0回答:1

在用pyfftw对一个二维ndarray进行ifft时,我发现结果相位在很多位置是不连续的。我的代码如下。

import numpy as np
import pyfftw
from scipy.fft import ifftshift,fftshift
import matplotlib.pyplot as plt

N = 256
kx = np.linspace(-np.floor(N/2),np.ceil(N/2)-1,N)
kX,kY = np.meshgrid(kx,kx)
kR = np.sqrt(kX**2 + kY**2)
mask = np.where((kR<=15),1,0)
ifft_obj = pyfftw.builders.ifft2(ifftshift(mask))
wave = fftshift(ifft_obj())

plt.imshow(np.angle(wave),cmap='jet')
plt.colorbar()

相位图如下enter image description here最小相位值为 -3.141592653589793 而最大值为 3.141592653589793 而且它们的差异大于2pi。使用scipy.fft只是得到同样的结果。然而,当我转向Matlab时,结果看起来更合理。我的代码是。

N = 256;
kx = linspace(-floor(N/2),ceil(N/2)-1,N);
[kX,kY] = meshgrid(kx,kx);
kR = sqrt(kX.^2 + kY.^2);
mask = single(kR<=15);
wave = fftshift(ifft2(ifftshift(mask)));
imshow(angle(wave));
caxis([min(angle(wave),[],'all') max(angle(wave),[],'all')]);
axis image; colormap jet;colorbar;

相位图是enter image description here

不知道是什么原因导致python代码中的相位不连续,如何纠正。

python fft pyfftw
1个回答
1
投票

您的输入是对称的,这导致了一个纯实数变换(正值时相位为0,负值时相位为π)。但是由于FFT算法的数值不准确,结果的虚值非常小。因此,相位与0和π有一点偏差。在您的彩色映射图像中,0的小偏差是看不到的,但π的小偏差会导致接近于-π的值(因为 乙方副总裁已经讨论过).

MATLAB没有显示这个问题,因为MATLAB的 ifft 识别输入是(共轭)对称的,并输出一个纯实像。它只是忽略了那些小的虚值。

您可以在 Python 中用

wave = np.real_if_close(wave, tol=1000)

这里的容忍度是 np.finfo(wave.dtype).eps * tol (2.22 10-13 对于双浮球)。) 根据需要进行调整。


3
投票

一个相位最好显示为单位圆上的一个角。而圆没有起点和终点。绕圆不会产生不连续。正好加上2*pi(绕圆一圈)不会改变相位,所以+pi和-pi是同一个相位。因此,这两个相位的绝对差不是2*pi,而是零。如果你考虑到微小的四舍五入误差,它几乎为零。

我的建议是使用一个 "循环 "的颜色方案(不知道更好的术语),其中一端接近+pi,另一端接近-pi,用相同的颜色给图形着色。

© www.soinside.com 2019 - 2024. All rights reserved.