numpy 中的实数 FFT 使用实值函数的傅立叶变换可以说是“斜对称”的事实,即频率值k
是频率值的复共轭N-k
for k=1..N-1
(正确的术语是厄米特)。所以rfft
仅返回结果中与非正频率相对应的部分。
对于大小的输入N
the rfft
函数返回对应于等于或低于频率的 FFT 输出部分N/2
。因此输出为rfft
是有尺寸的N/2+1
if N
是偶数(所有频率来自0
to N/2
), or (N+1)/2
if N
是奇数(从 0 到(N-1)/2
)。观察函数floor(n/2+1)
返回偶数和奇数输入大小的正确输出大小。
所以要重现rfft
在Matlab中
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 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
and also
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