什么是numpy.fft.rfft和numpy.fft.irfft及其在MATLAB中的等效代码

时间:2017-08-20 04:38:51

标签: python matlab numpy fft

我正在将python代码转换为MATLAB,其中一个代码使用numpy rfft。在numpy的文档中,它表示真正的输入。

  

计算一维离散傅立叶变换用于实际输入。

所以我在MATLAB中所做的就是使用abs但结果不同。

Python代码

ffta = np.fft.rfft(a) 

MATLAB代码

ffta = abs(fft(a));

我误解了什么?

1 个答案:

答案 0 :(得分:5)

numpy中的真实FFT使用了这样一个事实:实值函数的傅里叶变换就是说"偏斜对称",即频率k的值是复共轭N-k频率k=1..N-1的值(正确的术语是 Hermitian )。因此rfft仅返回与非正频率相对应的结果部分。

对于大小为N的输入,rfft函数返回与N/2或以下频率对应的FFT输出部分。因此rfft的输出大小为N/2+1,如果N为偶数(0N/2的所有频率),或(N+1)/2 N {1}}是奇数(从0到(N-1)/2的所有频率)。观察到函数floor(n/2+1)为偶数和奇数输入大小返回正确的输出大小。

所以要在matlab中重现rfft

function rfft = rfft(a)
     ffta = fft(a);
     rfft = ffta(1:(floor(length(ffta)/2)+1));
end

例如

a = [1,1,1,1,-1,-1,-1,-1];
rffta = rfft(a)

会产生

rffta =

 Columns 1 through 3:

   0.00000 + 0.00000i   2.00000 - 4.82843i   0.00000 + 0.00000i   

 Columns 4 through 5:

   2.00000 - 0.82843i   0.00000 + 0.00000i

现在将它与python

进行比较
>>> np.fft.rfft(a)
array([ 0.+0.j        ,  2.-4.82842712j,  0.-0.j        ,  
        2.-0.82842712j,  0.+0.j        ])

再现irfft

要重现irfft的基本功能,您需要从rfft输出中恢复丢失的频率。如果所需的输出长度是偶数,则输出长度可以从输入长度计算为2 (m - 1)。否则它应该是2 (m - 1) + 1

以下代码可以使用。

function irfft = irfft(x,even=true)
     n = 0; % the output length
     s = 0; % the variable that will hold the index of the highest
            % frequency below N/2, s = floor((n+1)/2)
     if (even)
        n = 2 * (length(x) - 1 );
        s = length(x) - 1;
     else
        n = 2 * (length(x) - 1 )+1;
        s = length(x);
     endif
     xn = zeros(1,n);
     xn(1:length(x)) = x;
     xn(length(x)+1:n) = conj(x(s:-1:2));
     irfft  = ifft(xn);
end

现在你应该

>> irfft(rfft(a))
ans =

   1.00000   1.00000   1.00000   1.00000  -1.00000  -1.00000  -1.00000  -1.00000

以及

abs( irfft(rfft(a)) - a ) < 1e-15

对于奇数输出长度,你得到

>> irfft(rfft(a(1:7)),even=false)
ans =

   1.0000   1.0000   1.0000   1.0000  -1.0000  -1.0000  -1.0000