我正在将python代码转换为MATLAB,其中一个代码使用numpy rfft。在numpy的文档中,它表示真正的输入。
计算一维离散傅立叶变换用于实际输入。
所以我在MATLAB中所做的就是使用abs但结果不同。
Python代码
ffta = np.fft.rfft(a)
MATLAB代码
ffta = abs(fft(a));
我误解了什么?
答案 0 :(得分:5)
numpy中的真实FFT使用了这样一个事实:实值函数的傅里叶变换就是说"偏斜对称",即频率k
的值是复共轭N-k
频率k=1..N-1
的值(正确的术语是 Hermitian )。因此rfft
仅返回与非正频率相对应的结果部分。
对于大小为N
的输入,rfft
函数返回与N/2
或以下频率对应的FFT输出部分。因此rfft
的输出大小为N/2+1
,如果N
为偶数(0
至N/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
的基本功能,您需要从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