实对称矢量的FFT不是真实的和对称的

cra*_*gim 8 matlab signal-processing fft symmetric dft

我很难理解什么应该是一个简单的概念.我在MATLAB中构造了一个真实且对称的向量.当我在MATLAB中进行FFT时,结果具有显着的虚部,即使傅里叶变换的对称规则说实际对称函数的FT也应该是实数和对称的.我的示例代码:

N = 1 + 2^8;
k = linspace(-1,1,N);

V = exp(-abs(k));

Vf1 = fft(fftshift(V));
Vf2 = fft(ifftshift(V));
Vf3 = ifft(fftshift(V));
Vf4 = ifft(ifftshift(V));
Vf5 = fft(V);
Vf6 = ifft(V);

disp([isreal(Vf1) isreal(Vf2) isreal(Vf3) isreal(Vf4) isreal(Vf5) isreal(Vf6)])
Run Code Online (Sandbox Code Playgroud)

结果:

0 0 0 0 0 0
Run Code Online (Sandbox Code Playgroud)

没有真正的对称矢量的组合(i)fft(i)fftshift导致它们.我尝试过偶数和奇数N(N = 2^8对比N = 1+2^8).

我曾尝试寻找k+flip(k)和有秩序的一些残余eps(1),但残差也是对称的,FFT的虚部不出来是模糊的顺序eps(1),而是用大小相媲美的实部.

我错过了什么令人眼花缭乱的明显事物?

我失踪的明显的事情:

FFT不是所有空间的积分,因此它假定为周期性信号.在上面,我复制了我选择偶数期间的最后一点N,因此没有办法将它移动到零开始,而没有小数索引,这是不存在的.

关于我选择的一个词k.这不是任意的.我试图解决的实际问题是生成模型FTIR干涉图,然后我将进行FFT以获得光谱.k是干涉仪行进的距离,它在波数中转换为频率.在实际问题中,将存在各种缩放因子,使得生成函数V将产生物理上有意义的数字.

Lui*_*ndo 9

它的

Vf = fftshift(fft(ifftshift(V)));
Run Code Online (Sandbox Code Playgroud)

也就是说,您需要ifftshift在时域中将样本解释为对称函数的样本,然后fftshift在频域中再次使对称明显.

这只适用于N奇数.对于N偶数,对称函数的概念没有意义:没有办法移动信号使其相对于原点对称(原点需要"在两个样本之间",这是不可能的).

对于您的示例V,上面的代码给出了Vf真实和对称.生成了下图semilogy(Vf),因此可以看到小值和大值.(当然,您可以修改水平轴,使图形以0的频率居中;但无论如何,图形看起来都是对称的.)

在此输入图像描述


Hei*_* M. 6

@Yvon对于对称性的评论是完全正确的.您的输入信号看起来是对称的,但不是因为对称性与原点0相关.在Matlab中使用linspace来构造信号通常是一个糟糕的选择.尝试用fftshift修复结果也是一个坏主意.

改为使用:

k = 2*(0:N-1)/N - 1;
Run Code Online (Sandbox Code Playgroud)

你会得到你期望的结果.然而,变换值的虚部不会完全为零.有一些数字噪音.

>> max(abs(imag(Vf5)))
ans =
2.5535e-15
Run Code Online (Sandbox Code Playgroud)

回答Yvon的问题:

为什么?>> N = 1 + 2 ^ 4 N = 17 >> x = linspace(-1,1,N)x = -1.0000 -0.8750 -0.7500 -0.6250 -0.5000 -0.3750 -0.2500 -0.1250 0 0.1250 0.2500 0.3750 0.5000 0.6250 0.7500 0.8750 1.0000 >> y = 2*(0:N-1)/ N-1 y = -1.0000 -0.8824 -0.7647 -0.6471 -0.5294 -0.4118 -0.2941 -0.1765 -0.0588 0.0588 0.1765 0.2941 0.4118 0.5294 0.6471 0.7647 0.8824 - Yvon 1

您的示例不是对称(偶数)函数,而是反对称(奇数)函数.但是,这没有区别.

对于长度为N的反对称函数,以下陈述为真:

f[i] == -f[-i] == -f[N-i]
Run Code Online (Sandbox Code Playgroud)

索引i从0到N-1.

让我们看看i = 2发生了.请记住,count从0开始,以16结束.

x[2] = -0.75
-x[N-2] == -x[17-2] == -x[15] = (-1) 0.875 = -0.875
x[2] != -x[N-2]

y[2] = -0.7647
-y[N-2] == -y[15] = (-1) 0.7647
y[2] == y[N-2]
Run Code Online (Sandbox Code Playgroud)

问题是,Matlab向量的起源始于1.模数(周期)向量从原点0开始.这种差异导致许多误解.

另一种解释为什么linspace(-1,+ 1,N)不正确的方法:

想象一下,你有一个矢量,它包含一个周期函数的周期,例如一个余弦函数.这个单一时期是无数个时期之一.Cosinus矢量的第一个值不能与矢量的最后一个值相同.然而,这正是linspace(-1,+ 1,N)所做的.这样做会产生一个序列,其中句点1的最后一个值与下一个句点2的第一个样本的值相同.这不是您想要的.为避免这种错误,使用t = 2*(0:N-1)/ N - 1.距离t [i + 1] -t [i]为2/N,最后一个值必须为t [N-1] ] = 1 - 2/N而不是1.

回答Yvon的第二条评论

无论你在DFT/FFT的输入矢量中放置什么,理论上它都被解释为周期函数.但这不是重点.

DFT执行集成.

fft(m) = Sum_(k=0)^(N-1) (x(k) exp(-i 2 pi m k/N )
Run Code Online (Sandbox Code Playgroud)

第一值x(k = 0)描述长度为1/N的第一积分区间的幅度.第二值x(k = 1)描述长度为1/N的第二积分区间的幅度.等等.

对称函数的最后一个积分区间与第一个样本相同的值结束.这意味着,最后一个积分区间的起点是k = N-1 = 1-1/N. 输入向量保存积分间隔的起始点.

因此,最后一个对称点k = N是函数的一个点,但它不是积分区间的起点,因此它不是输入向量的成员.