我正在测试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在这里是等价的,因为我的数组有偶数个元素。
答案 0 :(得分:5)
处理实值时域信号是一种相当普遍的现象。因此ifft
function具有对频域中出现的相应对称性的内置处理,如"算法"文档部分:
ifft
函数测试Y
中的向量是否是共轭对称的。当i th 元素满足v
时,向量v(i) = conj(v([1,end:-1:2]))
是共轭对称的。如果Y
中的向量是共轭对称的,则逆变换计算更快,输出是真实的。
换句话说,ifft
构造yIFFT
的虚部正好为0,因为它检测到您的输入具有共轭对称性。
另一方面,即使时域信号相对不太常见,Mathworks也不认为有必要在fft
function中执行类似的测试。也就是说,您仍然可以通过使用ifft
函数计算FFT来利用共轭对称性测试
% compute fft(x,[],dim) using ifft:
size(x,dim) * conj(ifft(conj(x),[],dim))
答案 1 :(得分:1)
您的代码中存在错误:
yFFT = fftshift(fft(fftshift(y)));
应该阅读
yFFT = fftshift(fft(ifftshift(y)));
ifftshift
功能将原点从中间移动到最左边的bin。 fftshift
将原点从最左边的bin移动到中间。对于偶数大小的奇数大小的数组,这两个操作类似但不相同。请注意,您的逆变换会遇到相同的问题,但没有出现错误,如SleuthEye所述。 [别介意,我觉得我有点困惑,你的情况应该没有区别。]
此外,
linspace(-nx/2,nx/2-1,nx)
会更好地写成
-nx/2 : nx/2-1
鉴于nx
是偶数。它更短,但由于计算事物的方式, 也会有更小的数值误差(可能没有区别,但我尽量避免linspace
当步长为1时。