【问题标题】:Why does zero padding in Fourier domain lead to an inverse transform which is complex?为什么傅里叶域中的零填充会导致复杂的逆变换?
【发布时间】:2017-10-16 12:22:31
【问题描述】:

如果我从一个只有实数值的信号开始,执行 fft 和 ifft 会返回准确的信号,没有预期的复杂条目。但是,如果我用零填充 fft 以获得时域中的插值,则反 fft 总是结果是复数。我已经注意执行 fftshift() 然后在两侧填充,以免破坏对称性。以下是显示此行为的示例代码。我是不是看错了,还是零填充后的计算错误有点太多了?我该如何克服这个问题?

代码:

%%%%%%%%%

x=linspace(0,2*pi,200);

y = sin(x)+sin(2*x);

Y = fftshift(fft(y));

n=400;

x1 = linspace(0,2*pi,n);

Y1 = zeros(1,n);

Y1((n-200)/2+1:end-(n-200)/2) = Y;

y2 = ifft(fftshift(2*Y1));

plot(x,y);

hold on;

plot(x1,y2(1:end),'x-');

isreal(y)==isreal(y2)

%%

【问题讨论】:

  • 注意:Y2 没有定义,为什么最后和Y2比较,我猜应该是y2
  • 为了比较,有一个 FEX 提交,您可以在其中看到它是如何编码的:Frequency-domain-zero-padding
  • 我的错,这是一个错字,应该是 y2,但这不是问题
  • @Irreducible,我检查了该页面上的代码。它做完全相同的事情。只是,在返回之前的最后,只考虑真实的部分。但是,忽略虚部,只会改变信号。我说的对吗?

标签: matlab signal-processing fft interpolation ifft


【解决方案1】:

可能是一个错误,或者没有忽略微观舍入误差值。为了使 IFFT 的结果是严格实数(除了微小的数值噪声量),复数输入向量必须围绕元素 0 完全共轭对称(或者对于偶数 N,在 N/2 附近)。

【讨论】:

    【解决方案2】:

    您的代码有几个小问题:

    1. 原始信号的样本数及其 FFT 应该是奇数。要了解原因,请注意 FFT 的第一个条目是零频率分量,它没有对称频率。 剩余的个频率应该是偶数,这样它们就可以分成两个对称的部分,并且可以在两个部分之间插入额外的零。

    2. 不应使用linspace 创建时间轴。由于linspace 修复了两个 端点,因此您无法获得2 的精确比例因子。为此,您需要使用 : (colon) 手动创建轴。

    3. 第二个fftshift 应该是ifftshift。这在这里并不重要,因为零填充 FFT 的大小是均匀的,所以 fftshiftifftshift 重合。但作为一般规则,您应该使用ifftshift 撤消fftshift 的操作。

    所以,代码变成:

    x = (0:200)/201*2*pi;
    y = sin(x)+sin(2*x);
    Y = fftshift(fft(y));
    x1 = (0:401)/402*2*pi;
    Y1 = [zeros(1,101) Y zeros(1,100)];
    y2 = ifft(ifftshift(2*Y1)); % or fftshift, since length is even
    plot(x,y,'o-');
    hold on;
    plot(x1,y2,'.:');
    isreal(y)==isreal(y2)
    max(abs(y-y2(1:2:end))) % should be of the order of eps
    

    现在我们可以检查了

    • 两个信号都是真实的:

      >> isreal(y)==isreal(y2)
      ans =
        logical
         1
      

      更好的测试是检查y1 的虚部(由于数值精度问题可能不完全为零)是eps 的数量级。

    • y1 的每个其他样本都与y 中的相应样本重合,最多为eps 数量级的数值错误:

      >> max(abs(y-y2(1:2:end)))
      ans =
           6.661338147750939e-16
      

    【讨论】:

    • 只是一个小修正;反 FFT 的长度不必为奇数,共轭对称也能产生实数输出。要求只是 Y(2:end) == conj(Y(end:-1:2))。这意味着条目 n/2 是真实的。以A = rand(3,1) + 1j*rand(3,1); Y = [10; A; 4; conj(flip(A))]; ifft(Y) 为例。这里的长度是偶数,但结果是真实的。
    • @CKT 我的意思是长度必须是奇数如果我们希望能够用零填充。如果是偶数,则归一化频率 pi rad/s 的分量必须“一分为二”以容纳两者之间的零点
    猜你喜欢
    • 1970-01-01
    • 2016-02-28
    • 1970-01-01
    • 2019-03-05
    • 2017-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多