Hermitian FFT 如何在 Numpy 中工作?

信息处理 fft 离散信号 傅里叶变换 Python
2022-02-19 09:49:27

说,我创建了一个 Hermitian 复数信号,使用

import numpy as np
t = np.arange(-4, 4)
z = np.exp(1j * t)

z应该是一个具有 Hermitian 对称性的复杂信号,如下所示。

In [2]: t
Out[2]: array([-4, -3, -2, -1,  0,  1,  2,  3])

In [3]: z
Out[3]:
array([-0.65364362+0.7568025j , -0.98999250-0.14112001j,
       -0.41614684-0.90929743j,  0.54030231-0.84147098j,
        1.00000000+0.j        ,  0.54030231+0.84147098j,
       -0.41614684+0.90929743j, -0.98999250+0.14112001j])

但是当我对这个信号进行傅里叶变换时,我没有得到真正的频谱,

In [8]: np.fft.fft(z)
Out[8]:
array([-1.38531768+0.7568025j, -7.02599565+0.7568025j,
        2.57935201+0.7568025j,  0.93952139+0.7568025j,
        0.41344309+0.7568025j,  0.08151870+0.7568025j,
       -0.22205190+0.7568025j, -0.60961892+0.7568025j])

但是,当我使用该hfft函数进行 Hermitian FFT 时,我得到

In [10]: np.fft.hfft(z[:5])
Out[10]:
array([-1.38531768, -7.02599565,  2.57935201,  0.93952139,  0.41344309,
        0.0815187 , -0.2220519 , -0.60961892])

这是我使用常规fft函数得到的结果的真正组成部分。我不明白我在这里做错了什么。当输入是 Hermitian 时,不fft应该给出一个虚部为零或几乎为零的结果吗?

我觉得我在这里做错了关于如何将信号呈现给fft.

1个回答

您正面临在Matlab、Octave 或 Python 等程序中表示非因果信号的实际问题。这些程序在默认情况下假定所有表示的序列都从时间索引开始。n=0

因此,开始于并结束于的 Hermitian 对称序列( for all )在这些程序中解释时将失去这种对称性。对于您的特定示例,效果是信号向右移动4x[n]=x[n]nn=4n=44

因此,您计算的不是原始对称序列的 FFT ,而是移位的非对称序列使用 DTFT / DFT 时移属性,我们可以看到实际计算为: x[n]=ejnw[n]=x[n4]

(1)W(ejω)=ej4ωX(ejω)
(2)W[k]=ej42πNkX[k]     ,   for    k=0,1,...,N1

其中是序列及其 DFT的长度。Nx[n]X[k]

的 DTFT / DFT具有零虚部,正如 Hermitian 对称信号所具有的那样,实际计算的具有非零虚部。x[n]W[k]

如果您愿意,您可以从计算中获得所需的的非零相位样本,如下所示:X[k]x[n]W[k]w[n]

(3)X[k]=ej42πNkW[k]    ,   for k=0,1,...,N1

以下 MATLAB 代码演示了该问题:

% Demonstrates the Hermitian symmetry and its handling in Matlab/Octave/Python
% environments...

a = -4;
b = +4;
n = [a:b];
x = exp(1j*n);      % Samples of Hermitian symmetrix input: x[k] = x[-k]*

figure,stem( imag( exp(-1j*2*pi*a*[0:(b-a)]/(b-a+1)).*fft(x) ));

输出是:

在此处输入图像描述