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

iHa*_*Uni 3 python matlab numpy fft

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

计算一维离散傅里叶变换以获得实际输入。

所以我在MATLAB中所做的是使用Abs,但结果却有所不同。

Python代码

ffta = np.fft.rfft(a) 
Run Code Online (Sandbox Code Playgroud)

MATLAB代码

ffta = abs(fft(a));
Run Code Online (Sandbox Code Playgroud)

我误会了什么?

Dmi*_*rov 7

在numpy的用途实FFT的事实,傅里叶变换实值函数是如此说“斜对称”,即是在频率值k是在频度的值的复共轭N-kk=1..N-1(正确的术语是厄密共轭) 。因此,rfft仅返回结果中与非正频率相对应的部分。

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

所以要rfft在matlab中重现

function rfft = rfft(a)
     ffta = fft(a);
     rfft = ffta(1:(floor(length(ffta)/2)+1));
end
Run Code Online (Sandbox Code Playgroud)

例如

a = [1,1,1,1,-1,-1,-1,-1];
rffta = rfft(a)
Run Code Online (Sandbox Code Playgroud)

会产生

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
Run Code Online (Sandbox Code Playgroud)

现在将其与python进行比较

>>> np.fft.rfft(a)
array([ 0.+0.j        ,  2.-4.82842712j,  0.-0.j        ,  
        2.-0.82842712j,  0.+0.j        ])
Run Code Online (Sandbox Code Playgroud)

复制irfft

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

以下代码将起作用。

function rfft = rfft(a)
     ffta = fft(a);
     rfft = ffta(1:(floor(length(ffta)/2)+1));
end
Run Code Online (Sandbox Code Playgroud)

现在你应该有

>> irfft(rfft(a))
ans =

   1.00000   1.00000   1.00000   1.00000  -1.00000  -1.00000  -1.00000  -1.00000
Run Code Online (Sandbox Code Playgroud)

并且

abs( irfft(rfft(a)) - a ) < 1e-15
Run Code Online (Sandbox Code Playgroud)

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

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

   1.0000   1.0000   1.0000   1.0000  -1.0000  -1.0000  -1.0000
Run Code Online (Sandbox Code Playgroud)