Matlab:对于偶实函数,FFT复数结果,IFFT实数结果
Matlab: for even real functions, FFT complex result, IFFT real result
我正在测试 Matlab 中 FFT 和 IFFT 函数的有效性。
我可以将这些函数的输出与一个众所周知的数学事实进行比较:偶实函数(如以 0 为中心的高斯函数)的傅里叶变换是另一个偶实函数(FFT[real,以 0 为中心的高斯] = 实数,以 0 为中心的高斯)。这个事实应该适用于 FFT 和 IFFT。
首先我制作网格:
nx = 256; % grid total pixel count
X = 500; % grid size (um)
dx = X/nx; % grid spacing (um)
x = linspace(-nx/2,nx/2-1,nx)*dx; % x grid (um)
df = 1/(nx*dx); % spectral grid spacing (1/um)
f = linspace(-nx/2,nx/2-1,nx)*df; % f grid (1/um)
然后我让我的高斯:
A = 1; % magnitude (arbitrary units)
x_fwhm = 7; % Full width at half maximum diameter (um)
x0 = x_fwhm/sqrt(2*log(2)); % 1/e^2 radius (um)
y = A*exp(-2*x.^2./(x0)^2); % Gaussian (arbitrary units)
并使用 FFT 进行傅里叶变换:
yFFT = fftshift(fft(fftshift(y)));
或者,使用 IFFT:
yIFFT = fftshift(ifft(fftshift(y)));
绘制结果:
IFFT 做得很完美:yIFFT 是纯实高斯分布。然而,FFT 产生一个复数:存在非常小的虚部。这很好,因为在傅立叶变换算法中应该会出现错误,而且无论如何都可以忽略不计。令我困惑的是为什么IFFT完全没有错误? FFT 和 IFFT 算法有很大不同吗?
*** 注意:fftshift 和 ifftshift 在这里是等价的,因为我的数组有偶数个元素。
实值时域信号的处理相当普遍。如此之多以至于 ifft
function 具有针对频域中出现的相应对称性的内置处理,如文档的 "Algorithm" 部分所述:
The ifft
function tests whether the vectors in Y
are conjugate symmetric. A vector v
is conjugate symmetric when the ith element satisfies v(i) = conj(v([1,end:-1:2]))
. If the vectors in Y
are conjugate symmetric, then the inverse transform computation is faster and the output is real.
换句话说,ifft
将 yIFFT
的虚部构造为恰好为 0,因为它检测到您的输入具有共轭对称性。
另一方面,即使是时域信号也相对不太常见,Mathworks 认为没有必要在 fft
function 中执行类似的测试。也就是说,您仍然可以通过使用 ifft
函数通过
计算 FFT 来利用共轭对称性测试
% compute fft(x,[],dim) using ifft:
size(x,dim) * conj(ifft(conj(x),[],dim))
您的代码有误:
yFFT = fftshift(fft(fftshift(y)));
应该阅读
yFFT = fftshift(fft(ifftshift(y)));
ifftshift
函数将原点从中间的 bin 移动到最左边的 bin。 fftshift
将原点从最左边的 bin 移到中间。对于 even-sized odd-sized 数组,这两个操作相似但不完全相同。请注意,您的逆变换也遇到同样的问题,但没有显示 SleuthEye 所解释的错误。 [没关系,我想我在那里有点困惑,你的情况应该没有区别。]
此外,
linspace(-nx/2,nx/2-1,nx)
最好写成
-nx/2 : nx/2-1
假设 nx
是偶数。它更短,但它 可能 由于计算方式的原因也有更小的数值误差(可能没有区别,但我尽量避免 linspace
当步长是1.
我正在测试 Matlab 中 FFT 和 IFFT 函数的有效性。
我可以将这些函数的输出与一个众所周知的数学事实进行比较:偶实函数(如以 0 为中心的高斯函数)的傅里叶变换是另一个偶实函数(FFT[real,以 0 为中心的高斯] = 实数,以 0 为中心的高斯)。这个事实应该适用于 FFT 和 IFFT。
首先我制作网格:
nx = 256; % grid total pixel count
X = 500; % grid size (um)
dx = X/nx; % grid spacing (um)
x = linspace(-nx/2,nx/2-1,nx)*dx; % x grid (um)
df = 1/(nx*dx); % spectral grid spacing (1/um)
f = linspace(-nx/2,nx/2-1,nx)*df; % f grid (1/um)
然后我让我的高斯:
A = 1; % magnitude (arbitrary units)
x_fwhm = 7; % Full width at half maximum diameter (um)
x0 = x_fwhm/sqrt(2*log(2)); % 1/e^2 radius (um)
y = A*exp(-2*x.^2./(x0)^2); % Gaussian (arbitrary units)
并使用 FFT 进行傅里叶变换:
yFFT = fftshift(fft(fftshift(y)));
或者,使用 IFFT:
yIFFT = fftshift(ifft(fftshift(y)));
绘制结果:
IFFT 做得很完美:yIFFT 是纯实高斯分布。然而,FFT 产生一个复数:存在非常小的虚部。这很好,因为在傅立叶变换算法中应该会出现错误,而且无论如何都可以忽略不计。令我困惑的是为什么IFFT完全没有错误? FFT 和 IFFT 算法有很大不同吗?
*** 注意:fftshift 和 ifftshift 在这里是等价的,因为我的数组有偶数个元素。
实值时域信号的处理相当普遍。如此之多以至于 ifft
function 具有针对频域中出现的相应对称性的内置处理,如文档的 "Algorithm" 部分所述:
The
ifft
function tests whether the vectors inY
are conjugate symmetric. A vectorv
is conjugate symmetric when the ith element satisfiesv(i) = conj(v([1,end:-1:2]))
. If the vectors inY
are conjugate symmetric, then the inverse transform computation is faster and the output is real.
换句话说,ifft
将 yIFFT
的虚部构造为恰好为 0,因为它检测到您的输入具有共轭对称性。
另一方面,即使是时域信号也相对不太常见,Mathworks 认为没有必要在 fft
function 中执行类似的测试。也就是说,您仍然可以通过使用 ifft
函数通过
% compute fft(x,[],dim) using ifft:
size(x,dim) * conj(ifft(conj(x),[],dim))
您的代码有误:
yFFT = fftshift(fft(fftshift(y)));
应该阅读
yFFT = fftshift(fft(ifftshift(y)));
ifftshift
函数将原点从中间的 bin 移动到最左边的 bin。 fftshift
将原点从最左边的 bin 移到中间。对于 even-sized odd-sized 数组,这两个操作相似但不完全相同。请注意,您的逆变换也遇到同样的问题,但没有显示 SleuthEye 所解释的错误。 [没关系,我想我在那里有点困惑,你的情况应该没有区别。]
此外,
linspace(-nx/2,nx/2-1,nx)
最好写成
-nx/2 : nx/2-1
假设 nx
是偶数。它更短,但它 可能 由于计算方式的原因也有更小的数值误差(可能没有区别,但我尽量避免 linspace
当步长是1.