在Matlab中使用FFT、IFFT和FFTShift

7
我正在尝试实现分裂-傅里叶方法,以解决光学中的非线性薛定谔方程。基本上它将线性部分和非线性部分分开处理。它通过使用傅里叶变换解决线性部分,并在时间域中解决非线性部分。
以下代码来自一本书:
alpha = 0
beta_2 = 1
gamma = 1

T = linspace(-5,5,2^13);
delta_T = T(2)-T(1);

L = max(size(A));
delta_omega = 1/L/delta_T*2*pi;
omega = (-L/2:1:L/2-1)*delta_omega;

A = 2*sech(T);
A_t = A;
step_num = 1000;
h = 0.5*pi/step_num;
results = zeros(L,step_num);

A_f = fftshift(fft(A_t));
for n=1:step_num
    A_f = A_f.*exp(-alpha*(h/2)-1i*beta_2/2*omega.^2*(h/2));
    A_t = ifft(A_f);
    A_t = A_t.*exp(1i*gamma*(abs(A_t).^2*h));
    A_f = fft(A_t);
    A_f = A_f.*exp(-alpha*(h/2)-1i*beta_2/2*omega.^2*(h/2));
    A_t = ifft(A_f);
    results(:,n) = abs(A_t);
end

其中A_t是脉冲(要解决的函数)。我不明白的是,在一开始它使用fftshift将零频率移动到中心,但后来在循环中它没有fftshift。我尝试在主循环中添加fftshift或在一开始删除它。两者都会导致错误的结果,为什么?通常情况下,我应该在什么时候使用fftshiftifftshift,特别是在像这种求解微分方程的情况下?

谢谢


我们需要查看 omega 是什么 - 通常情况下,当您假设频率为零中心时,您需要使用 fftshift 等函数,因为 fftifft 假定输入/输出以零开始。您能否发布一个简短但完整的示例? - Ahmed Fasih
修改了代码。 - Physicist
1个回答

2
您可以通过将信号绘制成图像并注意明显的差异来部分澄清疑惑,就像我尝试相同的那样。
首先,使用fftshift和ifftshift取决于您正在处理的信号类型。
1. fft函数认为您的信号从0开始,与我们通常在信号处理中使用的大多数情况不同。ifft也是如此。
2. 您实际的负面被认为是倒置的并移到极右侧,基本上使您的实际图形从-5到5变为0到10。
3. 这就是我们使用fftshift重新排列数据以将其恢复到以0为中心的地方。
4. 如果要将信号移回无序形式以计算fft或ifft(您应该这样做),则应使用ifftshift。它不是移动ifft。它是fftshift的相反操作。
好的,为了简化事情,请遵循以下switch case-
Switch(Signal): { Case(信号具有负值和正值部分,以零为中心): 将ifftshift应用于fft或ifft之前使其无序 将fftshift应用于结果,以使输出与信号形式相同。
Case(信号已经无序): 直接应用fft或ifft。 如果要以自然类型查看结果,则应用fftshift。
Case(同时应用fft和ifft): 继续,没问题。在执行单个操作时担心信号。 }

1
谢谢,但在我的例子中为什么在开头使用fftshift,而不是在主循环内部使用? - Physicist
这将非常有帮助,如果能提供一些简单的代码示例(原始帖子中的for循环代码并不是很清晰)。例如,case 3仅仅意味着“继续进行没问题”,同时应用fft和ifft 同时又意味着什么? Matlab中的fft()实现和文档都非常糟糕,这真是让人气愤。互联网上充满了关于如何正确使用它的困惑。 - eric

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接