我将一段Python代码转换为MATLAB,其中一段代码使用了numpy rfft。在numpy的文档中,它指出输入是实数。
计算实数输入的一维离散傅里叶变换。
因此,在MATLAB中,我使用了abs函数,但结果不同。
Python代码:
ffta = np.fft.rfft(a)
MATLAB 代码
ffta = abs(fft(a));
我理解有误了吗?
k
的值是频率为N-k
的值的复共轭,其中k=1..N-1
(正确的术语是厄米)。因此,rfft
仅返回与非正频率对应的结果部分。N
的输入,rfft
函数返回与频率在或低于N/2
处的FFT输出相对应的部分。因此,如果N
是偶数(从0
到N/2
的所有频率),rfft
的输出大小为N/2+1
,如果N
是奇数(从0
到(N-1)/2
的所有频率),rfft
的输出大小为(N+1)/2
。请注意,函数floor(n/2+1)
对于偶数和奇数输入大小都返回正确的输出大小。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
>>> 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 out = irfft(x, even)
if nargin == 1
even = true;
end
% `n`: the output length
% `s`: the variable that will hold the index of the highest
% frequency below N/2, s = floor((n+1)/2)
N = numel(x); % function assumes 1D input
if even
n = 2 * (N - 1);
s = N - 1;
else
n = 2 * (N - 1) + 1;
s = N;
end
outf = zeros(1, n);
outf(1:N) = x;
outf(N+1:n) = conj(x(s:-1:2));
out = ifft(outf);
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
function irfft = irfft(a)
iffta = ifft(a);
irfft = iffta(1:(2*(length(iffta)-1)));
end
- iHateUni@iHateUni irfft(rfft(a))
应该等于a
。因此,abs(x-y) < 1e-15
意味着使用双精度浮点数时,x
几乎等于y
,只是存在一些累积的舍入误差。 - Dima Chubarovrfft = ffta(1:(((length(ffta)+1)/2));
:) - iHateUnifloor(n/2)+1
等于n/2+1
,对于奇数而言,等于(n+1)/2
,因此我们上面的代码应该可以直接使用,无需更改。 - Dima Chubarov